diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp
index 9fd090801c0606cb9f5c6c9e7dd5f3816480eb39..9191aa314796562c8abc17737e7faa739281e9da 100644
--- a/SMPBasicBlock.cpp
+++ b/SMPBasicBlock.cpp
@@ -29,6 +29,7 @@
 #include "SMPFunction.h"
 
 #define SMP_DEBUG_DATAFLOW 0
+#define SMP_DEBUG_OPTIMIZATIONS 1
 
 // Basic block number 0 is the top of the CFG lattice.
 #define SMP_TOP_BLOCK 0 
@@ -590,7 +591,10 @@ void SMPBasicBlock::MarkDeadRegs(void) {
 			}
 		}
 		else if (this->MyFunc->IsGlobalName(FlagsOp)) {
+			;
+#if SMP_DEBUG_OPTIMIZATIONS
 			msg("Global EFLAGS in %s\n", this->MyFunc->GetFuncName());
+#endif
 		}
 		else { // EFLAGS are not locally used, but not global either; they are dead here
 			qstrncat(DeadString, " EFLAGS", sizeof(DeadString) - 1);
diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp
index 4b4c3d45a27c47aeeb1cfa2828a33d7884a22665..1775db670f2307748c73d6cbe750d823a895371c 100644
--- a/SMPDataFlowAnalysis.cpp
+++ b/SMPDataFlowAnalysis.cpp
@@ -1270,6 +1270,10 @@ void InitSMPUsesFlags(void) {
 	(void) memset(SMPUsesFlags, false, sizeof(SMPUsesFlags));
 
 SMPUsesFlags[NN_null] = true;            // Unknown Operation
+#if 1
+SMPUsesFlags[NN_aaa] = true;                 // ASCII adjust after addition
+SMPUsesFlags[NN_aas] = true;				 // ASCII adjust after subtraction
+#endif
 SMPUsesFlags[NN_adc] = true;                 // Add with Carry
 SMPUsesFlags[NN_into] = true;                // Call to Interrupt Procedure if Overflow Flag = 1
 SMPUsesFlags[NN_ja] = true;                  // Jump if Above (CF=0 & ZF=0)
@@ -1320,9 +1324,11 @@ SMPUsesFlags[NN_pushfd] = true;              // Push Flags Register onto the Sta
 SMPUsesFlags[NN_pushfq] = true;              // Push Flags Register onto the Stack (use64)
 SMPUsesFlags[NN_repe] = true;                // Repeat String Operation while ZF=1
 SMPUsesFlags[NN_repne] = true;               // Repeat String Operation while ZF=0
+#if 0
 SMPUsesFlags[NN_sahf] = true;                // Store AH into Flags Register
 SMPUsesFlags[NN_shl] = true;                 // Shift Logical Left
 SMPUsesFlags[NN_shr] = true;                 // Shift Logical Right
+#endif
 SMPUsesFlags[NN_sbb] = true;                 // Integer Subtraction with Borrow
 SMPUsesFlags[NN_seta] = true;                // Set Byte if Above (CF=0 & ZF=0)
 SMPUsesFlags[NN_setae] = true;               // Set Byte if Above or Equal (CF=0)
@@ -1365,7 +1371,9 @@ SMPUsesFlags[NN_stos] = true;                // Store String
 //
 
 SMPUsesFlags[NN_cpuid] = true;               // Get CPU ID
+#if 0
 SMPUsesFlags[NN_cmpxchg8b] = true;           // Compare and Exchange Eight Bytes
+#endif
 
 //
 //      Pentium Pro instructions
@@ -1397,7 +1405,7 @@ SMPUsesFlags[NN_fcmovnbe] = true;            // Floating Move if Not Below or Eq
 SMPUsesFlags[NN_fcmovnu] = true;             // Floating Move if Not Unordered     
 
 //
-//      FPP instructuions
+//      FPP instructions
 //
 
 
diff --git a/SMPStaticAnalyzer.cpp b/SMPStaticAnalyzer.cpp
index 8a8a857386ff9fc6c0c99245a446ecf3a6176deb..1f2264c3e7890c2ca1b7f462a2d0fbe4f0bbb828 100644
--- a/SMPStaticAnalyzer.cpp
+++ b/SMPStaticAnalyzer.cpp
@@ -25,6 +25,7 @@
 
 #include "SMPStaticAnalyzer.h"
 #include "SMPDataFlowAnalysis.h"
+#include "SMPProgram.h"
 #include "SMPFunction.h"
 #include "SMPInstr.h"
 
@@ -60,7 +61,7 @@ int OptCount[LAST_OPT_CATEGORY + 1];
 int AnnotationCount[LAST_OPT_CATEGORY + 1];
 
 // The types of data objects based on their first operand flags.
-static char *DataTypes[] = { "VOID", "NUMHEX", "NUMDEC", "CHAR",
+char *DataTypes[] = { "VOID", "NUMHEX", "NUMDEC", "CHAR",
 		"SEG", "OFFSET", "NUMBIN", "NUMOCT", "ENUM", "FORCED", 
 		"STRUCTOFFSET", "STACKVAR", "NUMFLOAT", "UNKNOWN", 
 		"UNKNOWN", "UNKNOWN", 0};
@@ -172,10 +173,6 @@ void IDAP_term(void) {
 
 void IDAP_run(int arg) {
 	segment_t *seg;
-	char buf[MAXSTR];
-	ea_t ea;
-	flags_t ObjFlags;
-	bool ReadOnlyFlag;
 	FILE *SymsFile;
 	SMPFunction *CurrFunc = NULL;
 	bool FuncsDumped = false;
@@ -227,183 +224,25 @@ void IDAP_run(int arg) {
 	FixupIDB();
 #endif
 
-	// First, examine the data segments and print info about static
-	//   data, such as name/address/size. Do the same for functions in
-	//   code segments.
-	// Loop through all segments.
-	for (int SegIndex = 0; SegIndex < get_segm_qty(); ++SegIndex) {
-		char SegName[MAXSTR];
-		seg = getnseg(SegIndex);
-		ssize_t SegNameSize = get_segm_name(seg, SegName, sizeof(SegName) - 1);
-
-		// We are only interested in the data segments of type
-		// SEG_DATA, SEG_BSS and SEG_COMM.
-		if ((seg->type == SEG_DATA) || (seg->type == SEG_BSS)
-		    || (seg->type == SEG_COMM)) {
-			// Loop through each of the segments we are interested in,
-			//  examining all data objects (effective addresses).
-			ReadOnlyFlag = ((seg->perm & SEGPERM_READ) && (!(seg->perm & SEGPERM_WRITE)));
-#if SMP_DEBUG
-			msg("Starting data segment of type %d", seg->type);
-			if (SegNameSize > 0)
-				msg(" SegName: %s\n", SegName);
-			else
-				msg("\n");
-			if (ReadOnlyFlag) {
-				msg("Read-only data segment.\n");
-			}
-#endif
-			ea = seg->startEA;
-			while (ea < seg->endEA) {
-				ObjFlags = get_flags_novalue(ea);
-				// Only process head bytes of data objects, i.e. isData().
-				if (isData(ObjFlags)) {
-				    // Compute the size of the data object.
-					ea_t NextEA = ea;
-				    do {
-				       NextEA = nextaddr(NextEA);
-					} while ((NextEA < seg->endEA) && (!isHead(get_flags_novalue(NextEA))));
-				    size_t ObjSize = (size_t) (NextEA - ea);
-					// Get the data object name using its address.
-				    char *TrueName = get_true_name(BADADDR, ea, buf, sizeof(buf));
-					if (NULL == TrueName) {
-						qstrncpy(buf, "SMP_dummy0", 12);
-					}
-				    // Output the name, address, size, and type info.
-					if (ReadOnlyFlag) {
-						qfprintf(SymsFile, 
-							"%x %d OBJECT GLOBAL %s  %s RO\n", ea, ObjSize,
-				  			buf, DataTypes[get_optype_flags0(ObjFlags) >> 20]);
-					}
-					else {
-						qfprintf(SymsFile, 
-							"%x %d OBJECT GLOBAL %s  %s RW\n", ea, ObjSize,
-				  			buf, DataTypes[get_optype_flags0(ObjFlags) >> 20]);
-					}
-					// Move on to next data object
-					ea = NextEA;
-				}
-				else {
-					ea = nextaddr(ea);
-				}
-			} // end while (ea < seg->endEA)
-		} // end if (seg->type == SEG_DATA ...)
-		else if (seg->type == SEG_CODE) {
-#if SMP_DEBUG
-			msg("Starting code segment");
-			if (SegNameSize > 0)
-				msg(" SegName: %s\n", SegName);
-			else
-				msg("\n");
-#endif
-#if SMP_DEBUG2
-			if (!FuncsDumped) {
-				for (size_t FuncIndex = 0; FuncIndex < get_func_qty(); ++FuncIndex) {
-					func_t *FuncInfo = getn_func(FuncIndex);
-					get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1);
-					msg("FuncName dump: %s\n", FuncName);
-				}
-				for (size_t ChunkIndex = 0; ChunkIndex < get_fchunk_qty(); ++ChunkIndex) {
-					func_t *ChunkInfo = getn_fchunk((int) ChunkIndex);
-					get_func_name(ChunkInfo->startEA, FuncName, MAXSTR-1);
-					if (0 == strcmp(FuncName, "fflush")) {
-						msg("fflush chunk: address %x", ChunkInfo->startEA);
-						if (is_func_tail(ChunkInfo))
-							msg(" TAIL\n");
-						else
-							msg(" ENTRY\n");
-					}
-					else if ((0x81498f0 < ChunkInfo->startEA)
-							&& (0x8149cb6 > ChunkInfo->startEA)) {
-						msg("Missing fflush chunk: %s %x",
-							FuncName, ChunkInfo->startEA);
-						if (is_func_tail(ChunkInfo))
-							msg(" TAIL\n");
-						else
-							msg(" ENTRY\n");
-					}
-				} // end for (size_t ChunkIndex = ...)
-				func_t *FuncInfo = get_func(0x8149be0);
-				if (NULL == FuncInfo)
-					msg("No func at 0x8149be0\n");
-				else {
-					get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1);
-					msg("Func at 0x8149be0: %s\n", FuncName);
-				}
-				FuncsDumped = true;
-			}
-#endif
-			for (size_t FuncIndex = 0; FuncIndex < get_func_qty(); ++FuncIndex) {
-				func_t *FuncInfo = getn_func(FuncIndex);
-
-				// If more than one SEG_CODE segment, only process 
-				//  functions within the current segment. Don't know
-				//  if multiple code segments are possible, but
-				//  get_func_qty() is for the whole program, not just
-				//  the current segment.
-				if (FuncInfo->startEA < seg->startEA) {
-					// Already processed this func in earlier segment.
-					continue;
-				}
-				else if (FuncInfo->startEA >= seg->endEA) {
-#if SMP_DEBUG2
-						get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1);
-						msg("Skipping function until we reach its segment: %s\n",
-							FuncName);
-#endif
-						break;
-				}
-
-				// Create a function object.
-				if (NULL != CurrFunc){
-					delete CurrFunc;
-					CurrFunc = NULL;
-				}
-				CurrFunc = new SMPFunction(FuncInfo);
-				
-
-#if SMP_BINARY_DEBUG
-				if (FuncsProcessed++ > SMP_DEBUG_COUNT) {
-					get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1);
-					msg("Debug termination. FuncName = %s \n", FuncName);
-					msg("Function startEA: %x endEA: %x \n",
-						FuncInfo->startEA,
-						FuncInfo->endEA);
-				    break;
-				}
-#endif
-#if SMP_BINARY_DEBUG
-				if (FuncsProcessed > SMP_DEBUG_COUNT) {
-					get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1);
-					msg("Final FuncName:  %s \n", FuncName);
-					SMPBinaryDebug = true;
-				}
-#endif
-				CurrFunc->Analyze();
-				CurrFunc->EmitAnnotations(SymsFile);
-				delete CurrFunc;
-				CurrFunc = NULL;
-			} // end for (size_t FuncIndex = 0; ...) 
+	SMPProgram *CurrProg = new SMPProgram();
+	CurrProg->Analyze();
+	CurrProg->EmitAnnotations(SymsFile);
 
 #if SMP_FIND_ORPHANS
+	for (int SegIndex = 0; SegIndex < get_segm_qty(); ++SegIndex) {
+		seg = getnseg(SegIndex);
+		if (seg->type == SEG_CODE)
 			FindOrphanedCode(seg, SymsFile);
+	}
 #endif
 
-		} // end else if (seg->type === SEG_CODE)
-		else {
-#if SMP_DEBUG
-			msg("Not processing segment of type %d SegName: %s\n",
-				seg->type, SegName);
-#endif
-		}
-	} // end for (int SegIndex = 0; ... )
-
 	for (int OptType = 0; OptType <= LAST_OPT_CATEGORY; ++OptType) {
 		msg("Optimization Category Count %d:  %d Annotations: %d\n",
 			OptType, OptCount[OptType], AnnotationCount[OptType]);
 	}
 
 	qfclose(SymsFile);
+	delete CurrProg;
 	return;
 } // end IDAP_run()
 
diff --git a/SMPStaticAnalyzer.h b/SMPStaticAnalyzer.h
index 3d5f6d4465f4f9ed2698f8997bf4ded57f1bb37c..a2785f128f64ad073098e4ddbd1afeac5f50c949 100644
--- a/SMPStaticAnalyzer.h
+++ b/SMPStaticAnalyzer.h
@@ -12,4 +12,6 @@ extern int OptCategory[];
 extern int OptCount[LAST_OPT_CATEGORY + 1];
 extern int AnnotationCount[LAST_OPT_CATEGORY + 1];
 
+extern char *DataTypes[];
+
 #endif