diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1377554ebea6f98a2c748183bc5a96852af12ac2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.swp
diff --git a/include/inc-cfg/BasicBlock.hpp b/include/inc-cfg/BasicBlock.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c04e48348f90f90a215efa7107b2b931ffae7184
--- /dev/null
+++ b/include/inc-cfg/BasicBlock.hpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014 - Zephyr Software LLC
+ *
+ * This file may be used and modified for non-commercial purposes as long as
+ * all copyright, permission, and nonwarranty notices are preserved.
+ * Redistribution is prohibited without prior written consent from Zephyr
+ * Software.
+ *
+ * Please contact the authors for restrictions applying to commercial use.
+ *
+ * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Zephyr Software
+ * e-mail: jwd@zephyr-software.com
+ * URL   : http://www.zephyr-software.com/
+ *
+ */
+
+#include <ostream>
+#include <set>
+
+namespace IRDB_SDK
+{
+	using namespace std;
+
+	class BasicBlock_t;
+
+	using BasicBlockSet_t = set<BasicBlock_t*>;
+
+	class BasicBlock_t
+	{
+		protected:
+			BasicBlock_t() {}
+			BasicBlock_t(const BasicBlock_t& copy) = delete;
+		public:
+
+			bool                       getIsExitBlock()     const = 0;
+			const InstructionVector_t& getInstructions()    const = 0;
+			const BasicBlockSet_t&     getPredecessors()    const = 0;
+			const BasicBlockSet_t&     getSuccessors()      const = 0;
+			const BasicBlockSet_t&     getIndirectTargets() const = 0;
+			const BasicBlock_t*        getFallthrough()     const = 0;
+			const BasicBlock_t*        getTarget()          const = 0;
+
+
+			bool           endsInBranch()            = 0;
+			bool           endsInIndirectBranch()    = 0;
+			bool           endsInConditionalBranch() = 0;
+			Instruction_t* getBranchInstruction()    = 0;
+
+			void           dump(ostream &os=std::cout) = 0 ;
+
+	};
+	ostream& operator<<(ostream& os, const BasicBlock_t& block);
+
+}
diff --git a/include/inc-cfg/CFG.hpp b/include/inc-cfg/CFG.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8bf1d0b2f752590fb8609b2e79807eb1d3cf6895
--- /dev/null
+++ b/include/inc-cfg/CFG.hpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 - Zephyr Software LLC
+ *
+ * This file may be used and modified for non-commercial purposes as long as
+ * all copyright, permission, and nonwarranty notices are preserved.
+ * Redistribution is prohibited without prior written consent from Zephyr
+ * Software.
+ *
+ * Please contact the authors for restrictions applying to commercial use.
+ *
+ * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Zephyr Software
+ * e-mail: jwd@zephyr-software.com
+ * URL   : http://www.zephyr-software.com/
+ *
+ */
+
+enum CFG_EdgeTypeEnum { CFG_FallthroughEdge, CFG_TargetEdge, CFG_IndirectEdge };
+typedef std::set<CFG_EdgeTypeEnum> CFG_EdgeType;
+
+class ControlFlowGraph_t
+{
+	public:
+		ControlFlowGraph_t(Function_t* func);
+		BasicBlock_t* GetEntry() const { return entry; }
+		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(Function_t *func);
+		void alloc_blocks(const InstructionSet_t &starts, map<Instruction_t*,BasicBlock_t*>& insn2block_map);
+		void build_blocks(const map<Instruction_t*,BasicBlock_t*>& insn2block_map);
+		void find_unblocked_instructions(InstructionSet_t &starts, Function_t* func);
+
+	// data
+		BasicBlockSet_t blocks;
+		BasicBlock_t* entry;
+		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);
+
+
diff --git a/include/inc-cfg/callgraph.hpp b/include/inc-cfg/callgraph.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f1c00777e687000a1034e1ec2c8d39fc265e8d4d
--- /dev/null
+++ b/include/inc-cfg/callgraph.hpp
@@ -0,0 +1,71 @@
+
+
+namespace IRDB_SDK
+{
+	using namespace std;
+
+
+	class CallGraphNode_t
+	{
+		protected:
+			CallGraphNode_t() { }
+			CallGraphNode_t(const CallGraphNode_t& copy) = delete;
+		public:
+			virtual ~CallGraphNode_t() { }
+
+			bool isHellnode() const  =0;
+			Function_t* getFunction() const  =0;
+	};
+
+
+
+	using CallGraphEdge_t    = pair<CallGraphNode_t*,CallGraphNode_t*>;
+	using CallGraphNodeSet_t = set<CallGraphNode_t*>;
+	using CallSite_t         = Instruction_t*;
+	using CallSiteSet_t      = set<CallSite_t>;
+
+	class Callgraph_t
+	{
+		protected:
+			Callgraph_t() {}
+			Callgraph_t(const Callgraph_t& copy) = delete;
+		public:
+			virtual ~Callgraph_t() { }
+			
+			virtual void addFile() = 0;
+
+			virtual bool  edgeExists(const CallGraphEdge_t& edge) const = 0;
+
+			virtual const CallGraphNodeSet_t& 
+			              getCallersOfNode(CallGraphNode_t* const node)  const = 0;
+
+			virtual const CallGraphNodeSet_t& 
+			              getCalleesOfNode(CallGraphNode_t* const node)  const = 0;
+			
+			virtual const CallGraphNodeSet_t& ancestors, 
+				       getAncestors
+			               (
+				        const Function_t* const fn, 
+				        const bool skipHellNode = false
+				       )                                            const = 0;
+			virtual const  CallSiteSet_t& 
+			               getCallSites(CallGraphNode_t* const n1)      const = 0;
+
+			virtual void   dump(std::ostream& fout)                     const = 0;
+			virtual string getNodeName(const CallGraphNode_t* const n1) const = 0;
+			virtual string getCallsiteDisassembly(const CallSite_t &c)  const = 0;
+			virtual bool   isReachable
+			               (
+			                CallGraphNode_t* const from, 
+			                CallGraphNode_t* const to, 
+			                bool skipHellNode = false
+			               ) const = 0;
+
+			virtual const  CallGraphNode_t& 
+			               getDefaultHellNode()                         const = 0; 
+
+			virtual CallGraphNode_t* 
+			               findNode(Function_t* const fn)               const = 0;
+	};
+
+}
diff --git a/include/inc-cfg/criticaledge.hpp b/include/inc-cfg/criticaledge.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6126703ea5fa32f25c13ad7aeca0392dcaff6508
--- /dev/null
+++ b/include/inc-cfg/criticaledge.hpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019 - Zephyr Software LLC
+ *
+ * This file may be used and modified for non-commercial purposes as long as
+ * all copyright, permission, and nonwarranty notices are preserved.
+ * Redistribution is prohibited without prior written consent from Zephyr
+ * Software.
+ *
+ * Please contact the authors for restrictions applying to commercial use.
+ *
+ * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Zephyr Software
+ * e-mail: jwd@zephyr-software.com
+ * URL   : http://www.zephyr-software.com/
+ *
+ */
+
+typedef std::tuple<BasicBlock_t*, BasicBlock_t*> BasicBlockEdge_t;
+typedef std::set<BasicBlockEdge_t> BasicBlockEdgeSet_t;
+
+class CriticalEdgeAnalyzer_t
+{
+	public:
+		CriticalEdgeAnalyzer_t(const ControlFlowGraph_t &p_cfg, const bool p_conservative=true);
+		BasicBlockEdgeSet_t GetAllCriticalEdges() const;
+
+	private:
+		const ControlFlowGraph_t m_cfg;
+		const bool m_conservative;
+};
diff --git a/include/inc-cfg/domgraph.hpp b/include/inc-cfg/domgraph.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..087fc4dd604d8458be76de68b188447ffaf68ba9
--- /dev/null
+++ b/include/inc-cfg/domgraph.hpp
@@ -0,0 +1,54 @@
+
+
+
+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]; }
+
+		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; }
+
+
+		// 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; }
+
+
+	private:
+
+        	typedef const BasicBlockSet_t& (*pred_func_ptr_t) (const 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_graph;
+		BlockToBlockMap_t idom_graph;
+
+		DominatorMap_t post_dom_graph;
+		BlockToBlockMap_t post_idom_graph;
+
+		const ControlFlowGraph_t& cfg;	// a reference to our cfg.
+
+		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/include/inc-core/eh.hpp b/include/inc-core/eh.hpp
index 7ee13d4ab6bdea79fd51da118e0444a30d7c3110..de66dde36bce5125e6ac4611d8bf1af3087af5ed 100644
--- a/include/inc-core/eh.hpp
+++ b/include/inc-core/eh.hpp
@@ -21,8 +21,8 @@ namespace IRDB_SDK
 			virtual void setCodeAlignmentFactor(const uint64_t caf) = 0;
 			virtual void setDataAlignmentFactor(const int64_t daf)  = 0;
 			virtual void setReturnRegNumber    (const uint8_t rr  ) = 0;
-			virtual void getCIEProgram(const EhProgramListing_t& pgm) const = 0;
-			virtual void getFDEProgram(const EhProgramListing_t& pgm) const = 0;
+			virtual void setCIEProgram(const EhProgramListing_t& p) = 0;
+			virtual void setFDEProgram(const EhProgramListing_t& p) = 0;
 
 			// helpers
 			virtual void print() const = 0;
diff --git a/include/inc-core/fileir.hpp b/include/inc-core/fileir.hpp
index 0f2973c21e05c785dcfd9857f4c1a8c38b192835..ee9c49232015b4e804988c9ea5947f04b74da53d 100644
--- a/include/inc-core/fileir.hpp
+++ b/include/inc-core/fileir.hpp
@@ -25,22 +25,23 @@ namespace IRDB_SDK
 			virtual DataScoop_t*            findScoop(
 			         const VirtualOffset_t &p_addr)             const = 0;
 
-			virtual void         setBaseIDS()                                                   = 0;
-			virtual void         assembleRegistry()                                             = 0;
-			virtual void         registerAssembly(Instruction_t *p_instr, string p_assembly)    = 0;
-			virtual void         unregisterAssembly(Instruction_t *p_instr)                     = 0;
-			virtual string       lookupAssembly(Instruction_t *p_instr)                         = 0;
-			virtual void         changeRegistryKey(
-			                                   Instruction_t* p_orig, Instruction_t* p_updated) = 0;
-			virtual void         splitScoop(
-			                                DataScoop_t *p_to_split, 
-			                                const VirtualOffset_t &p_addr, 
-			                                size_t p_size, 
-			                                DataScoop_t* &p_before,
-			                                DataScoop_t* &p_containing, 
-			                                DataScoop_t* &p_after, 
-			                                DatabaseID_t *p_max_id=NULL
-			                               )                                                    = 0;
+			virtual void   setAllEhPrograms(const EhProgramSet_t& new_pgms)               = 0;
+			virtual void   setBaseIDS()                                                   = 0;
+			virtual void   assembleRegistry()                                             = 0;
+			virtual void   registerAssembly(Instruction_t *p_instr, string p_assembly)    = 0;
+			virtual void   unregisterAssembly(Instruction_t *p_instr)                     = 0;
+			virtual string lookupAssembly(Instruction_t *p_instr)                         = 0;
+			virtual void   changeRegistryKey(
+					             Instruction_t* p_orig, Instruction_t* p_updated) = 0;
+			virtual void   splitScoop(
+						DataScoop_t *p_to_split, 
+						const VirtualOffset_t &p_addr, 
+						size_t p_size, 
+						DataScoop_t* &p_before,
+						DataScoop_t* &p_containing, 
+						DataScoop_t* &p_after, 
+						DatabaseID_t *p_max_id=NULL
+					       )                                                    = 0;
 
 			virtual void writeToDB(std::ostream *verbose_logging=&std::cerr) = 0;
 
@@ -63,7 +64,7 @@ namespace IRDB_SDK
 					const EhProgramListing_t& p_fde_program={}
 					) = 0;
 
-			virtual AddressID_t* addNewAddress(const DatabaseID_t& myfileID, const VirtualOffset_t& voff) =0 ;
+			virtual AddressID_t* addNewAddress(const DatabaseID_t& myfileID, const VirtualOffset_t& voff=0) =0 ;
 			virtual ICFS_t*      addNewICFS   (Instruction_t* insn=nullptr, const InstructionSet_t& targets={}, const ICFSAnalysisStatus_t& status=iasAnalysisIncomplete) = 0; 
 
 			virtual Instruction_t* addNewInstruction(
@@ -88,6 +89,7 @@ namespace IRDB_SDK
 
 			virtual void removeScoop(DataScoop_t* s) = 0;
 			virtual void moveRelocation(Relocation_t* reloc, Instruction_t* from, Instruction_t* to) = 0;
+			virtual EhProgram_t* copyEhProgram(const EhProgram_t& orig) = 0;
 
 
 		// static methods