diff --git a/.gitattributes b/.gitattributes
index 47d84484299f8a17cd50e756e0c5651302cef9d9..6998f5d3c0cd002a25f7579a65ed1e6e73bbf752 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,6 +1,8 @@
 * text=auto !eol
 /Build.sh -text
 /Makefile.in -text
+/ProfilerInformation.cpp -text
+/ProfilerInformation.h -text
 /README.txt -text
 /SMP-analyze.sh -text
 /SMP.idc -text
diff --git a/ProfilerInformation.cpp b/ProfilerInformation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..766d182776c3006a2eee071f6361fd2d7b0e81bf
--- /dev/null
+++ b/ProfilerInformation.cpp
@@ -0,0 +1,215 @@
+
+
+
+
+#include "ProfilerInformation.h"
+
+
+#define qfeof feof
+
+ProfilerInformation::ProfilerInformation(const char* fn)
+	: filename(std::string(fn))
+{
+
+	FILE* fin;
+	int addr;
+	union { int size, type;} size_type_u;
+	char type[200];
+	char scope[200];
+	char remainder[2000];
+	int line=0;
+
+	if(fn[0]==0)
+		return;
+
+	fin=qfopen(fn, "r");
+
+	if(!fin)
+	{
+		msg("Cannot open strata annotation file %s\n", fn);
+		return;
+	}
+
+
+
+	do 
+	{
+		qfscanf(fin, "%x %d\n", &addr, &size_type_u);
+
+		if(qfeof(fin))		// deal with blank lines at the EOF
+			break;
+		
+		qfscanf(fin, "%s%s", type,scope);
+
+		/* if the size > 0, then this is a declaration of a variable */
+		if(strcmp(type,"FUNC")==0)
+		{
+			// no useful info for the SA.
+			
+		}
+		else if(strcmp(type,"MEMORYHOLE")==0)
+		{
+			// no useful info for the SA.
+		}
+		else if(strcmp(type,"INSTR")==0)
+		{
+			// no useful info for the SA.
+		}
+                else if(strcmp(type,"PTRIMMEDEBP")==0 || 
+			strcmp(type,"PTRIMMEDESP")==0 || 
+			strcmp(type,"PTRIMMEDESP2")==0 || 
+			strcmp(type,"PTRIMMEDABSOLUTE")==0
+		       )
+		{
+                        int the_const;
+                        int real_const=0;
+			char field[100];
+			assert(strcmp(scope,"STACK")==0 || strcmp(scope,"GLOBAL")==0);
+
+			/* remaining params are <const> <field> <real_const_if_global> <comment> */ 
+			qfscanf(fin, "%d %s", &the_const, field);
+			if( 	strcmp(type,"PTRIMMEDESP2")==0 || 
+				strcmp(type,"PTRIMMEDABSOLUTE")==0
+			  )
+				qfscanf(fin, "%x", &real_const);
+			else
+				real_const=the_const;
+
+			// successfully read in, but, ignoring for now.
+			if(strcmp(type,"PTRIMMEDESP2")==0 || strcmp(type,"PTRIMMEDABSOLUTE")==0 )
+			{
+				profileAddressingInformation(addr,size_type_u.size,type, scope,the_const,field,real_const);
+			}
+			
+		}
+		else if(strcmp(type,"DATAREF")==0)
+		{
+			// no useful info for the SA.
+
+		}
+		else if (strcmp(type,"DEALLOC")==0)
+		{
+			// no useful info for the SA.
+			assert(strcmp(scope,"STACK")==0);
+			/* remaining params: comment */
+		}
+		else if(strcmp(type,"PROFILEDNUMERIC")==0)
+		{
+			/* profiler generated information */
+			addProfileInformation(addr,atoll(scope),0,0);
+		}
+		else if(strcmp(type,"PROFILEDPOINTER")==0 )
+		{
+			/* profiler generated information */
+			addProfileInformation(addr,0,atoll(scope),0);
+		}
+		else if(strcmp(type,"PROFILEDOTHER")==0 )
+		{
+			/* profiler generated information */
+			addProfileInformation(addr,0,0,atoll(scope));
+		}
+		else
+		{
+			assert(0);
+		}
+	
+		qfgets(remainder, sizeof(remainder), fin);
+		line++;
+	} while(!qfeof(fin));
+	qfclose(fin);
+
+	msg("Successfully loaded annotation file %s\n", fn);
+}
+
+ProfilerInformation::~ProfilerInformation()
+{
+	FILE* fout=qfopen(filename.c_str(), "a+");
+	
+	if(!fout)
+	{
+		msg("Cannot open annotations file (%s) for output\n", filename.c_str());		
+		assert(0);
+	}
+
+	for( 	std::set<std::string>::iterator iter=constant_info.begin();
+		iter != constant_info.end();
+		++iter
+	   )
+	{
+		qfprintf(fout, "%s", (*iter).c_str());
+	}
+
+	for( 	std::map<ea_t,InstructionInformation*>::iterator iter=the_map.begin();
+		iter != the_map.end();
+		++iter
+	   )
+	{
+		ea_t addr=(*iter).first;
+		InstructionInformation *ii=(*iter).second;
+		if(ii)
+		{
+
+			if(ii->getNumericCount())
+			{
+				qfprintf(fout, "%x %d %s %d Profiler generated, summarized by idal\n",
+					addr, 0, "PROFILEDNUMERIC", ii->getNumericCount());
+			}
+			if(ii->getPointerCount())
+			{
+				qfprintf(fout, "%x %d %s %d Profiler generated, summarized by idal\n",
+					addr, 0, "PROFILEDPOINTER", ii->getPointerCount());
+			}
+			if(ii->getOtherCount())
+			{
+				qfprintf(fout, "%x %d %s %d Profiler generated, summarized by idal\n",
+					addr, 0, "PROFILEDOTHER", ii->getOtherCount());
+			}
+			delete ii;
+		}
+	}
+
+	qfclose(fout);
+
+}
+
+void ProfilerInformation::addProfileInformation(ea_t addr, long long nc, long long pc, long long oc)
+{
+	InstructionInformation *ii=GetInfo(addr);
+
+	if(!ii)
+	{
+		ii = new InstructionInformation;
+		SetInfo(addr,ii);
+	}
+
+	if(nc)
+		ii->setNumericCount(nc);
+	if(pc)
+		ii->setPointerCount(pc);
+	if(oc)
+		ii->setOtherCount(oc);
+
+//	msg("Profiled %x to be nc:%lld pc:%lld oc:%lld\n", addr,
+//		ii->getNumericCount(),
+//		ii->getPointerCount(),
+//		ii->getOtherCount());
+
+	return;
+}
+
+void ProfilerInformation::profileAddressingInformation
+	(
+		ea_t addr,
+		int size,
+		char *type,
+		char *scope, 
+		ea_t the_const,
+		char* field, 
+		ea_t real_const
+	)
+{
+	char buffer[1000];
+	qsnprintf(buffer, sizeof(buffer), "%x %d %s %s %d %s %x Profiler generated, idal summarized\n", 
+		addr, size, type, scope,the_const,field,real_const); 
+	constant_info.insert(std::string(buffer));
+}
diff --git a/ProfilerInformation.h b/ProfilerInformation.h
new file mode 100644
index 0000000000000000000000000000000000000000..125ae09ca19c14fb738c13b6673594d5b1377d07
--- /dev/null
+++ b/ProfilerInformation.h
@@ -0,0 +1,70 @@
+#ifndef PROFILERINFORMATION_H
+#define PROFILERINFORMATION_H
+
+#include <utility>
+#include <list>
+#include <vector>
+#include <map>
+#include <set>
+#include <string>
+
+#include <cstddef>
+
+#include <pro.h>
+#include <ida.hpp>
+#include <ua.hpp>
+
+
+class InstructionInformation
+{
+	public:
+		InstructionInformation() : numeric_count(0), pointer_count(0), other_count(0) {};
+		virtual ~InstructionInformation() {};
+
+		inline int isNumeric() { return numeric_count>0 && pointer_count==0 && other_count==0; }
+		inline void setNumericCount(int nc) { numeric_count=nc;}
+		inline void setPointerCount(int pc) { pointer_count=pc;}
+		inline void setOtherCount(int oc) { other_count=oc;}
+		inline long long getNumericCount() { return numeric_count; }
+		inline long long getPointerCount() { return pointer_count; }
+		inline long long getOtherCount() { return other_count; }
+
+	private:
+
+		long long numeric_count;
+		long long pointer_count;
+		long long other_count;
+};
+
+class ProfilerInformation
+{
+	public:
+		ProfilerInformation(const char*);
+		virtual ~ProfilerInformation();
+
+		inline InstructionInformation* GetInfo(ea_t addr) { return the_map[addr]; }
+
+	protected:
+		// add type information from profiler about loads
+		void addProfileInformation(ea_t addr, long long nc, long long pc, long long oc);
+		
+		// add pre-dec info from profiler
+		void profileAddressingInformation ( ea_t addr, int size, char *type, 
+			char *scope, ea_t the_const, char* field, ea_t real_const);
+
+		inline void SetInfo(ea_t addr, InstructionInformation* ii) { the_map[addr]=ii; }
+
+	private:
+
+		// annotations that are used for numeric type propogation.
+		std::map<ea_t,InstructionInformation*> 	the_map;	
+	
+		// annotations to spew back out verbatim.
+		std::set<std::string>			constant_info;	
+
+		std::string filename;
+
+};
+
+#endif
+