diff --git a/ir_builders/build_callgraph.cpp b/ir_builders/build_callgraph.cpp
index 2542a41799296c1bfb9b606332f167905391c4cd..a0ca36f7209ae516387bcc5893e81674ac06714b 100644
--- a/ir_builders/build_callgraph.cpp
+++ b/ir_builders/build_callgraph.cpp
@@ -20,8 +20,8 @@
 
 
 
-#include <libIRDB-core.hpp>
-#include <libIRDB-cfg.hpp>
+#include <irdb=-sdk>
+#include <irdb-cfg>
 #include <utils.hpp> // to_string function from libIRDB
 #include <iostream>
 #include <fstream>
@@ -29,7 +29,6 @@
 #include <string.h>
 #include <assert.h>
 
-using namespace libIRDB;
 using namespace std;
 
 //
@@ -62,7 +61,7 @@ main(int argc, char* argv[])
 		varidp=new VariantID_t(atoi(argv[1]));
 
 		// A callgraph 
-		Callgraph_t *cg=new Callgraph_t;
+		auto cg=Callgraph_t::factory();
 
 		assert(varidp->IsRegistered()==true);
 
diff --git a/ir_builders/check_thunks.cpp b/ir_builders/check_thunks.cpp
index dd3052250e7cedf3b631dd6ab244fd3576059cea..1c0dfa54c14fa092e4774cf26e64f00d93b23249 100644
--- a/ir_builders/check_thunks.cpp
+++ b/ir_builders/check_thunks.cpp
@@ -24,7 +24,6 @@
 
 
 #include <irdb-core>
-#include <libIRDB-cfg.hpp>
 #include <utils.hpp>
 #include <iostream>
 #include <stdlib.h>
diff --git a/ir_builders/find_strings.cpp b/ir_builders/find_strings.cpp
index a91071a648113177c306da94e5955057ada7a0ce..e1f7146d093f6f81d99ae6a029d99e919fef350b 100644
--- a/ir_builders/find_strings.cpp
+++ b/ir_builders/find_strings.cpp
@@ -21,7 +21,7 @@
 
 
 #include <libIRDB-core.hpp>
-#include <libIRDB-cfg.hpp>
+#include <irdb-cfg.hpp>
 #include <iostream>
 #include <stdlib.h>
 #include <cctype>
diff --git a/ir_builders/fix_calls.cpp b/ir_builders/fix_calls.cpp
index 9ef6496b41304e7afdf51eaf9bd8c9ec38908db3..5959be0ca1de48f56ff8cc9d55a35d3e68846514 100644
--- a/ir_builders/fix_calls.cpp
+++ b/ir_builders/fix_calls.cpp
@@ -20,7 +20,7 @@
 
 
 #include <irdb-core>
-#include <libIRDB-cfg.hpp>
+#include <irdb-cfg>
 #include <utils.hpp>
 #include <iostream>
 #include <stdlib.h>
@@ -95,13 +95,13 @@ size_t not_calls=0;
 bool opt_fix_icalls = false;
 bool opt_fix_safefn = true;
 
-bool check_entry(bool &found, libIRDB::ControlFlowGraph_t* cfg)
+bool check_entry(bool &found, ControlFlowGraph_t* cfg)
 {
 
-	auto entry=cfg->GetEntry();
+	auto entry=cfg->getEntry();
 	found=false;
 
-	for(auto insn : entry->GetInstructions())
+	for(auto insn : entry->getInstructions())
 	{
 		auto disasmp = DecodedInstruction_t::factory(insn);
 		auto &disasm = *disasmp;
@@ -136,7 +136,7 @@ bool check_entry(bool &found, libIRDB::ControlFlowGraph_t* cfg)
 	return false;
 }
 
-using ControlFlowGraphMap_t = map<Function_t*, libIRDB::ControlFlowGraph_t*>;
+using ControlFlowGraphMap_t = map<Function_t*, shared_ptr<ControlFlowGraph_t> >;
 ControlFlowGraphMap_t cfg_optimizer;
 
 bool call_needs_fix(Instruction_t* insn)
@@ -242,16 +242,16 @@ bool call_needs_fix(Instruction_t* insn)
 
 	if(!is_found)
 		/* build a cfg for this function */
-		cfg_optimizer[func]=new libIRDB::ControlFlowGraph_t(func);
+		cfg_optimizer[func]=shared_ptr<ControlFlowGraph_t>(move(ControlFlowGraph_t::factory(func)));
 
-	auto cfg=cfg_optimizer[func];
+	auto cfg=cfg_optimizer[func].get();
 	
 
 
-	assert(cfg->GetEntry());
+	assert(cfg->getEntry());
 	
 	/* if the call instruction isn't to a function entry point */
-	if(cfg->GetEntry()->GetInstructions()[0]!=target)
+	if(cfg->getEntry()->getInstructions()[0]!=target)
 	{
 		call_to_not_entry++;
 		/* then we need to fix it */
diff --git a/ir_builders/read_ehframe.cpp b/ir_builders/read_ehframe.cpp
index 1ea7a13a37a3317a662db51d60a85318e63f35c6..1cf13f499735b89de30cd4bb9da72d5b41cfc2db 100644
--- a/ir_builders/read_ehframe.cpp
+++ b/ir_builders/read_ehframe.cpp
@@ -23,7 +23,6 @@
 
 
 #include <irdb-core>
-#include <libIRDB-cfg.hpp>
 #include <utils.hpp>
 #include <iostream>
 #include <stdlib.h>
diff --git a/libIRDB/include/bea_deprecated.hpp b/libIRDB/include/bea_deprecated.hpp
deleted file mode 100644
index 6868f1cd1118fe8b01c7c972a49f5191157192cd..0000000000000000000000000000000000000000
--- a/libIRDB/include/bea_deprecated.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef bea_deprecated_h
-#define bea_deprecated_h
-
-
-#include <libIRDB-core.hpp>
-#include <beaengine/BeaEngine.h>
-
-
-static inline int Disassemble(const libIRDB::Instruction_t* const insn, DISASM &disasm)
-{
-	assert(insn);
-        memset(&disasm, 0, sizeof(DISASM));
-        disasm.Options = NasmSyntax + PrefixedNumeral;
-        disasm.Archi = libIRDB::FileIR_t::GetArchitectureBitWidth();
-        disasm.EIP = (UIntPtr) insn->GetDataBits().c_str();
-        disasm.VirtualAddr = insn->GetAddress()->GetVirtualOffset();
-        int instr_len = Disasm(&disasm);
-        return instr_len;  
-} 
-
-static inline bool SetsStackPointer(const ARGTYPE* arg)
-{
-        if((arg->AccessMode & WRITE ) == 0)
-                return false;
-        int access_type=arg->ArgType;
-
-        if(access_type==REGISTER_TYPE + GENERAL_REG +REG4)
-                return true;
-        return false;
-        
-}
-
-static inline bool SetsStackPointer(const DISASM* disasm)
-{
-        if(strstr(disasm->Instruction.Mnemonic, "push")!=NULL)
-                return true;
-        if(strstr(disasm->Instruction.Mnemonic, "pop")!=NULL)
-                return true;
-        if(strstr(disasm->Instruction.Mnemonic, "call")!=NULL)
-                return true;
-        if(disasm->Instruction.ImplicitModifiedRegs==REGISTER_TYPE+GENERAL_REG+REG4)
-                return true;
-
-        if(SetsStackPointer(&disasm->Argument1)) return true;
-        if(SetsStackPointer(&disasm->Argument2)) return true;
-        if(SetsStackPointer(&disasm->Argument3)) return true;
-
-        return false;
-
-}
-
-#endif
diff --git a/libIRDB/include/cfg/BasicBlock.hpp b/libIRDB/include/cfg/BasicBlock.hpp
index 3abf761d6162e1bbe028c9acade6f438fa4d4497..d2059b22eca8bf27a7df1c8991de15116ede1822 100644
--- a/libIRDB/include/cfg/BasicBlock.hpp
+++ b/libIRDB/include/cfg/BasicBlock.hpp
@@ -19,56 +19,57 @@
  */
 
 
-class BasicBlock_t;
-typedef std::set<BasicBlock_t*> BasicBlockSet_t;
-typedef std::vector<IRDB_SDK::Instruction_t*> InstructionVector_t;
-
-class BasicBlock_t
+namespace libIRDB
 {
+	using namespace std;
+
+	class BasicBlock_t : public IRDB_SDK::BasicBlock_t
+	{
 
-	public:
-		BasicBlock_t();
+		public:
+			BasicBlock_t();
+			virtual ~BasicBlock_t() { }
 
-		bool GetIsExitBlock() { return is_exit_block; }
-		void SetIsExitBlock(bool is_exit) { is_exit_block=is_exit; }
+			bool getIsExitBlock() const { return is_exit_block; }
+			void setIsExitBlock(bool is_exit) { is_exit_block=is_exit; }
 
-		InstructionVector_t& GetInstructions() { return instructions; }
-		BasicBlockSet_t&     GetPredecessors() { return predecessors; }
-		BasicBlockSet_t&     GetSuccessors()   { return successors; }
-		BasicBlockSet_t&     GetIndirectTargets() { return indirect_targets; }
-		BasicBlock_t* GetFallthrough();
-		BasicBlock_t* getTarget();
+			IRDB_SDK::InstructionVector_t& GetInstructions() { return instructions; }
+			IRDB_SDK::BasicBlockSet_t&     GetPredecessors() { return predecessors; }
+			IRDB_SDK::BasicBlockSet_t&     GetSuccessors()   { return successors; }
+			IRDB_SDK::BasicBlockSet_t&     GetIndirectTargets() { return indirect_targets; }
 
-		// for const correctness if you aren't modifying.
-		const InstructionVector_t& GetInstructions() const { return instructions; }
-		const BasicBlockSet_t&     GetPredecessors() const { return predecessors; }
-		const BasicBlockSet_t&     GetSuccessors()   const { return successors; }
-		const BasicBlockSet_t&     GetIndirectTargets() const { return indirect_targets; }
+			// for const correctness if you aren't modifying.
+			const IRDB_SDK::InstructionVector_t& getInstructions()    const { return instructions; }
+			const IRDB_SDK::BasicBlockSet_t&     getPredecessors()    const { return predecessors; }
+			const IRDB_SDK::BasicBlockSet_t&     getSuccessors()      const { return successors; }
+			const IRDB_SDK::BasicBlockSet_t&     getIndirectTargets() const { return indirect_targets; }
+//			      IRDB_SDK::BasicBlock_t   *     getFallthrough()     const ;
+//			      IRDB_SDK::BasicBlock_t   *     getTarget()          const ;
 
-		bool EndsInBranch();
-		bool EndsInIndirectBranch();
-		bool EndsInConditionalBranch();
-		IRDB_SDK::Instruction_t* GetBranchInstruction();
-		void dump(std::ostream &os=std::cout) const { os<<*this; }
+			bool endsInBranch() const;
+			bool endsInIndirectBranch() const;
+			bool endsInConditionalBranch() const;
+			IRDB_SDK::Instruction_t* getBranchInstruction() const;
+			void dump(ostream &os=cout) const ; 
 
-	protected:
+		protected:
 
-		void BuildBlock( IRDB_SDK::Instruction_t* insn,
-                		const std::map<IRDB_SDK::Instruction_t*,BasicBlock_t*> &insn2block_map
-        			);
+			void BuildBlock( IRDB_SDK::Instruction_t* insn,
+					const map<IRDB_SDK::Instruction_t*,BasicBlock_t*> &insn2block_map
+					);
 
 
-	private:
+		private:
 
-		InstructionVector_t instructions;
-		BasicBlockSet_t  predecessors;
-		BasicBlockSet_t  successors;
-		BasicBlockSet_t  indirect_targets;
-		bool is_exit_block;
+			IRDB_SDK::InstructionVector_t instructions;
+			IRDB_SDK::BasicBlockSet_t  predecessors;
+			IRDB_SDK::BasicBlockSet_t  successors;
+			IRDB_SDK::BasicBlockSet_t  indirect_targets;
+			bool is_exit_block;
 
-	friend std::ostream& operator<<(std::ostream& os, const BasicBlock_t& block);
-	friend class ControlFlowGraph_t;
-};
+		friend ostream& operator<<(ostream& os, const BasicBlock_t& block);
+		friend class ControlFlowGraph_t;
+	};
 
-std::ostream& operator<<(std::ostream& os, const BasicBlock_t& block);
 
+}
diff --git a/libIRDB/include/cfg/CFG.hpp b/libIRDB/include/cfg/CFG.hpp
index f254fe734395dc21a0bda6f1147da62cd3fbd95c..2499b994eea66f87fe85f49cd85dffaaa056489e 100644
--- a/libIRDB/include/cfg/CFG.hpp
+++ b/libIRDB/include/cfg/CFG.hpp
@@ -18,39 +18,35 @@
  *
  */
 
-enum CFG_EdgeTypeEnum { CFG_FallthroughEdge, CFG_TargetEdge, CFG_IndirectEdge };
-typedef std::set<CFG_EdgeTypeEnum> CFG_EdgeType;
-
-class ControlFlowGraph_t
+namespace libIRDB
 {
-	public:
-		ControlFlowGraph_t(IRDB_SDK::Function_t* func);
-		BasicBlock_t* GetEntry() const { return entry; }
-		IRDB_SDK::Function_t* getFunction() const { return function; }
-		BasicBlockSet_t& GetBlocks()   { return blocks; }
-		const BasicBlockSet_t& GetBlocks()   const { return blocks; }
-		void dump(std::ostream &os=std::cout) const { os<<*this; }
-		bool HasEdge(BasicBlock_t *p_src, BasicBlock_t *p_tgt) const;
-		CFG_EdgeType GetEdgeType(const BasicBlock_t *p_src, const BasicBlock_t *p_tgt) const;
-
-	private:
-	// methods 
-		void Build(IRDB_SDK::Function_t *func);
-		void alloc_blocks(const IRDB_SDK::InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map);
-		void build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map);
-		void find_unblocked_instructions(InstructionSet_t &starts, IRDB_SDK::Function_t* func);
-
-	// data
-		BasicBlockSet_t blocks;
-		BasicBlock_t* entry;
-		IRDB_SDK::Function_t* function;
-
-	/* friends */
-	public:
-		friend std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg);
-};
-
-
-std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg);
-
-
+	using namespace std;
+
+	class ControlFlowGraph_t : public IRDB_SDK::ControlFlowGraph_t
+	{
+		public:
+			ControlFlowGraph_t(IRDB_SDK::Function_t* func);
+			virtual ~ControlFlowGraph_t() { }
+			IRDB_SDK::BasicBlock_t* getEntry() const { return entry; }
+			IRDB_SDK::Function_t* getFunction() const { return function; }
+			IRDB_SDK::BasicBlockSet_t& GetBlocks()   { return blocks; }
+			const IRDB_SDK::BasicBlockSet_t& getBlocks()   const { return blocks; }
+			void dump(ostream &os=cout) const; 
+			bool hasEdge(IRDB_SDK::BasicBlock_t *p_src, IRDB_SDK::BasicBlock_t *p_tgt) const;
+			IRDB_SDK::CFGEdgeType_t getEdgeType(const IRDB_SDK::BasicBlock_t *p_src, const IRDB_SDK::BasicBlock_t *p_tgt) const;
+
+		private:
+		// methods 
+			void Build(IRDB_SDK::Function_t *func);
+			void alloc_blocks(const IRDB_SDK::InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map);
+			void build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map);
+			void find_unblocked_instructions(InstructionSet_t &starts, IRDB_SDK::Function_t* func);
+
+		// data
+			IRDB_SDK::BasicBlockSet_t blocks;
+			IRDB_SDK::BasicBlock_t* entry;
+			IRDB_SDK::Function_t* function;
+
+	};
+
+}
diff --git a/libIRDB/include/cfg/callgraph.hpp b/libIRDB/include/cfg/callgraph.hpp
index f60221c7ce03f0e7708f18eaa3376de3fb99a801..bc5f383923e2e686c9c08325aa175a7b008db8b4 100644
--- a/libIRDB/include/cfg/callgraph.hpp
+++ b/libIRDB/include/cfg/callgraph.hpp
@@ -21,138 +21,169 @@
 #ifndef irdb_cfg_callgraph_h
 #define irdb_cfg_callgraph_h
 
-// only one type of hell node for now, but leave
-// open the possibilty for multiple hell nodes
-typedef enum { DEFAULT_HELL_NODE = 0 } HellNodeType; 
-
-class CallGraphNode_t
+namespace libIRDB
 {
-	public:
-		CallGraphNode_t(IRDB_SDK::Function_t* f = NULL) {
-			if (f) {
-				SetFunction(f);
-			} else {
-				m_isHellNode = true;
-				m_node.hellNodeType = DEFAULT_HELL_NODE;
+
+	using namespace std;
+
+	// only one type of hell node for now, but leave
+	// open the possibilty for multiple hell nodes
+	typedef enum { DEFAULT_HELL_NODE = 0 } HellNodeType; 
+
+	class CallGraphNode_t : public IRDB_SDK::CallGraphNode_t
+	{
+		public:
+			virtual ~CallGraphNode_t(){ }
+			CallGraphNode_t(IRDB_SDK::Function_t* f = NULL) {
+				if (f) {
+					SetFunction(f);
+				} else {
+					m_isHellNode = true;
+					m_node.hellNodeType = DEFAULT_HELL_NODE;
+				}
 			}
-		}
-
-		bool IsHellnode() const { return m_isHellNode; }
-
-		IRDB_SDK::Function_t* getFunction() const {
-			assert(!m_isHellNode);
-			if (m_isHellNode) 
-				return NULL;					
-			else
-				return m_node.func;
-		}
-
-		HellNodeType GetHellNodeType() const {
-			assert(m_isHellNode);
-			return m_node.hellNodeType;
-		}
-
-		bool operator==(const CallGraphNode_t &other) const {
-			if (this == &other) return true;
-			if (m_isHellNode)
-			{
-				return m_node.hellNodeType == other.m_node.hellNodeType;
+
+			bool isHellnode() const { return m_isHellNode; }
+
+			IRDB_SDK::Function_t* getFunction() const {
+				assert(!m_isHellNode);
+				if (m_isHellNode) 
+					return NULL;					
+				else
+					return m_node.func;
 			}
-			else
-				return m_node.func == other.m_node.func;
-		}
-
-	private:
-		void SetFunction(IRDB_SDK::Function_t* const f) {
-			assert(f);
-			m_node.func = f;
-			m_isHellNode = false;
-		}
-
-	private:
-		bool m_isHellNode;
-		union {
-			IRDB_SDK::Function_t* func;
-			HellNodeType hellNodeType;
-		} m_node;
-};
-
-typedef std::pair<CallGraphNode_t*,CallGraphNode_t*> CallGraphEdge_t;
-typedef std::set<CallGraphNode_t*> CallGraphNodeSet_t;
-typedef IRDB_SDK::Instruction_t* CallSite_t;
-typedef std::set<CallSite_t> CallSiteSet_t;
-
-class Callgraph_t
-{
-	public:
-		Callgraph_t();
-		virtual ~Callgraph_t();
-		void AddFile(IRDB_SDK::FileIR_t* const firp);
-
-		bool EdgeExists(const CallGraphEdge_t& edge)
-		{
-			CallGraphNode_t *from=edge.first;
-			CallGraphNode_t *to=edge.second;
-				
-			const CallGraphNodeSet_t& calleeSet = callers[from];
-			return calleeSet.find(to)!=calleeSet.end();
-		}
-		bool EdgeExists(CallGraphNode_t& n1, CallGraphNode_t& n2) 
-			{ return EdgeExists(CallGraphEdge_t(&n1,&n2));}
-
-		CallGraphNodeSet_t& GetCallersOfNode(CallGraphNode_t* const node)
-			{ return callers[node]; }
-		CallGraphNodeSet_t& GetCalleesOfNode(CallGraphNode_t* const node)
-			{ return callees[node]; }
-		
-		void GetAncestors(IRDB_SDK::Function_t* const fn, CallGraphNodeSet_t& ancestors, bool skipHellNode = false);
-		void GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t& ancestors, bool skipHellNode = false);
-
-		CallSiteSet_t& GetCallSites(CallGraphNode_t* const n1)
-			{ return call_sites[n1]; }
-
-		void Dump(std::ostream& fout);
-
-		std::string GetNodeName(const CallGraphNode_t* const n1) const {
-			assert(n1);
-			if (n1->IsHellnode()) {
-				std::ostringstream s;
-				s << "HELLNODE" << n1->GetHellNodeType();
-				return s.str();
-			} else {
-				assert(n1->getFunction());
-				return n1->getFunction()->getName(); 
+
+			HellNodeType GetHellNodeType() const {
+				assert(m_isHellNode);
+				return m_node.hellNodeType;
+			}
+
+			bool operator==(const CallGraphNode_t &other) const {
+				if (this == &other) return true;
+				if (m_isHellNode)
+				{
+					return m_node.hellNodeType == other.m_node.hellNodeType;
+				}
+				else
+					return m_node.func == other.m_node.func;
+			}
+			void dump(ostream& os=cout) const;
+
+		private:
+			void SetFunction(IRDB_SDK::Function_t* const f) {
+				assert(f);
+				m_node.func = f;
+				m_isHellNode = false;
 			}
-		}
 
-		std::string GetCallsiteDisassembly(const CallSite_t &c) const
-			{ return c ? c->getDisassembly() : "NOFROMFUNC"; } 
+		private:
+			bool m_isHellNode;
+			union {
+				IRDB_SDK::Function_t* func;
+				HellNodeType hellNodeType;
+			} m_node;
+	};
+
+
+	class Callgraph_t : public IRDB_SDK::CallGraph_t
+	{
+		public:
+			Callgraph_t();
+			virtual ~Callgraph_t();
+			void addFile(IRDB_SDK::FileIR_t* const firp);
+
+			bool edgeExists(const IRDB_SDK::CallGraphEdge_t& edge) const
+			{
+				const auto from = dynamic_cast<CallGraphNode_t*>(edge.first);
+				const auto to   = dynamic_cast<CallGraphNode_t*>(edge.second);
+					
+				const auto caller_it  = callers.find(from);
+				if(caller_it==callers.end())
+					return false;
+
+				const auto &calleeSet = caller_it->second;
+				return calleeSet.find(to)!=calleeSet.end();
+			}
+			bool edgeExists(IRDB_SDK::CallGraphNode_t& n1, IRDB_SDK::CallGraphNode_t& n2)  const
+				{ return edgeExists(IRDB_SDK::CallGraphEdge_t(&n1,&n2));}
+
+			IRDB_SDK::CallGraphNodeSet_t& GetCallersOfNode(IRDB_SDK::CallGraphNode_t* const node)
+				{ return callers[node]; }
+			IRDB_SDK::CallGraphNodeSet_t& GetCalleesOfNode(IRDB_SDK::CallGraphNode_t* const node)
+				{ return callees[node]; }
+
+			const IRDB_SDK::CallGraphNodeSet_t& getCallersOfNode(IRDB_SDK::CallGraphNode_t* const node) const
+			{ 
+				static const auto empty = IRDB_SDK::CallGraphNodeSet_t();
+				const auto it=callers.find(node);
+				return (it==callers.end()) ?  empty : it->second;
+			}
+			const IRDB_SDK::CallGraphNodeSet_t& getCalleesOfNode(IRDB_SDK::CallGraphNode_t* const node) const
+			{ 
+				static const auto empty = IRDB_SDK::CallGraphNodeSet_t();
+				const auto it=callees.find(node);
+				return (it==callees.end()) ?  empty : it->second;
+			}
+			
+			void GetAncestors(IRDB_SDK::Function_t* const fn, IRDB_SDK::CallGraphNodeSet_t& ancestors, bool skipHellNode = false) const;
+			void GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t& ancestors, bool skipHellNode = false) const;
+
+			const IRDB_SDK::CallSiteSet_t& GetCallSites(IRDB_SDK::CallGraphNode_t* const n1) const
+			{ 
+				static const auto empty = IRDB_SDK::CallSiteSet_t();
+				const auto it=call_sites.find(n1);
+				return (it==call_sites.end()) ?  empty : it->second;
+			}
+			
+
+			IRDB_SDK::CallSiteSet_t& getCallSites(IRDB_SDK::CallGraphNode_t* const n1)
+				{ return call_sites[n1]; }
+
+			void dump(ostream& fout) const;
+
+			string GetNodeName(const IRDB_SDK::CallGraphNode_t* const p_n1) const {
+				auto n1=dynamic_cast<CallGraphNode_t const*>(p_n1);
+				assert(n1);
+				if (n1->isHellnode()) {
+					ostringstream s;
+					s << "HELLNODE" << n1->GetHellNodeType();
+					return s.str();
+				} else {
+					assert(n1->getFunction());
+					return n1->getFunction()->getName(); 
+				}
+			}
 
-		bool Reachable(CallGraphNode_t* const from, CallGraphNode_t* const to, bool skipHellNode = false);
+			string GetCallsiteDisassembly(const IRDB_SDK::CallSite_t &c) const
+				{ return c ? c->getDisassembly() : "NOFROMFUNC"; } 
 
-		CallGraphNode_t& GetDefaultHellNode() { return default_hellnode; }
+			bool isReachable(IRDB_SDK::CallGraphNode_t* const from, IRDB_SDK::CallGraphNode_t* const to, bool skipHellNode = false) const;
 
-		CallGraphNode_t* FindNode(IRDB_SDK::Function_t* const fn);
+			CallGraphNode_t& GetDefaultHellNode() { return default_hellnode; }
+			const CallGraphNode_t& getDefaultHellNode() const { return default_hellnode; }
 
-	private:
-		// create nodes from functions
-		void CreateNodes(IRDB_SDK::FileIR_t *firp);
+			IRDB_SDK::CallGraphNode_t* findNode(IRDB_SDK::Function_t* const fn) const;
 
-		// mark the given insn as a call site.
-		void MarkCallSite(Instruction_t* const insn);
+		private:
+			// create nodes from functions
+			void CreateNodes(IRDB_SDK::FileIR_t *firp);
 
-		// traverse graph to retrieve all ancestors
-		void _GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t &ancestors, CallGraphNodeSet_t &visited, bool skipHellNode);
+			// mark the given insn as a call site.
+			void MarkCallSite(IRDB_SDK::Instruction_t* const insn);
 
-		typedef	std::map<CallGraphNode_t*, CallGraphNodeSet_t > CGNodeToCGNodeSetMap_t;
-		typedef std::map<CallGraphNode_t*, CallSiteSet_t > NodeToCallSiteSetMap_t;
-		typedef std::map<IRDB_SDK::Function_t*, CallGraphNode_t*> FunctionToCGNodeMap_t;
+			// traverse graph to retrieve all ancestors
+			void _GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, IRDB_SDK::CallGraphNodeSet_t &visited, bool skipHellNode) const;
 
-		CGNodeToCGNodeSetMap_t callers;     // map a callee to its callees
-		CGNodeToCGNodeSetMap_t callees;     // map a caller to its callers
-		NodeToCallSiteSetMap_t call_sites;
-		CallGraphNode_t default_hellnode;   // default hell node
-		FunctionToCGNodeMap_t nodes;        // maps functions to call graph nodes
-};
+			using CGNodeToCGNodeSetMap_t = map<IRDB_SDK::CallGraphNode_t*, IRDB_SDK::CallGraphNodeSet_t > ;
+			using NodeToCallSiteSetMap_t = map<IRDB_SDK::CallGraphNode_t*, IRDB_SDK::CallSiteSet_t      > ;
+			using FunctionToCGNodeMap_t  = map<IRDB_SDK::Function_t*     , IRDB_SDK::CallGraphNode_t*   > ;
+;
+			CGNodeToCGNodeSetMap_t callers;     // map a callee to its callees
+			CGNodeToCGNodeSetMap_t callees;     // map a caller to its callers
+			NodeToCallSiteSetMap_t call_sites;
+			CallGraphNode_t default_hellnode;   // default hell node
+			FunctionToCGNodeMap_t nodes;        // maps functions to call graph nodes
+	};
 
+}
 #endif
diff --git a/libIRDB/include/cfg/criticaledge.hpp b/libIRDB/include/cfg/criticaledge.hpp
index 6126703ea5fa32f25c13ad7aeca0392dcaff6508..244e68347ab77f4e565bb300fc98e8a6b4e81911 100644
--- a/libIRDB/include/cfg/criticaledge.hpp
+++ b/libIRDB/include/cfg/criticaledge.hpp
@@ -18,16 +18,22 @@
  *
  */
 
-typedef std::tuple<BasicBlock_t*, BasicBlock_t*> BasicBlockEdge_t;
-typedef std::set<BasicBlockEdge_t> BasicBlockEdgeSet_t;
-
-class CriticalEdgeAnalyzer_t
+namespace libIRDB
 {
-	public:
-		CriticalEdgeAnalyzer_t(const ControlFlowGraph_t &p_cfg, const bool p_conservative=true);
-		BasicBlockEdgeSet_t GetAllCriticalEdges() const;
+	using namespace std;
+
+	class CriticalEdgeAnalyzer_t : public IRDB_SDK::CriticalEdges_t
+	{
+		public:
+			CriticalEdgeAnalyzer_t(const ControlFlowGraph_t *p_cfg, const bool p_conservative=true);
+			virtual ~CriticalEdgeAnalyzer_t() { }
+			const IRDB_SDK::BasicBlockEdgeSet_t& getAllCriticalEdges() const { return criticals; }
+
+		private:
+			void init();
+			const IRDB_SDK::ControlFlowGraph_t *m_cfg;
+			const bool m_conservative;
+		        IRDB_SDK::BasicBlockEdgeSet_t criticals;
 
-	private:
-		const ControlFlowGraph_t m_cfg;
-		const bool m_conservative;
-};
+	};
+}
diff --git a/libIRDB/include/cfg/domgraph.hpp b/libIRDB/include/cfg/domgraph.hpp
index 087fc4dd604d8458be76de68b188447ffaf68ba9..932a34475e59e7044cffb485dcca828bc87a6f43 100644
--- a/libIRDB/include/cfg/domgraph.hpp
+++ b/libIRDB/include/cfg/domgraph.hpp
@@ -1,54 +1,61 @@
+#include <ostream>
+namespace libIRDB
+{
+	using namespace std;
 
+        using  DominatorMap_t    = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlockSet_t>;
+        using  BlockToBlockMap_t = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlock_t*>;
 
 
-typedef std::map<const BasicBlock_t*, BasicBlockSet_t> DominatorMap_t;
-typedef std::map<const BasicBlock_t*, BasicBlock_t*> BlockToBlockMap_t;
 
-class DominatorGraph_t
-{
-	public:
-		DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms=false, bool needs_idoms=false);
 
 
-		// get the (post) dominators for a node 
-		BasicBlockSet_t& GetDominators(const BasicBlock_t* node) { return dom_graph[node]; }
-		BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) { return post_dom_graph[node]; }
+	class DominatorGraph_t : public IRDB_SDK::DominatorGraph_t
+	{
+		public:
+			DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms=false, bool needs_idoms=false);
+			virtual ~DominatorGraph_t() { } 
+
+
+			// get the (post) dominators for a node 
+			IRDB_SDK::BasicBlockSet_t& GetDominators(const IRDB_SDK::BasicBlock_t* node) { return dom_graph[node]; }
+			IRDB_SDK::BasicBlockSet_t& GetPostDominators(const IRDB_SDK::BasicBlock_t* node) { return post_dom_graph[node]; }
+
+			const IRDB_SDK::BasicBlockSet_t& getDominators(const IRDB_SDK::BasicBlock_t* node) const { return dom_graph.at(node); }
+			const IRDB_SDK::BasicBlockSet_t& getPostDominators(const IRDB_SDK::BasicBlock_t* node) const { return post_dom_graph.at(node); }
 
-		const BasicBlockSet_t& GetDominators(const BasicBlock_t* node) const { return dom_graph.at(node); }
-		const BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) const { return post_dom_graph.at(node); }
+			bool hasWarnings() const { return warn; }
 
-		bool HasWarnings() const { return warn; }
 
+			// get the immeidate (post) dominators for a node 
+			const IRDB_SDK::BasicBlock_t* getImmediateDominator(const IRDB_SDK::BasicBlock_t* node)  const
+			{ auto it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; }
+			const IRDB_SDK::BasicBlock_t* getImmediatePostDominators(const IRDB_SDK::BasicBlock_t* node)  const
+			{ auto it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; }
 
-		// get the immeidate (post) dominators for a node 
-		const BasicBlock_t* GetImmediateDominator(const BasicBlock_t* node)  const
-		{ BlockToBlockMap_t::const_iterator it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; }
-		const BasicBlock_t* GetImmediatePostDominators(const BasicBlock_t* node)  const
-		{ BlockToBlockMap_t::const_iterator it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; }
+			void dump(ostream& os=cout) const; 
 
 
-	private:
+		private:
 
-        	typedef const BasicBlockSet_t& (*pred_func_ptr_t) (const BasicBlock_t* node);
+			typedef const IRDB_SDK::BasicBlockSet_t& (*pred_func_ptr_t) (const IRDB_SDK::BasicBlock_t* node);
 
-		DominatorMap_t Dom_Comp(const BasicBlockSet_t& N, pred_func_ptr_t pred_func, BasicBlock_t* r);
-		BlockToBlockMap_t Idom_Comp(const BasicBlockSet_t& N, const DominatorMap_t &Domin, BasicBlock_t* r);
+			DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r);
+			BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r);
 
 
-		DominatorMap_t dom_graph;
-		BlockToBlockMap_t idom_graph;
+			DominatorMap_t dom_graph;
+			BlockToBlockMap_t idom_graph;
 
-		DominatorMap_t post_dom_graph;
-		BlockToBlockMap_t post_idom_graph;
+			DominatorMap_t post_dom_graph;
+			BlockToBlockMap_t post_idom_graph;
 
-		const ControlFlowGraph_t& cfg;	// a reference to our cfg.
+			const ControlFlowGraph_t& cfg;	// a reference to our cfg.
 
-		bool warn;
+			bool warn;
 
-                friend std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg);
-	
-};
+	};
 
-std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg);
 
 
+}
diff --git a/libIRDB/include/libIRDB-cfg.hpp b/libIRDB/include/libIRDB-cfg.hpp
index 3546227c6cd6845328825c61424f945f8a043581..25ed68d1d8b8bc9cedcb1cc068115e6c9daa9a7a 100644
--- a/libIRDB/include/libIRDB-cfg.hpp
+++ b/libIRDB/include/libIRDB-cfg.hpp
@@ -23,6 +23,7 @@
 
 
 /* Building a CFG depends on core functionality */
+#include <irdb-cfg>
 #include <libIRDB-core.hpp>
 
 #include <vector>
@@ -30,17 +31,11 @@
 #include <map>
 #include <ostream>
 
-namespace libIRDB 
-{
-
-	using namespace std;
-
 #include <cfg/BasicBlock.hpp>
 #include <cfg/CFG.hpp>
 #include <cfg/callgraph.hpp>
 #include <cfg/domgraph.hpp>
 #include <cfg/criticaledge.hpp>
 
-};
 
 #endif
diff --git a/libIRDB/src/cfg/BasicBlock.cpp b/libIRDB/src/cfg/BasicBlock.cpp
index db79f64fb935c2deb0faff85cb90d9f00e859c5b..a294e07dcc45fb6f25357051844420127f2acaf7 100644
--- a/libIRDB/src/cfg/BasicBlock.cpp
+++ b/libIRDB/src/cfg/BasicBlock.cpp
@@ -146,23 +146,8 @@ void BasicBlock_t::BuildBlock
 }
 
 
-std::ostream& libIRDB::operator<<(std::ostream& os, const BasicBlock_t& block)
-{
-	os<<block.is_exit_block;
-	os<<"\t ---- Starting block print -----" <<endl;
-	for(auto i=0U;i<block.instructions.size();i++)
-	{
-		const auto insn=block.instructions[i];
-		os<<"\t Instruction "<<std::dec<<i<<" at " << std::hex << insn->getAddress()->getVirtualOffset() << " with id " << std::dec << insn->getBaseID() << " " << insn->getComment() << endl;
-	}
-	os<<"\t ---- done block print -----" <<endl;
-	os<<endl;
-
-	return os;
-}
-
 
-bool BasicBlock_t::EndsInBranch() 
+bool BasicBlock_t::endsInBranch()  const
 {
 	const auto branch=instructions[instructions.size()-1];	
 	assert(branch);
@@ -172,7 +157,7 @@ bool BasicBlock_t::EndsInBranch()
 
 	
 }
-bool BasicBlock_t::EndsInIndirectBranch() 
+bool BasicBlock_t::endsInIndirectBranch()  const
 {
 	const auto *branch=instructions[instructions.size()-1];	
 	assert(branch);
@@ -192,9 +177,9 @@ bool BasicBlock_t::EndsInIndirectBranch()
 	}
 	return false;
 }
-bool BasicBlock_t::EndsInConditionalBranch() 
+bool BasicBlock_t::endsInConditionalBranch() const
 {
-	if(!EndsInBranch())
+	if(!endsInBranch())
 		return false;
 	const auto branch=instructions[instructions.size()-1];	
 	assert(branch);
@@ -203,13 +188,32 @@ bool BasicBlock_t::EndsInConditionalBranch()
 	return d->isConditionalBranch(); 
 }
 
-IRDB_SDK::Instruction_t* BasicBlock_t::GetBranchInstruction()
+IRDB_SDK::Instruction_t* BasicBlock_t::getBranchInstruction() const
 
 {
-	if(!EndsInBranch())
+	if(!endsInBranch())
 		return NULL;
 
 	auto branch=instructions[instructions.size()-1];	
 	return branch;
 }
 
+
+std::ostream& IRDB_SDK::operator<<(std::ostream& os, const IRDB_SDK::BasicBlock_t& block)
+{
+	block.dump(os);
+	return os;
+}
+void  BasicBlock_t::dump(std::ostream& os) const
+{
+	os<<getIsExitBlock();
+	os<<"\t ---- Starting block print -----" <<endl;
+	for(auto i=0U;i<getInstructions().size();i++)
+	{
+		const auto insn=getInstructions()[i];
+		os<<"\t Instruction "<<std::dec<<i<<" at " << std::hex << insn->getAddress()->getVirtualOffset() << " with id " << std::dec << insn->getBaseID() << " " << insn->getComment() << endl;
+	}
+	os<<"\t ---- done block print -----" <<endl;
+	os<<endl;
+}
+
diff --git a/libIRDB/src/cfg/CFG.cpp b/libIRDB/src/cfg/CFG.cpp
index 36be933e2e58df273adfd393fd5449a7f48f86b7..3a20e1a2d95ba882aed6ce4b79e21e5a20080737 100644
--- a/libIRDB/src/cfg/CFG.cpp
+++ b/libIRDB/src/cfg/CFG.cpp
@@ -89,7 +89,7 @@ ControlFlowGraph_t::ControlFlowGraph_t(IRDB_SDK::Function_t* func) :
 }
 
 
-void ControlFlowGraph_t::alloc_blocks(const InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map)
+void ControlFlowGraph_t::alloc_blocks(const IRDB_SDK::InstructionSet_t &starts, map<IRDB_SDK::Instruction_t*,BasicBlock_t*>& insn2block_map)
 {
 	/* create a basic block for each instruction that starts a block */
 	for(const auto &insn : starts)
@@ -115,7 +115,7 @@ void ControlFlowGraph_t::build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBl
 		const auto insn=it.first;
 		const auto block=it.second;
 
-		if(block->GetInstructions().size()>0) // already built
+		if(block->getInstructions().size()>0) // already built
 			continue;
 
 		assert(insn && block);
@@ -126,12 +126,12 @@ void ControlFlowGraph_t::build_blocks(const map<IRDB_SDK::Instruction_t*,BasicBl
 
 }
 
-void ControlFlowGraph_t::find_unblocked_instructions(InstructionSet_t &starts, IRDB_SDK::Function_t* func)
+void ControlFlowGraph_t::find_unblocked_instructions(IRDB_SDK::InstructionSet_t &starts, IRDB_SDK::Function_t* func)
 {
 	auto mapped_instructions=InstructionSet_t();
 	auto missed_instructions=InstructionSet_t();
 	for(const auto block : GetBlocks())
-		mapped_instructions.insert(ALLOF(block->GetInstructions()));
+		mapped_instructions.insert(ALLOF(block->getInstructions()));
 
 	auto my_inserter=inserter(missed_instructions,missed_instructions.end());
 	set_difference(ALLOF(func->getInstructions()), ALLOF(mapped_instructions), my_inserter);
@@ -166,37 +166,37 @@ void ControlFlowGraph_t::Build(IRDB_SDK::Function_t* func)
 }
 
 // returns true iff there's an edge from <p_src> to <p_tgt> in the CFG
-bool ControlFlowGraph_t::HasEdge(BasicBlock_t *p_src, BasicBlock_t *p_tgt) const
+bool ControlFlowGraph_t::hasEdge(IRDB_SDK::BasicBlock_t *p_src, IRDB_SDK::BasicBlock_t *p_tgt) const
 {
 	const auto src_exists = blocks.find(p_src) != blocks.end();
 	const auto tgt_exists = blocks.find(p_tgt) != blocks.end();
 
 	if (!src_exists || !tgt_exists) return false;
 
-	const auto successors = p_src->GetSuccessors();
+	const auto successors = p_src->getSuccessors();
 	return successors.find(p_tgt) != successors.end();
 }
 
-CFG_EdgeType ControlFlowGraph_t::GetEdgeType(const BasicBlock_t *p_src, const BasicBlock_t *p_tgt) const
+IRDB_SDK::CFGEdgeType_t ControlFlowGraph_t::getEdgeType(const IRDB_SDK::BasicBlock_t *p_src, const IRDB_SDK::BasicBlock_t *p_tgt) const
 {
-	const auto last_in_src = p_src->GetInstructions()[p_src->GetInstructions().size()-1];
-	const auto first_in_tgt = p_tgt->GetInstructions()[0];
+	const auto last_in_src = p_src->getInstructions()[p_src->getInstructions().size()-1];
+	const auto first_in_tgt = p_tgt->getInstructions()[0];
 
-	auto edgeType = CFG_EdgeType();
+	auto edgeType = IRDB_SDK::CFGEdgeType_t();
 
 	if (last_in_src->getFallthrough() == first_in_tgt)
 	{
-		edgeType.insert(CFG_FallthroughEdge);
+		edgeType.insert(IRDB_SDK::cetFallthroughEdge);
 	}
 
 	if (last_in_src->getTarget() == first_in_tgt)
 	{
-		edgeType.insert(CFG_TargetEdge);
+		edgeType.insert(IRDB_SDK::cetTargetEdge);
 	}
 
 	if (edgeType.size() == 0)
 	{
-		edgeType.insert(CFG_IndirectEdge);
+		edgeType.insert(IRDB_SDK::cetIndirectEdge);
 	}
 
 	return edgeType;
@@ -205,50 +205,50 @@ CFG_EdgeType ControlFlowGraph_t::GetEdgeType(const BasicBlock_t *p_src, const Ba
 /*
  *  output operator
  */
-ostream& libIRDB::operator<<(ostream& os, const ControlFlowGraph_t& cfg)
+ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::ControlFlowGraph_t& cfg)
+{
+	cfg.dump(os);
+	return os;
+}
+
+void ControlFlowGraph_t::dump(ostream& os) const
 {
 	int i=0;
 
-	map<BasicBlock_t*,int> blk_numbers;
-	for(
-		set<BasicBlock_t*>::const_iterator it=cfg.blocks.begin();
-		it!=cfg.blocks.end();
-		++it
-	   )
+	auto blk_numbers = map<IRDB_SDK::BasicBlock_t*,int>();
+	for(auto blk : getBlocks() ) 
 	{
-			blk_numbers[*it]=i++;
+			blk_numbers[blk]=i++;
 	}
 	
 
-	for(
-		set<BasicBlock_t*>::const_iterator it=cfg.blocks.begin();
-		it!=cfg.blocks.end();
-		++it
-	   )
+	for(auto block : getBlocks())
 	{
-		BasicBlock_t *block=*it;
-
-		if(block==cfg.GetEntry())
+		if(block==getEntry())
 			os<<"**** Entry    ";
 		else
 			os<<"---- NotEntry ";
 		os<<"block "<<std::dec<<blk_numbers[block]<<endl;
 		os<<"Successors: ";
-		for_each(block->GetSuccessors().begin(), block->GetSuccessors().end(), [&](BasicBlock_t* succ)
+		for(auto succ : block->getSuccessors())
 		{
 			os<<blk_numbers[succ]<<", ";
 			
-		});
+		};
 		os<<endl;
 		os<<"Predecessors: ";
-		for_each(block->GetPredecessors().begin(), block->GetPredecessors().end(), [&](BasicBlock_t* pred)
+		for(auto pred : block->getPredecessors())
 		{
 			os<<blk_numbers[pred]<<", ";
-		});
+		};
 		os<<endl;
 		os << *block;
 	}
 
-	return os;
+}
+
+unique_ptr<IRDB_SDK::ControlFlowGraph_t> IRDB_SDK::ControlFlowGraph_t::factory(IRDB_SDK::Function_t* func)
+{
+	return unique_ptr<IRDB_SDK::ControlFlowGraph_t>(new libIRDB::ControlFlowGraph_t(func));
 }
 
diff --git a/libIRDB/src/cfg/callgraph.cpp b/libIRDB/src/cfg/callgraph.cpp
index e126f5620f99f6150de2d4b360f62df8b5776f62..31f4b036f54b5bd8211bffbb912f06d4b1817080 100644
--- a/libIRDB/src/cfg/callgraph.cpp
+++ b/libIRDB/src/cfg/callgraph.cpp
@@ -34,12 +34,20 @@ Callgraph_t::Callgraph_t() :
 {
 }
 
+unique_ptr<IRDB_SDK::CallGraph_t>  IRDB_SDK::CallGraph_t::factory(FileIR_t* const firp)
+{
+	auto ret=unique_ptr<IRDB_SDK::CallGraph_t>(new libIRDB::Callgraph_t());
+	if(firp != nullptr)
+		ret->addFile(firp);
+	return ret;
+}
+
+
 Callgraph_t::~Callgraph_t()
 {
-	for (FunctionToCGNodeMap_t::iterator it = nodes.begin(); it != nodes.end(); ++it)
+	for (auto p : nodes)
 	{
-		CallGraphNode_t* n = it->second;
-		delete(n);
+		delete p.second;
 	}
 	nodes.clear();
 }
@@ -80,14 +88,14 @@ static bool IsPushJmpSite(Instruction_t* insn)
 	return true;
 }
 
-void Callgraph_t::MarkCallSite(Instruction_t* insn)
+void Callgraph_t::MarkCallSite(IRDB_SDK::Instruction_t* insn)
 {
 	auto from_func=insn->getFunction();
 	auto to_insn=insn->getTarget();
 	auto to_func= to_insn==NULL? NULL : to_insn->getFunction();
 
-	auto from_node = FindNode(from_func);
-	auto to_node = FindNode(to_func);
+	auto from_node = findNode(from_func);
+	auto to_node = findNode(to_func);
 
 	if (!from_node)
 		from_node = &GetDefaultHellNode();
@@ -114,7 +122,7 @@ void Callgraph_t::CreateNodes(IRDB_SDK::FileIR_t *firp)
 	}
 }
 
-void Callgraph_t::AddFile(IRDB_SDK::FileIR_t* const firp)
+void Callgraph_t::addFile(IRDB_SDK::FileIR_t* const firp)
 {
 	// Create CG Nodes from functions
 	CreateNodes(firp);
@@ -133,7 +141,7 @@ void Callgraph_t::AddFile(IRDB_SDK::FileIR_t* const firp)
 		if(insn->getFunction() && insn->getFunction()->getEntryPoint()==insn
 			&& insn->getIndirectBranchTargetAddress())
 		{
-				auto node = FindNode(insn->getFunction());
+				auto node = findNode(insn->getFunction());
 				assert(node);
 				callees[&GetDefaultHellNode()].insert(node);
 				callers[node].insert(&GetDefaultHellNode());
@@ -141,43 +149,102 @@ void Callgraph_t::AddFile(IRDB_SDK::FileIR_t* const firp)
 	}
 }
 
-void Callgraph_t::Dump(std::ostream& fout)
+
+void Callgraph_t::_GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, IRDB_SDK::CallGraphNodeSet_t &visited, bool skipHellNode) const
+{
+	if (!node || visited.count(node) > 0)
+		return;
+
+	cerr << "visiting node: " << GetNodeName(node) << " visited(size):" << visited.size() << endl;
+
+        // ancestor-traversal(node X)
+        //    mark X visited
+        //    get parents P of X
+        //    if P[i] not visited:
+        //         add P[i] to ancestors
+        //         ancestor-traversal(P[i])
+
+	visited.insert(node);
+
+	const auto &directPredecessors = getCallersOfNode(node);
+	for (const auto pred : directPredecessors ) // it = directPredecessors.begin(); it != directPredecessors.end(); ++it)
+	{
+		if (visited.count(pred) == 0)
+		{
+			assert(pred);
+			if (pred->isHellnode() && skipHellNode) continue;
+
+			cerr << "adding " << GetNodeName(pred) << " to ancestor list " << hex << pred << dec << endl;
+			ancestors.insert(pred);
+			_GetAncestors(pred, ancestors, visited, skipHellNode);
+		}
+	}
+}
+
+IRDB_SDK::CallGraphNode_t* Callgraph_t::findNode(IRDB_SDK::Function_t* const fn) const
+{
+	auto node_it=nodes.find(fn);
+	return (node_it==nodes.end()) ? nullptr : node_it->second;
+}
+
+void Callgraph_t::GetAncestors(IRDB_SDK::Function_t* const fn, IRDB_SDK::CallGraphNodeSet_t &ancestors, bool skipHellNode) const
+{
+	auto node = findNode(fn);
+	if (node)
+		GetAncestors(node, ancestors, skipHellNode);
+}
+
+void Callgraph_t::GetAncestors(IRDB_SDK::CallGraphNode_t* const node, IRDB_SDK::CallGraphNodeSet_t &ancestors, bool skipHellNode) const
+{
+	auto visited=IRDB_SDK::CallGraphNodeSet_t();
+	_GetAncestors(node, ancestors, visited, skipHellNode);
+}
+
+bool Callgraph_t::isReachable(IRDB_SDK::CallGraphNode_t* const from, IRDB_SDK::CallGraphNode_t* const to, bool skipHellNode) const
+{
+	auto ancestors=IRDB_SDK::CallGraphNodeSet_t();
+	GetAncestors(to, ancestors, skipHellNode);
+	return (ancestors.count(from) > 0);
+}
+
+void Callgraph_t::dump(std::ostream& fout) const
 {
 
 	fout<<"Dumping callgraph ..."<<endl;
 
 	fout<<"Mapping one way ..."<<endl;
-	for(auto it=callees.begin(); callees.end()!=it; ++it)
+	for(const auto p : callees) // it=callees.begin(); callees.end()!=it; ++it)
 	{
-		CallGraphNode_t* node = it->first;
+		// CallGraphNode_t* node = it->first;
+		// CallGraphNodeSet_t &node_callers=it->second;
+		const auto  node        =p.first;
+		const auto &node_callers=p.second;
 
 		fout<<"Function "<<GetNodeName(node)<<" calls: ";
-		CallGraphNodeSet_t &node_callers=it->second;
-		for(auto it2=node_callers.begin(); node_callers.end()!=it2; ++it2)
+		for(const auto &the_callee : node_callers) // auto it2=node_callers.begin(); node_callers.end()!=it2; ++it2)
 		{
-			CallGraphNode_t* the_callee=*it2;
+			// CallGraphNode_t* the_callee=*it2;
 			fout<<GetNodeName(the_callee)<<", ";
 		}
 		fout<<endl;
-		for(auto it2=GetCallSites(node).begin(); GetCallSites(node).end() != it2; ++it2)
+		for(const auto the_call_site : GetCallSites(node)) // auto it2=GetCallSites(node).begin(); GetCallSites(node).end() != it2; ++it2)
 		{
-			CallSite_t the_call_site=*it2;
+			// CallSite_t the_call_site=*it2;
 			fout<<"\t"<<GetCallsiteDisassembly(the_call_site)<<endl;
 		}
 	}
 
 	fout<<"Mapping the other way ..."<<endl;
-	for(auto it=callers.begin(); callers.end()!=it; ++it)
+	for(const auto p : callers) // auto it=callers.begin(); callers.end()!=it; ++it)
 	{
-		CallGraphNode_t* n=it->first;
+		// CallGraphNode_t* n=it->first;
+		const auto  n           =p.first;
+		const auto &node_callees=p.second;
 
 		fout<<"Function "<<GetNodeName(n)<<" called by: ";
-		CallGraphNodeSet_t &node_callees=it->second;
-		for(CallGraphNodeSet_t::iterator it2=node_callees.begin();
-			node_callees.end()!=it2;
-			++it2)
+		for(auto the_caller : node_callees) // CallGraphNodeSet_t::iterator it2=node_callees.begin(); node_callees.end()!=it2; ++it2)
 		{
-			CallGraphNode_t* the_caller=*it2;
+			// CallGraphNode_t* the_caller=*it2;
 			fout<<GetNodeName(the_caller)<<", ";
 
 		}
@@ -186,16 +253,16 @@ void Callgraph_t::Dump(std::ostream& fout)
 
 
 	fout<<"Printing call sites..."<<endl;
-	for(auto it=call_sites.begin(); call_sites.end()!=it; ++it)
+	for(const auto p : call_sites) // auto it=call_sites.begin(); call_sites.end()!=it; ++it)
 	{
-		auto from_node=it->first;
-		auto &call_sites_for_func=it->second;
+		const auto from_node=p.first;
+		const auto &call_sites_for_func=p.second;
 
 		fout<<"Call Sites for "<<GetNodeName(from_node)<<": ";
 
-		for(auto it2=call_sites_for_func.begin(); call_sites_for_func.end() != it2; ++it2)
+		for(const auto the_call_site : call_sites_for_func) // auto it2=call_sites_for_func.begin(); call_sites_for_func.end() != it2; ++it2)
 		{
-			auto the_call_site=*it2;
+			// auto the_call_site=*it2;
 			fout<<GetCallsiteDisassembly(the_call_site)<<", ";
 		}
 		fout<<endl;
@@ -204,58 +271,27 @@ void Callgraph_t::Dump(std::ostream& fout)
 	fout<<"Done!"<<endl;
 }
 
-void Callgraph_t::_GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t &ancestors, CallGraphNodeSet_t &visited, bool skipHellNode)
+void CallGraphNode_t::dump(std::ostream& fout) const
 {
-	if (!node || visited.count(node) > 0)
-		return;
-
-cerr << "visiting node: " << GetNodeName(node) << " visited(size):" << visited.size() << endl;
-
-        // ancestor-traversal(node X)
-        //    mark X visited
-        //    get parents P of X
-        //    if P[i] not visited:
-        //         add P[i] to ancestors
-        //         ancestor-traversal(P[i])
-
-	visited.insert(node);
-
-	auto directPredecessors = GetCallersOfNode(node);
-	for (auto it = directPredecessors.begin(); it != directPredecessors.end(); ++it)
+	if (isHellnode()) 
 	{
-		if (visited.count(*it) == 0)
-		{
-			assert(*it);
-			if ((*it)->IsHellnode() && skipHellNode) continue;
-
-cerr << "adding " << GetNodeName(*it) << " to ancestor list " << hex << *it << dec << endl;
-			ancestors.insert(*it);
-			_GetAncestors(*it, ancestors, visited, skipHellNode);
-		}
+		fout << "HELLNODE" << GetHellNodeType();
+	} 
+	else 
+	{
+		assert(getFunction());
+		fout << getFunction()->getName();
 	}
 }
 
-CallGraphNode_t* Callgraph_t::FindNode(IRDB_SDK::Function_t* const fn)
+ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::CallGraph_t& cg)
 {
-	return nodes[fn];
+	cg.dump(os);
+	return os;
 }
-
-void Callgraph_t::GetAncestors(IRDB_SDK::Function_t* const fn, CallGraphNodeSet_t &ancestors, bool skipHellNode)
+ostream& IRDB_SDK::operator<<(ostream& os, const IRDB_SDK::CallGraphNode_t& cgn)
 {
-	auto node = FindNode(fn);
-	if (node)
-		GetAncestors(node, ancestors, skipHellNode);
+	cgn.dump(os);
+	return os;
 }
 
-void Callgraph_t::GetAncestors(CallGraphNode_t* const node, CallGraphNodeSet_t &ancestors, bool skipHellNode)
-{
-	auto visited=CallGraphNodeSet_t();
-	_GetAncestors(node, ancestors, visited, skipHellNode);
-}
-
-bool Callgraph_t::Reachable(CallGraphNode_t* const from, CallGraphNode_t* const to, bool skipHellNode)
-{
-	auto ancestors=CallGraphNodeSet_t();
-	GetAncestors(to, ancestors, skipHellNode);
-	return (ancestors.count(from) > 0);
-}
diff --git a/libIRDB/src/cfg/criticaledge.cpp b/libIRDB/src/cfg/criticaledge.cpp
index d1d58e4e59e7197f5620ffcb168d47080c2e37ca..17011037e6536e3e98532f7aedc993dcbe98ca13 100644
--- a/libIRDB/src/cfg/criticaledge.cpp
+++ b/libIRDB/src/cfg/criticaledge.cpp
@@ -25,59 +25,66 @@
 using namespace std;
 using namespace libIRDB;
 
-CriticalEdgeAnalyzer_t::CriticalEdgeAnalyzer_t(const ControlFlowGraph_t& p_cfg, const bool p_conservative) :
+#define ALLOF(a) begin(a),end(a)
+
+CriticalEdgeAnalyzer_t::CriticalEdgeAnalyzer_t(const ControlFlowGraph_t* p_cfg, const bool p_conservative) :
 	m_cfg(p_cfg),
 	m_conservative(p_conservative)
 {
+	init();
 }
 
 /*
 *   Critical edge between two nodes is where the source node has multiple successsors,
 *   and the target node has multiple predecessors 
 */
-BasicBlockEdgeSet_t CriticalEdgeAnalyzer_t::GetAllCriticalEdges() const
+void CriticalEdgeAnalyzer_t::init()
 {
-	BasicBlockEdgeSet_t criticals; 
-	for (const auto &src : m_cfg.GetBlocks())
+	for (const auto &src : m_cfg->getBlocks())
 	{
-		auto num_successors = src->GetSuccessors().size();
+		auto num_successors = src->getSuccessors().size();
 		if (!m_conservative)
 		{
 			// in aggressive (non conservative) mode, ignore indirect edges
 			// when counting number of successors
-			num_successors = count_if(
-				src->GetSuccessors().begin(), src->GetSuccessors().end(),
-				[&] (const BasicBlock_t* bb_tgt) {
-					CFG_EdgeType myEdgeType = m_cfg.GetEdgeType(src, bb_tgt);
-					return myEdgeType.find(CFG_TargetEdge)!=myEdgeType.end() || 
-					       myEdgeType.find(CFG_FallthroughEdge)!=myEdgeType.end();
-					});
+			num_successors = count_if
+				(
+					ALLOF(src->getSuccessors()),
+					[&] (const IRDB_SDK::BasicBlock_t* bb_tgt) 
+					{
+						auto myEdgeType = m_cfg->getEdgeType(src, bb_tgt);
+						return myEdgeType.find(IRDB_SDK::cetTargetEdge)!=myEdgeType.end() || 
+						       myEdgeType.find(IRDB_SDK::cetFallthroughEdge)!=myEdgeType.end();
+					}
+				);
 		}
 
 		if (num_successors <= 1) continue;
 
-		for (const auto &tgt : src->GetSuccessors())
+		for (const auto &tgt : src->getSuccessors())
 		{
-			auto num_predecessors = tgt->GetPredecessors().size();
+			auto num_predecessors = tgt->getPredecessors().size();
 			if (!m_conservative)
 			{
 				// in aggressive (non conservative) mode, ignore indirect edges
 				// when counting number of predecessors
-				num_predecessors = count_if(
-					tgt->GetPredecessors().begin(), tgt->GetPredecessors().end(),
-					[&] (const BasicBlock_t* bb_pred) {
-						CFG_EdgeType myEdgeType = m_cfg.GetEdgeType(bb_pred, tgt);
-						return myEdgeType.find(CFG_TargetEdge)!=myEdgeType.end() || 
-						       myEdgeType.find(CFG_FallthroughEdge)!=myEdgeType.end();
-						});
+				num_predecessors = count_if
+					(
+						ALLOF(tgt->getPredecessors()),
+						[&] (const IRDB_SDK::BasicBlock_t* bb_pred) 
+						{
+							auto myEdgeType = m_cfg->getEdgeType(bb_pred, tgt);
+							return myEdgeType.find(IRDB_SDK::cetTargetEdge)!=myEdgeType.end() || 
+							       myEdgeType.find(IRDB_SDK::cetFallthroughEdge)!=myEdgeType.end();
+						}
+					);
 			}
 
 			if (num_predecessors > 1)
 			{
-				BasicBlockEdge_t e(src, tgt);
+				auto e=IRDB_SDK::BasicBlockEdge_t(src, tgt);
 				criticals.insert(e);
 			}
 		}
 	}
-	return criticals;
 }
diff --git a/libIRDB/src/cfg/domgraph.cpp b/libIRDB/src/cfg/domgraph.cpp
index 228a13673c6a3e97de2302997d6c011108d7086a..5ba6beee3f258edb14c79368e2245d04d3d5d6ae 100644
--- a/libIRDB/src/cfg/domgraph.cpp
+++ b/libIRDB/src/cfg/domgraph.cpp
@@ -20,13 +20,13 @@ DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_p
 
 
 //	typedef const BasicBlockSet_t& (*) (const BasicBlock_t* node) pred_func_ptr_t;
-	pred_func_ptr_t func_get_predecessors=[](const BasicBlock_t* node) -> const BasicBlockSet_t&
+	pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t&
 	{
-		return node->GetPredecessors();
+		return node->getPredecessors();
 	};
 
-	dom_graph=Dom_Comp(p_cfg->GetBlocks(), func_get_predecessors, p_cfg->GetEntry());
-	idom_graph=Idom_Comp(p_cfg->GetBlocks(), dom_graph, p_cfg->GetEntry());
+	dom_graph=Dom_Comp(p_cfg->getBlocks(), func_get_predecessors, p_cfg->getEntry());
+	idom_graph=Idom_Comp(p_cfg->getBlocks(), dom_graph, p_cfg->getEntry());
 
 // a func may have multiple exit nodes.  how do we deal with that?
 // psuedo-block?  invoke this for each exit block?
@@ -78,7 +78,7 @@ end || Dom_Comp
 
 */
 
-DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_ptr_t get_preds,  BasicBlock_t* r)
+DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t get_preds,  IRDB_SDK::BasicBlock_t* r)
 {
 /*
 	D, T: set of Node
@@ -87,12 +87,12 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt
 	Domin: Node -> set of Node
 	Domin(r) := { r } 
 */
-	BasicBlockSet_t D, T;
+	IRDB_SDK::BasicBlockSet_t D, T;
 	bool change=true;
 	DominatorMap_t Domin;
 	Domin[r].insert(r);
 
-	BasicBlockSet_t NminusR=N;
+	IRDB_SDK::BasicBlockSet_t NminusR=N;
 	NminusR.erase(r);
 
 /*
@@ -100,10 +100,10 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt
 		Domin(n)={N}
 	od
 */
-	for_each( NminusR.begin(), NminusR.end(), [&](BasicBlock_t* n)
+	for( auto n : NminusR)
 	{
 		Domin[n]=N;
-	});
+	};
 
 /* 
 	repeat
@@ -114,7 +114,7 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt
 		/*
 		for each n \in N - {r} do		
 		*/
-		for_each(NminusR.begin(), NminusR.end(), [&](BasicBlock_t* n)
+		for( auto n : NminusR)
 		{
 			/* T := N */
 			T=N;
@@ -124,13 +124,13 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt
 				T = T intersect Domin(p)
 			done
 */
-			for_each(get_preds(n).begin(), get_preds(n).end(), [&](const BasicBlock_t* p)
+			for(auto p : get_preds(n) )
 			{
-				BasicBlockSet_t tmp;
+				IRDB_SDK::BasicBlockSet_t tmp;
 				set_intersection(T.begin(), T.end(), Domin[p].begin(), Domin[p].end(), inserter(tmp,tmp.begin()));
 				T=tmp;
 				
-			});
+			};
 			/*
 			D = {n} union T
 			*/
@@ -148,7 +148,7 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt
 				change=true;	// keep trying
 				Domin[n]=D;
 			}
-		});
+		};
 /*
 		done
 	until ! change
@@ -164,7 +164,7 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const BasicBlockSet_t& N, pred_func_pt
                 {
                         assert(blk);
                         const BasicBlockSet_t& blk_dominates=Domin[blk];
-                        Instruction_t* first_insn=*(blk->GetInstructions().begin());
+                        Instruction_t* first_insn=*(blk->getInstructions().begin());
                         assert(first_insn);
 #if 1
                         cout<<"\tBlock " <<endl<<*blk<<endl;
@@ -215,7 +215,7 @@ end || IDom_Comp
 	
 
 
-BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const BasicBlockSet_t& N, const DominatorMap_t &Domin, BasicBlock_t* r) 
+BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r) 
 {
 	// n, s, t: Node
 	//BasicBlock_t* n=NULL, *s=NULL, *t=NULL;
@@ -228,30 +228,32 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const BasicBlockSet_t& N, const Do
 
 
 	// calculate this set as we use it several times
-	BasicBlockSet_t NminusR = N;
+	IRDB_SDK::BasicBlockSet_t NminusR = N;
 	NminusR.erase(r);
 
 
 	// for each n \in N do
-	for_each( N.begin(), N.end(), [&](BasicBlock_t* n)
+	for(auto n : N)
 	{
 		//Tmp(n) := Domin(n) - {n} 
 		Tmp[n] = Domin.at(n);
 		Tmp[n].erase(n);
 	// od
-	});
+	};
 
 
 	//for each n \in N - {r} do
-	for_each( NminusR.begin(), NminusR.end(), [&]( BasicBlock_t* n)
+	for(auto n : NminusR)
 	{
 		// for each s \in Tmp(n) do
 		auto Tmp_n=Tmp[n];
-		for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s)
+		// for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s)
+		for (auto s : Tmp_n)
 		{
 
 			//for each t \in Tmp(n) - {s}  do
-			for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* t)
+			// for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* t)
+			for (auto t : Tmp_n)
 			{
 				// quickly do Tmp(n)-s 
 				if(t != s)   
@@ -263,48 +265,54 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const BasicBlockSet_t& N, const Do
 						Tmp[n].erase(t);
 					}
 				}
-			});
-		});
-	});
+			};
+		};
+	};
 
 	//for each n \in N-{r} do
-	for_each( NminusR.begin(), NminusR.end(), [&](BasicBlock_t* n)
+	for (auto n : NminusR)
 	{
 		//IDom(n) = <only element in>Tmp(n)
 		IDom[n]= *(Tmp[n].begin());
 		if(Tmp[n].size()!=1)	// should only be one idominator.
 			warn=true;
-	});
+	};
 	return IDom;
 } // IDom_Comp
 
 
 
 
-ostream& libIRDB::operator<<(ostream& os, const DominatorGraph_t& dg)
+ostream& IRDB_SDK::operator<<(ostream& os, const DominatorGraph_t& dg)
+{
+	dg.dump(os);
+	return os;
+}
+
+void DominatorGraph_t::dump(ostream& os) const
 {
-	for_each(dg.cfg.GetBlocks().begin(), dg.cfg.GetBlocks().end(), [&](const BasicBlock_t* blk)
+	// for_each(dg.cfg.GetBlocks().begin(), dg.cfg.GetBlocks().end(), [&](const BasicBlock_t* blk)
+	for(auto blk : cfg.getBlocks())
 	{
 		assert(blk);
-		const BasicBlockSet_t& blk_dominates=dg.GetDominators(blk);
-		auto first_insn=*(blk->GetInstructions().begin());
+		const auto& blk_dominates=getDominators(blk);
+		auto first_insn=*(blk->getInstructions().begin());
 		assert(first_insn);
 
-		os<<"\tBlock entry id:" <<blk->GetInstructions()[0]->getBaseID()<<endl;
+		os<<"\tBlock entry id:" <<blk->getInstructions()[0]->getBaseID()<<endl;
 		os<<"\t\tDominated by: ";
-		for_each(blk_dominates.begin(), blk_dominates.end(), [&os](const BasicBlock_t* dom)
+		for(auto dom : blk_dominates)
 		{
-			os<<dom->GetInstructions()[0]->getBaseID()<<", ";
-		});
+			os<<dom->getInstructions()[0]->getBaseID()<<", ";
+		};
 		os<<endl;
 
-		const BasicBlock_t* idom=dg.GetImmediateDominator(blk);
+		const IRDB_SDK::BasicBlock_t* idom=getImmediateDominator(blk);
 		if(idom)
-			os<<"\t\tImmediate Dominator: "<<hex<<idom->GetInstructions()[0]->getBaseID()<<endl;
+			os<<"\t\tImmediate Dominator: "<<hex<<idom->getInstructions()[0]->getBaseID()<<endl;
 		else
 			os<<"\t\tNo Immed Dominator."<<endl;
 
-	});
+	};
 
-	return os;
 }