diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index 28ff48a8a4816f184a41a785f12298d5b6fcb792..648f8cf31b6c2a4cba3033888ff4f48b616061c0 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -43,8 +43,6 @@ using namespace libIRDB;
 using namespace std;
 using namespace EXEIO;
 
-#define HELLNODE_ID 0
-#define INDIRECT_CALLS_ID 1
 int next_icfs_set_id = 2;
 
 ICFS_t* hellnode_tgts = NULL;
@@ -248,6 +246,11 @@ void mark_jmptables(FileIR_t *firp)
 		Instruction_t* instr = it->first;
 		set<Instruction_t*> instruction_targets = it->second;
 
+		// ignore if instr already marked complete.
+		// FIXME: assert that fill_in_indtarg analysis matches already complete analysis.
+		if(instr->GetIBTargets() && instr->GetIBTargets()->IsComplete())
+			continue;
+
 		assert(instruction_targets.size() > 0);
 
 		ICFS_t* new_icfs = new ICFS_t(next_icfs_set_id++, true);
@@ -1421,11 +1424,25 @@ void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DISASM d
 	jmptables[IJ] = ibtargets;
 }
 
+template <class T> T MAX(T a, T b) 
+{
+	return a>b ? a : b;
+}
+
 void icfs_init(FileIR_t* firp)
 {
+
+
 	assert(firp);
-	hellnode_tgts = new ICFS_t(HELLNODE_ID, false);
-	indirect_calls = new ICFS_t(INDIRECT_CALLS_ID, false); 
+	db_id_t max_id=0;
+	for(ICFSSet_t::iterator it=firp->GetAllICFS().begin(); it!=firp->GetAllICFS().end(); ++it)
+	{
+		max_id=MAX<db_id_t>(max_id, (*it)->GetBaseID());
+	}
+	next_icfs_set_id = max_id+1;
+	cerr<<"Found max ICFS id=="<<max_id<<endl;
+	hellnode_tgts = new ICFS_t(next_icfs_set_id++, false);
+	indirect_calls = new ICFS_t(next_icfs_set_id++, false); 
 	firp->GetAllICFS().insert(hellnode_tgts);
 	firp->GetAllICFS().insert(indirect_calls);
 }
@@ -1433,13 +1450,13 @@ void icfs_init(FileIR_t* firp)
 void icfs_set_indirect_calls(FileIR_t* const firp, ICFS_t* const targets)
 {
 	assert(firp && targets);
-    for(
-       	FunctionSet_t::const_iterator it=firp->GetFunctions().begin();
-       	it!=firp->GetFunctions().end();
-        ++it
-        )
-    {
-        Function_t *func=*it;
+    	for(
+       	    FunctionSet_t::const_iterator it=firp->GetFunctions().begin();
+       	    it!=firp->GetFunctions().end();
+            ++it
+           )
+    	{
+        	Function_t *func=*it;
 		if(!func->GetEntryPoint())
 			continue;
 		targets->insert(func->GetEntryPoint());
@@ -1472,6 +1489,10 @@ void check_for_ret(FileIR_t* const firp, Instruction_t* const insn)
 	if(strstr(d.Instruction.Mnemonic, "ret")==NULL)
 		return;
 
+	// already analysed by ida.
+	if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete())
+		return;
+
 	insn->SetIBTargets(hellnode_tgts);
 }
 
@@ -1487,11 +1508,17 @@ void check_for_indirect_jmp(FileIR_t* const firp, Instruction_t* const insn)
 
 	if(d.Argument1.ArgType&REGISTER_TYPE)
 	{
+		// already analysed by ida.
+		if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete())
+			return;
 		insn->SetIBTargets(hellnode_tgts);
 	}
 	else if(d.Argument1.ArgType&MEMORY_TYPE &&
 			(!d.Argument1.ArgType&RELATIVE_))
 	{
+		// already analysed by ida.
+		if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete())
+			return;
 		insn->SetIBTargets(hellnode_tgts);
 	}
 }
@@ -1509,6 +1536,10 @@ void check_for_indirect_call(FileIR_t* const firp, Instruction_t* const insn)
 	if(d.Argument1.ArgType&CONSTANT_TYPE)
 		return;
 
+	// already analysed by ida.
+	if(insn->GetIBTargets() && insn->GetIBTargets()->IsComplete())
+		return;
+
 	insn->SetIBTargets(indirect_calls);
 }
 
diff --git a/tools/meds2pdb/meds2pdb.cpp b/tools/meds2pdb/meds2pdb.cpp
index bed63cfbd406a9ce00546fb84faffcdf9feaee90..e12b6098972ba0fbede16079e497b16042a11481 100644
--- a/tools/meds2pdb/meds2pdb.cpp
+++ b/tools/meds2pdb/meds2pdb.cpp
@@ -41,6 +41,8 @@ string functionTable;
 string addressTable;
 string instructionTable;
 string typesTable;
+string icfsTable;
+string icfsMapTable;
 
 static const int STRIDE = 50;
 
@@ -56,6 +58,7 @@ inline std::string my_to_string (const T& t)
 int next_address_id=0;
 
 map<app_iaddr_t,int> address_to_instructionid_map;
+map<wahoo::Instruction*,int> instruction_to_addressid_map;
 
 // extract the file id from the md5 hash and the program name
 int get_file_id(char *progName, char *md5hash)
@@ -81,8 +84,63 @@ int get_file_id(char *progName, char *md5hash)
 }
 
 
+void insert_icfs(int fileID, const vector<wahoo::Instruction*>& instructions)
+{
+	using namespace wahoo;
+
+  	connection conn;
+  	work txn(conn);
+  	txn.exec("SET client_encoding='LATIN1';");
+
+	int next_icfs_id=0;
+
+  	for (int i = 0; i < instructions.size(); i ++)
+	{
+      		wahoo::Instruction *instruction = instructions[i];
+		assert(instruction);
+
+		const std::set<Instruction*> &ibts=instruction->getIBTs();
+		
+		if(ibts.size()==0)
+			continue;
+		cerr<<"Found fromIB=="<<instruction->getAddress()<<endl;
+    
+		string query = "INSERT INTO " + icfsTable;
+    		query += " (icfs_id,is_complete) VALUES ";
+      		query += "(";
+      		query += txn.quote(next_icfs_id) + ",";
+      		query += txn.quote(1);
+		query += ")";
+
+		string query2 = "INSERT INTO " + icfsMapTable;
+    		query2 += " (icfs_id,address_id) VALUES ";
+
+		for(set<Instruction*>::iterator it=ibts.begin(); it!=ibts.end(); it++)
+		{
+			cerr<<"Found toIBT=="<<(*it)->getAddress()<<endl;
+			if(it!=ibts.begin())
+				query2+=",";
+			int target_address_id=instruction_to_addressid_map[*it];
+      			query2 += "(";
+      			query2 += txn.quote(next_icfs_id) + ",";
+      			query2 += txn.quote(target_address_id);
+			query2 += ")";
+			
+		}
+		
+		query+=";";
+		query2+=";";
+    		txn.exec(query+query2);
+		next_icfs_id++;
+	}
+ 	cerr<<"Finished inserting ICFS into IR."<<endl; 
+	txn.commit();
+
+}
+
+
 // insert addresses & instructions into DB
-void insert_instructions(int fileID, vector<wahoo::Instruction*> instructions, vector<wahoo::Function*> functions)
+void insert_instructions(int fileID, const vector<wahoo::Instruction*> &instructions, const vector<wahoo::Function*> &functions)
 {
   cerr << "Inserting instructions in the DB"<<endl;
   connection conn;
@@ -115,6 +173,7 @@ void insert_instructions(int fileID, vector<wahoo::Instruction*> instructions, v
       address_to_instructionid_map[addr]=j;
 
       int address_id = next_address_id++;
+      instruction_to_addressid_map[instruction]=address_id;
 
       // insert into address table
       if (j != i) query += ",";
@@ -329,7 +388,7 @@ void populate_predefined_types()
 	txn.commit(); 
 }
 
-void update_function_prototype(vector<wahoo::Function*> functions, char* annotFile)
+void update_function_prototype(const vector<wahoo::Function*> &functions, char* annotFile)
 {
 	populate_predefined_types();
 
@@ -456,9 +515,9 @@ void update_function_prototype(vector<wahoo::Function*> functions, char* annotFi
 
 int main(int argc, char **argv)
 {
-  	if (argc != 10)
+  	if (argc != 12)
   	{
-    		cerr << "usage: " << argv[0] << " <annotations file> <info annotation file> <file id> <func tab name> <insn tab name> <addr tab name> <types tab name> <elf file> <STARSxref file>" << endl;
+    		cerr << "usage: " << argv[0] << " <annotations file> <info annotation file> <file id> <func tab name> <insn tab name> <addr tab name> <types tab name> <icfs table name> <icfs map table name> <elf file> <STARSxref file>" << endl;
     		return 1;
   	}
 
@@ -469,22 +528,30 @@ int main(int argc, char **argv)
   	char *myInstructionTable=argv[5];
   	char *myAddressTable=argv[6];
   	char *myTypesTable=argv[7];
-  	char *elfFile=argv[8];
-  	char *starsXrefFile=argv[9];
+  	char *myicfsTable=argv[8];
+  	char *myicfsMapTable=argv[9];
+  	char *elfFile=argv[10];
+  	char *starsXrefFile=argv[11];
 
 	cout<<"Annotation file: "<< annotFile<<endl;
 	cout<<"Info annotation file: "<< infoAnnotFile<<endl;
 	cout<<"File ID: "<< fid<<endl;
-	cout<<"FTN:: "<< myFunctionTable<<endl;
+	cout<<"FTN: "<< myFunctionTable<<endl;
 	cout<<"ITN: "<< myInstructionTable<<endl;
 	cout<<"ATN: "<< myAddressTable<<endl;
 	cout<<"TYP: "<< myTypesTable<<endl;
+	cout<<"ICFSTab: "<< myicfsTable<<endl;
+	cout<<"ICFSMapTab: "<< myicfsMapTable<<endl;
+	cout<<"elfFile: "<< elfFile<<endl;
+	cout<<"xrefFile: "<< starsXrefFile<<endl;
 
 	// set global vars for importing.
 	functionTable=myFunctionTable;
 	addressTable=myAddressTable;
 	instructionTable=myInstructionTable;
 	typesTable=myTypesTable;
+	icfsTable=myicfsTable;
+	icfsMapTable=myicfsMapTable;
 
   	Rewriter *rewriter = new Rewriter(elfFile, annotFile, starsXrefFile);
 
@@ -504,6 +571,7 @@ int main(int argc, char **argv)
   	insert_functions(fileID, functions);
   	insert_instructions(fileID, instructions, functions);
   	update_functions(fileID, functions);
+  	insert_icfs(fileID, instructions);
 
 	// add function prototype information to the IRDB
 	update_function_prototype(functions, infoAnnotFile);
diff --git a/xform/instruction_descriptor.h b/xform/instruction_descriptor.h
index e09c6bfd7705f4bab2b9402c48feef8c9aa7e9b1..420332a4f631f82f4f4afc95ff19f751f07dfc57 100644
--- a/xform/instruction_descriptor.h
+++ b/xform/instruction_descriptor.h
@@ -2,6 +2,7 @@
 #define _instruction_h_
 
 #include <string>
+#include <set>
 
 #include "targ-config.h"
 
@@ -46,6 +47,10 @@ class Instruction {
     void setVisited() { m_isVisited = true; }
     bool isVisited() const { return m_isVisited; }
 
+    // include Indirect branch targets for insructions.
+    void addIBT(Instruction* insn) { ibts.insert(insn); }
+    const std::set<Instruction*>&  getIBTs() { return ibts; }
+
   private:
     app_iaddr_t     m_address;
     app_iaddr_t     m_ibt_address;
@@ -61,6 +66,9 @@ class Instruction {
     bool            m_varStackRef;
 
     bool            m_isVisited;
+
+    std::set<Instruction*> ibts;
+
 };
 
 }
diff --git a/xform/rewriter.cpp b/xform/rewriter.cpp
index 7c7a45db44137ee222cdb1227f9992030e135483..6e80e709c2535532d10ae41a9f9625adee439d39 100644
--- a/xform/rewriter.cpp
+++ b/xform/rewriter.cpp
@@ -652,16 +652,20 @@ void Rewriter::readXrefsFile(char p_filename[])
 	do
 	{
 
-
+		addr=0;
                 fscanf(fin, "%p %d\n", (void**)&addr, &size_type_u.size);
 
                 if(feof(fin))           // deal with blank lines at the EOF
                         break;
 		fscanf(fin, "%s%s", type,scope);
+                if(feof(fin))           // deal with blank lines at the EOF
+                        break;
 
 		assert(strcmp(type,"INSTR")==0);
 		assert(strcmp(scope,"XREF")==0);
-		fscanf(fin, "%s%s%s", ibt,fromib,dest);
+		fscanf(fin, "%s%s", ibt,fromib);
+                if(feof(fin))           // deal with blank lines at the EOF
+                        break;
 		assert(strcmp(ibt,"IBT")==0);
 		assert(strcmp(fromib,"FROMIB")==0 || strcmp(fromib,"FROMDATA")==0 
 			|| strcmp(fromib,"FROMUNKNOWN")==0);
@@ -672,11 +676,29 @@ void Rewriter::readXrefsFile(char p_filename[])
 		{
 			// cout<<"Setting IBT for addr "<<std::hex<<addr<<std::dec<<endl;
 			instr->setIBTAddress(addr);
+			if(strcmp(fromib,"FROMIB")==0)
+			{
+				// get the from point into memory.
+				app_iaddr_t from_addr = 0;
+				fscanf(fin, "%p\n", (void**)&from_addr);
+				if(feof(fin))           // deal with blank lines at the EOF
+					break;
+
+				// find that instruction
+				wahoo::Instruction *from_instr = addr_to_insn_map[from_addr];
+				assert(from_instr);
+			
+				// record in the IR listing.
+				from_instr->addIBT(instr);
+			}
 		}
 		else
 		{
-			cerr<<"Warning, instruction at "<<std::hex<<addr<<std::dec<<" not in db?"<<endl;
+			cerr<<"Error: instruction at "<<std::hex<<addr<<std::dec<<" not in db?"<<endl;
+			// assert(0);
 		}
+
+
 		
 		char remainder[2000];
 		fgets(remainder, sizeof(remainder), fin);
diff --git a/xform/rewriter.h b/xform/rewriter.h
index 417c2950117b819f6860419aa48df71331f364a8..c035835215fa86a001a66380de4dcd5f89a35584 100644
--- a/xform/rewriter.h
+++ b/xform/rewriter.h
@@ -1,4 +1,5 @@
 #include <map>
+#include <set>
 #include "targ-config.h"
 #include "elfio/elfio.hpp"
 #include "elfio/elfio_dump.hpp"
@@ -6,6 +7,7 @@
 #include "elfreader.h"
 #include "function_descriptor.h"
 
+
 using namespace std;
 
 class Rewriter