about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-21 04:36:41 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-21 04:36:41 +0000
commit6f290d8f9e9d7faac295cb51fc96884a18f4ded4 (patch)
tree46e7d426abc0c9f06ac472ac6f7f9e661b5d78cb
parenta55960edd4dcd7535526de8d2277642522aa0209 (diff)
downloadklee-6f290d8f9e9d7faac295cb51fc96884a18f4ded4.tar.gz
Initial KLEE checkin.
 - Lots more tweaks, documentation, and web page content is needed,
   but this should compile & work on OS X & Linux.


git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@72205 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--LICENSE.TXT19
-rw-r--r--Makefile57
-rw-r--r--Makefile.common26
-rw-r--r--Makefile.config.in45
-rw-r--r--README.txt30
-rw-r--r--TODO.txt59
-rwxr-xr-xautoconf/AutoRegen.sh41
-rwxr-xr-xautoconf/config.guess1447
-rwxr-xr-xautoconf/config.sub1555
-rw-r--r--autoconf/configure.ac253
-rwxr-xr-xautoconf/install-sh322
-rwxr-xr-xconfigure6039
-rw-r--r--docs/SMT-COMP/BitVector_ArraysEx.smt74
-rw-r--r--docs/SMT-COMP/BitVectors.smt187
-rw-r--r--docs/SMT-COMP/QF_AUFBV.smt19
-rw-r--r--docs/SMT-COMP/QF_BV.smt261
-rw-r--r--docs/doxygen.cfg1291
-rw-r--r--docs/intro10
-rw-r--r--docs/overview104
-rw-r--r--examples/regexp/Regexp.c62
-rw-r--r--examples/regexp/notes.txt26
-rw-r--r--examples/sort/sort.c78
-rw-r--r--include/expr/Lexer.h114
-rw-r--r--include/expr/Parser.h178
-rw-r--r--include/klee/Config/config.h.in64
-rw-r--r--include/klee/Constraints.h79
-rw-r--r--include/klee/ExecutionState.h250
-rw-r--r--include/klee/Expr.h808
-rw-r--r--include/klee/IncompleteSolver.h108
-rw-r--r--include/klee/Internal/ADT/BOut.h62
-rw-r--r--include/klee/Internal/ADT/DiscretePDF.h47
-rw-r--r--include/klee/Internal/ADT/DiscretePDF.inc342
-rw-r--r--include/klee/Internal/ADT/ImmutableMap.h104
-rw-r--r--include/klee/Internal/ADT/ImmutableSet.h101
-rw-r--r--include/klee/Internal/ADT/ImmutableTree.h619
-rw-r--r--include/klee/Internal/ADT/MapOfSets.h385
-rw-r--r--include/klee/Internal/ADT/RNG.h50
-rw-r--r--include/klee/Internal/ADT/TreeStream.h77
-rw-r--r--include/klee/Internal/Module/Cell.h23
-rw-r--r--include/klee/Internal/Module/InstructionInfoTable.h70
-rw-r--r--include/klee/Internal/Module/KInstIterator.h49
-rw-r--r--include/klee/Internal/Module/KInstruction.h50
-rw-r--r--include/klee/Internal/Module/KModule.h119
-rw-r--r--include/klee/Internal/README.txt3
-rw-r--r--include/klee/Internal/Support/FloatEvaluation.h258
-rw-r--r--include/klee/Internal/Support/IntEvaluation.h164
-rw-r--r--include/klee/Internal/Support/ModuleUtil.h40
-rw-r--r--include/klee/Internal/Support/QueryLog.h63
-rw-r--r--include/klee/Internal/Support/Timer.h28
-rw-r--r--include/klee/Internal/System/Time.h20
-rw-r--r--include/klee/Interpreter.h149
-rw-r--r--include/klee/Machine.h28
-rw-r--r--include/klee/Solver.h216
-rw-r--r--include/klee/SolverImpl.h63
-rw-r--r--include/klee/Statistic.h65
-rw-r--r--include/klee/Statistics.h154
-rw-r--r--include/klee/TimerStatIncrementer.h32
-rw-r--r--include/klee/klee.h120
-rw-r--r--include/klee/util/Assignment.h100
-rw-r--r--include/klee/util/BitArray.h42
-rw-r--r--include/klee/util/Bits.h102
-rw-r--r--include/klee/util/ExprEvaluator.h39
-rw-r--r--include/klee/util/ExprHashMap.h48
-rw-r--r--include/klee/util/ExprPPrinter.h58
-rw-r--r--include/klee/util/ExprRangeEvaluator.h283
-rw-r--r--include/klee/util/ExprUtil.h43
-rw-r--r--include/klee/util/ExprVisitor.h95
-rw-r--r--include/klee/util/Ref.h303
-rw-r--r--lib/Basic/BOut.cpp236
-rw-r--r--lib/Basic/Makefile16
-rw-r--r--lib/Basic/README.txt3
-rw-r--r--lib/Basic/Statistics.cpp84
-rw-r--r--lib/Core/AddressSpace.cpp334
-rw-r--r--lib/Core/AddressSpace.h131
-rw-r--r--lib/Core/CallPathManager.cpp103
-rw-r--r--lib/Core/CallPathManager.h83
-rw-r--r--lib/Core/Common.cpp110
-rw-r--r--lib/Core/Common.h56
-rw-r--r--lib/Core/CoreStats.cpp29
-rw-r--r--lib/Core/CoreStats.h53
-rw-r--r--lib/Core/ExecutionState.cpp417
-rw-r--r--lib/Core/Executor.cpp3260
-rw-r--r--lib/Core/Executor.h445
-rw-r--r--lib/Core/ExecutorTimers.cpp220
-rw-r--r--lib/Core/ExecutorUtil.cpp144
-rw-r--r--lib/Core/ExternalDispatcher.cpp230
-rw-r--r--lib/Core/ExternalDispatcher.h50
-rw-r--r--lib/Core/ImpliedValue.cpp274
-rw-r--r--lib/Core/ImpliedValue.h38
-rwxr-xr-xlib/Core/Makefile16
-rw-r--r--lib/Core/Memory.cpp812
-rw-r--r--lib/Core/Memory.h239
-rw-r--r--lib/Core/MemoryManager.cpp69
-rw-r--r--lib/Core/MemoryManager.h41
-rw-r--r--lib/Core/ObjectHolder.h33
-rw-r--r--lib/Core/PTree.cpp103
-rw-r--r--lib/Core/PTree.h53
-rw-r--r--lib/Core/Searcher.cpp575
-rw-r--r--lib/Core/Searcher.h279
-rw-r--r--lib/Core/SeedInfo.cpp151
-rw-r--r--lib/Core/SeedInfo.h48
-rw-r--r--lib/Core/SpecialFunctionHandler.cpp727
-rw-r--r--lib/Core/SpecialFunctionHandler.h106
-rw-r--r--lib/Core/StatsTracker.cpp814
-rw-r--r--lib/Core/StatsTracker.h93
-rw-r--r--lib/Core/TimingSolver.cpp147
-rw-r--r--lib/Core/TimingSolver.h70
-rw-r--r--lib/Core/UserSearcher.cpp175
-rw-r--r--lib/Core/UserSearcher.h25
-rw-r--r--lib/Expr/Constraints.cpp155
-rw-r--r--lib/Expr/Expr.cpp1122
-rw-r--r--lib/Expr/ExprEvaluator.cpp74
-rw-r--r--lib/Expr/ExprPPrinter.cpp478
-rw-r--r--lib/Expr/ExprUtil.cpp127
-rw-r--r--lib/Expr/ExprVisitor.cpp253
-rw-r--r--lib/Expr/Lexer.cpp261
-rw-r--r--lib/Expr/Makefile16
-rw-r--r--lib/Expr/Parser.cpp1310
-rw-r--r--lib/Expr/Updates.cpp126
-rw-r--r--lib/Makefile15
-rw-r--r--lib/Module/Checks.cpp68
-rw-r--r--lib/Module/InstructionInfoTable.cpp196
-rw-r--r--lib/Module/IntrinsicCleaner.cpp119
-rw-r--r--lib/Module/KInstruction.cpp19
-rw-r--r--lib/Module/KModule.cpp506
-rw-r--r--lib/Module/LowerSwitch.cpp134
-rwxr-xr-xlib/Module/Makefile16
-rw-r--r--lib/Module/ModuleUtil.cpp101
-rw-r--r--lib/Module/Optimize.cpp272
-rw-r--r--lib/Module/Passes.h132
-rw-r--r--lib/Module/PhiCleaner.cpp83
-rw-r--r--lib/Module/RaiseAsm.cpp69
-rw-r--r--lib/README.txt18
-rw-r--r--lib/Solver/CachingSolver.cpp241
-rw-r--r--lib/Solver/CexCachingSolver.cpp313
-rw-r--r--lib/Solver/ConstantDivision.cpp146
-rw-r--r--lib/Solver/ConstantDivision.h51
-rw-r--r--lib/Solver/FastCexSolver.cpp959
-rw-r--r--lib/Solver/IncompleteSolver.cpp136
-rw-r--r--lib/Solver/IndependentSolver.cpp314
-rwxr-xr-xlib/Solver/Makefile16
-rw-r--r--lib/Solver/PCLoggingSolver.cpp134
-rw-r--r--lib/Solver/STPBuilder.cpp819
-rw-r--r--lib/Solver/STPBuilder.h125
-rw-r--r--lib/Solver/Solver.cpp643
-rw-r--r--lib/Solver/SolverStats.cpp23
-rw-r--r--lib/Solver/SolverStats.h32
-rw-r--r--lib/Support/Makefile16
-rw-r--r--lib/Support/README.txt2
-rw-r--r--lib/Support/RNG.cpp146
-rw-r--r--lib/Support/Time.cpp27
-rw-r--r--lib/Support/Timer.cpp27
-rw-r--r--lib/Support/TreeStream.cpp201
-rw-r--r--runtime/Intrinsic/Makefile20
-rw-r--r--runtime/Intrinsic/klee_div_zero_check.c15
-rw-r--r--runtime/Intrinsic/klee_int.c17
-rw-r--r--runtime/Intrinsic/klee_make_symbolic.c14
-rw-r--r--runtime/Intrinsic/klee_range.c33
-rw-r--r--runtime/Intrinsic/memcpy.c19
-rw-r--r--runtime/Intrinsic/memmove.c28
-rw-r--r--runtime/Intrinsic/mempcpy.c19
-rw-r--r--runtime/Intrinsic/memset.c17
-rwxr-xr-xruntime/Makefile26
-rw-r--r--runtime/POSIX/Makefile20
-rw-r--r--runtime/POSIX/fd.c1287
-rw-r--r--runtime/POSIX/fd.h90
-rw-r--r--runtime/POSIX/fd_32.c196
-rw-r--r--runtime/POSIX/fd_64.c90
-rw-r--r--runtime/POSIX/fd_init.c161
-rw-r--r--runtime/POSIX/illegal.c70
-rw-r--r--runtime/POSIX/klee_init_env.c181
-rw-r--r--runtime/POSIX/misc.c87
-rw-r--r--runtime/POSIX/selinux.c80
-rw-r--r--runtime/POSIX/stubs.c560
l---------runtime/POSIX/testing-dir/a1
l---------runtime/POSIX/testing-dir/b1
-rwxr-xr-xruntime/POSIX/testing-dir/c2
-rw-r--r--runtime/POSIX/testing-dir/d0
-rw-r--r--runtime/POSIX/testing-env27
-rw-r--r--runtime/Runtest/Makefile19
-rw-r--r--runtime/Runtest/intrinsics.c154
-rwxr-xr-xruntime/klee-libc/Makefile19
-rw-r--r--runtime/klee-libc/__cxa_atexit.c49
-rw-r--r--runtime/klee-libc/abort.c16
-rw-r--r--runtime/klee-libc/atexit.c16
-rw-r--r--runtime/klee-libc/atoi.c37
-rw-r--r--runtime/klee-libc/calloc.c46
-rw-r--r--runtime/klee-libc/htonl.c49
-rw-r--r--runtime/klee-libc/klee-choose.c20
-rw-r--r--runtime/klee-libc/memchr.c54
-rw-r--r--runtime/klee-libc/memcmp.c53
-rw-r--r--runtime/klee-libc/memcpy.c19
-rw-r--r--runtime/klee-libc/memmove.c28
-rw-r--r--runtime/klee-libc/mempcpy.c19
-rw-r--r--runtime/klee-libc/memset.c17
-rw-r--r--runtime/klee-libc/putchar.c17
-rw-r--r--runtime/klee-libc/stpcpy.c43
-rw-r--r--runtime/klee-libc/strcat.c47
-rw-r--r--runtime/klee-libc/strchr.c23
-rw-r--r--runtime/klee-libc/strcmp.c14
-rw-r--r--runtime/klee-libc/strcoll.c15
-rw-r--r--runtime/klee-libc/strcpy.c17
-rw-r--r--runtime/klee-libc/strlen.c17
-rw-r--r--runtime/klee-libc/strncmp.c49
-rw-r--r--runtime/klee-libc/strncpy.c58
-rw-r--r--runtime/klee-libc/strrchr.c21
-rw-r--r--runtime/klee-libc/strtol.c135
-rw-r--r--runtime/klee-libc/strtoul.c113
-rw-r--r--runtime/klee-libc/tolower.c14
-rw-r--r--runtime/klee-libc/toupper.c14
-rwxr-xr-xscripts/IStatsMerge.py175
-rwxr-xr-xscripts/IStatsSum.py129
-rwxr-xr-xscripts/PrintStats.py231
-rwxr-xr-xscripts/klee-control89
-rwxr-xr-xscripts/objdump41
-rw-r--r--stp/AST/AST.cpp1587
-rw-r--r--stp/AST/AST.h1805
-rw-r--r--stp/AST/ASTKind.kinds71
-rw-r--r--stp/AST/ASTUtil.cpp45
-rw-r--r--stp/AST/ASTUtil.h107
-rw-r--r--stp/AST/BitBlast.cpp812
-rw-r--r--stp/AST/Makefile54
-rw-r--r--stp/AST/STLport_config.h20
-rw-r--r--stp/AST/SimpBool.cpp408
-rw-r--r--stp/AST/ToCNF.cpp506
-rw-r--r--stp/AST/ToSAT.cpp1385
-rw-r--r--stp/AST/Transform.cpp492
-rw-r--r--stp/AST/asttest.cpp29
-rw-r--r--stp/AST/bbtest.cpp96
-rw-r--r--stp/AST/cnftest.cpp47
-rwxr-xr-xstp/AST/genkinds.pl123
-rw-r--r--stp/INSTALL10
-rw-r--r--stp/LICENSE17
-rw-r--r--stp/Makefile64
-rw-r--r--stp/Makefile.common.in16
-rw-r--r--stp/README26
-rw-r--r--stp/bitvec/Makefile11
-rw-r--r--stp/bitvec/consteval.cpp1044
-rw-r--r--stp/c_interface/Makefile13
-rw-r--r--stp/c_interface/c_interface.cpp1548
-rw-r--r--stp/c_interface/c_interface.h401
-rw-r--r--stp/c_interface/fdstream.h186
-rw-r--r--stp/constantbv/Makefile13
-rw-r--r--stp/constantbv/constantbv.cpp3571
-rw-r--r--stp/constantbv/constantbv.h316
-rw-r--r--stp/parser/Makefile27
-rw-r--r--stp/parser/PL.lex128
-rw-r--r--stp/parser/PL.y1006
-rw-r--r--stp/parser/let-funcs.cpp85
-rw-r--r--stp/parser/main.cpp181
-rw-r--r--stp/parser/smtlib.lex232
-rw-r--r--stp/parser/smtlib.y1036
-rw-r--r--stp/sat/Global.h255
-rw-r--r--stp/sat/Heap.h151
-rw-r--r--stp/sat/LICENSE20
-rw-r--r--stp/sat/Makefile16
-rw-r--r--stp/sat/Simplifier.C542
-rw-r--r--stp/sat/Solver.C811
-rw-r--r--stp/sat/Solver.h359
-rw-r--r--stp/sat/SolverTypes.h127
-rw-r--r--stp/sat/Sort.h133
-rw-r--r--stp/sat/VarOrder.h146
-rw-r--r--stp/simplifier/Makefile11
-rw-r--r--stp/simplifier/bvsolver.cpp714
-rw-r--r--stp/simplifier/bvsolver.h134
-rw-r--r--stp/simplifier/simplifier.cpp2495
-rw-r--r--test/CXX/ArrayNew.cpp38
-rw-r--r--test/CXX/New.cpp29
-rw-r--r--test/CXX/SimpleVirtual.cpp38
-rw-r--r--test/CXX/StaticConstructor.cpp25
-rw-r--r--test/CXX/StaticDestructor.cpp24
-rw-r--r--test/CXX/Trivial.cpp22
-rw-r--r--test/CXX/dg.exp3
-rw-r--r--test/Concrete/BitwiseOps.ll15
-rw-r--r--test/Concrete/BoolReadWrite.ll13
-rwxr-xr-xtest/Concrete/Casts.ll28
-rw-r--r--test/Concrete/CmpEq.ll14
-rwxr-xr-xtest/Concrete/ConcreteTest.py99
-rw-r--r--test/Concrete/ConstantExpr.ll166
-rw-r--r--test/Concrete/FloatingPointOps.ll685
-rwxr-xr-xtest/Concrete/GlobalInitializers.ll47
-rw-r--r--test/Concrete/GlobalVariable.ll9
-rw-r--r--test/Concrete/ICmp.ll245
-rw-r--r--test/Concrete/InvokeAndReturn.ll18
-rw-r--r--test/Concrete/InvokeAndUnwindOnce.ll18
-rw-r--r--test/Concrete/InvokeAndUnwindTwice.ll22
-rw-r--r--test/Concrete/Makefile55
-rw-r--r--test/Concrete/OneCall.ll12
-rw-r--r--test/Concrete/OverlappingPhiNodes.ll15
-rw-r--r--test/Concrete/Select.ll15
-rw-r--r--test/Concrete/Shifts.ll21
-rw-r--r--test/Concrete/SimpleStoreAndLoad.ll17
-rw-r--r--test/Concrete/UnconditionalBranch.ll10
-rw-r--r--test/Concrete/UnconditionalBranchWithSimplePhi.ll14
-rw-r--r--test/Concrete/UnorderedPhiNodes.ll15
-rw-r--r--test/Concrete/_testingUtils.c32
-rw-r--r--test/Concrete/ackermann.c16
-rw-r--r--test/Concrete/arith_test.ll76
-rw-r--r--test/Coverage/ReadArgs.c9
-rw-r--r--test/Coverage/ReplayOutDir.c11
-rw-r--r--test/Coverage/dg.exp3
-rw-r--r--test/Dogfood/ImmutableSet.cpp134
-rw-r--r--test/Dogfood/dg.exp3
-rw-r--r--test/Expr/dg.exp3
-rw-r--r--test/Feature/Alias.c25
-rw-r--r--test/Feature/AliasFunction.c33
-rw-r--r--test/Feature/AliasFunctionExit.c30
-rw-r--r--test/Feature/AsmAddresses.c22
-rw-r--r--test/Feature/ByteSwap.c16
-rw-r--r--test/Feature/CallToUndefinedExternal.cpp11
-rw-r--r--test/Feature/CheckForImpliedValue.c.failing23
-rw-r--r--test/Feature/CheckMemoryAccess.c26
-rw-r--r--test/Feature/CopyOnWrite.c26
-rw-r--r--test/Feature/DanglingConcreteReadExpr.c22
-rw-r--r--test/Feature/DefineFixedObject.c17
-rw-r--r--test/Feature/DoubleFree.c10
-rw-r--r--test/Feature/DumpStatesOnHalt.c8
-rw-r--r--test/Feature/Envp.c18
-rw-r--r--test/Feature/ExprLogging.c43
-rw-r--r--test/Feature/ExternalWeakLinkage.c11
-rw-r--r--test/Feature/FunctionPointer.c36
-rw-r--r--test/Feature/GetValue.c17
-rw-r--r--test/Feature/ImpliedValue.c.failing147
-rw-r--r--test/Feature/InAndOutOfBounds.c19
-rw-r--r--test/Feature/IndirectCallToBuiltin.c15
-rw-r--r--test/Feature/IndirectCallToExternal.c15
-rw-r--r--test/Feature/InvalidBitfieldAccess.c.failing28
-rw-r--r--test/Feature/IsSymbolic.c16
-rw-r--r--test/Feature/KleeReportError.c23
-rw-r--r--test/Feature/LongDoubleSupport.c20
-rw-r--r--test/Feature/LowerSwitch.c30
-rw-r--r--test/Feature/MakeConcreteSymbolic.c19
-rw-r--r--test/Feature/MakeSymbolicName.c17
-rw-r--r--test/Feature/MemoryLimit.c37
-rw-r--r--test/Feature/MultipleFreeResolution.c39
-rw-r--r--test/Feature/MultipleReadResolution.c43
-rw-r--r--test/Feature/MultipleReallocResolution.c63
-rw-r--r--test/Feature/MultipleWriteResolution.c43
-rw-r--r--test/Feature/NamedSeedMatching.c41
-rw-r--r--test/Feature/OneFreeError.c10
-rw-r--r--test/Feature/OneOutOfBounds.c10
-rw-r--r--test/Feature/Optimize.c22
-rw-r--r--test/Feature/OverlappedError.c19
-rw-r--r--test/Feature/PreferCex.c18
-rw-r--r--test/Feature/RaiseAsm.c39
-rw-r--r--test/Feature/ReallocFailure.c18
-rw-r--r--test/Feature/ReplayPath.c27
-rw-r--r--test/Feature/Searchers.c52
-rw-r--r--test/Feature/SetForking.c28
-rw-r--r--test/Feature/Vararg.c82
-rw-r--r--test/Feature/WithLibc.c22
-rw-r--r--test/Feature/WriteCov.c15
-rw-r--r--test/Feature/_utils._ll71
-rw-r--r--test/Feature/const_array_opt1.c37
-rw-r--r--test/Feature/dg.exp3
-rw-r--r--test/Feature/utils.h16
-rw-r--r--test/Makefile101
-rw-r--r--test/Makefile.tests80
-rw-r--r--test/README1
-rw-r--r--test/Runtime/POSIX/DirConsistency.c64
-rw-r--r--test/Runtime/POSIX/DirSeek.c57
-rw-r--r--test/Runtime/POSIX/FDNumbers.c24
-rw-r--r--test/Runtime/POSIX/FD_Fail.c25
-rw-r--r--test/Runtime/POSIX/FD_Fail2.c34
-rw-r--r--test/Runtime/POSIX/Fcntl.c17
-rw-r--r--test/Runtime/POSIX/FilePerm.c20
-rw-r--r--test/Runtime/POSIX/FreeArgv.c20
-rw-r--r--test/Runtime/POSIX/Getenv.c21
-rw-r--r--test/Runtime/POSIX/Ioctl.c31
-rw-r--r--test/Runtime/POSIX/Isatty.c33
-rw-r--r--test/Runtime/POSIX/PrgName.c31
-rw-r--r--test/Runtime/POSIX/Read1.c34
-rw-r--r--test/Runtime/POSIX/SELinux.c30
-rw-r--r--test/Runtime/POSIX/SeedAndFail.c38
-rw-r--r--test/Runtime/POSIX/Stdin.c56
-rw-r--r--test/Runtime/POSIX/Write1.c23
-rw-r--r--test/Runtime/POSIX/Write2.c21
-rw-r--r--test/Runtime/POSIX/dg.exp5
-rw-r--r--test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c19
-rw-r--r--test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c12
-rw-r--r--test/Runtime/Uclibc/Environ.c10
-rw-r--r--test/Runtime/Uclibc/dg.exp5
-rwxr-xr-xtest/TestRunner.sh36
-rw-r--r--test/lib/llvm.exp213
-rw-r--r--test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c20
-rw-r--r--test/regression/2007-07-30-unflushed-byte.c18
-rw-r--r--test/regression/2007-08-01-bool-zext-in-call.ll22
-rw-r--r--test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c25
-rw-r--r--test/regression/2007-08-06-64bit-shift.c20
-rw-r--r--test/regression/2007-08-06-access-after-free.c29
-rw-r--r--test/regression/2007-08-08-free-zero.c8
-rw-r--r--test/regression/2007-08-16-invalid-constant-value.c31
-rw-r--r--test/regression/2007-08-16-valid-write-to-freed-object.c24
-rw-r--r--test/regression/2007-10-11-free-of-alloca.c9
-rw-r--r--test/regression/2007-10-11-illegal-access-after-free-and-branch.c19
-rw-r--r--test/regression/2007-10-12-failed-make-symbolic-after-copy.c22
-rw-r--r--test/regression/2008-02-11-phi-nodes-after-invoke.ll47
-rw-r--r--test/regression/2008-03-04-free-of-global.c10
-rw-r--r--test/regression/2008-03-11-free-of-malloc-zero.c16
-rw-r--r--test/regression/2008-04-10-bad-alloca-free.c12
-rw-r--r--test/regression/2008-05-23-gep-with-global-const.c15
-rw-r--r--test/regression/dg.exp3
-rw-r--r--tools/Makefile21
-rw-r--r--tools/gen-random-bout/Makefile7
-rw-r--r--tools/gen-random-bout/gen-random-bout.cpp124
-rw-r--r--tools/kleaver/Makefile19
-rw-r--r--tools/kleaver/main.cpp120
-rw-r--r--tools/klee-bout-tool/Makefile46
-rwxr-xr-xtools/klee-bout-tool/klee-bout-tool106
-rw-r--r--tools/klee/Debug.cpp12
-rw-r--r--tools/klee/Makefile22
-rw-r--r--tools/klee/main.cpp1422
-rw-r--r--unittests/Expr/ExprTest.cpp112
-rw-r--r--unittests/Expr/Makefile11
-rwxr-xr-xunittests/Makefile18
-rw-r--r--unittests/Solver/Makefile11
-rw-r--r--unittests/Solver/SolverTest.cpp164
-rw-r--r--unittests/TestMain.cpp15
-rw-r--r--utils/emacs/klee-pc-mode.el64
-rw-r--r--utils/valgrind/README.txt2
-rw-r--r--utils/valgrind/valgrind-llvm.supp24
-rw-r--r--utils/valgrind/valgrind-stp.supp32
-rw-r--r--www/Examples.html34
-rw-r--r--www/GetInvolved.html34
-rw-r--r--www/GetStarted.html101
-rw-r--r--www/bugs.html2
-rw-r--r--www/content.css20
-rw-r--r--www/index.html4
-rw-r--r--www/install.html2
-rw-r--r--www/menu.html.incl7
-rw-r--r--www/tutorials.html4
431 files changed, 74977 insertions, 34 deletions
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 20b7da58..ce3677c5 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -11,8 +11,7 @@ Developed by:
 
     klee Team
 
-    Stanford Checking Group: Daniel Dunbar, Cristian Cadar, Peter
-    Pawlowki, Dawson Engler.
+    Stanford Checking Group
 
     http://klee.llvm.org
 
@@ -30,10 +29,10 @@ so, subject to the following conditions:
       this list of conditions and the following disclaimers in the
       documentation and/or other materials provided with the distribution.
 
-    * Neither the names of the LLVM Team, University of Illinois at
-      Urbana-Champaign, nor the names of its contributors may be used to
-      endorse or promote products derived from this Software without specific
-      prior written permission.
+    * Neither the names of the klee Team, Stanford University, nor the
+      names of its contributors may be used to endorse or promote
+      products derived from this Software without specific prior
+      written permission.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
@@ -50,10 +49,9 @@ This file will describe the copyrights, license, and restrictions which apply
 to that code.
 
 The disclaimer of warranty in the University of Illinois Open Source License
-applies to all code in the klee Distribution, and nothing in any of the
-other licenses gives permission to use the names of the klee Team or the
-University of Illinois to endorse or promote products derived from this
-Software.
+applies to all code in the klee Distribution, and nothing in any of the other 
+licenses gives permission to use the names of the klee Team or Stanford 
+University to endorse or promote products derived from this Software.
 
 The following pieces of software have additional or alternate copyrights,
 licenses, and/or restrictions:
@@ -61,4 +59,5 @@ licenses, and/or restrictions:
 Program             Directory
 -------             ---------
 STP                 klee/stp
+klee-libc           runtime/klee-libc
 
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..ec9c7cca
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,57 @@
+#===-- klee/Makefile ---------------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+#
+# Indicates our relative path to the top of the project's root directory.
+#
+LEVEL = .
+
+DIRS = stp lib tools runtime
+EXTRA_DIST = include
+
+# Only build support directories when building unittests.
+ifeq ($(MAKECMDGOALS),unittests)
+  DIRS := $(filter-out tools runtime, $(DIRS)) unittests
+  OPTIONAL_DIRS :=
+endif
+
+#
+# Include the Master Makefile that knows how to build all.
+#
+include $(LEVEL)/Makefile.common
+
+.PHONY: doxygen
+doxygen:
+	doxygen docs/doxygen.cfg
+
+.PHONY: cscope.files
+cscope.files:
+	find \
+          lib include stp tools runtime examples unittests \
+          -name Makefile -or \
+          -name \*.in -or \
+          -name \*.c -or \
+          -name \*.cpp -or \
+          -name \*.exp -or \
+          -name \*.inc -or \
+          -name \*.h | sort > cscope.files
+
+test::
+	-(cd test/ && make)
+
+.PHONY: klee-cov
+klee-cov:
+	rm -rf klee-cov
+	zcov-scan --look-up-dirs=1 klee.zcov .
+	zcov-genhtml --root $$(pwd) klee.zcov klee-cov
+
+clean::
+	$(MAKE) -C test clean 
+	$(MAKE) -C unittests clean
+	rm -rf docs/doxygen
diff --git a/Makefile.common b/Makefile.common
new file mode 100644
index 00000000..b8b352aa
--- /dev/null
+++ b/Makefile.common
@@ -0,0 +1,26 @@
+# -*- Makefile -*-
+
+include $(LEVEL)/Makefile.config
+
+# Include LLVM's Master Makefile config and rules.
+include $(LLVM_OBJ_ROOT)/Makefile.config
+
+ifeq ($(BYTECODE_LIBRARY), 1)
+#
+# Override make variables based on the runtime configuration. We want
+# to override whatever the user may have said on the command line,
+# hence the use of override.
+#
+
+override ENABLE_OPTIMIZED := $(RUNTIME_ENABLE_OPTIMIZED)
+override DISABLE_ASSERTIONS := $(RUNTIME_DISABLE_ASSERTIONS)
+override ENABLE_PROFILING := $(RUNTIME_ENABLE_PROFILING)
+override ENABLE_COVERAGE := $(RUNTIME_ENABLE_COVERAGE)
+endif
+
+include $(LLVM_OBJ_ROOT)/Makefile.rules
+
+LD.Flags += -L$(PROJ_SRC_ROOT)/stp/lib
+CXX.Flags += -DLLVM_23
+CXX.Flags += -I$(PROJ_SRC_ROOT)/stp/include
+CXX.Flags += -DKLEE_DIR=\"$(PROJ_SRC_ROOT)\"
diff --git a/Makefile.config.in b/Makefile.config.in
new file mode 100644
index 00000000..0b858831
--- /dev/null
+++ b/Makefile.config.in
@@ -0,0 +1,45 @@
+# -*- Makefile -*-
+
+# Set the name of the project here
+PROJECT_NAME := klee
+PROJ_VERSION := 0.01
+
+# Set this variable to the top of the LLVM source tree.
+LLVM_SRC_ROOT = @LLVM_SRC@
+
+# Set this variable to the top level directory where LLVM was built
+# (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config).
+LLVM_OBJ_ROOT = @LLVM_OBJ@
+
+# Set the directory root of this project's source files
+PROJ_SRC_ROOT := $(subst //,/,@abs_top_srcdir@)
+
+# Set the root directory of this project's object files
+PROJ_OBJ_ROOT := $(subst //,/,@abs_top_objdir@)
+
+# Set the root directory of this project's install prefix
+PROJ_INSTALL_ROOT := @prefix@
+
+ENABLE_POSIX_RUNTIME := @ENABLE_POSIX_RUNTIME@
+ENABLE_STPLOG := @ENABLE_STPLOG@
+ENABLE_UCLIBC := @ENABLE_UCLIBC@
+
+HAVE_SELINUX := @HAVE_SELINUX@
+
+RUNTIME_ENABLE_OPTIMIZED := @RUNTIME_ENABLE_OPTIMIZED@
+RUNTIME_DISABLE_ASSERTIONS :=
+RUNTIME_ENABLE_COVERAGE :=
+RUNTIME_ENABLE_PROFILING :=
+
+# A list of "features" which tests can check for in XFAIL:
+TEST_FEATURE_LIST :=
+
+ifeq ($(HAVE_SELINUX_SELINUX_H),1)
+  TEST_FEATURE_LIST += have-selinux
+else
+  TEST_FEATURE_LIST += no-selinux
+endif
+
+CFLAGS := @CFLAGS@
+CXXFLAGS := @CXXFLAGS@
+LDFLAGS := @LDFLAGS@
diff --git a/README.txt b/README.txt
index 0c1a79e9..96d60a9e 100644
--- a/README.txt
+++ b/README.txt
@@ -1,24 +1,24 @@
 //===----------------------------------------------------------------------===//
 // Klee Symbolic Virtual Machine
 //===----------------------------------------------------------------------===//
-                                                             Daniel Dunbar
 
 klee is a symbolic virtual machine built on top of the LLVM compiler
-infrastructure. Currently, there are two primary components.
+infrastructure. Currently, there are two primary components:
 
-1. The core symbolic virtual machine engine; this is responsible for
-executing LLVM bitcode modules with support for symbolic values. This
-is comprised of the code in lib/.
+  1. The core symbolic virtual machine engine; this is responsible for
+     executing LLVM bitcode modules with support for symbolic
+     values. This is comprised of the code in lib/.
 
-2. An emulation layer for the Linux system call interface, with
-additional support for making parts of the operating environment
-symbolic. This is found in models/simple.
+  2. A POSIX/Linux emulation layer oriented towards supporting uClibc,
+     with additional support for making parts of the operating system
+     environment symbolic.
 
-Additionally, there is a simple library in runtime/ which supports
-replaying computed inputs on native code. There is a more complicated
-library in replay/ which supports running inputs computed as part of
-the system call emulation layer natively -- setting up files, pipes,
-etc. on the native system to match the inputs that the emulation layer
-provided.
+Additionally, there is a simple library for replaying computed inputs
+on native code (for closed programs). There is also a more complicated
+infrastructure for replaying the inputs generated for the POSIX/Linux
+emulation layer, which handles running native programs in an
+environment that matches a computed test input, including setting up
+files, pipes, environment variables, and passing command line
+arguments.
 
-For further information, see the docs in www/.
+For further information, see the webpage or docs in www/.
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 00000000..bbdd4c86
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,59 @@
+TODO
+--
+
+Build System / Configure / Release Cleanups
+--
+ o Rename .bout to .ktest (klee test)
+
+ o Rename .pc to .kquery (kleaver query)
+
+ o Configure doesn't check for bison / flex, we don't really use these
+   for anything important (just the command line STP tool), it would
+   be nice if they weren't required.
+
+ o Need a way to hide LLVM options in "klee --help".
+
+Klee Internal
+--
+ o Make sure that namespaces and .cpp locations match with reorganized
+   include locations.
+
+ o Add replay framework for POSIX model tests.
+
+Kleaver Internal
+--
+ o We need to fix the constants-in-exprs problem, this makes
+   separating out a Kleaver expr library much more difficult. There
+   are two parts:
+   
+     1. Pull fast (pure constant) path operations out of Expr.cpp,
+        into Executor.cpp.
+
+     2. Lift constants-are-immediate optimization out of ref<Expr>
+        into Cell. Expressions in memory already have the concrete
+        cache, so we get that part for free. 
+
+        We will need a way to distinguish if a cell has an expr or a
+        constant. Incidentally, this gives us an extra sentinel value
+        (is-expr == true and Expr* == null) we can use to mark
+        uninitialized-value of a register.
+
+   It may be worth sinking Expr construction into a Builder class
+   while we are at it.
+
+   There is a also a nice cleanup/perf win where we can work with
+   registers (Cells) directly, now that we build the constant table,
+   it might be worth doing this at the same time. This exposes a win
+   for IVC where it can write back a constant value into a register,
+   which needs to be done with care but would be a big improvement for
+   IVC.
+
+ o The stpArray field of an UpdateNode needs to die. This isn't as
+   easy as dropping it from the map, because we also need a
+   notification to free it. I think probably what we should do is
+   introduce an ExprContext can be used to deal with such things.
+     o The ExprContext could also have the default builder, for
+       example, which would make it easy to swap in an optimizing
+       builder.
+
+
diff --git a/autoconf/AutoRegen.sh b/autoconf/AutoRegen.sh
new file mode 100755
index 00000000..4a34f8c0
--- /dev/null
+++ b/autoconf/AutoRegen.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+if ([ "$#" != 1 ] || 
+    [ ! -d "$1" ] ||
+    [ ! -d "$1/autoconf/m4" ]); then
+    echo "usage: $0 <llvmsrc-dir>" 1>& 2
+    exit 1
+fi
+
+llvm_src_root=$(cd $1; pwd)
+llvm_m4=$llvm_src_root/autoconf/m4
+die () {
+	echo "$@" 1>&2
+	exit 1
+}
+test -d autoconf && test -f autoconf/configure.ac && cd autoconf
+test -f configure.ac || die "Can't find 'autoconf' dir; please cd into it first"
+autoconf --version | egrep '2\.60' > /dev/null
+if test $? -ne 0 ; then
+  die "Your autoconf was not detected as being 2.60"
+fi
+# Patch LLVM_SRC_ROOT in configure.ac
+sed -e "s#^LLVM_SRC_ROOT=.*#LLVM_SRC_ROOT=\"$llvm_src_root\"#" \
+    configure.ac > configure.tmp.ac
+echo "Regenerating aclocal.m4 with aclocal"
+rm -f aclocal.m4
+echo aclocal -I $llvm_m4 -I "$llvm_m4/.." || die "aclocal failed"
+aclocal -I $llvm_m4 -I "$llvm_m4/.." || die "aclocal failed"
+echo "Regenerating configure with autoconf 2.60"
+echo autoconf --warnings=all -o ../configure configure.tmp.ac || die "autoconf failed"
+autoconf --warnings=all -o ../configure configure.tmp.ac || die "autoconf failed"
+cp ../configure ../configure.bak
+sed -e "s#^LLVM_SRC_ROOT=.*#LLVM_SRC_ROOT=\".\"#" \
+    ../configure.bak > ../configure
+cd ..
+echo "Regenerating config.h.in with autoheader"
+autoheader --warnings=all \
+    -I autoconf -I autoconf/m4 \
+    autoconf/configure.tmp.ac || die "autoheader failed"
+rm -f autoconf/configure.tmp.ac configure.bak
+exit 0
diff --git a/autoconf/config.guess b/autoconf/config.guess
new file mode 100755
index 00000000..7d0185e0
--- /dev/null
+++ b/autoconf/config.guess
@@ -0,0 +1,1447 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-09-07'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amd64:OpenBSD:*:*)
+	echo x86_64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    cats:OpenBSD:*:*)
+	echo arm-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    luna88k:OpenBSD:*:*)
+    	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit 0 ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+	i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms && exit 0 ;;
+	    I*) echo ia64-dec-vms && exit 0 ;;
+	    V*) echo vax-dec-vms && exit 0 ;;
+	esac
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/autoconf/config.sub b/autoconf/config.sub
new file mode 100755
index 00000000..edb6b663
--- /dev/null
+++ b/autoconf/config.sub
@@ -0,0 +1,1555 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-08-29'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
new file mode 100644
index 00000000..9c24a1ef
--- /dev/null
+++ b/autoconf/configure.ac
@@ -0,0 +1,253 @@
+dnl **************************************************************************
+dnl * Initialize
+dnl **************************************************************************
+AC_INIT([[KLEE]],[[0.01]],[daniel@minormatter.com])
+
+dnl Identify where LLVM source tree is (this is patched by
+dnl AutoRegen.sh)
+LLVM_SRC_ROOT=XXX
+
+dnl Tell autoconf that the auxilliary files are actually located in
+dnl the LLVM autoconf directory, not here.
+AC_CONFIG_AUX_DIR($LLVM_SRC_ROOT/autoconf)
+
+dnl Tell autoconf that this is an LLVM project being configured
+dnl This provides the --with-llvmsrc and --with-llvmobj options
+LLVM_CONFIG_PROJECT("","")
+
+dnl Verify that the source directory is valid
+AC_CONFIG_SRCDIR(["Makefile.config.in"])
+
+dnl Configure a common Makefile
+AC_CONFIG_FILES(Makefile.config)
+AC_CONFIG_FILES(stp/Makefile.common)
+
+dnl Configure project makefiles
+dnl List every Makefile that exists within your source tree
+AC_CONFIG_HEADERS([include/klee/Config/config.h])
+
+dnl FIXME: Make out of tree builds work.
+
+AC_LANG([C++])
+
+dnl **************************************************************************
+dnl Find the host
+
+AC_CANONICAL_TARGET
+
+dnl Determine the platform type and cache its value. This helps us configure
+dnl the System library to the correct build platform.
+AC_CACHE_CHECK([type of operating system we're going to host on],
+               [klee_cv_os_type],
+[case $host in
+  *-*-linux*)
+    host_supports_posix_runtime=yes ;;
+  *)
+    host_supports_posix_runtime=no ;;
+esac])
+
+dnl **************************************************************************
+dnl Verify that we can find llvm
+
+dnl --with-llvm is a shortcut for setting srcdir and objdir.
+AC_ARG_WITH(llvm,
+  AS_HELP_STRING([--with-llvm],
+    [Location of LLVM Source and Object code]),,)
+
+AC_MSG_CHECKING([llvm source dir])
+
+if test X${with_llvm} != X; then
+    dnl Verify that --with-llvm{src,obj} were not given.
+    if test X${with_llvmsrc} != X; then
+       AC_MSG_ERROR([--with-llvmsrc cannot be specified when using --with-llvm])
+    fi   
+    if test X${with_llvmobj} != X; then
+       AC_MSG_ERROR([--with-llvmobj cannot be specified when using --with-llvm])
+    fi   
+    with_llvmsrc=$with_llvm
+    with_llvmobj=$with_llvm
+fi
+
+dnl If one of with_llvmsrc or with_llvmobj was given, we must have both.
+if (test X${with_llvmsrc} != X || test X${with_llvmobj} != X); then
+    dnl Verify that with_llvmobj was given as well.
+    if test X${with_llvmsrc} = X; then
+       AC_MSG_ERROR([--with-llvmsrc must be specified when using --with-llvmobj])
+    fi      
+    if test X${with_llvmobj} = X; then
+       AC_MSG_ERROR([--with-llvmobj must be specified when using --with-llvmsrc])
+    fi      
+else
+    dnl Otherwise try and use llvm-config to find.
+    llvm_version=`llvm-config --version`
+    if test X${llvm_version} = X; then
+       AC_MSG_ERROR([unable to find llvm, use --with-llvmsrc and --with-llvmobj])
+    fi
+    
+    with_llvmsrc=`llvm-config --src-root`
+    with_llvmobj=`llvm-config --obj-root`
+fi
+
+dnl Try to validate directories
+if test ! -f ${with_llvmsrc}/Makefile.rules; then
+   AC_MSG_ERROR([invalid llvmsrc directory: ${with_llvmsrc}])
+fi
+if test ! -f ${with_llvmobj}/Makefile.config; then
+   AC_MSG_ERROR([invalid llvmobj directory: ${with_llvmobj}])
+fi
+
+dnl Make the paths absolute
+llvm_src=`cd $with_llvmsrc 2> /dev/null; pwd`
+llvm_obj=`cd $with_llvmobj 2> /dev/null; pwd`
+   
+AC_MSG_RESULT([$llvm_src])
+
+dnl Report obj dir as well.
+AC_MSG_CHECKING([llvm obj dir])
+AC_MSG_RESULT([$llvm_obj])
+
+AC_SUBST(LLVM_SRC,$llvm_src)
+AC_SUBST(LLVM_OBJ,$llvm_obj)
+
+dnl **************************************************************************
+dnl User option to enable uClibc support.
+
+AC_ARG_WITH(uclibc,
+  AS_HELP_STRING([--with-uclibc],
+    [Enable use of the klee uclibc at the given path]),,)
+
+dnl If uclibc wasn't given, check for a uclibc in the current
+dnl directory.
+if (test X${with_uclibc} = X && test -d uclibc); then
+   with_uclibc=uclibc
+fi
+
+dnl Validate uclibc if given.
+
+AC_MSG_CHECKING([uclibc])
+if (test X${with_uclibc} != X); then
+   if test ! -d ${with_uclibc}; then
+       AC_MSG_ERROR([invalid uclibc directory: ${with_uclibc}])
+   fi
+
+   dnl Make the path absolute
+   with_uclibc=`cd $with_uclibc 2> /dev/null; pwd`
+
+   AC_MSG_RESULT([$with_uclibc])
+else
+   AC_MSG_RESULT([no])
+fi
+
+AC_DEFINE_UNQUOTED(KLEE_UCLIBC, "$with_uclibc", [Path to KLEE's uClibc])
+AC_SUBST(KLEE_UCLIBC)         
+
+if test X${with_uclibc} != X ; then
+  AC_SUBST(ENABLE_UCLIBC,[[1]])
+else
+  AC_SUBST(ENABLE_UCLIBC,[[0]])
+fi
+
+dnl **************************************************************************
+dnl User option to enable the POSIX runtime
+
+AC_ARG_ENABLE(posix-runtime,
+              AS_HELP_STRING([--enable-posix-runtime],
+                             [Enable the POSIX runtime]),
+                             ,enableval=default)
+
+AC_MSG_CHECKING([POSIX runtime])
+if test ${enableval} = "default" ; then
+  if test X${with_uclibc} != X; then
+    enableval=$host_supports_posix_runtime
+    if test ${enableval} = "yes"; then
+      AC_MSG_RESULT([default (enabled)])
+    else
+      AC_MSG_RESULT([default (disabled, unsupported target)])
+    fi
+  else
+    enableval="no"
+    AC_MSG_RESULT([default (disabled, no uclibc)])
+  fi
+else
+  if test ${enableval} = "yes" ; then
+    AC_MSG_RESULT([yes])
+  else
+    AC_MSG_RESULT([no])
+  fi
+fi
+
+if test ${enableval} = "yes" ; then
+  AC_SUBST(ENABLE_POSIX_RUNTIME,[[1]])
+else
+  AC_SUBST(ENABLE_POSIX_RUNTIME,[[0]])
+fi
+
+dnl **************************************************************************
+dnl User option to select runtime version
+
+AC_ARG_WITH(runtime,
+  AS_HELP_STRING([--with-runtime],
+    [Select build configuration for runtime libraries (default [Release])]),,
+    withval=default)
+
+if test X"${withval}" = Xdefault; then
+   with_runtime=Release
+fi
+
+AC_MSG_CHECKING([runtime configuration])
+if test X${with_runtime} = XRelease; then
+    AC_MSG_RESULT([Release])
+    AC_SUBST(RUNTIME_ENABLE_OPTIMIZED,[[1]])
+elif test X${with_runtime} = XDebug; then
+   AC_MSG_RESULT([Debug])
+   AC_SUBST(RUNTIME_ENABLE_OPTIMIZED,[[0]])
+else
+   AC_MSG_ERROR([invalid configuration: ${with_runtime}])
+fi
+
+AC_DEFINE_UNQUOTED(RUNTIME_CONFIGURATION, "$with_runtime", [Configuration for runtime libraries])
+AC_SUBST(RUNTIME_CONFIGURATION)
+
+dnl **************************************************************************
+dnl See if we should support __ctype_b_loc externals.
+
+dnl FIXME: Do the proper test if we continue to need this.
+case $host in
+  *-*-linux*)
+    AC_DEFINE_UNQUOTED(HAVE_CTYPE_EXTERNALS, 1, [Does the platform use __ctype_b_loc, etc.])
+esac
+
+dnl **************************************************************************
+dnl Checks for header files.
+
+dnl NOTE: This is mostly just to force autoconf to make CFLAGS defines
+dnl for us.
+AC_LANG_PUSH([C])
+
+AC_CHECK_HEADERS([sys/acl.h])
+
+AC_LANG_POP([C])
+
+AC_CHECK_HEADERS([selinux/selinux.h],
+        AC_SUBST(HAVE_SELINUX, 1),
+        AC_SUBST(HAVE_SELINUX, 0))
+
+dnl User option to use stplog.
+
+AC_ARG_ENABLE(stplog,
+              AS_HELP_STRING([--enable-stplog],
+                             [Compile with the stplog library [[disabled]]]),
+                             ,enableval=no)
+if test ${enableval} = "yes" ; then
+  AC_SUBST(ENABLE_STPLOG,[[1]])
+else
+  AC_SUBST(ENABLE_STPLOG,[[0]])
+fi
+AC_DEFINE_UNQUOTED([ENABLE_STPLOG],$ENABLE_STPLOG,[Define if stplog enabled])
+
+dnl **************************************************************************
+dnl * Create the output files
+dnl **************************************************************************
+
+dnl This must be last
+AC_OUTPUT
diff --git a/autoconf/install-sh b/autoconf/install-sh
new file mode 100755
index 00000000..dd97db7a
--- /dev/null
+++ b/autoconf/install-sh
@@ -0,0 +1,322 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2004-09-10.20
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit 0;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+	shift
+	shift
+	continue;;
+
+    -T) no_target_directory=true
+	shift
+	continue;;
+
+    --version) echo "$0 $scriptversion"; exit 0;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+	# When -t is used, the destination is already specified.
+	test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+	for arg
+	do
+          if test -n "$dstarg"; then
+	    # $@ is not empty: it contains at least $arg.
+	    set fnord "$@" "$dstarg"
+	    shift # fnord
+	  fi
+	  shift # arg
+	  dstarg=$arg
+	done
+	break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dstarg: Is a directory" >&2
+	exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+	 '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+	# mkdir can fail with a `File exist' error in case several
+	# install-sh are creating the directory concurrently.  This
+	# is OK.
+	test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Copy the file name to the temp name.
+    $doit $cpprog "$src" "$dsttmp" &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+	   # The rename failed, perhaps because mv can't rename something else
+	   # to itself, or perhaps because mv is so ancient that it does not
+	   # support -f.
+
+	   # Now remove or move aside any old file at destination location.
+	   # We try this two ways since rm can't unlink itself on some
+	   # systems and the destination file might be busy for other
+	   # reasons.  In this case, the final cleanup might fail but the new
+	   # file should still install successfully.
+	   {
+	     if test -f "$dstdir/$dstfile"; then
+	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+	       || {
+		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		 (exit 1); exit
+	       }
+	     else
+	       :
+	     fi
+	   } &&
+
+	   # Now rename the file to the real destination.
+	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+	 }
+    }
+  fi || { (exit 1); exit; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 00000000..9ca86611
--- /dev/null
+++ b/configure
@@ -0,0 +1,6039 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.60 for KLEE 0.01.
+#
+# Report bugs to <daniel@minormatter.com>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+  if (eval ":") 2>/dev/null; then
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+
+  if test $as_have_required = yes && 	 (eval ":
+(as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=\$LINENO
+  as_lineno_2=\$LINENO
+  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+  :
+else
+  as_candidate_shells=
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  case $as_dir in
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+	   done;;
+       esac
+done
+IFS=$as_save_IFS
+
+
+      for as_shell in $as_candidate_shells $SHELL; do
+	 # Try only shells that exist, to save several forks.
+	 if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		{ ("$as_shell") 2> /dev/null <<\_ASEOF
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+:
+_ASEOF
+}; then
+  CONFIG_SHELL=$as_shell
+	       as_have_required=yes
+	       if { "$as_shell" 2> /dev/null <<\_ASEOF
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+:
+(as_func_return () {
+  (exit $1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+  break
+fi
+
+fi
+
+      done
+
+      if test "x$CONFIG_SHELL" != x; then
+  for as_var in BASH_ENV ENV
+        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+        done
+        export CONFIG_SHELL
+        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+    if test $as_have_required = no; then
+  echo This script requires a shell more modern than all the
+      echo shells that I found on your system.  Please install a
+      echo modern shell, or manually run the script under such a
+      echo shell if you do have one.
+      { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+  echo No shell found that supports shell functions.
+  echo Please tell autoconf@gnu.org about your system,
+  echo including any error possibly output before this
+  echo message
+}
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
+# systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  as_executable_p="test -x"
+else
+  as_executable_p=:
+fi
+rm -f conf$$.file
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='KLEE'
+PACKAGE_TARNAME='-klee-'
+PACKAGE_VERSION='0.01'
+PACKAGE_STRING='KLEE 0.01'
+PACKAGE_BUGREPORT='daniel@minormatter.com'
+
+ac_unique_file=""Makefile.config.in""
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+LLVM_SRC
+LLVM_OBJ
+build
+build_cpu
+build_vendor
+build_os
+host
+host_cpu
+host_vendor
+host_os
+target
+target_cpu
+target_vendor
+target_os
+KLEE_UCLIBC
+ENABLE_UCLIBC
+ENABLE_POSIX_RUNTIME
+RUNTIME_ENABLE_OPTIMIZED
+RUNTIME_CONFIGURATION
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CC
+EXEEXT
+OBJEXT
+CPP
+GREP
+EGREP
+HAVE_SELINUX
+CXX
+CXXFLAGS
+ac_ct_CXX
+CXXCPP
+ENABLE_STPLOG
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+CXXCPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval enable_$ac_feature=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval enable_$ac_feature=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval with_$ac_package=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval with_$ac_package=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  { echo "$as_me: error: Working directory cannot be determined" >&2
+   { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  { echo "$as_me: error: pwd does not report name of working directory" >&2
+   { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+   { (exit 1); exit 1; }; }
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures KLEE 0.01 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR          info documentation [DATAROOTDIR/info]
+  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR           man documentation [DATAROOTDIR/man]
+  --docdir=DIR           documentation root [DATAROOTDIR/doc/-klee-]
+  --htmldir=DIR          html documentation [DOCDIR]
+  --dvidir=DIR           dvi documentation [DOCDIR]
+  --pdfdir=DIR           pdf documentation [DOCDIR]
+  --psdir=DIR            ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of KLEE 0.01:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-posix-runtime  Enable the POSIX runtime
+  --enable-stplog         Compile with the stplog library [disabled]
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-llvmsrc          Location of LLVM Source Code
+  --with-llvmobj          Location of LLVM Object Code
+  --with-llvm             Location of LLVM Source and Object code
+  --with-uclibc           Enable use of the klee uclibc at the given path
+  --with-runtime          Select build configuration for runtime libraries
+                          (default Release)
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <daniel@minormatter.com>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" || continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+KLEE configure 0.01
+generated by GNU Autoconf 2.60
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by KLEE $as_me 0.01, which was
+generated by GNU Autoconf 2.60.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+  set x "$ac_default_prefix/share/config.site" \
+	"$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+LLVM_SRC_ROOT="."
+
+ac_aux_dir=
+for ac_dir in $LLVM_SRC_ROOT/autoconf "$srcdir"/$LLVM_SRC_ROOT/autoconf; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $LLVM_SRC_ROOT/autoconf \"$srcdir\"/$LLVM_SRC_ROOT/autoconf" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $LLVM_SRC_ROOT/autoconf \"$srcdir\"/$LLVM_SRC_ROOT/autoconf" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+
+
+# Check whether --with-llvmsrc was given.
+if test "${with_llvmsrc+set}" = set; then
+  withval=$with_llvmsrc; llvm_src="$withval"
+else
+  llvm_src=""""
+fi
+
+  LLVM_SRC=$llvm_src
+
+
+# Check whether --with-llvmobj was given.
+if test "${with_llvmobj+set}" = set; then
+  withval=$with_llvmobj; llvm_obj="$withval"
+else
+  llvm_obj=""""
+fi
+
+  LLVM_OBJ=$llvm_obj
+
+  ac_config_commands="$ac_config_commands setup"
+
+
+
+
+
+ac_config_files="$ac_config_files Makefile.config"
+
+ac_config_files="$ac_config_files stp/Makefile.common"
+
+
+ac_config_headers="$ac_config_headers include/klee/Config/config.h"
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+{ echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+echo "$as_me: error: invalid value of canonical build" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+echo "$as_me: error: invalid value of canonical host" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6; }
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5
+echo "$as_me: error: invalid value of canonical target" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+{ echo "$as_me:$LINENO: checking type of operating system we're going to host on" >&5
+echo $ECHO_N "checking type of operating system we're going to host on... $ECHO_C" >&6; }
+if test "${klee_cv_os_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $host in
+  *-*-linux*)
+    host_supports_posix_runtime=yes ;;
+  *)
+    host_supports_posix_runtime=no ;;
+esac
+fi
+{ echo "$as_me:$LINENO: result: $klee_cv_os_type" >&5
+echo "${ECHO_T}$klee_cv_os_type" >&6; }
+
+
+
+# Check whether --with-llvm was given.
+if test "${with_llvm+set}" = set; then
+  withval=$with_llvm;
+fi
+
+
+{ echo "$as_me:$LINENO: checking llvm source dir" >&5
+echo $ECHO_N "checking llvm source dir... $ECHO_C" >&6; }
+
+if test X${with_llvm} != X; then
+        if test X${with_llvmsrc} != X; then
+       { { echo "$as_me:$LINENO: error: --with-llvmsrc cannot be specified when using --with-llvm" >&5
+echo "$as_me: error: --with-llvmsrc cannot be specified when using --with-llvm" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test X${with_llvmobj} != X; then
+       { { echo "$as_me:$LINENO: error: --with-llvmobj cannot be specified when using --with-llvm" >&5
+echo "$as_me: error: --with-llvmobj cannot be specified when using --with-llvm" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    with_llvmsrc=$with_llvm
+    with_llvmobj=$with_llvm
+fi
+
+if (test X${with_llvmsrc} != X || test X${with_llvmobj} != X); then
+        if test X${with_llvmsrc} = X; then
+       { { echo "$as_me:$LINENO: error: --with-llvmsrc must be specified when using --with-llvmobj" >&5
+echo "$as_me: error: --with-llvmsrc must be specified when using --with-llvmobj" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test X${with_llvmobj} = X; then
+       { { echo "$as_me:$LINENO: error: --with-llvmobj must be specified when using --with-llvmsrc" >&5
+echo "$as_me: error: --with-llvmobj must be specified when using --with-llvmsrc" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+else
+        llvm_version=`llvm-config --version`
+    if test X${llvm_version} = X; then
+       { { echo "$as_me:$LINENO: error: unable to find llvm, use --with-llvmsrc and --with-llvmobj" >&5
+echo "$as_me: error: unable to find llvm, use --with-llvmsrc and --with-llvmobj" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    with_llvmsrc=`llvm-config --src-root`
+    with_llvmobj=`llvm-config --obj-root`
+fi
+
+if test ! -f ${with_llvmsrc}/Makefile.rules; then
+   { { echo "$as_me:$LINENO: error: invalid llvmsrc directory: ${with_llvmsrc}" >&5
+echo "$as_me: error: invalid llvmsrc directory: ${with_llvmsrc}" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test ! -f ${with_llvmobj}/Makefile.config; then
+   { { echo "$as_me:$LINENO: error: invalid llvmobj directory: ${with_llvmobj}" >&5
+echo "$as_me: error: invalid llvmobj directory: ${with_llvmobj}" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+llvm_src=`cd $with_llvmsrc 2> /dev/null; pwd`
+llvm_obj=`cd $with_llvmobj 2> /dev/null; pwd`
+
+{ echo "$as_me:$LINENO: result: $llvm_src" >&5
+echo "${ECHO_T}$llvm_src" >&6; }
+
+{ echo "$as_me:$LINENO: checking llvm obj dir" >&5
+echo $ECHO_N "checking llvm obj dir... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $llvm_obj" >&5
+echo "${ECHO_T}$llvm_obj" >&6; }
+
+LLVM_SRC=$llvm_src
+
+LLVM_OBJ=$llvm_obj
+
+
+
+
+# Check whether --with-uclibc was given.
+if test "${with_uclibc+set}" = set; then
+  withval=$with_uclibc;
+fi
+
+
+if (test X${with_uclibc} = X && test -d uclibc); then
+   with_uclibc=uclibc
+fi
+
+
+{ echo "$as_me:$LINENO: checking uclibc" >&5
+echo $ECHO_N "checking uclibc... $ECHO_C" >&6; }
+if (test X${with_uclibc} != X); then
+   if test ! -d ${with_uclibc}; then
+       { { echo "$as_me:$LINENO: error: invalid uclibc directory: ${with_uclibc}" >&5
+echo "$as_me: error: invalid uclibc directory: ${with_uclibc}" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+      with_uclibc=`cd $with_uclibc 2> /dev/null; pwd`
+
+   { echo "$as_me:$LINENO: result: $with_uclibc" >&5
+echo "${ECHO_T}$with_uclibc" >&6; }
+else
+   { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define KLEE_UCLIBC "$with_uclibc"
+_ACEOF
+
+
+
+if test X${with_uclibc} != X ; then
+  ENABLE_UCLIBC=1
+
+else
+  ENABLE_UCLIBC=0
+
+fi
+
+
+# Check whether --enable-posix-runtime was given.
+if test "${enable_posix_runtime+set}" = set; then
+  enableval=$enable_posix_runtime;
+else
+  enableval=default
+fi
+
+
+{ echo "$as_me:$LINENO: checking POSIX runtime" >&5
+echo $ECHO_N "checking POSIX runtime... $ECHO_C" >&6; }
+if test ${enableval} = "default" ; then
+  if test X${with_uclibc} != X; then
+    enableval=$host_supports_posix_runtime
+    if test ${enableval} = "yes"; then
+      { echo "$as_me:$LINENO: result: default (enabled)" >&5
+echo "${ECHO_T}default (enabled)" >&6; }
+    else
+      { echo "$as_me:$LINENO: result: default (disabled, unsupported target)" >&5
+echo "${ECHO_T}default (disabled, unsupported target)" >&6; }
+    fi
+  else
+    enableval="no"
+    { echo "$as_me:$LINENO: result: default (disabled, no uclibc)" >&5
+echo "${ECHO_T}default (disabled, no uclibc)" >&6; }
+  fi
+else
+  if test ${enableval} = "yes" ; then
+    { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  else
+    { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+  fi
+fi
+
+if test ${enableval} = "yes" ; then
+  ENABLE_POSIX_RUNTIME=1
+
+else
+  ENABLE_POSIX_RUNTIME=0
+
+fi
+
+
+
+# Check whether --with-runtime was given.
+if test "${with_runtime+set}" = set; then
+  withval=$with_runtime;
+else
+  withval=default
+fi
+
+
+if test X"${withval}" = Xdefault; then
+   with_runtime=Release
+fi
+
+{ echo "$as_me:$LINENO: checking runtime configuration" >&5
+echo $ECHO_N "checking runtime configuration... $ECHO_C" >&6; }
+if test X${with_runtime} = XRelease; then
+    { echo "$as_me:$LINENO: result: Release" >&5
+echo "${ECHO_T}Release" >&6; }
+    RUNTIME_ENABLE_OPTIMIZED=1
+
+elif test X${with_runtime} = XDebug; then
+   { echo "$as_me:$LINENO: result: Debug" >&5
+echo "${ECHO_T}Debug" >&6; }
+   RUNTIME_ENABLE_OPTIMIZED=0
+
+else
+   { { echo "$as_me:$LINENO: error: invalid configuration: ${with_runtime}" >&5
+echo "$as_me: error: invalid configuration: ${with_runtime}" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define RUNTIME_CONFIGURATION "$with_runtime"
+_ACEOF
+
+
+
+
+case $host in
+  *-*-linux*)
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CTYPE_EXTERNALS 1
+_ACEOF
+
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort.  b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions.  Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	CFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_c89=$ac_arg
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+  xno)
+    { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_GREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in grep ggrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue
+    # Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_GREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_EGREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in egrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue
+    # Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_EGREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+
+   fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in sys/acl.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ------------------------------------- ##
+## Report this to daniel@minormatter.com ##
+## ------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	CXXFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for ac_header in selinux/selinux.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ------------------------------------- ##
+## Report this to daniel@minormatter.com ##
+## ------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ HAVE_SELINUX=1
+
+else
+  HAVE_SELINUX=0
+
+fi
+
+done
+
+
+
+# Check whether --enable-stplog was given.
+if test "${enable_stplog+set}" = set; then
+  enableval=$enable_stplog;
+else
+  enableval=no
+fi
+
+if test ${enableval} = "yes" ; then
+  ENABLE_STPLOG=1
+
+else
+  ENABLE_STPLOG=0
+
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define ENABLE_STPLOG $ENABLE_STPLOG
+_ACEOF
+
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
+# systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  as_executable_p="test -x"
+else
+  as_executable_p=:
+fi
+rm -f conf$$.file
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by KLEE $as_me 0.01, which was
+generated by GNU Autoconf 2.60.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+KLEE config.status 0.01
+configured by $0, generated by GNU Autoconf 2.60,
+  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    { echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  CONFIG_SHELL=$SHELL
+  export CONFIG_SHELL
+  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS
+#
+llvm_src="${LLVM_SRC}"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "setup") CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;;
+    "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
+    "stp/Makefile.common") CONFIG_FILES="$CONFIG_FILES stp/Makefile.common" ;;
+    "include/klee/Config/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/klee/Config/config.h" ;;
+
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+LLVM_SRC!$LLVM_SRC$ac_delim
+LLVM_OBJ!$LLVM_OBJ$ac_delim
+build!$build$ac_delim
+build_cpu!$build_cpu$ac_delim
+build_vendor!$build_vendor$ac_delim
+build_os!$build_os$ac_delim
+host!$host$ac_delim
+host_cpu!$host_cpu$ac_delim
+host_vendor!$host_vendor$ac_delim
+host_os!$host_os$ac_delim
+target!$target$ac_delim
+target_cpu!$target_cpu$ac_delim
+target_vendor!$target_vendor$ac_delim
+target_os!$target_os$ac_delim
+KLEE_UCLIBC!$KLEE_UCLIBC$ac_delim
+ENABLE_UCLIBC!$ENABLE_UCLIBC$ac_delim
+ENABLE_POSIX_RUNTIME!$ENABLE_POSIX_RUNTIME$ac_delim
+RUNTIME_ENABLE_OPTIMIZED!$RUNTIME_ENABLE_OPTIMIZED$ac_delim
+RUNTIME_CONFIGURATION!$RUNTIME_CONFIGURATION$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+CPP!$CPP$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+HAVE_SELINUX!$HAVE_SELINUX$ac_delim
+CXX!$CXX$ac_delim
+CXXFLAGS!$CXXFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
+CXXCPP!$CXXCPP$ac_delim
+ENABLE_STPLOG!$ENABLE_STPLOG$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 74; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+   { (exit 1); exit 1; }; };;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+   { (exit 1); exit 1; }; };;
+      esac
+      ac_file_inputs="$ac_file_inputs $ac_f"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input="Generated from "`IFS=:
+	  echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    fi
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin";;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  { as_dir="$ac_dir"
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+   { (exit 1); exit 1; }; }; }
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+    s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out"; rm -f "$tmp/out";;
+  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+  esac
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+_ACEOF
+
+# Transform confdefs.h into a sed script `conftest.defines', that
+# substitutes the proper values into config.h.in to produce config.h.
+rm -f conftest.defines conftest.tail
+# First, append a space to every undef/define line, to ease matching.
+echo 's/$/ /' >conftest.defines
+# Then, protect against being on the right side of a sed subst, or in
+# an unquoted here document, in config.status.  If some macros were
+# called several times there might be several #defines for the same
+# symbol, which is useless.  But do not sort them, since the last
+# AC_DEFINE must be honored.
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
+# NAME is the cpp macro being defined, VALUE is the value it is being given.
+# PARAMS is the parameter list in the macro definition--in most cases, it's
+# just an empty string.
+ac_dA='s,^\\([	 #]*\\)[^	 ]*\\([	 ]*'
+ac_dB='\\)[	 (].*,\\1define\\2'
+ac_dC=' '
+ac_dD=' ,'
+
+uniq confdefs.h |
+  sed -n '
+	t rset
+	:rset
+	s/^[	 ]*#[	 ]*define[	 ][	 ]*//
+	t ok
+	d
+	:ok
+	s/[\\&,]/\\&/g
+	s/^\('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
+	s/^\('"$ac_word_re"'\)[	 ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
+  ' >>conftest.defines
+
+# Remove the space that was appended to ease matching.
+# Then replace #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+# (The regexp can be short, since the line contains either #define or #undef.)
+echo 's/ $//
+s,^[	 #]*u.*,/* & */,' >>conftest.defines
+
+# Break up conftest.defines:
+ac_max_sed_lines=50
+
+# First sed command is:	 sed -f defines.sed $ac_file_inputs >"$tmp/out1"
+# Second one is:	 sed -f defines.sed "$tmp/out1" >"$tmp/out2"
+# Third one will be:	 sed -f defines.sed "$tmp/out2" >"$tmp/out1"
+# et cetera.
+ac_in='$ac_file_inputs'
+ac_out='"$tmp/out1"'
+ac_nxt='"$tmp/out2"'
+
+while :
+do
+  # Write a here document:
+    cat >>$CONFIG_STATUS <<_ACEOF
+    # First, check the format of the line:
+    cat >"\$tmp/defines.sed" <<\\CEOF
+/^[	 ]*#[	 ]*undef[	 ][	 ]*$ac_word_re[	 ]*\$/b def
+/^[	 ]*#[	 ]*define[	 ][	 ]*$ac_word_re[(	 ]/b def
+b
+:def
+_ACEOF
+  sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+    sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
+  ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
+  sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
+  grep . conftest.tail >/dev/null || break
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines conftest.tail
+
+echo "ac_result=$ac_in" >>$CONFIG_STATUS
+cat >>$CONFIG_STATUS <<\_ACEOF
+  if test x"$ac_file" != x-; then
+    echo "/* $configure_input  */" >"$tmp/config.h"
+    cat "$ac_result" >>"$tmp/config.h"
+    if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f $ac_file
+      mv "$tmp/config.h" $ac_file
+    fi
+  else
+    echo "/* $configure_input  */"
+    cat "$ac_result"
+  fi
+  rm -f "$tmp/out12"
+ ;;
+
+  :C)  { echo "$as_me:$LINENO: executing $ac_file commands" >&5
+echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/docs/SMT-COMP/BitVector_ArraysEx.smt b/docs/SMT-COMP/BitVector_ArraysEx.smt
new file mode 100644
index 00000000..a60413ca
--- /dev/null
+++ b/docs/SMT-COMP/BitVector_ArraysEx.smt
@@ -0,0 +1,74 @@
+(theory BitVector_ArraysEx
+
+ :written_by {Clark Barrett}
+ :date {May 7, 2007}
+ 
+:sorts_description {
+    All sort symbols of the form BitVec[m],
+    where m is a numeral greater than 0.
+
+    All sort symbols of the form Array[m:n],
+    where m and n are numerals with m > 0 and n > 0.
+}
+
+:funs_description {
+    All functions from the theory Fixed_Size_Bitvectors.
+}
+
+:funs_description {
+    All function symbols with arity of the form
+
+      (select Array[m:n] BitVec[m] BitVec[n])
+
+    where
+    - m,n are numerals
+    - m > 0, n > 0
+}
+
+:funs_description {
+    All function symbols with arity of the form
+
+      (store Array[m:n] BitVec[m] BitVec[n] Array[m:n])
+
+    where
+    - m,n are numerals
+    - m > 0, n > 0
+}
+
+:preds_description {
+    All predicates from the theory Fixed_Size_Bitvectors.
+}
+
+
+ :definition 
+ "This is a theory containing an infinite number of copies of the theory of
+  functional arrays with extensionality: one for each pair of bitvector sorts.
+  It can be formally defined as the union of the SMT-LIB theory
+  Fixed_Size_Bitvectors and an infinite number of variants of the SMT-LIB
+  theory ArraysEx: one for each distinct signature morphism mapping the sort Index
+  to BitVec[m] and the sort Element to Bitvec[n] where m and n range over all
+  positive numerals.  In each of the copies of ArraysEx, the sort Array is
+  renamed to Array[m:n] and each copy of ArraysEx contributes exactly one select
+  function and one store function to the infinite polymorphic family of select
+  and store functions described above.
+ "
+
+ :notes
+ "As in the theory Fixed_Size_Bitvectors, this theory does not
+  provide a value for the formal attributes :sorts, :funs, and :preds because
+  there are an infinite number of them.  See the notes in theory
+  Fixed_Size_Bitvectors for details.
+
+  If for i=1,2, T_i is an SMT-LIB theory with sorts S_i, function symbols F_i,
+  predicate symbols P_i, and axioms A_i, by \"union\" of T_1 and T_2 
+  we mean the theory T with sorts S_1 U S_2, function symbols F_1 U F_2,
+  predicate symbols P_1 U P_2, and axioms A_1 U A_2 (where U stands for set
+  theoretic union).
+
+  The theory T is a well-defined SMT-LIB theory whenever S_1, S_2, F_1, F_2, 
+  P_1, P_2 are all pairwise disjoint, as is the case for the component theories
+  considered here. 
+ "
+)
+
+
diff --git a/docs/SMT-COMP/BitVectors.smt b/docs/SMT-COMP/BitVectors.smt
new file mode 100644
index 00000000..f2cde1b3
--- /dev/null
+++ b/docs/SMT-COMP/BitVectors.smt
@@ -0,0 +1,187 @@
+(theory Fixed_Size_BitVectors
+
+:written_by {Silvio Ranise, Cesare Tinelli, and Clark Barrett}
+
+:date {May 7, 2007}
+
+:notes
+   "Against the requirements of the current SMT-LIB standard this theory does
+    not provide a value for the formal attributes :sorts, :funs, and :preds.
+    The reason is that the theory has an infinite number of sort, function, and
+    predicate symbols, and so they cannot be specified formally in the current
+    SMT-LIB language.  While extending SMT-LIB's type system with dependent
+    types would allow a finitary formal specification of all the symbols in
+    this theory's signature, such an extension does not seem to be worth the
+    trouble at the moment.  As a temporary ad-hoc solution, this theory
+    declaration specifies the signature, in English, in the user-defined
+    attributes :sorts_description, :funs_description, and :preds_description.
+    "
+
+:sorts_description {
+    All sort symbols of the form BitVec[m],
+    where m is a numeral greater than 0.
+}
+
+:funs_description {
+    Constant symbols bit0 and bit1 of sort BitVec[1]
+}
+
+:funs_description {
+    All function symbols with arity of the form
+
+      (concat BitVec[i] BitVec[j] BitVec[m])
+
+    where
+    - i,j,m are numerals
+    - i,j > 0
+    - i + j = m
+}
+
+:funs_description {
+    All function symbols with arity of the form
+
+      (extract[i:j] BitVec[m] BitVec[n])
+
+    where
+    - i,j,m,n are numerals
+    - m > i >= j >= 0,
+    - n = i-j+1.
+}
+
+:funs_description {
+    All function symbols with arity of the form
+
+       (op1 BitVec[m] BitVec[m])
+    or
+       (op2 BitVec[m] BitVec[m] BitVec[m])
+
+    where
+    - op1 is from {bvnot, bvneg}
+    - op2 is from {bvand, bvor, bvadd, bvmul, bvudiv, bvurem, bvshl, bvlshr}
+    - m is a numeral greater than 0
+}
+
+:preds_description {
+    All predicate symbols with arity of the form
+
+       (pred BitVec[m] BitVec[m])
+
+    where
+    - pred is from {bvult}
+    - m is a numeral greater than 0
+}
+
+:definition
+  "This is a core theory for fixed-size bitvectors where the operations
+   of concatenation and extraction of bitvectors as well as the usual
+   logical and arithmetic operations are overloaded.
+   The theory is defined semantically as follows.
+
+   The sort BitVec[m] (for m > 0) is the set of finite functions
+   whose domain is the initial segment of the naturals [0...m), meaning
+   that 0 is included and m is excluded, and the co-domain is {0,1}.
+
+   The semantic interpretation [[_]] of well-sorted BitVec-terms is
+   inductively defined as follows.
+
+   - Variables
+
+   If v is a variable of sort BitVec[m] with 0 < m, then
+   [[v]] is some element of [{0,...,m-1} -> {0,1}], the set of total
+   functions from {0,...,m-1} to {0,1}.
+
+   - Constant symbols bit0 and bit1 of sort BitVec[1]
+
+   [[bit0]] := \lambda x : [0,1). 0
+   [[bit1]] := \lambda x : [0,1). 1
+
+   - Function symbols for concatenation
+
+   [[(concat s t)]] := \lambda x : [0...n+m).
+                          if (x<m) then [[t]](x) else [[s]](x-m)
+   where
+   s and t are terms of sort BitVec[n] and BitVec[m], respectively,
+   0 < n, 0 < m.
+
+   - Function symbols for extraction
+
+   [[(extract[i:j] s)]] := \lambda x : [0...i-j+1). [[s]](j+x)
+   where s is of sort BitVec[l], 0 <= j <= i < l.
+
+   - Bit-wise operations
+
+   [[(bvnot s)]] := \lambda x : [0...m). if [[s]](x) = 0 then 1 else 0
+
+   [[(bvand s t)]] := \lambda x : [0...m).
+                         if [[s]](x) = 0 then 0 else [[t]](x)
+
+   [[(bvor s t)]] := \lambda x : [0...m).
+                         if [[s]](x) = 1 then 1 else [[t]](x)
+
+   where s and t are both of sort BitVec[m] and 0 < m.
+
+   - Arithmetic operations
+
+   To define the semantics of the bitvector arithmetic operators, we first
+   introduce some additional definitions:
+
+   o (x div y) where x and y are integers with x >= 0 and y > 0 returns the
+     integer part of x divided by y (i.e., truncated integer division).
+
+   o (x rem y) where x and y are integers with x >= 0 and y > 0 returns the
+     remainder when x is divided by y.  Note that we always have the following
+     equivalence (for y > 0): (x div y) * y + (x rem y) = x.
+
+   o bv2nat which takes a bitvector b: [0...m) --> {0,1}
+     with 0 < m, and returns an integer in the range [0...2^m),
+     and is defined as follows:
+
+       bv2nat(b) := b(m-1)*2^{m-1} + b(m-2)*2^{m-2} + ... + b(0)*2^0
+
+   o nat2bv[m], with 0 < m, which takes a non-negative integer
+     n and returns the (unique) bitvector b: [0,...,m) -> {0,1}
+     such that
+
+       b(m-1)*2^{m-1} + ... + b(0)*2^0 = n rem 2^m
+
+   Now, we can define the following operations.  Suppose s and t are both terms
+   of sort BitVec[m], m > 0.
+
+   [[(bvneg s)]] := nat2bv[m](2^m - bv2nat([[s]]))
+
+   [[(bvadd s t)]] := nat2bv[m](bv2nat([[s]]) + bv2nat([[t]]))
+
+   [[(bvmul s t)]] := nat2bv[m](bv2nat([[s]]) * bv2nat([[t]]))
+
+   [[(bvudiv s t)]] := if bv2nat([[t]]) != 0 then
+                          nat2bv[m](bv2nat([[s]]) div bv2nat([[t]]))
+
+   [[(bvurem s t)]] := if bv2nat([[t]]) != 0 then
+                          nat2bv[m](bv2nat([[s]]) rem bv2nat([[t]]))
+
+   - Shift operations
+
+   Suppose s and t are both terms of sort BitVec[m], m > 0.  We make use of the
+   definitions given for the arithmetic operations, above.
+
+   [[(bvshl s t)]] := nat2bv[m](bv2nat([[s]]) * 2^(bv2nat([[t]])))
+
+   [[(bvlshr s t)]] := nat2bv[m](bv2nat([[s]]) div 2^(bv2nat([[t]])))
+
+   Finally, we can define the binary predicate bvult:
+
+   (bvult s t) is interpreted to be true iff bv2nat([[s]]) < bv2nat([[t]])
+
+   Note that the semantic interpretation above is underspecified because it
+   does not specify the meaning of (bvudiv s t) or (bvurem s t) in case
+   bv2nat([[t]]) is 0.  Since the semantics of SMT-LIB's underlying logic
+   associates *total* functions to function symbols, we then consider as models
+   of this theory *any* interpretation conforming to the specifications above
+   (and defining bvudiv and bvurem arbitrarily when the second argument
+   evaluates to 0).  Benchmarks using this theory should only include a
+   :status sat or :status unsat attribute if the status is independent of
+   the particular choice of model for the theory.
+
+  "
+
+)
diff --git a/docs/SMT-COMP/QF_AUFBV.smt b/docs/SMT-COMP/QF_AUFBV.smt
new file mode 100644
index 00000000..bc055c35
--- /dev/null
+++ b/docs/SMT-COMP/QF_AUFBV.smt
@@ -0,0 +1,19 @@
+(logic QF_AUFBV
+
+ :written_by {Clark Barrett}
+ :date {May 7, 2007}
+ 
+ :theory BV_ArraysEx
+
+ :language 
+ "Closed quantifier-free formulas built over an arbitrary expansion of the
+  BV_ArraysEx signature with free function and predicate symbols over
+  the sorts of BV_ArraysEx.  Formulas in ite terms must satisfy the same
+  restriction as well, with the exception that they need not be closed (because
+  they may be in the scope of a let expression).
+ "
+ :extensions
+ "As in the logic QF_BV."
+)
+
+
diff --git a/docs/SMT-COMP/QF_BV.smt b/docs/SMT-COMP/QF_BV.smt
new file mode 100644
index 00000000..edf02241
--- /dev/null
+++ b/docs/SMT-COMP/QF_BV.smt
@@ -0,0 +1,261 @@
+(logic QF_BV
+
+:written_by {Silvio Ranise, Cesare Tinelli, and Clark Barrett}
+:date {May 7, 2007}
+
+:theory Fixed_Size_BitVectors
+
+:language
+
+ "Closed quantifier-free formulas built over an arbitrary expansion of the
+  Fixed_Size_BitVectors signature with free constant symbols over the sorts
+  BitVec[m] for 0 < m.  Formulas in ite terms must satisfy the same restriction
+  as well, with the exception that they need not be closed (because they may be
+  in the scope of a let expression).
+ "
+
+:notes
+ "For quick reference, the following is a brief and informal summary of the
+  legal symbols in this logic and their meaning (formal definitions are found
+  either in the Fixed_Size_Bitvectors theory, or in the extensions below).
+
+  Defined in theory Fixed_Size_Bitvectors:
+
+    Functions/Constants:
+
+    (bit0 BitVec[1])
+      - the constant consisting of a single bit with value 0
+    (bit1 BitVec[1])
+      - the constant consisting of a single bit with value 1
+    (concat BitVec[i] BitVec[j] BitVec[m])
+      - concatenation of bitvectors of size i and j to get a new bitvector of
+        size m, where m = i + j
+    (extract[i:j] BitVec[m] BitVec[n])
+      - extraction of bits i down to j from a bitvector of size m to yield a
+        new bitvector of size n, where n = i - j + 1
+    (bvnot BitVec[m] BitVec[m])
+      - bitwise negation
+    (bvand BitVec[m] BitVec[m] BitVec[m])
+      - bitwise and
+    (bvor BitVec[m] BitVec[m] BitVec[m])
+      - bitwise or
+    (bvneg BitVec[m] BitVec[m])
+      - 2's complement unary minus
+    (bvadd BitVec[m] BitVec[m] BitVec[m])
+      - addition modulo 2^m
+    (bvmul BitVec[m] BitVec[m] BitVec[m])
+      - multiplication modulo 2^m
+    (bvudiv BitVec[m] BitVec[m] BitVec[m])
+      - unsigned division, truncating towards 0 (undefined if divisor is 0)
+    (bvurem BitVec[m] BitVec[m] BitVec[m])
+      - unsigned remainder from truncating division (undefined if divisor is 0)
+    (bvshl BitVec[m] BitVec[m] BitVec[m])
+      - shift left (equivalent to multiplication by 2^x where x is the value of
+        the second argument)
+    (bvlshr BitVec[m] BitVec[m] BitVec[m])
+      - logical shift right (equivalent to unsigned division by 2^x where x is
+        the value of the second argument)
+
+    Predicates:
+
+    (bvult BitVec[m] BitVec[m])
+      - binary predicate for unsigned less than
+
+  Defined below:
+
+    Functions/Constants:
+
+    Bitvector constants:
+      - bvX[m] where X is a numeral in base 10 defines the bitvector constant
+        with numeric value X of size m.
+      - bvbinX where X is a binary numeral of length m defines the
+        bitvector constant with value X and size m.
+      - bvhexX where X is a hexadecimal numeral of length m defines the
+        bitvector constant with value X and size 4*m.
+    (bvnand BitVec[m] BitVec[m] BitVec[m])
+      - bitwise nand (negation of and)
+    (bvnor BitVec[m] BitVec[m] BitVec[m])
+      - bitwise nor (negation of or)
+    (bvxor BitVec[m] BitVec[m] BitVec[m])
+      - bitwise exclusive or
+    (bvxnor BitVec[m] BitVec[m] BitVec[m])
+      - bitwise equivalence (equivalently, negation of bitwise exclusive or)
+    (bvcomp BitVec[m] BitVec[m] BitVec[1])
+      - bit comparator: equals bit1 iff all bits are equal
+    (bvsub BitVec[m] BitVec[m] BitVec[m])
+      - 2's complement subtraction modulo 2^m
+    (bvsdiv BitVec[m] BitVec[m] BitVec[m])
+      - 2's complement signed division
+    (bvsrem BitVec[m] BitVec[m] BitVec[m])
+      - 2's complement signed remainder (sign follows dividend)
+    (bvsmod BitVec[m] BitVec[m] BitVec[m])
+      - 2's complement signed remainder (sign follows divisor)
+    (bvashr BitVec[m] BitVec[m] BitVec[m])
+      - Arithmetic shift right, like logical shift right except that the most
+        significant bits of the result always copy the most significant
+        bit of the first argument.
+
+    The following symbols are parameterized by the numeral i, where i >= 0.
+
+    (repeat[i] BitVec[m] BitVec[i*m])
+      - (repeat[i] x) means concatenate i copies of x
+    (zero_extend[i] BitVec[m] BitVec[m+i])
+      - (zero_extend[i] x) means extend x with zeroes to the (unsigned)
+        equivalent bitvector of size m+i
+    (sign_extend[i] BitVec[m] BitVec[m+i])
+      - (sign_extend[i] x) means extend x to the (signed) equivalent bitvector
+        of size m+i
+    (rotate_left[i] BitVec[m] BitVec[m])
+      - (rotate_left[i] x) means rotate bits of x to the left i times
+    (rotate_right[i] BitVec[m] BitVec[m])
+      - (rotate_right[i] x) means rotate bits of x to the right y times
+
+    Predicates:
+
+    (bvule BitVec[m] BitVec[m])
+      - binary predicate for unsigned less than or equal
+    (bvugt BitVec[m] BitVec[m])
+      - binary predicate for unsigned greater than
+    (bvuge BitVec[m] BitVec[m])
+      - binary predicate for unsigned greater than or equal
+    (bvslt BitVec[m] BitVec[m])
+      - binary predicate for signed less than
+    (bvsle BitVec[m] BitVec[m])
+      - binary predicate for signed less than or equal
+    (bvsgt BitVec[m] BitVec[m])
+      - binary predicate for signed greater than
+    (bvsge BitVec[m] BitVec[m])
+      - binary predicate for signed greater than or equal
+
+ "
+
+:extensions
+ "Below, let |exp| denote the integer resulting from the evaluation
+  of the arithmetic expression exp.
+
+  - Bitvector Constants:
+    The string bv followed by the numeral n and a size [m] (as in bv13[32])
+    abbreviates any term t of sort BitVec[m] built only out of the symbols in
+    {concat, bit0, bit1} such that
+
+    [[t]] = nat2bv[m](n) for n=0, ..., 2^m - 1.
+
+    See the specification of the theory's semantics for a definition
+    of the functions [[_]] and nat2bv.  Note that this convention implicitly
+    considers the numeral n as a number written in base 10.
+
+    For backward compatibility, if the size [m] is omitted, then the size is
+    assumed to be 32.
+
+    The string bvbin followed by a sequence of 0's and 1's abbreviates the
+    concatenation of a similar sequence of bit0 and bit1 terms.  Thus,
+    if n is the numeral represented in base 2 by the sequence of 0's and 1's
+    and m is the length of the sequence, then the term represents
+    nat2bv[m](n).  For example bvbin0101 is equivalent to bv5[4].
+
+    The string bvhex followed by a sequence of digits and/or letters from A to
+    F is interpreted similarly as a concatenation of bit0 and bit1 as follows.
+    If n is the numeral represented in hexadecimal (base 16) by the sequence of
+    digits and letters from A to F and m is four times the length of the
+    sequence, then the term represents nat2bv[m](n).  For example, bvbinFF is
+    equivalent to bv255[8].  Letters in the hexadecimal sequence may be in
+    either upper or lower case.
+
+  - Bitwise operators
+
+    For all terms s,t of sort BitVec[m], where 0 < m,
+
+    (bvnand s t) abbreviates (bvnot (bvand s t))
+    (bvnor s t) abbreviates (bvnot (bvor s t))
+    (bvxor s t) abbreviates (bvor (bvand s (bvnot t)) (bvand (bvnot s) t))
+    (bvxnor s t) abbreviates (bvor (bvand s t) (bvand (bvnot s) (bvnot t)))
+    (bvcomp s t) abbreviates (bvxnor s t) if m = 1, and
+       (bvand (bvxnor (extract[|m-1|:|m-1|] s) (extract[|m-1|:|m-1|] t))
+              (bvcomp (extract[|m-2|:0] s) (extract[|m-2|:0] t))) otherwise
+
+  - Arithmetic operators
+
+    For all terms s,t of sort BitVec[m], where 0 < m,
+
+    (bvsub s t) abbreviates (bvadd s (bvneg t))
+    (bvsdiv s t) abbreviates
+      (let (?msb_s (extract[|m-1|:|m-1|] s))
+      (let (?msb_t (extract[|m-1|:|m-1|] t))
+      (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
+           (bvudiv s t)
+      (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
+           (bvneg (bvudiv (bvneg s) t))
+      (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
+           (bvneg (bvudiv s (bvneg t)))
+           (bvudiv (bvneg s) (bvneg t)))))))
+    (bvsrem s t) abbreviates
+      (let (?msb_s (extract[|m-1|:|m-1|] s))
+      (let (?msb_t (extract[|m-1|:|m-1|] t))
+      (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
+           (bvurem s t)
+      (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
+           (bvneg (bvurem (bvneg s) t))
+      (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
+           (bvurem s (bvneg t)))
+           (bvneg (bvurem (bvneg s) (bvneg t)))))))
+    (bvsmod s t) abbreviates
+      (let (?msb_s (extract[|m-1|:|m-1|] s))
+      (let (?msb_t (extract[|m-1|:|m-1|] t))
+      (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
+           (bvurem s t)
+      (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
+           (bvadd (bvneg (bvurem (bvneg s) t)) t)
+      (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
+           (bvadd (bvurem s (bvneg t)) t)
+           (bvneg (bvurem (bvneg s) (bvneg t)))))))
+    (bvule s t) abbreviates (or (bvult s t) (= s t))
+    (bvugt s t) abbreviates (bvult t s)
+    (bvuge s t) abbreviates (or (bvult t s) (= s t))
+    (bvslt s t) abbreviates:
+      (or (and (= (extract[|m-1|:|m-1|] s) bit1)
+               (= (extract[|m-1|:|m-1|] t) bit0))
+          (and (= (extract[|m-1|:|m-1|] s) (extract[|m-1|:|m-1|] t))
+               (bvult s t)))
+    (bvsle s t) abbreviates:
+      (or (and (= (extract[|m-1|:|m-1|] s) bit1)
+               (= (extract[|m-1|:|m-1|] t) bit0))
+          (and (= (extract[|m-1|:|m-1|] s) (extract[|m-1|:|m-1|] t))
+               (bvule s t)))
+    (bvsgt s t) abbreviates (bvslt t s)
+    (bvsge s t) abbreviates (bvsle t s)
+
+  - Other operations
+
+    For all numerals j > 1 and 0 < m, and all terms of s and t of
+    sort BitVec[m],
+
+    (bvashr s t) abbreviates 
+      (ite (= (extract[|m-1|:|m-1|] s) bit0)
+           (bvlshr s t)
+           (bvnot (bvlshr (bvnot s) t)))
+
+    (repeat[1] t) stands for t
+    (repeat[j] t) abbreviates (concat t (repeat[|j-1|] t))
+
+    (zero_extend[0] t) stands for t
+    (zero_extend[j] t) abbreviates (concat (repeat[j] bit0) t)
+
+    (sign_extend[0] t) stands for t
+    (sign_extend[j] t) abbreviates
+      (concat (repeat[j] (extract[|m-1|:|m-1|] t)) t)
+
+    (rotate_left[0] t) stands for t
+    (rotate_left[j] t) abbreviates t if m = 1, and
+      (rotate_left[|j-1|]
+        (concat (extract[|m-2|:0] t) (extract[|m-1|:|m-1|] t))
+      otherwise
+
+    (rotate_right[0] t) stands for t
+    (rotate_right[j] t) abbreviates t if m = 1, and
+      (rotate_right[|j-1|]
+        (concat (extract[0:0] t) (extract[|m-1|:1] t)))
+      otherwise
+
+ "
+)
+
diff --git a/docs/doxygen.cfg b/docs/doxygen.cfg
new file mode 100644
index 00000000..b13a65ec
--- /dev/null
+++ b/docs/doxygen.cfg
@@ -0,0 +1,1291 @@
+# Doxyfile 1.5.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = klee
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = docs/doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be extracted 
+# and appear in the documentation as a namespace called 'anonymous_namespace{file}', 
+# where file will be replaced with the base name of the file that contains the anonymous 
+# namespace. By default anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = tools/ \
+                         lib/ \
+                         include/klee \
+                         docs/intro \
+                         docs/overview
+
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =  */.svn* */Debug*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH 
+# then you must also enable this option. If you don't then doxygen will produce 
+# a warning and turn it on anyway
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the number 
+# of direct children of the root node in a graph is already larger than 
+# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = YES
diff --git a/docs/intro b/docs/intro
new file mode 100644
index 00000000..c3451789
--- /dev/null
+++ b/docs/intro
@@ -0,0 +1,10 @@
+/// @mainpage KLEE
+///
+/// @section main_intro Introduction
+/// Welcome to KLEE. KLEE is a symbolic execution engine that works on LLVM
+/// bitcode.
+/// 
+/// @section Documentation
+/// The documentation of KLEE is composed of the Doxygen documentation
+/// of the code as well as the following documents:
+/// - @subpage overview
diff --git a/docs/overview b/docs/overview
new file mode 100644
index 00000000..666a23d9
--- /dev/null
+++ b/docs/overview
@@ -0,0 +1,104 @@
+/// @page overview High level overview of KLEE.
+/// This document contains a high level overview of the inner workings of KLEE.
+///
+/// KLEE implements symbolic execution by interpreting LLVM bitcode. Symbolic
+/// memory is defined by inserting special calls to KLEE (namely
+/// klee_make_symbolic)
+/// During execution, KLEE tracks all uses of symbolic memory. Constraints
+/// on symbolic memory usage are collected. Memory
+/// that is defined using previously declared symbolic memory become
+/// symbolic as well.
+/// Whenever a branch refering to symbolic memory is encountered, KLEE forks
+/// the entire states and explores each side of the branch for which a possible
+/// solution to the symbolic constraints can be found.
+/// KLEE makes queries to STP to solve symbolic constraints.
+///
+/// The rest of this document describes some of the important components of KLEE
+/// 
+/// @section executor Interpreter
+/// klee::Interpreter is the main abstract class defining the interface of the
+/// bitcode interpreter. klee::Executor is the main concrete instance of this
+/// class.
+/// Application states (i.e. memory, registers and PC) are stored in instances of
+/// class klee::ExecutionState. There is one such instance for each path beeing
+/// executed (except when some states are merged together).
+/// On a branch, if condition is symbolic, klee::Executor::fork returns a
+/// klee::ExecutionState::StatePair which is a pair of ExecutionState to be
+/// executed.
+/// 
+/// @section memory Memory model
+/// MemoryObject's represent allocation sites in the program (calls to malloc, stack
+/// objects, global variables)
+/// and, at least conceptually, can be thought of as the unique name for the object
+/// allocated at that site.
+/// ObjectState's are used to store the actual contents of a MemoryObject in a
+/// particular ExecutionState (but
+/// can be shared). I need better names for these two things. 
+/// 
+/// Each ExecutionState stores a mapping of MemoryObjects -> ObjectState using the
+/// AddressSpace data
+/// structure (implemented as an immutable tree so that copying is cheap and the
+/// shared structure is exploited).
+/// Each AddressSpace may "own" some subset of the ObjectStates in the mapping. When
+/// an AddressSpace
+/// is duplicated it loses ownership of the ObjectState in the map. Any subsequent
+/// write to an ObjectState will
+/// create a copy of the object (AddressSpace::getWriteable). This is the COW
+/// mechanism (which gets used
+/// for all objects, not just globals).
+/// 
+/// From the point of view of the state and this mapping there is no distinction
+/// between stack, heap, and global
+/// objects. The only special handling for stack objects is that the MemoryObject is
+/// marked as isLocal and the
+/// MemoryObject is stored in the StackFrame alloca list. When the StackFrame is
+/// popped these objects are
+/// then unbound so that the state can no longer access the memory directly
+/// (references to the memory object
+/// may still remain in ReadExprs, but conceptually the actual memory is no longer
+/// addressable).
+/// 
+/// It is also important that the AddressSpace mapping is ordered. We use this when
+/// we need to resolve a symbolic
+/// address to an ObjectState by first getting a particular value for the symbolic
+/// address, and using that value to start
+/// looking for objects that the pointer can fall within.
+/// Difference betweens MemoryObjects and ObjectStates ?
+///
+/// @section expression Expressions
+/// The various Expr classes mostly model the llvm instruction set. ref<Expr> is
+/// used to maintain the reference count
+/// but also embeds any constant expressions. In fact in the current code base
+/// ConstantExprs should almost never be
+/// created. Most of the Expr's are straightforward. Some of the most important ones
+/// are Concat?Expr, which join
+/// some number of bytes into a larger type, ExtractExpr which extracts smaller
+/// types from larger ones, and ReadExpr
+/// which is a symbolic array access.
+///
+/// The way memory is implemented all accesses are broken down into byte level
+/// operations. This means that the
+/// memory system (by which I mean the ObjectState data structure) tends to use a
+/// lot of ExtractExpr and Concat?Expr,
+/// so it is very important that these expressions fold their operands when
+/// possible.
+///
+/// The ReadExpr is probably the most important one. Conceptually it is simply an
+/// index and a list of (index, value)
+/// updates (writes). The ReadExpr evaluates to all the values for which the two
+/// indices can be equal. The ObjectState
+/// structure uses a cache for concrete writes and for symbolic writes at concrete
+/// indices, but for writes at symbolic
+/// indices it must construct a list of such updates. These are stored in the
+/// UpdateList and UpdateNode structures
+/// which are again immutable data structures so that copy is cheap and the sharing
+/// is exploited.
+/// 
+/// @section searcher Searcher
+/// Base classe: klee::Searcher. The Executor uses a Searcher to select the next
+/// state (i.e. program instance following a single path) for which an
+/// instruction
+/// will be executed. There are multiple implementations of Searcher in klee,
+/// implementing different search policies. klee::RandomSearcher selects the next state randomly.
+/// klee::DFSSearcher uses a depth first approach. klee::MergingSearcher tries
+/// to merge states ?
diff --git a/examples/regexp/Regexp.c b/examples/regexp/Regexp.c
new file mode 100644
index 00000000..f3e751f9
--- /dev/null
+++ b/examples/regexp/Regexp.c
@@ -0,0 +1,62 @@
+/* 
+ * Simple regular expression matching.
+ *
+ * From:
+ *   The Practice of Programming
+ *   Brian W. Kernighan, Rob Pike
+ *
+ */ 
+
+#include <klee/klee.h>
+
+static int matchhere(char*,char*);
+
+static int matchstar(int c, char *re, char *text) {
+  do {
+    if (matchhere(re, text))
+      return 1;
+  } while (*text != '\0' && (*text++ == c || c== '.'));
+  return 0;
+}
+
+static int matchhere(char *re, char *text) {
+  if (re[0] == '\0')
+     return 0;
+  if (re[1] == '*')
+    return matchstar(re[0], re+2, text);
+  if (re[0] == '$' && re[1]=='\0')
+    return *text == '\0';
+  if (*text!='\0' && (re[0]=='.' || re[0]==*text))
+    return matchhere(re+1, text+1);
+  return 0;
+}
+
+int match(char *re, char *text) {
+  if (re[0] == '^')
+    return matchhere(re+1, text);
+  do {
+    if (matchhere(re, text))
+      return 1;
+  } while (*text++ != '\0');
+  return 0;
+}
+
+/*
+ * Harness for testing with KLEE.
+ */
+
+// The size of the buffer to test with.
+#define SIZE 7
+
+int main() {
+  // The input regular expression.
+  char re[SIZE];
+  
+  // Make the input symbolic. 
+  klee_make_symbolic_name(re, sizeof re, "re");
+
+  // Try to match against a constant string "hello".
+  match(re, "hello");
+
+  return 0;
+}
diff --git a/examples/regexp/notes.txt b/examples/regexp/notes.txt
new file mode 100644
index 00000000..7d25585c
--- /dev/null
+++ b/examples/regexp/notes.txt
@@ -0,0 +1,26 @@
+clang -m32 -I ~/private/klee/include -c -emit-llvm Regexp.c
+
+klee Regexp.o
+klee --only-output-states-covering-new Regexp.o
+ls -l klee-out-0
+ls -l klee-out-1
+ls -l klee-last
+
+cd klee-last
+klee-bout-tool *.bout
+klee-bout-tool --trim-zeros *.bout
+
+Stuff to show:
+Adding klee_prefer_cex
+
+PrintStats.py klee-last
+
+PrintStats.py klee-last
+Why not 100% coverage?
+
+clang -g -m32 -I ~/private/klee/include -c -emit-llvm Regexp.c
+
+KCachegrind?
+
+Disable klee_assume, show coverage again (why is klee-check-div getting pulled
+in?)
diff --git a/examples/sort/sort.c b/examples/sort/sort.c
new file mode 100644
index 00000000..a1629c6b
--- /dev/null
+++ b/examples/sort/sort.c
@@ -0,0 +1,78 @@
+#include <klee/klee.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+static void insert_ordered(int *array, unsigned nelem, int item) {
+  unsigned i = 0;
+
+  for (; i != nelem; ++i) {
+    if (item < array[i]) {
+      memmove(&array[i+1], &array[i], sizeof(*array) * (nelem - i));
+      break;
+    }
+  }
+
+  array[i] = item;
+}
+
+void bubble_sort(int *array, unsigned nelem) {
+  for (;;) {
+    int done = 1;
+
+    for (unsigned i = 0; i + 1 < nelem; ++i) {
+      if (array[i+1] < array[i]) {
+        int t = array[i + 1];
+        array[i + 1] = array[i];
+        array[i] = t;
+        done = 0;
+      }
+    }
+
+    break;
+  }
+}
+
+void insertion_sort(int *array, unsigned nelem) {
+  int *temp = malloc(sizeof(*temp) * nelem);
+
+  for (unsigned i = 0; i != nelem; ++i)
+    insert_ordered(temp, i, array[i]);
+
+  memcpy(array, temp, sizeof(*array) * nelem);
+  free(temp);
+}
+
+void test(int *array, unsigned nelem) {
+  int *temp1 = malloc(sizeof(*array) * nelem);
+  int *temp2 = malloc(sizeof(*array) * nelem);
+
+  printf("input: [%d, %d, %d, %d]\n",
+         array[0], array[1], array[2], array[3]);
+
+  memcpy(temp1, array, sizeof(*array) * 4);
+  memcpy(temp2, array, sizeof(*array) * 4);
+
+  insertion_sort(temp1, 4);
+  bubble_sort(temp2, 4);
+
+  printf("insertion_sort: [%d, %d, %d, %d]\n",
+         temp1[0], temp1[1], temp1[2], temp1[3]);
+
+  printf("bubble_sort   : [%d, %d, %d, %d]\n",
+         temp2[0], temp2[1], temp2[2], temp2[3]);
+
+  for (unsigned i = 0; i != nelem; ++i)
+    assert(temp1[i] == temp2[i]);
+}
+
+int main() {
+  int input[4] = { 4, 3, 2, 1};
+
+  klee_make_symbolic(&input, sizeof(input));
+  test(input, 4);
+
+  return 0;
+}
diff --git a/include/expr/Lexer.h b/include/expr/Lexer.h
new file mode 100644
index 00000000..4ae760a0
--- /dev/null
+++ b/include/expr/Lexer.h
@@ -0,0 +1,114 @@
+//===-- Lexer.h -------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPR_LEXER_H
+#define KLEE_EXPR_LEXER_H
+
+#include <string>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace klee {
+namespace expr {
+  struct Token {
+    enum Kind {
+      At,                       /// '@'
+      Arrow,                    /// '->'
+      Colon,                    /// ':'
+      Comma,                    /// ','
+      Comment,                  /// #[^\n]+
+      EndOfFile,                /// <end of file>
+      Equals,                   /// ' = '
+      Identifier,               /// [a-zA-Z_][a-zA-Z0-9._]*
+      KWFalse,                  /// 'false'
+      KWQuery,                  /// 'query'
+      KWReserved,               /// fp[0-9]+([.].*)?, i[0-9]+
+      KWTrue,                   /// 'true'
+      KWWidth,                  /// w[0-9]+
+      LBrace,                   /// '{'
+      LParen,                   /// '('
+      LSquare,                  /// '['
+      Number,                   /// [+-]?[0-9][a-zA-Z0-9_]+
+      RBrace,                   /// '}'
+      RParen,                   /// ')'
+      RSquare,                  /// ']'
+      Semicolon,                /// ';'
+      Unknown                   /// <other>
+    };
+
+    Kind        kind;           /// The token kind.
+    const char *start;          /// The beginning of the token string. 
+    unsigned    length;         /// The length of the token.
+    unsigned    line;           /// The line number of the start of this token.
+    unsigned    column;         /// The column number at the start of
+                                /// this token.
+
+    /// getKindName - The name of this token's kind.
+    const char *getKindName() const;
+
+    /// getString - The string spanned by this token. This is not
+    /// particularly efficient, use start and length when reasonable.
+    std::string getString() const { return std::string(start, length); }
+
+    /// isKeyword - True if this token is a keyword.
+    bool isKeyword() const { 
+      return kind >= KWFalse && kind <= KWTrue; 
+    }
+
+    // dump - Dump the token to stderr.
+    void dump();
+  };
+
+  /// Lexer - Interface for lexing tokens from a .pc language file.
+  class Lexer {
+    const char *BufferPos;      /// The current lexer position.
+    const char *BufferEnd;      /// The buffer end position.
+    unsigned    LineNumber;     /// The current line.
+    unsigned    ColumnNumber;   /// The current column.
+
+    /// GetNextChar - Eat a character or -1 from the stream.
+    int GetNextChar();
+
+    /// PeekNextChar - Return the next character without consuming it
+    /// from the stream. This does not perform newline
+    /// canonicalization.
+    int PeekNextChar();
+
+    /// SetTokenKind - Set the token kind and length (using the
+    /// token's start pointer, which must have been initialized).
+    Token &SetTokenKind(Token &Result, Token::Kind k);
+
+    /// SetTokenKind - Set an identifiers token kind. This has the
+    /// same requirements as SetTokenKind and additionally takes care
+    /// of keyword recognition.
+    Token &SetIdentifierTokenKind(Token &Result);
+  
+    void SkipToEndOfLine();
+
+    /// LexNumber - Lex a number which does not have a base specifier.
+    Token &LexNumber(Token &Result);
+
+    /// LexIdentifier - Lex an identifier.
+    Token &LexIdentifier(Token &Result);
+
+  public:
+    explicit Lexer(const llvm::MemoryBuffer *_buf);
+    ~Lexer();
+
+    /// Lex - Return the next token from the file or EOF continually
+    /// when the end of the file is reached. The input argument is
+    /// used as the result, for convenience.
+    Token &Lex(Token &Result);
+  };
+}
+}
+
+#endif
diff --git a/include/expr/Parser.h b/include/expr/Parser.h
new file mode 100644
index 00000000..7634d66a
--- /dev/null
+++ b/include/expr/Parser.h
@@ -0,0 +1,178 @@
+//===-- Parser.h ------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPR_PARSER_H
+#define KLEE_EXPR_PARSER_H
+
+#include "klee/Expr.h"
+
+#include <vector>
+#include <string>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace klee {
+namespace expr {
+  // These are the language types we manipulate.
+  typedef ref<Expr> ExprHandle;
+  typedef UpdateList VersionHandle;
+  
+  /// Identifier - Wrapper for a uniqued string.
+  struct Identifier {
+    const std::string Name;
+
+  public:
+    Identifier(const std::string _Name) : Name(_Name) {}
+  };
+
+  // FIXME: Do we have a use for tracking source locations?
+
+  /// Decl - Base class for top level declarations.
+  class Decl {
+  public:
+    Decl();
+    virtual ~Decl() {}
+
+    /// dump - Dump the AST node to stderr.
+    virtual void dump() = 0;
+  };
+
+  /// ArrayDecl - Array declarations.
+  ///
+  /// For example:
+  ///   array obj : 32 -> 8 = symbolic
+  ///   array obj[32] : 32 -> 8 = { ... }
+  class ArrayDecl : public Decl {
+  public:
+    /// Name - The name of this array.
+    const Identifier *Name;
+
+    /// Size - The maximum array size (or 0 if unspecified). Concrete
+    /// arrays always are specified with a size.
+    const unsigned Size;
+
+    /// Domain - The width of indices.
+    const unsigned Domain;
+
+    /// Range - The width of array contents.
+    const unsigned Range;
+    
+    /// Contents - The initial contents of the array. The array is
+    /// symbolic if no contents are specified. The contained
+    /// expressions are guaranteed to be constants.
+    const std::vector<ExprHandle> Contents;
+
+  public:
+    template<typename InputIterator>
+    ArrayDecl(const Identifier *_Name, unsigned _Size, 
+              unsigned _Domain, unsigned _Range,
+              InputIterator ContentsBegin=InputIterator(), 
+              InputIterator ContentsEnd=InputIterator()) 
+      : Name(_Name), Size(_Size), Domain(_Domain), Range(_Range),
+        Contents(ContentsBegin, ContentsEnd) {}
+  };
+
+  /// VarDecl - Variable declarations, used to associate names to
+  /// expressions or array versions outside of expressions.
+  /// 
+  /// For example:
+  // FIXME: What syntax are we going to use for this? We need it.
+  class VarDecl : public Decl {
+  public:
+    const Identifier *Name;    
+  };
+
+  /// ExprVarDecl - Expression variable declarations.
+  class ExprVarDecl : public VarDecl {
+  public:
+    ExprHandle Value;
+  };
+
+  /// VersionVarDecl - Array version variable declarations.
+  class VersionVarDecl : public VarDecl {
+  public:
+    VersionHandle Value;
+  };
+
+  /// CommandDecl - Base class for language commands.
+  class CommandDecl : public Decl {
+  public:
+    const Identifier *Name;
+  };
+
+  /// QueryCommand - Query commands.
+  ///
+  /// (query [ ... constraints ... ] expression)
+  /// (query [ ... constraints ... ] expression values)
+  /// (query [ ... constraints ... ] expression values objects)
+  class QueryCommand : public CommandDecl {
+  public:
+    // FIXME: One issue with STP... should we require the FE to
+    // guarantee that these are consistent? That is a cornerstone of
+    // being able to do independence. We may want this as a flag, if
+    // we are to interface with things like SMT.
+
+    /// Constraints - The list of constraints to assume for this
+    /// expression.
+    const std::vector<ExprHandle> Constraints;
+    
+    /// Query - The expression being queried.
+    ExprHandle Query;
+
+    /// Values - The expressions for which counterexamples should be
+    /// given if the query is invalid.
+    const std::vector<ExprHandle> Values;
+
+    /// Objects - Symbolic arrays whose initial contents should be
+    /// given if the query is invalid.
+    const std::vector<ArrayDecl> Objects;
+
+  public:
+    template<typename InputIterator>
+    QueryCommand(InputIterator ConstraintsBegin, 
+                 InputIterator ConstraintsEnd,
+                 ExprHandle _Query)
+      : Constraints(ConstraintsBegin, ConstraintsEnd),
+        Query(_Query) {}
+
+    virtual void dump();
+  };
+  
+  /// Parser - Public interface for parsing a .pc language file.
+  class Parser {
+  protected:
+    Parser();
+  public:
+    virtual ~Parser();
+
+    /// SetMaxErrors - Suppress anything beyond the first N errors.
+    virtual void SetMaxErrors(unsigned N) = 0;
+    
+    /// GetNumErrors - Return the number of encountered errors.
+    virtual unsigned GetNumErrors() const = 0;
+
+    /// ParseTopLevelDecl - Parse and return a top level declaration,
+    /// which the caller assumes ownership of.
+    ///
+    /// \return NULL indicates the end of the file has been reached.
+    virtual Decl *ParseTopLevelDecl() = 0;
+
+    /// CreateParser - Create a parser implementation for the given
+    /// MemoryBuffer.
+    ///
+    /// \arg Name - The name to use in diagnostic messages.
+    static Parser *Create(const std::string Name,
+                          const llvm::MemoryBuffer *MB);
+  };
+}
+}
+
+#endif
diff --git a/include/klee/Config/config.h.in b/include/klee/Config/config.h.in
new file mode 100644
index 00000000..ef41d786
--- /dev/null
+++ b/include/klee/Config/config.h.in
@@ -0,0 +1,64 @@
+/* include/klee/Config/config.h.in.  Generated from autoconf/configure.tmp.ac by autoheader.  */
+
+/* Define if stplog enabled */
+#undef ENABLE_STPLOG
+
+/* Does the platform use __ctype_b_loc, etc. */
+#undef HAVE_CTYPE_EXTERNALS
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <selinux/selinux.h> header file. */
+#undef HAVE_SELINUX_SELINUX_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/acl.h> header file. */
+#undef HAVE_SYS_ACL_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Path to KLEE's uClibc */
+#undef KLEE_UCLIBC
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Configuration for runtime libraries */
+#undef RUNTIME_CONFIGURATION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
diff --git a/include/klee/Constraints.h b/include/klee/Constraints.h
new file mode 100644
index 00000000..87069f89
--- /dev/null
+++ b/include/klee/Constraints.h
@@ -0,0 +1,79 @@
+//===-- Constraints.h -------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_CONSTRAINTS_H
+#define KLEE_CONSTRAINTS_H
+
+#include "klee/Expr.h"
+
+// FIXME: Currently we use ConstraintManager for two things: to pass
+// sets of constraints around, and to optimize constraints. We should
+// move the first usage into a separate data structure
+// (ConstraintSet?) which ConstraintManager could embed if it likes.
+namespace klee {
+
+class ExprVisitor;
+  
+class ConstraintManager {
+public:
+  typedef std::vector< ref<Expr> > constraints_ty;
+  typedef constraints_ty::iterator iterator;
+  typedef constraints_ty::const_iterator const_iterator;
+
+  ConstraintManager() {}
+
+  // create from constraints with no optimization
+  explicit
+  ConstraintManager(const std::vector< ref<Expr> > &_constraints) :
+    constraints(_constraints) {}
+
+  ConstraintManager(const ConstraintManager &cs) : constraints(cs.constraints) {}
+
+  typedef std::vector< ref<Expr> >::const_iterator constraint_iterator;
+
+  // given a constraint which is known to be valid, attempt to 
+  // simplify the existing constraint set
+  void simplifyForValidConstraint(ref<Expr> e);
+
+  ref<Expr> simplifyExpr(ref<Expr> e) const;
+
+  void addConstraint(ref<Expr> e);
+  
+  bool empty() const {
+    return constraints.empty();
+  }
+  ref<Expr> back() const {
+    return constraints.back();
+  }
+  constraint_iterator begin() const {
+    return constraints.begin();
+  }
+  constraint_iterator end() const {
+    return constraints.end();
+  }
+  size_t size() const {
+    return constraints.size();
+  }
+
+  bool operator==(const ConstraintManager &other) const {
+    return constraints == other.constraints;
+  }
+  
+private:
+  std::vector< ref<Expr> > constraints;
+
+  // returns true iff the constraints were modified
+  bool rewriteConstraints(ExprVisitor &visitor);
+
+  void addConstraintInternal(ref<Expr> e);
+};
+
+}
+
+#endif /* KLEE_CONSTRAINTS_H */
diff --git a/include/klee/ExecutionState.h b/include/klee/ExecutionState.h
new file mode 100644
index 00000000..09ce2a4b
--- /dev/null
+++ b/include/klee/ExecutionState.h
@@ -0,0 +1,250 @@
+//===-- ExecutionState.h ----------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXECUTIONSTATE_H
+#define KLEE_EXECUTIONSTATE_H
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/Internal/ADT/TreeStream.h"
+
+// FIXME: We do not want to be exposing these? :(
+#include "../../lib/Core/AddressSpace.h"
+#include "klee/Internal/Module/KInstIterator.h"
+
+#include <map>
+#include <set>
+#include <vector>
+
+namespace klee {
+  class CallPathNode;
+  class Cell;
+  class KFunction;
+  class KInstruction;
+  class MemoryObject;
+  class PTreeNode;
+  class InstructionInfo;
+  class ExecutionTraceEvent;
+
+std::ostream &operator<<(std::ostream &os, const MemoryMap &mm);
+
+struct StackFrame {
+  KInstIterator caller;
+  KFunction *kf;
+  CallPathNode *callPathNode;
+
+  std::vector<const MemoryObject*> allocas;
+  Cell *locals;
+
+  /// Minimum distance to an uncovered instruction once the function
+  /// returns. This is not a good place for this but is used to
+  /// quickly compute the context sensitive minimum distance to an
+  /// uncovered instruction. This value is updated by the StatsTracker
+  /// periodically.
+  unsigned minDistToUncoveredOnReturn;
+
+  // For vararg functions: arguments not passed via parameter are
+  // stored (packed tightly) in a local (alloca) memory object. This
+  // is setup to match the way the front-end generates vaarg code (it
+  // does not pass vaarg through as expected). VACopy is lowered inside
+  // of intrinsic lowering.
+  MemoryObject *varargs;
+
+  StackFrame(KInstIterator caller, KFunction *kf);
+  StackFrame(const StackFrame &s);
+  ~StackFrame();
+};
+
+// FIXME: Redo execution trace stuff to use a TreeStream, there is no
+// need to keep this stuff in memory as far as I can tell.
+
+// each state should have only one of these guys ...
+class ExecutionTraceManager {
+public:
+  ExecutionTraceManager() : hasSeenUserMain(false) {}
+
+  void addEvent(ExecutionTraceEvent* evt);
+  void printAllEvents(std::ostream &os) const;
+
+private:
+  // have we seen a call to __user_main() yet?
+  // don't bother tracing anything until we see this,
+  // or else we'll get junky prologue shit
+  bool hasSeenUserMain;
+
+  // ugh C++ only supports polymorphic calls thru pointers
+  //
+  // WARNING: these are NEVER FREED, because they are shared
+  // across different states (when states fork), so we have 
+  // an *intentional* memory leak, but oh wellz ;)
+  std::vector<ExecutionTraceEvent*> events;
+};
+
+
+class ExecutionState {
+public:
+  typedef std::vector<StackFrame> stack_ty;
+
+private:
+  // unsupported, use copy constructor
+  ExecutionState &operator=(const ExecutionState&); 
+  std::map< std::string, std::string > fnAliases;
+
+public:
+  bool fakeState;
+  // Are we currently underconstrained?  Hack: value is size to make fake
+  // objects.
+  unsigned underConstrained;
+  unsigned depth;
+  
+  // pc - pointer to current instruction stream
+  KInstIterator pc, prevPC;
+  stack_ty stack;
+  ConstraintManager constraints;
+  mutable double queryCost;
+  double weight;
+  AddressSpace addressSpace;
+  TreeOStream pathOS, symPathOS;
+  unsigned instsSinceCovNew;
+  bool coveredNew;
+
+  // for printing execution traces when this state terminates
+  ExecutionTraceManager exeTraceMgr;
+
+  /// Disables forking, set by user code.
+  bool forkDisabled;
+
+  std::map<const std::string*, std::set<unsigned> > coveredLines;
+  PTreeNode *ptreeNode;
+
+  /// ordered list of symbolics: used to generate test cases. 
+  //
+  // FIXME: Move to a shared list structure (not critical).
+  std::vector<const MemoryObject*> symbolics;
+
+  // Used by the checkpoint/rollback methods for fake objects.
+  // FIXME: not freeing things on branch deletion.
+  MemoryMap shadowObjects;
+
+  unsigned incomingBBIndex;
+
+  std::string getFnAlias(std::string fn);
+  void addFnAlias(std::string old_fn, std::string new_fn);
+  void removeFnAlias(std::string fn);
+  
+private:
+  ExecutionState() : fakeState(false), underConstrained(0), ptreeNode(0) {};
+
+public:
+  ExecutionState(KFunction *kf);
+
+  // XXX total hack, just used to make a state so solver can
+  // use on structure
+  ExecutionState(const std::vector<ref<Expr> > &assumptions);
+
+  ~ExecutionState();
+  
+  ExecutionState *branch();
+
+  void pushFrame(KInstIterator caller, KFunction *kf);
+  void popFrame();
+
+  void addSymbolic(const MemoryObject *mo) { 
+    symbolics.push_back(mo);
+  }
+  void addConstraint(ref<Expr> e) { 
+    constraints.addConstraint(e); 
+  }
+
+  // Used for checkpoint/rollback of fake objects created during tainting.
+  ObjectState *cloneObject(ObjectState *os, MemoryObject *mo);
+
+  //
+
+  bool merge(const ExecutionState &b);
+};
+
+
+// for producing abbreviated execution traces to help visualize
+// paths and diagnose bugs
+
+class ExecutionTraceEvent {
+public:
+  // the location of the instruction:
+  std::string file;
+  unsigned line;
+  std::string funcName;
+  unsigned stackDepth;
+
+  unsigned consecutiveCount; // init to 1, increase for CONSECUTIVE
+                             // repetitions of the SAME event
+
+  ExecutionTraceEvent()
+    : file("global"), line(0), funcName("global_def"),
+      consecutiveCount(1) {}
+
+  ExecutionTraceEvent(ExecutionState& state, KInstruction* ki);
+
+  virtual ~ExecutionTraceEvent() {}
+
+  void print(std::ostream &os) const;
+
+  // return true if it shouldn't be added to ExecutionTraceManager
+  //
+  virtual bool ignoreMe() const;
+
+private:
+  virtual void printDetails(std::ostream &os) const = 0;
+};
+
+
+class FunctionCallTraceEvent : public ExecutionTraceEvent {
+public:
+  std::string calleeFuncName;
+
+  FunctionCallTraceEvent(ExecutionState& state, KInstruction* ki,
+                         const std::string& _calleeFuncName)
+    : ExecutionTraceEvent(state, ki), calleeFuncName(_calleeFuncName) {}
+
+private:
+  virtual void printDetails(std::ostream &os) const {
+    os << "CALL " << calleeFuncName;
+  }
+
+};
+
+class FunctionReturnTraceEvent : public ExecutionTraceEvent {
+public:
+  FunctionReturnTraceEvent(ExecutionState& state, KInstruction* ki)
+    : ExecutionTraceEvent(state, ki) {}
+
+private:
+  virtual void printDetails(std::ostream &os) const {
+    os << "RETURN";
+  }
+};
+
+class BranchTraceEvent : public ExecutionTraceEvent {
+public:
+  bool trueTaken;         // which side taken?
+  bool canForkGoBothWays;
+
+  BranchTraceEvent(ExecutionState& state, KInstruction* ki,
+                   bool _trueTaken, bool _isTwoWay)
+    : ExecutionTraceEvent(state, ki),
+      trueTaken(_trueTaken),
+      canForkGoBothWays(_isTwoWay) {}
+
+private:
+  virtual void printDetails(std::ostream &os) const;
+};
+
+}
+
+#endif
diff --git a/include/klee/Expr.h b/include/klee/Expr.h
new file mode 100644
index 00000000..d16a09bf
--- /dev/null
+++ b/include/klee/Expr.h
@@ -0,0 +1,808 @@
+//===-- Expr.h --------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPR_H
+#define KLEE_EXPR_H
+
+#include "Machine.h"
+#include "klee/util/Bits.h"
+
+#include "llvm/Support/Streams.h"
+#include "llvm/ADT/SmallVector.h"
+
+#include <set>
+#include <vector>
+
+namespace llvm {
+  class Type;
+}
+
+namespace klee {
+
+class Array;
+class ConstantExpr;
+class ObjectState;
+class MemoryObject;
+
+template<class T> class ref;
+
+
+/// Class representing symbolic expressions.
+/**
+
+<b>Expression canonicalization</b>: we define certain rules for
+canonicalization rules for Exprs in order to simplify code that
+pattern matches Exprs (since the number of forms are reduced), to open
+up further chances for optimization, and to increase similarity for
+caching and other purposes.
+
+The general rules are:
+<ol>
+<li> No Expr has all constant arguments.</li>
+
+<li> Booleans:
+    <ol type="a">
+    <li> Boolean not is written as <tt>(false == ?)</tt> </li>
+     <li> \c Ne, \c Ugt, \c Uge, \c Sgt, \c Sge are not used </li>
+     <li> The only acceptable operations with boolean arguments are \c And, 
+          \c Or, \c Xor, \c Eq, as well as \c SExt, \c ZExt,
+          \c Select and \c NotOptimized. </li>
+     <li> The only boolean operation which may involve a constant is boolean not (<tt>== false</tt>). </li>
+     </ol>
+</li>
+
+<li> Linear Formulas: 
+   <ol type="a">
+   <li> For any subtree representing a linear formula, a constant
+   term must be on the LHS of the root node of the subtree.  In particular, 
+   in a BinaryExpr a constant must always be on the LHS.  For example, subtraction 
+   by a constant c is written as <tt>add(-c, ?)</tt>.  </li>
+    </ol>
+</li>
+
+
+<li> Chains are unbalanced to the right </li>
+
+</ol>
+
+
+<b>Steps required for adding an expr</b>:
+   -# Add case to printKind
+   -# Add to ExprVisitor
+   -# Add to IVC (implied value concretization) if possible
+
+Todo: Shouldn't bool \c Xor just be written as not equal?
+
+*/
+
+class Expr {
+public:
+  static unsigned count;
+  static const unsigned MAGIC_HASH_CONSTANT = 39;
+
+  /// The type of an expression is simply its width, in bits. 
+  typedef unsigned Width; 
+  
+  static const Width InvalidWidth = 0;
+  static const Width Bool = 1;
+  static const Width Int8 = 8;
+  static const Width Int16 = 16;
+  static const Width Int32 = 32;
+  static const Width Int64 = 64;
+  
+
+  enum Kind {
+    InvalidKind = -1,
+
+    // Primitive
+
+    Constant = 0,
+
+    // Special
+
+    /// Prevents optimization below the given expression.  Used for
+    /// testing: make equality constraints that KLEE will not use to
+    /// optimize to concretes.
+    NotOptimized,
+
+    //// Skip old varexpr, just for deserialization, purge at some point
+    Read=NotOptimized+2, 
+    Select,
+    Concat,
+    Extract,
+
+    // Casting,
+    
+    ZExt,
+    SExt,
+
+    // Arithmetic
+    Add,
+    Sub,
+    Mul,
+    UDiv,
+    SDiv,
+    URem,
+    SRem,
+
+    // Bit
+    And,
+    Or,
+    Xor,
+    Shl,
+    LShr,
+    AShr,
+    
+    // Compare
+    Eq,
+    Ne,  /// Not used in canonical form
+    Ult,
+    Ule,
+    Ugt, /// Not used in canonical form
+    Uge, /// Not used in canonical form
+    Slt,
+    Sle,
+    Sgt, /// Not used in canonical form
+    Sge, /// Not used in canonical form
+
+    LastKind=Sge
+  };
+
+  unsigned refCount;
+
+protected:  
+  unsigned hashValue;
+  
+public:
+  Expr() : refCount(0) { Expr::count++; }
+  virtual ~Expr() { Expr::count--; } 
+
+  virtual Kind getKind() const = 0;
+  virtual Width getWidth() const = 0;
+  
+  virtual unsigned getNumKids() const = 0;
+  virtual ref<Expr> getKid(unsigned i) const = 0;
+    
+  virtual void print(std::ostream &os) const;
+
+  /// Returns the pre-computed hash of the current expression
+  virtual unsigned hash() const { return hashValue; }
+
+  /// (Re)computes the hash of the current expression.
+  /// Returns the hash value. 
+  virtual unsigned computeHash();
+  
+  static unsigned hashConstant(uint64_t val, Width w) {
+    return val ^ (w * MAGIC_HASH_CONSTANT);
+  }
+  
+  /// Returns 0 iff b is structuraly equivalent to *this
+  int compare(const Expr &b) const;
+  virtual int compareContents(const Expr &b) const { return 0; }
+
+  // Given an array of new kids return a copy of the expression
+  // but using those children. 
+  virtual ref<Expr> rebuild(ref<Expr> kids[/* getNumKids() */]) const = 0;
+
+  ///
+
+  uint64_t getConstantValue() const;
+
+  /* Static utility methods */
+
+  static void printKind(std::ostream &os, Kind k);
+  static void printWidth(std::ostream &os, Expr::Width w);
+  static Width getWidthForLLVMType(const llvm::Type *type);
+
+  /// returns the smallest number of bytes in which the given width fits
+  static inline unsigned getMinBytesForWidth(Width w) {
+      return (w + 7) / 8;
+  }
+
+  /* Kind utilities */
+
+  /* Utility creation functions */
+  static ref<Expr> createCoerceToPointerType(ref<Expr> e);
+  static ref<Expr> createNot(ref<Expr> e);
+  static ref<Expr> createImplies(ref<Expr> hyp, ref<Expr> conc);
+  static ref<Expr> createIsZero(ref<Expr> e);
+
+  /// Create a little endian read of the given type at offset 0 of the
+  /// given object.
+  static ref<Expr> createTempRead(const Array *array, Expr::Width w);
+  
+  static ref<Expr> createPointer(uint64_t v);
+
+  // do not use
+  static Expr *createConstant(uint64_t val, Width w);
+  
+  struct CreateArg;
+  static ref<Expr> createFromKind(Kind k, std::vector<CreateArg> args);
+
+  static bool isValidKidWidth(unsigned kid, Width w) { return true; }
+  static bool needsResultType() { return false; }
+};
+// END class Expr
+
+
+
+#include "klee/util/Ref.h"
+
+struct Expr::CreateArg {
+  ref<Expr> expr;
+  Width width;
+  
+  CreateArg(Width w = Bool) : expr(0, Expr::Bool), width(w) {}
+  CreateArg(ref<Expr> e) : expr(e), width(Expr::InvalidWidth) {}
+  
+  bool isExpr() { return !isWidth(); }
+  bool isWidth() { return width != Expr::InvalidWidth; }
+};
+
+// Comparison operators
+
+inline bool operator==(const Expr &lhs, const Expr &rhs) {
+  return lhs.compare(rhs) == 0;
+}
+
+inline bool operator<(const Expr &lhs, const Expr &rhs) {
+  return lhs.compare(rhs) < 0;
+}
+
+inline bool operator!=(const Expr &lhs, const Expr &rhs) {
+  return !(lhs == rhs);
+}
+
+inline bool operator>(const Expr &lhs, const Expr &rhs) {
+  return rhs < lhs;
+}
+
+inline bool operator<=(const Expr &lhs, const Expr &rhs) {
+  return !(lhs > rhs);
+}
+
+inline bool operator>=(const Expr &lhs, const Expr &rhs) {
+  return !(lhs < rhs);
+}
+
+// Printing operators
+
+inline std::ostream &operator<<(std::ostream &os, const Expr &e) {
+  e.print(os);
+  return os;
+}
+
+inline std::ostream &operator<<(std::ostream &os, const Expr::Kind kind) {
+  Expr::printKind(os, kind);
+  return os;
+}
+
+// Terminal Exprs
+
+class ConstantExpr : public Expr {
+public:
+  static const Kind kind = Constant;
+  static const unsigned numKids = 0;
+  
+public:
+  union {
+    uint64_t asUInt64;
+  };
+  Width width;
+
+public:
+  ~ConstantExpr() {};
+  // should change the code to make this private
+  ConstantExpr(uint64_t v, Width w) : asUInt64(v), width(w) {}
+  
+  Width getWidth() const { return width; }
+  Kind getKind() const { return Constant; }
+
+  unsigned getNumKids() const { return 0; }
+  ref<Expr> getKid(unsigned i) const { return 0; }
+
+  int compareContents(const Expr &b) const { 
+    const ConstantExpr &cb = static_cast<const ConstantExpr&>(b);
+    if (width != cb.width) return width < cb.width ? -1 : 1;
+    if (asUInt64 < cb.asUInt64) {
+      return -1;
+    } else if (asUInt64 > cb.asUInt64) {
+      return 1;
+    } else {
+      return 0;
+    }
+  }
+
+  virtual ref<Expr> rebuild(ref<Expr> kids[]) const { 
+    assert(0 && "rebuild() on ConstantExpr"); 
+  }
+
+  virtual unsigned computeHash();
+  
+  static ref<ConstantExpr> fromMemory(void *address, Width w);
+  void toMemory(void *address);
+
+  static ref<ConstantExpr> alloc(uint64_t v, Width w) {
+    // constructs an "optimized" ConstantExpr
+    return ref<ConstantExpr>(v, w);
+  }
+  
+  static ref<ConstantExpr> create(uint64_t v, Width w) {
+    assert(v == bits64::truncateToNBits(v, w) &&
+           "invalid constant");
+    return alloc(v, w);
+  }
+};
+
+  
+// Utility classes
+
+class BinaryExpr : public Expr {
+public:
+  ref<Expr> left, right;
+
+public:
+  unsigned getNumKids() const { return 2; }
+  ref<Expr> getKid(unsigned i) const { 
+    if(i == 0)
+      return left;
+    if(i == 1)
+      return right;
+    return 0;
+  }
+ 
+protected:
+  BinaryExpr(const ref<Expr> &l, const ref<Expr> &r) : left(l), right(r) {}
+};
+
+
+class CmpExpr : public BinaryExpr {
+
+protected:
+  CmpExpr(ref<Expr> l, ref<Expr> r) : BinaryExpr(l,r) {}
+  
+public:                                                       
+  Width getWidth() const { return Bool; }
+};
+
+// Special
+
+class NotOptimizedExpr : public Expr {
+public:
+  static const Kind kind = NotOptimized;
+  static const unsigned numKids = 1;
+  ref<Expr> src;
+
+  static ref<Expr> alloc(const ref<Expr> &src) {
+    ref<Expr> r(new NotOptimizedExpr(src));
+    r.computeHash();
+    return r;
+  }
+  
+  static ref<Expr> create(ref<Expr> src);
+  
+  Width getWidth() const { return src.getWidth(); }
+  Kind getKind() const { return NotOptimized; }
+
+  unsigned getNumKids() const { return 1; }
+  ref<Expr> getKid(unsigned i) const { return src; }
+
+  virtual ref<Expr> rebuild(ref<Expr> kids[]) const { return create(kids[0]); }
+
+private:
+  NotOptimizedExpr(const ref<Expr> &_src) : src(_src) {}
+};
+
+
+/// Class representing a byte update of an array.
+class UpdateNode {
+  friend class UpdateList;
+  friend class STPBuilder; // for setting STPArray
+
+  mutable unsigned refCount;
+  // gross
+  mutable void *stpArray;
+  // cache instead of recalc
+  unsigned hashValue;
+
+public:
+  const UpdateNode *next;
+  ref<Expr> index, value;
+  
+private:
+  /// size of this update sequence, including this update
+  unsigned size;
+  
+public:
+  UpdateNode(const UpdateNode *_next, 
+             const ref<Expr> &_index, 
+             const ref<Expr> &_value);
+
+  unsigned getSize() const { return size; }
+
+  int compare(const UpdateNode &b) const;  
+  unsigned hash() const { return hashValue; }
+
+private:
+  UpdateNode() : refCount(0), stpArray(0) {}
+  ~UpdateNode();
+
+  unsigned computeHash();
+};
+
+class Array {
+public:
+  const MemoryObject *object;
+  unsigned id;
+  unsigned size;
+
+  // FIXME: This does not belong here.
+  mutable void *stpInitialArray;
+
+public:
+  // NOTE: id's ***MUST*** be unique to ensure sanity w.r.t. STP,
+  // which hashes different arrays with the same id to the same
+  // object! We should probably use the pointer for talking to STP, as
+  // long as we can guarantee that it won't be a "stale" reference
+  // once we have freed it.
+  Array(const MemoryObject *_object, unsigned _id, uint64_t _size) 
+    : object(_object), id(_id), size(_size), stpInitialArray(0) {}
+  ~Array() {
+    // FIXME: This relies on caller to delete the STP array.
+    assert(!stpInitialArray && "Array must be deleted by caller!");
+  }
+};
+
+/// Class representing a complete list of updates into an array. 
+/** The main trick is the isRooted bit, which enables important optimizations. 
+    ...
+ */
+class UpdateList { 
+  friend class ReadExpr; // for default constructor
+
+public:
+  const Array *root;
+  
+  /// pointer to the most recent update node
+  const UpdateNode *head;
+  
+  // shouldn't this be part of the ReadExpr? 
+  bool isRooted;
+
+public:
+  UpdateList(const Array *_root, bool isRooted, const UpdateNode *_head);
+  UpdateList(const UpdateList &b);
+  ~UpdateList();
+  
+  UpdateList &operator=(const UpdateList &b);
+
+  /// size of this update list
+  unsigned getSize() const { return (head ? head->getSize() : 0); }
+  
+  void extend(const ref<Expr> &index, const ref<Expr> &value);
+
+  int compare(const UpdateList &b) const;
+  unsigned hash() const;
+};
+
+/// Class representing a one byte read from an array. 
+class ReadExpr : public Expr {
+public:
+  static const Kind kind = Read;
+  static const unsigned numKids = 1;
+  
+public:
+  UpdateList updates;
+  ref<Expr> index;
+
+public:
+  static ref<Expr> alloc(const UpdateList &updates, const ref<Expr> &index) {
+    ref<Expr> r(new ReadExpr(updates, index));
+    r.computeHash();
+    return r;
+  }
+  
+  static ref<Expr> create(const UpdateList &updates, ref<Expr> i);
+  
+  Width getWidth() const { return Expr::Int8; }
+  Kind getKind() const { return Read; }
+  
+  unsigned getNumKids() const { return numKids; }
+  ref<Expr> getKid(unsigned i) const { return !i ? index : 0; }  
+  
+  int compareContents(const Expr &b) const;
+
+  virtual ref<Expr> rebuild(ref<Expr> kids[]) const { 
+    return create(updates, kids[0]);
+  }
+
+  virtual unsigned computeHash();
+
+private:
+  ReadExpr(const UpdateList &_updates, const ref<Expr> &_index) : 
+    updates(_updates), index(_index) {}
+};
+
+
+/// Class representing an if-then-else expression.
+class SelectExpr : public Expr {
+public:
+  static const Kind kind = Select;
+  static const unsigned numKids = 3;
+  
+public:
+  ref<Expr> cond, trueExpr, falseExpr;
+
+public:
+  static ref<Expr> alloc(const ref<Expr> &c, const ref<Expr> &t, const ref<Expr> &f) {
+    ref<Expr> r(new SelectExpr(c, t, f));
+    r.computeHash();
+    return r;
+  }
+  
+  static ref<Expr> create(ref<Expr> c, ref<Expr> t, ref<Expr> f);
+
+  Width getWidth() const { return trueExpr.getWidth(); }
+  Kind getKind() const { return Select; }
+
+  unsigned getNumKids() const { return numKids; }
+  ref<Expr> getKid(unsigned i) const { 
+        switch(i) {
+        case 0: return cond;
+        case 1: return trueExpr;
+        case 2: return falseExpr;
+        default: return 0;
+        }
+   }
+
+  static bool isValidKidWidth(unsigned kid, Width w) {
+    if (kid == 0)
+      return w == Bool;
+    else
+      return true;
+  }
+    
+  virtual ref<Expr> rebuild(ref<Expr> kids[]) const { 
+    return create(kids[0], kids[1], kids[2]);
+  }
+
+private:
+  SelectExpr(const ref<Expr> &c, const ref<Expr> &t, const ref<Expr> &f) 
+    : cond(c), trueExpr(t), falseExpr(f) {}
+};
+
+
+/** Children of a concat expression can have arbitrary widths.  
+    Kid 0 is the left kid, kid 1 is the right kid.
+*/
+class ConcatExpr : public Expr { 
+public: 
+  static const Kind kind = Concat;
+  static const unsigned numKids = 2;
+
+private:
+  Width width;
+  ref<Expr> left, right;  
+
+public:
+  static ref<Expr> alloc(const ref<Expr> &l, const ref<Expr> &r) {
+    ref<Expr> c(new ConcatExpr(l, r));
+    c.computeHash();
+    return c;
+  }
+  
+  static ref<Expr> create(const ref<Expr> &l, const ref<Expr> &r);
+
+  Width getWidth() const { return width; }
+  Kind getKind() const { return kind; }
+  ref<Expr> getLeft() const { return left; }
+  ref<Expr> getRight() const { return right; }
+
+  unsigned getNumKids() const { return numKids; }
+  ref<Expr> getKid(unsigned i) const { 
+    if (i == 0) return left; 
+    else if (i == 1) return right;
+    else return NULL;
+  }
+
+  /// Shortcuts to create larger concats.  The chain returned is unbalanced to the right
+  static ref<Expr> createN(unsigned nKids, const ref<Expr> kids[]);
+  static ref<Expr> create4(const ref<Expr> &kid1, const ref<Expr> &kid2,
+			   const ref<Expr> &kid3, const ref<Expr> &kid4);
+  static ref<Expr> create8(const ref<Expr> &kid1, const ref<Expr> &kid2,
+			   const ref<Expr> &kid3, const ref<Expr> &kid4,
+			   const ref<Expr> &kid5, const ref<Expr> &kid6,
+			   const ref<Expr> &kid7, const ref<Expr> &kid8);
+  
+  virtual ref<Expr> rebuild(ref<Expr> kids[]) const { return create(kids[0], kids[1]); }
+
+
+  /* These will be eliminated */
+  bool is2ByteConcat() const { return false; }
+  bool is4ByteConcat() const { return false; }
+  bool is8ByteConcat() const { return false; }
+  
+private:
+  ConcatExpr(const ref<Expr> &l, const ref<Expr> &r) : left(l), right(r) {
+    width = l.getWidth() + r.getWidth();
+  }
+};
+
+
+/** This class represents an extract from expression {\tt expr}, at
+    bit offset {\tt offset} of width {\tt width}.  Bit 0 is the right most 
+    bit of the expression.
+ */
+class ExtractExpr : public Expr { 
+public:
+  static const Kind kind = Extract;
+  static const unsigned numKids = 1;
+  
+public:
+  ref<Expr> expr;
+  unsigned offset;
+  Width width;
+
+public:  
+  static ref<Expr> alloc(const ref<Expr> &e, unsigned o, Width w) {
+    ref<Expr> r(new ExtractExpr(e, o, w));
+    r.computeHash();
+    return r;
+  }
+  
+  /// Creates an ExtractExpr with the given bit offset and width
+  static ref<Expr> create(ref<Expr> e, unsigned bitOff, Width w);
+
+  /// Creates an ExtractExpr with the given byte offset and width
+  static ref<Expr> createByteOff(ref<Expr> e, unsigned byteOff, Width w=Expr::Int8);
+
+  Width getWidth() const { return width; }
+  Kind getKind() const { return Extract; }
+
+  unsigned getNumKids() const { return numKids; }
+  ref<Expr> getKid(unsigned i) const { return expr; }
+
+  int compareContents(const Expr &b) const {
+    const ExtractExpr &eb = static_cast<const ExtractExpr&>(b);
+    if (offset != eb.offset) return offset < eb.offset ? -1 : 1;
+    if (width != eb.width) return width < eb.width ? -1 : 1;
+    return 0;
+  }
+
+  virtual ref<Expr> rebuild(ref<Expr> kids[]) const { 
+    return create(kids[0], offset, width);
+  }
+
+  virtual unsigned computeHash();
+
+private:
+  ExtractExpr(const ref<Expr> &e, unsigned b, Width w) 
+    : expr(e),offset(b),width(w) {}
+};
+
+
+// Casting
+
+class CastExpr : public Expr {
+public:
+  ref<Expr> src;
+  Width width;
+
+public:
+  CastExpr(const ref<Expr> &e, Width w) : src(e), width(w) {}
+
+  Width getWidth() const { return width; }
+
+  unsigned getNumKids() const { return 1; }
+  ref<Expr> getKid(unsigned i) const { return (i==0) ? src : 0; }
+  
+  static bool needsResultType() { return true; }
+  
+  int compareContents(const Expr &b) const {
+    const CastExpr &eb = static_cast<const CastExpr&>(b);
+    if (width != eb.width) return width < eb.width ? -1 : 1;
+    return 0;
+  }
+
+  virtual unsigned computeHash();
+};
+
+#define CAST_EXPR_CLASS(_class_kind)                        \
+class _class_kind ## Expr : public CastExpr {               \
+public:                                                     \
+  static const Kind kind = _class_kind;                     \
+  static const unsigned numKids = 1;                        \
+public:                                                     \
+    _class_kind ## Expr(ref<Expr> e, Width w) : CastExpr(e,w) {} \
+    static ref<Expr> alloc(const ref<Expr> &e, Width w) {                   \
+      ref<Expr> r(new _class_kind ## Expr(e, w));                     \
+      r.computeHash();                                                    \
+      return r;                                                       \
+    }                                                       \
+    static ref<Expr> create(const ref<Expr> &e, Width w);                   \
+    Kind getKind() const { return _class_kind; }            \
+    virtual ref<Expr> rebuild(ref<Expr> kids[]) const { \
+      return create(kids[0], width); \
+    } \
+};                                                          \
+
+CAST_EXPR_CLASS(SExt)
+CAST_EXPR_CLASS(ZExt)
+
+// Arithmetic/Bit Exprs
+
+#define ARITHMETIC_EXPR_CLASS(_class_kind)                      \
+class _class_kind ## Expr : public BinaryExpr {                 \
+public:                                                         \
+  static const Kind kind = _class_kind;                         \
+  static const unsigned numKids = 2;                            \
+public:                                                         \
+    _class_kind ## Expr(const ref<Expr> &l, const ref<Expr> &r) : BinaryExpr(l,r) {}  \
+    static ref<Expr> alloc(const ref<Expr> &l, const ref<Expr> &r) {          \
+      ref<Expr> res(new _class_kind ## Expr (l, r));                      \
+      res.computeHash();                                                      \
+      return res;                                                         \
+    }                                                           \
+    static ref<Expr> create(const ref<Expr> &l, const ref<Expr> &r);                      \
+    Width getWidth() const { return left.getWidth(); }            \
+    Kind getKind() const { return _class_kind; }                \
+    virtual ref<Expr> rebuild(ref<Expr> kids[]) const { \
+      return create(kids[0], kids[1]); \
+    } \
+};                                                              \
+
+ARITHMETIC_EXPR_CLASS(Add)
+ARITHMETIC_EXPR_CLASS(Sub)
+ARITHMETIC_EXPR_CLASS(Mul)
+ARITHMETIC_EXPR_CLASS(UDiv)
+ARITHMETIC_EXPR_CLASS(SDiv)
+ARITHMETIC_EXPR_CLASS(URem)
+ARITHMETIC_EXPR_CLASS(SRem)
+ARITHMETIC_EXPR_CLASS(And)
+ARITHMETIC_EXPR_CLASS(Or)
+ARITHMETIC_EXPR_CLASS(Xor)
+ARITHMETIC_EXPR_CLASS(Shl)
+ARITHMETIC_EXPR_CLASS(LShr)
+ARITHMETIC_EXPR_CLASS(AShr)
+
+// Comparison Exprs
+
+#define COMPARISON_EXPR_CLASS(_class_kind)                  \
+class _class_kind ## Expr : public CmpExpr {                \
+public:                                                     \
+  static const Kind kind = _class_kind;                     \
+  static const unsigned numKids = 2;                        \
+public:                                                     \
+    _class_kind ## Expr(const ref<Expr> &l, const ref<Expr> &r) : CmpExpr(l,r) {} \
+    static ref<Expr> alloc(const ref<Expr> &l, const ref<Expr> &r) {                  \
+      ref<Expr> res(new _class_kind ## Expr (l, r));                    \
+      res.computeHash();                                                    \
+      return res;                                                       \
+    }                                                       \
+    static ref<Expr> create(const ref<Expr> &l, const ref<Expr> &r);                  \
+    Kind getKind() const { return _class_kind; }            \
+    virtual ref<Expr> rebuild(ref<Expr> kids[]) const { \
+      return create(kids[0], kids[1]); \
+    } \
+};                                                          \
+
+COMPARISON_EXPR_CLASS(Eq)
+COMPARISON_EXPR_CLASS(Ne)
+COMPARISON_EXPR_CLASS(Ult)
+COMPARISON_EXPR_CLASS(Ule)
+COMPARISON_EXPR_CLASS(Ugt)
+COMPARISON_EXPR_CLASS(Uge)
+COMPARISON_EXPR_CLASS(Slt)
+COMPARISON_EXPR_CLASS(Sle)
+COMPARISON_EXPR_CLASS(Sgt)
+COMPARISON_EXPR_CLASS(Sge)
+
+} // End klee namespace
+
+#endif
diff --git a/include/klee/IncompleteSolver.h b/include/klee/IncompleteSolver.h
new file mode 100644
index 00000000..f72607b5
--- /dev/null
+++ b/include/klee/IncompleteSolver.h
@@ -0,0 +1,108 @@
+//===-- IncompleteSolver.h --------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_INCOMPLETESOLVER_H
+#define KLEE_INCOMPLETESOLVER_H
+
+#include "klee/Solver.h"
+#include "klee/SolverImpl.h"
+
+namespace klee {
+
+/// IncompleteSolver - Base class for incomplete solver
+/// implementations.
+///
+/// Incomplete solvers are useful for implementing optimizations which
+/// may quickly compute an answer, but cannot always compute the
+/// correct answer. They can be used with the StagedSolver to provide
+/// a complete Solver implementation.
+class IncompleteSolver {
+public:
+  /// PartialValidity - Represent a possibility incomplete query
+  /// validity.
+  enum PartialValidity {
+    /// The query is provably true.
+    MustBeTrue = 1,
+
+    /// The query is provably false.
+    MustBeFalse = -1,
+
+    /// The query is not provably false (a true assignment is known to
+    /// exist).
+    MayBeTrue = 2,
+
+    /// The query is not provably true (a false assignment is known to
+    /// exist).
+    MayBeFalse = -2,
+
+    /// The query is known to have both true and false assignments.
+    TrueOrFalse = 0,
+
+    /// The validity of the query is unknown.
+    None = 3
+  };
+
+  static PartialValidity negatePartialValidity(PartialValidity pv);
+
+public:
+  IncompleteSolver() {};
+  virtual ~IncompleteSolver() {};
+
+  /// computeValidity - Compute a partial validity for the given query.
+  ///
+  /// The passed expression is non-constant with bool type.
+  ///
+  /// The IncompleteSolver class provides an implementation of
+  /// computeValidity using computeTruth. Sub-classes may override
+  /// this if a more efficient implementation is available.
+  virtual IncompleteSolver::PartialValidity computeValidity(const Query&);
+
+  /// computeValidity - Compute a partial validity for the given query.
+  ///
+  /// The passed expression is non-constant with bool type.
+  virtual IncompleteSolver::PartialValidity computeTruth(const Query&) = 0;
+  
+  /// computeValue - Attempt to compute a value for the given expression.
+  virtual bool computeValue(const Query&, ref<Expr> &result) = 0;
+
+  /// computeInitialValues - Attempt to compute the constant values
+  /// for the initial state of each given object. If a correct result
+  /// is not found, then the values array must be unmodified.
+  virtual bool computeInitialValues(const Query&,
+                                    const std::vector<const Array*> 
+                                      &objects,
+                                    std::vector< std::vector<unsigned char> > 
+                                      &values,
+                                    bool &hasSolution) = 0;
+};
+
+/// StagedSolver - Adapter class for staging an incomplete solver with
+/// a complete secondary solver, to form an (optimized) complete
+/// solver.
+class StagedSolverImpl : public SolverImpl {
+private:
+  IncompleteSolver *primary;
+  Solver *secondary;
+  
+public:
+  StagedSolverImpl(IncompleteSolver *_primary, Solver *_secondary);
+  ~StagedSolverImpl();
+    
+  bool computeTruth(const Query&, bool &isValid);
+  bool computeValidity(const Query&, Solver::Validity &result);
+  bool computeValue(const Query&, ref<Expr> &result);
+  bool computeInitialValues(const Query&,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution);
+};
+
+}
+
+#endif
diff --git a/include/klee/Internal/ADT/BOut.h b/include/klee/Internal/ADT/BOut.h
new file mode 100644
index 00000000..14aeb714
--- /dev/null
+++ b/include/klee/Internal/ADT/BOut.h
@@ -0,0 +1,62 @@
+//===-- BOut.h --------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __COMMON_BOUT_H__
+#define __COMMON_BOUT_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  typedef struct BOutObject BOutObject;
+  struct BOutObject {
+    char *name;
+    unsigned numBytes;
+    unsigned char *bytes;
+  };
+  
+  typedef struct BOut BOut;
+  struct BOut {
+    /* file format version */
+    unsigned version; 
+    
+    unsigned numArgs;
+    char **args;
+
+    unsigned symArgvs;
+    unsigned symArgvLen;
+
+    unsigned numObjects;
+    BOutObject *objects;
+  };
+
+  
+  /* returns the current .bout file format version */
+  unsigned bOut_getCurrentVersion();
+  
+  /* return true iff file at path matches BOut header */
+  int   bOut_isBOutFile(const char *path);
+
+  /* returns NULL on (unspecified) error */
+  BOut* bOut_fromFile(const char *path);
+
+  /* returns 1 on success, 0 on (unspecified) error */
+  int   bOut_toFile(BOut *, const char *path);
+  
+  /* returns total number of object bytes */
+  unsigned bOut_numBytes(BOut *);
+
+  void  bOut_free(BOut *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/klee/Internal/ADT/DiscretePDF.h b/include/klee/Internal/ADT/DiscretePDF.h
new file mode 100644
index 00000000..bda851fa
--- /dev/null
+++ b/include/klee/Internal/ADT/DiscretePDF.h
@@ -0,0 +1,47 @@
+//===-- DiscretePDF.h -------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace klee {
+  template <class T>
+  class DiscretePDF {
+    // not perfectly parameterized, but float/double/int should work ok,
+    // although it would be better to have choose argument range from 0
+    // to queryable max.
+    typedef double weight_type;
+
+  public:
+    DiscretePDF();
+    ~DiscretePDF();
+
+    bool empty() const;
+    void insert(T item, weight_type weight);
+    void update(T item, weight_type newWeight);
+    void remove(T item);
+    bool inTree(T item);
+    weight_type getWeight(T item);
+	
+    /* pick a tree element according to its
+     * weight. p should be in [0,1).
+     */
+    T choose(double p);
+    
+  private:
+    class Node;
+    Node *m_root;
+    
+    Node **lookup(T item, Node **parent_out);
+    void split(Node *node);
+    void rotate(Node *node);
+    void lengthen(Node *node);
+    void propogateSumsUp(Node *n);
+  };
+
+}
+
+#include "DiscretePDF.inc"
diff --git a/include/klee/Internal/ADT/DiscretePDF.inc b/include/klee/Internal/ADT/DiscretePDF.inc
new file mode 100644
index 00000000..1eb23629
--- /dev/null
+++ b/include/klee/Internal/ADT/DiscretePDF.inc
@@ -0,0 +1,342 @@
+//===- DiscretePDF.inc - --*- C++ -*-===//
+
+//
+
+namespace klee {
+
+template <class T>
+class DiscretePDF<T>::Node
+{
+private:
+  bool m_mark;
+
+public:
+  Node *parent, *left, *right;
+  T key;
+  weight_type weight, sumWeights;
+
+public:
+  Node(T key_, weight_type weight_, Node *parent_);
+  ~Node();
+
+  Node *sibling() { return this==parent->left?parent->right:parent->left; }
+
+  void markRed() { m_mark = true; }
+  void markBlack() { m_mark = false; }
+  bool isBlack() { return !m_mark; }
+  bool leftIsBlack() { return !left || left->isBlack(); }
+  bool rightIsBlack() { return !right || right->isBlack(); }
+  void setSum() { 
+    sumWeights = weight;
+    if (left) sumWeights += left->sumWeights;
+    if (right) sumWeights += right->sumWeights;
+  }
+};
+
+  ///
+
+template <class T>
+DiscretePDF<T>::Node::Node(T key_, weight_type weight_, Node *parent_) {
+  m_mark = false;
+
+  key = key_;
+  weight = weight_;
+  sumWeights = 0;
+  left = right = 0;
+  parent = parent_;
+}
+
+template <class T>
+DiscretePDF<T>::Node::~Node() {
+  if (left) delete left;
+  if (right) delete right;
+}
+
+//
+
+template <class T>
+DiscretePDF<T>::DiscretePDF() {
+  m_root = 0;
+}
+
+template <class T>
+DiscretePDF<T>::~DiscretePDF() {
+  if (m_root) delete m_root;
+}
+
+template <class T>
+bool DiscretePDF<T>::empty() const {
+  return m_root == 0;
+}
+
+template <class T>
+void DiscretePDF<T>::insert(T item, weight_type weight) {
+  Node *p=0, *n=m_root;
+
+  while (n) {
+    if (!n->leftIsBlack() && !n->rightIsBlack())
+      split(n);
+
+    p = n;
+    if (n->key==item) {
+      assert(0 && "insert: argument(item) already in tree");
+    } else {
+      n = (item<n->key)?n->left:n->right;
+    }
+  }
+
+  n = new Node(item, weight, p);
+
+  if (!p) {
+    m_root = n;
+  } else {
+    if (item<p->key) {
+      p->left = n;
+    } else {
+      p->right = n;
+    }
+
+    split(n);
+  }
+
+  propogateSumsUp(n);
+}
+
+template <class T>
+void DiscretePDF<T>::remove(T item) {
+  Node **np = lookup(item, 0);
+  Node *child, *n = *np;
+
+  if (!n) {
+    assert(0 && "remove: argument(item) not in tree");
+  } else {
+    if (n->left) {
+      Node **leftMaxp = &n->left;
+
+      while ((*leftMaxp)->right)
+        leftMaxp = &(*leftMaxp)->right;
+
+      n->key = (*leftMaxp)->key;
+      n->weight = (*leftMaxp)->weight;
+
+      np = leftMaxp;
+      n = *np;
+    }
+
+    // node now has at most one child
+
+    child = n->left?n->left:n->right;
+    *np = child;
+
+    if (child) {
+      child->parent = n->parent;
+
+      if (n->isBlack()) {
+        lengthen(child);
+      }
+    }
+
+    propogateSumsUp(n->parent);
+
+    n->left = n->right = 0;
+    delete n;
+  }
+}
+
+template <class T>
+void DiscretePDF<T>::update(T item, weight_type weight) {
+  Node *n = *lookup(item, 0);
+
+  if (!n) {
+    assert(0 && "update: argument(item) not in tree");
+  } else {
+    n->weight = weight;
+    propogateSumsUp(n);
+  }
+}
+
+template <class T>
+T DiscretePDF<T>::choose(double p) {
+  if (p<0.0 || p>=1.0) {
+    assert(0 && "choose: argument(p) outside valid range");
+  } else if (!m_root) {
+    assert(0 && "choose: choose() called on empty tree");
+  } else {
+    weight_type w = (weight_type) (m_root->sumWeights * p);
+    Node *n = m_root;
+
+    while (1) {
+      if (n->left) {
+        if (w<n->left->sumWeights) {
+          n = n->left;
+          continue;
+        } else {
+          w -= n->left->sumWeights;
+        }
+      }
+      if (w<n->weight || !n->right) {
+        break; // !n->right condition shouldn't be necessary, just sanity check
+      }
+      w -= n->weight;
+      n = n->right;
+    }
+
+    return n->key;
+  }
+}
+
+template <class T>
+bool DiscretePDF<T>::inTree(T item) {
+  Node *n = *lookup(item, 0);
+
+  return !!n;
+}
+
+template <class T>
+typename DiscretePDF<T>::weight_type DiscretePDF<T>::getWeight(T item) {
+  Node *n = *lookup(item, 0);
+  assert(n);
+  return n->weight;
+}
+
+//
+
+template <class T>
+typename DiscretePDF<T>::Node **
+DiscretePDF<T>::lookup(T item, Node **parent_out) {
+  Node *n, *p=0, **np=&m_root;
+
+  while ((n = *np)) {
+    if (n->key==item) {
+      break;
+    } else {
+      p = n;
+      if (item<n->key) {
+        np = &n->left;
+      } else {
+        np = &n->right;
+      }
+    }
+  }
+
+  if (parent_out)
+    *parent_out = p;
+  return np;
+}
+
+template <class T>
+void DiscretePDF<T>::split(Node *n) {
+  if (n->left) n->left->markBlack();
+  if (n->right) n->right->markBlack();
+
+  if (n->parent) {
+    Node *p = n->parent;
+
+    n->markRed();
+
+    if (!p->isBlack()) {
+      p->parent->markRed();
+
+      // not same direction
+      if (!((n==p->left && p==p->parent->left) || 
+            (n==p->right && p==p->parent->right))) {
+        rotate(n);
+        p = n;
+      }
+
+      rotate(p);
+      p->markBlack();
+    }
+  }
+}
+
+template <class T>
+void DiscretePDF<T>::rotate(Node *n) {
+  Node *p=n->parent, *pp=p->parent;
+
+  n->parent = pp;
+  p->parent = n;
+
+  if (n==p->left) {
+    p->left = n->right;
+    n->right = p;
+    if (p->left) p->left->parent = p;
+  } else {
+    p->right = n->left;
+    n->left = p;
+    if (p->right) p->right->parent = p;
+  }
+
+  n->setSum();
+  p->setSum();
+	
+  if (!pp) {
+    m_root = n;
+  } else {
+    if (p==pp->left) {
+      pp->left = n;
+    } else {
+      pp->right = n;
+    }
+  }
+}
+
+template <class T>
+void DiscretePDF<T>::lengthen(Node *n) {
+  if (!n->isBlack()) {
+    n->markBlack();
+  } else if (n->parent) {
+    Node *sibling = n->sibling();
+
+    if (sibling && !sibling->isBlack()) {
+      n->parent->markRed();
+      sibling->markBlack();
+
+      rotate(sibling); // node sibling is now old sibling child, must be black
+      sibling = n->sibling();
+    }
+
+    // sibling is black
+
+    if (!sibling) {
+      lengthen(n->parent);
+    } else if (sibling->leftIsBlack() && sibling->rightIsBlack()) {
+      if (n->parent->isBlack()) {
+        sibling->markRed();
+        lengthen(n->parent);
+      } else {
+        sibling->markRed();
+        n->parent->markBlack();
+      }
+    } else {
+      if (n==n->parent->left && sibling->rightIsBlack()) {
+        rotate(sibling->left); // sibling->left must be red
+        sibling->markRed();
+        sibling->parent->markBlack();
+        sibling = sibling->parent;
+      } else if (n==n->parent->right && sibling->leftIsBlack()) {
+        rotate(sibling->right); // sibling->right must be red
+        sibling->markRed();
+        sibling->parent->markBlack();
+        sibling = sibling->parent;
+      }
+
+      // sibling is black, and sibling's far child is red
+
+      rotate(sibling);
+      if (!n->parent->isBlack()) 
+        sibling->markRed();
+      sibling->left->markBlack();
+      sibling->right->markBlack();
+    }
+  }
+}
+
+template <class T>
+void DiscretePDF<T>::propogateSumsUp(Node *n) {
+  for (; n; n=n->parent)
+    n->setSum();
+}
+
+}
+
diff --git a/include/klee/Internal/ADT/ImmutableMap.h b/include/klee/Internal/ADT/ImmutableMap.h
new file mode 100644
index 00000000..c7af3786
--- /dev/null
+++ b/include/klee/Internal/ADT/ImmutableMap.h
@@ -0,0 +1,104 @@
+//===-- ImmutableMap.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_IMMUTABLEMAP_H__
+#define __UTIL_IMMUTABLEMAP_H__
+
+#include <functional>
+
+#include "ImmutableTree.h"
+
+namespace klee {
+  template<class V, class D>
+  struct _Select1st {
+    D &operator()(V &a) const { return a.first; }
+    const D &operator()(const V &a) const { return a.first; }
+  };
+  
+  template<class K, class D, class CMP=std::less<K> >
+  class ImmutableMap {
+  public:
+    typedef K key_type;
+    typedef std::pair<K,D> value_type;
+
+    typedef ImmutableTree<K, value_type, _Select1st<value_type,key_type>, CMP> Tree;
+    typedef typename Tree::iterator iterator;
+
+  private:
+    Tree elts;
+
+    ImmutableMap(const Tree &b): elts(b) {}
+
+  public:
+    ImmutableMap() {}
+    ImmutableMap(const ImmutableMap &b) : elts(b.elts) {}
+    ~ImmutableMap() {}
+
+    ImmutableMap &operator=(const ImmutableMap &b) { elts = b.elts; return *this; }
+    
+    bool empty() const { 
+      return elts.empty(); 
+    }
+    unsigned count(const key_type &key) const { 
+      return elts.count(key); 
+    }
+    const value_type *lookup(const key_type &key) const { 
+      return elts.lookup(key); 
+    }
+    const value_type *lookup_previous(const key_type &key) const { 
+      return elts.lookup_previous(key); 
+    }
+    const value_type &min() const { 
+      return elts.min(); 
+    }
+    const value_type &max() const { 
+      return elts.max(); 
+    }
+    unsigned size() const { 
+      return elts.size(); 
+    }
+
+    ImmutableMap insert(const value_type &value) const { 
+      return elts.insert(value); 
+    }
+    ImmutableMap replace(const value_type &value) const { 
+      return elts.replace(value); 
+    }
+    ImmutableMap remove(const key_type &key) const { 
+      return elts.remove(key); 
+    }
+    ImmutableMap popMin(const value_type &valueOut) const { 
+      return elts.popMin(valueOut); 
+    }
+    ImmutableMap popMax(const value_type &valueOut) const { 
+      return elts.popMax(valueOut); 
+    }
+
+    iterator begin() const { 
+      return elts.begin(); 
+    }
+    iterator end() const { 
+      return elts.end(); 
+    }
+    iterator find(const key_type &key) const { 
+      return elts.find(key); 
+    }
+    iterator lower_bound(const key_type &key) const { 
+      return elts.lower_bound(key); 
+    }
+    iterator upper_bound(const key_type &key) const { 
+      return elts.upper_bound(key); 
+    }
+
+    static unsigned getAllocated() { return Tree::allocated; }
+  };
+
+}
+
+#endif
diff --git a/include/klee/Internal/ADT/ImmutableSet.h b/include/klee/Internal/ADT/ImmutableSet.h
new file mode 100644
index 00000000..0c79eb9c
--- /dev/null
+++ b/include/klee/Internal/ADT/ImmutableSet.h
@@ -0,0 +1,101 @@
+//===-- ImmutableSet.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_IMMUTABLESET_H__
+#define __UTIL_IMMUTABLESET_H__
+
+#include <functional>
+
+#include "ImmutableTree.h"
+
+namespace klee {
+  template<class T>
+  struct _Identity {
+    T &operator()(T &a) const { return a; }
+    const T &operator()(const T &a) const { return a; }
+  };
+  
+  template<class T, class CMP=std::less<T> >
+  class ImmutableSet {
+  public:
+    typedef T key_type;
+    typedef T value_type;
+
+    typedef ImmutableTree<T, T, _Identity<T>, CMP> Tree;
+    typedef typename Tree::iterator iterator;
+
+  private:
+    Tree elts;
+
+    ImmutableSet(const Tree &b): elts(b) {}
+
+  public:
+    ImmutableSet() {}
+    ImmutableSet(const ImmutableSet &b) : elts(b.elts) {}
+    ~ImmutableSet() {}
+
+    ImmutableSet &operator=(const ImmutableSet &b) { elts = b.elts; return *this; }
+    
+    bool empty() const { 
+      return elts.empty(); 
+    }
+    unsigned count(const key_type &key) const { 
+      return elts.count(key); 
+    }
+    const value_type *lookup(const key_type &key) const { 
+      return elts.lookup(key); 
+    }
+    const value_type &min() const { 
+      return elts.min(); 
+    }
+    const value_type &max() const { 
+      return elts.max(); 
+    }
+    unsigned size() { 
+      return elts.size(); 
+    }
+
+    ImmutableSet insert(const value_type &value) const {
+      return elts.insert(value); 
+    }
+    ImmutableSet replace(const value_type &value) const {
+      return elts.replace(value); 
+    }
+    ImmutableSet remove(const key_type &key) const { 
+      return elts.remove(key); 
+    }
+    ImmutableSet popMin(const value_type &valueOut) const { 
+      return elts.popMin(valueOut); 
+    }
+    ImmutableSet popMax(const value_type &valueOut) const { 
+      return elts.popMax(valueOut); 
+    }
+
+    iterator begin() const { 
+      return elts.begin(); 
+    }
+    iterator end() const { 
+      return elts.end(); 
+    }
+    iterator find(const key_type &key) const { 
+      return elts.find(key); 
+    }
+    iterator lower_bound(const key_type &key) const { 
+      return elts.lower_bound(key); 
+    }
+    iterator upper_bound(const key_type &key) const { 
+      return elts.upper_bound(key); 
+    }
+
+    static unsigned getAllocated() { return Tree::allocated; }
+  };
+
+}
+
+#endif
diff --git a/include/klee/Internal/ADT/ImmutableTree.h b/include/klee/Internal/ADT/ImmutableTree.h
new file mode 100644
index 00000000..2f294077
--- /dev/null
+++ b/include/klee/Internal/ADT/ImmutableTree.h
@@ -0,0 +1,619 @@
+//===-- ImmutableTree.h -----------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_IMMUTABLETREE_H__
+#define __UTIL_IMMUTABLETREE_H__
+
+#include <cassert>
+#include <vector>
+
+namespace klee {
+  template<class K, class V, class KOV, class CMP>
+  class ImmutableTree {
+  public:
+    static unsigned allocated;
+    class iterator;
+
+    typedef K key_type;
+    typedef V value_type;
+    typedef KOV key_of_value;
+    typedef CMP key_compare;
+
+  public:
+    ImmutableTree();
+    ImmutableTree(const ImmutableTree &s);
+    ~ImmutableTree();
+
+    ImmutableTree &operator=(const ImmutableTree &s);
+
+    bool empty() const;
+
+    unsigned count(const key_type &key) const; // always 0 or 1
+    const value_type *lookup(const key_type &key) const;
+
+    // find the last value less than or equal to key, or null if
+    // no such value exists
+    const value_type *lookup_previous(const key_type &key) const;
+
+    const value_type &min() const;
+    const value_type &max() const;
+    unsigned size() const;
+
+    ImmutableTree insert(const value_type &value) const;
+    ImmutableTree replace(const value_type &value) const;
+    ImmutableTree remove(const key_type &key) const;
+    ImmutableTree popMin(value_type &valueOut) const;
+    ImmutableTree popMax(value_type &valueOut) const;
+
+    iterator begin() const;
+    iterator end() const;
+    iterator find(const key_type &key) const;
+    iterator lower_bound(const key_type &key) const;
+    iterator upper_bound(const key_type &key) const;
+
+    static unsigned getAllocated() { return allocated; }
+
+  private:
+    class Node;
+
+    Node *node;
+    ImmutableTree(Node *_node);
+  };
+
+  /***/
+
+  template<class K, class V, class KOV, class CMP>
+  class ImmutableTree<K,V,KOV,CMP>::Node {
+  public:
+    static Node terminator;
+    Node *left, *right;
+    value_type value;
+    unsigned height, references;
+
+  protected:
+    Node(); // solely for creating the terminator node
+    static Node *balance(Node *left, const value_type &value, Node *right);
+
+  public:
+
+    Node(Node *_left, Node *_right, const value_type &_value);
+    ~Node();
+
+    void decref();
+    Node *incref();
+
+    bool isTerminator();
+
+    unsigned size();
+    Node *popMin(value_type &valueOut);
+    Node *popMax(value_type &valueOut);
+    Node *insert(const value_type &v);
+    Node *replace(const value_type &v);
+    Node *remove(const key_type &k);
+  };
+
+  // Should live somewhere else, this is a simple stack with maximum size.
+  template<typename T>
+  class FixedStack {
+    unsigned pos, max;
+    T *elts;
+
+  public:
+    FixedStack(unsigned _max) : pos(0),
+                                max(_max),
+                                elts(new T[max]) {}
+    FixedStack(const FixedStack &b) : pos(b.pos),
+                                      max(b.max),
+                                      elts(new T[b.max]) {
+      std::copy(b.elts, b.elts+pos, elts);
+    }
+    ~FixedStack() { delete[] elts; }
+
+    void push_back(const T &elt) { elts[pos++] = elt; }
+    void pop_back() { --pos; }
+    bool empty() { return pos==0; }
+    T &back() { return elts[pos-1]; }
+
+
+    FixedStack &operator=(const FixedStack &b) {
+      assert(max == b.max); 
+      pos = b.pos;
+      std::copy(b.elts, b.elts+pos, elts);
+      return *this;
+    }
+
+    bool operator==(const FixedStack &b) {
+      return (pos == b.pos &&
+              std::equal(elts, elts+pos, b.elts));
+    }
+    bool operator!=(const FixedStack &b) { return !(*this==b); }
+  };
+
+  template<class K, class V, class KOV, class CMP>
+  class ImmutableTree<K,V,KOV,CMP>::iterator {
+    friend class ImmutableTree<K,V,KOV,CMP>;
+  private:
+    Node *root; // so can back up from end
+    FixedStack<Node*> stack;
+    
+  public:
+    iterator(Node *_root, bool atBeginning) : root(_root->incref()),
+                                              stack(root->height) {
+      if (atBeginning) {
+        for (Node *n=root; !n->isTerminator(); n=n->left)
+          stack.push_back(n);
+      }
+    }
+    iterator(const iterator &i) : root(i.root->incref()),
+                                  stack(i.stack) {
+    }
+    ~iterator() {
+      root->decref();
+    }
+
+    iterator &operator=(const iterator &b) {
+      b.root->incref();
+      root->decref();
+      root = b.root;
+      stack = b.stack;
+      return *this;
+    }
+
+    const value_type &operator*() {
+      Node *n = stack.back();
+      return n->value;
+    }
+
+    const value_type *operator->() {
+      Node *n = stack.back();
+      return &n->value;
+    }
+
+    bool operator==(const iterator &b) {
+      return stack==b.stack;
+    }
+    bool operator!=(const iterator &b) {
+      return stack!=b.stack;
+    }
+    
+    iterator &operator--() {
+      if (stack.empty()) {
+        for (Node *n=root; !n->isTerminator(); n=n->right)
+          stack.push_back(n);
+      } else {
+        Node *n = stack.back();
+        if (n->left->isTerminator()) {
+          for (;;) {
+            Node *prev = n;
+            stack.pop_back();
+            if (stack.empty()) {
+              break;
+            } else {
+              n = stack.back();
+              if (prev==n->right)
+                break;
+            }
+          }
+        } else {
+          stack.push_back(n->left);
+          for (n=n->left->right; !n->isTerminator(); n=n->right)
+            stack.push_back(n);
+        }
+      }
+      return *this;
+    }
+
+    iterator &operator++() {
+      assert(!stack.empty());
+      Node *n = stack.back();
+      if (n->right->isTerminator()) {
+        for (;;) {
+          Node *prev = n;
+          stack.pop_back();
+          if (stack.empty()) {
+            break;
+          } else {
+            n = stack.back();
+            if (prev==n->left)
+              break;
+          }
+        }
+      } else {
+        stack.push_back(n->right);
+        for (n=n->right->left; !n->isTerminator(); n=n->left)
+          stack.push_back(n);
+      }
+      return *this;
+    }
+  };
+
+  /***/
+
+  template<class K, class V, class KOV, class CMP> 
+  typename ImmutableTree<K,V,KOV,CMP>::Node 
+  ImmutableTree<K,V,KOV,CMP>::Node::terminator;
+
+  template<class K, class V, class KOV, class CMP> 
+  unsigned ImmutableTree<K,V,KOV,CMP>::allocated = 0;
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP>::Node::Node() 
+    : left(&terminator), 
+      right(&terminator), 
+      height(0), 
+      references(3) { 
+    assert(this==&terminator);
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP>::Node::Node(Node *_left, Node *_right, const value_type &_value)
+    : left(_left), 
+      right(_right), 
+      value(_value), 
+      height(std::max(left->height, right->height) + 1),
+      references(1) 
+  {
+    ++allocated;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP>::Node::~Node() {
+    left->decref();
+    right->decref();
+    --allocated;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  inline void ImmutableTree<K,V,KOV,CMP>::Node::decref() {
+    --references;
+    if (references==0) delete this;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  inline typename ImmutableTree<K,V,KOV,CMP>::Node *ImmutableTree<K,V,KOV,CMP>::Node::incref() {
+    ++references;
+    return this;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  inline bool ImmutableTree<K,V,KOV,CMP>::Node::isTerminator() {
+    return this==&terminator;
+  }
+
+  /***/
+
+  template<class K, class V, class KOV, class CMP>
+  typename ImmutableTree<K,V,KOV,CMP>::Node *
+  ImmutableTree<K,V,KOV,CMP>::Node::balance(Node *left, const value_type &value, Node *right) {
+    if (left->height > right->height + 2) {
+      Node *ll = left->left;
+      Node *lr = left->right;
+      if (ll->height >= lr->height) {
+        Node *nlr = new Node(lr->incref(), right, value);
+        Node *res = new Node(ll->incref(), nlr, left->value);
+        left->decref();
+        return res;
+      } else {
+        Node *lrl = lr->left;
+        Node *lrr = lr->right;
+        Node *nll = new Node(ll->incref(), lrl->incref(), left->value);
+        Node *nlr = new Node(lrr->incref(), right, value);
+        Node *res = new Node(nll, nlr, lr->value);
+        left->decref();
+        return res;
+      }
+    } else if (right->height > left->height + 2) {
+      Node *rl = right->left;
+      Node *rr = right->right;
+      if (rr->height >= rl->height) {
+        Node *nrl = new Node(left, rl->incref(), value);
+        Node *res = new Node(nrl, rr->incref(), right->value);
+        right->decref();
+        return res;
+      } else {
+        Node *rll = rl->left;
+        Node *rlr = rl->right;
+        Node *nrl = new Node(left, rll->incref(), value);
+        Node *nrr = new Node(rlr->incref(), rr->incref(), right->value);
+        Node *res = new Node(nrl, nrr, rl->value);
+        right->decref();
+        return res;
+      }
+    } else {
+      return new Node(left, right, value);
+    }
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  unsigned ImmutableTree<K,V,KOV,CMP>::Node::size() {
+    if (isTerminator()) {
+      return 0;
+    } else {
+      return left->size() + 1 + right->size();
+    }
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  typename ImmutableTree<K,V,KOV,CMP>::Node *
+  ImmutableTree<K,V,KOV,CMP>::Node::popMin(value_type &valueOut) {
+    if (left->isTerminator()) {
+      valueOut = value;
+      return right->incref();
+    } else {
+      return balance(left->popMin(valueOut), value, right->incref());
+    }
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  typename ImmutableTree<K,V,KOV,CMP>::Node *
+  ImmutableTree<K,V,KOV,CMP>::Node::popMax(value_type &valueOut) {
+    if (right->isTerminator()) {
+      valueOut = value;
+      return left->incref();
+    } else {
+      return balance(left->incref(), value, right->popMax(valueOut));
+    }
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  typename ImmutableTree<K,V,KOV,CMP>::Node *
+  ImmutableTree<K,V,KOV,CMP>::Node::insert(const value_type &v) {
+    if (isTerminator()) {
+      return new Node(terminator.incref(), terminator.incref(), v);
+    } else {
+      if (key_compare()(key_of_value()(v), key_of_value()(value))) {
+        return balance(left->insert(v), value, right->incref());
+      } else if (key_compare()(key_of_value()(value), key_of_value()(v))) {
+        return balance(left->incref(), value, right->insert(v));
+      } else {
+        return incref();
+      }
+    }
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  typename ImmutableTree<K,V,KOV,CMP>::Node *
+  ImmutableTree<K,V,KOV,CMP>::Node::replace(const value_type &v) {
+    if (isTerminator()) {
+      return new Node(terminator.incref(), terminator.incref(), v);
+    } else {
+      if (key_compare()(key_of_value()(v), key_of_value()(value))) {
+        return balance(left->replace(v), value, right->incref());
+      } else if (key_compare()(key_of_value()(value), key_of_value()(v))) {
+        return balance(left->incref(), value, right->replace(v));
+      } else {
+        return new Node(left->incref(), right->incref(), v);
+      }
+    }
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  typename ImmutableTree<K,V,KOV,CMP>::Node *
+  ImmutableTree<K,V,KOV,CMP>::Node::remove(const key_type &k) {
+    if (isTerminator()) {
+      return incref();
+    } else {
+      if (key_compare()(k, key_of_value()(value))) {
+        return balance(left->remove(k), value, right->incref());
+      } else if (key_compare()(key_of_value()(value), k)) {
+        return balance(left->incref(), value, right->remove(k));
+      } else {
+        if (left->isTerminator()) {
+          return right->incref();
+        } else if (right->isTerminator()) {
+          return left->incref();
+        } else {
+          value_type min;
+          Node *nr = right->popMin(min);
+          return balance(left->incref(), min, nr);
+        }
+      }
+    }
+  }
+
+  /***/
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP>::ImmutableTree() 
+    : node(Node::terminator.incref()) {
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP>::ImmutableTree(Node *_node) 
+    : node(_node) {
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP>::ImmutableTree(const ImmutableTree &s) 
+    : node(s.node->incref()) {
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP>::~ImmutableTree() {
+    node->decref(); 
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP> &ImmutableTree<K,V,KOV,CMP>::operator=(const ImmutableTree &s) {
+    Node *n = s.node->incref();
+    node->decref();
+    node = n;
+    return *this;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  bool ImmutableTree<K,V,KOV,CMP>::empty() const {
+    return node->isTerminator();
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  unsigned ImmutableTree<K,V,KOV,CMP>::count(const key_type &k) const {
+    Node *n = node;
+    while (!n->isTerminator()) {
+      key_type key = key_of_value()(n->value);
+      if (key_compare()(k, key)) {
+        n = n->left;
+      } else if (key_compare()(key, k)) {
+        n = n->right;
+      } else {
+        return 1;
+      }
+    }
+    return 0;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  const typename ImmutableTree<K,V,KOV,CMP>::value_type *
+  ImmutableTree<K,V,KOV,CMP>::lookup(const key_type &k) const {
+    Node *n = node;
+    while (!n->isTerminator()) {
+      key_type key = key_of_value()(n->value);
+      if (key_compare()(k, key)) {
+        n = n->left;
+      } else if (key_compare()(key, k)) {
+        n = n->right;
+      } else {
+        return &n->value;
+      }
+    }
+    return 0;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  const typename ImmutableTree<K,V,KOV,CMP>::value_type *
+  ImmutableTree<K,V,KOV,CMP>::lookup_previous(const key_type &k) const {
+    Node *n = node;
+    Node *result = 0;
+    while (!n->isTerminator()) {
+      key_type key = key_of_value()(n->value);
+      if (key_compare()(k, key)) {
+        n = n->left;
+      } else if (key_compare()(key, k)) {
+        result = n;
+        n = n->right;
+      } else {
+        return &n->value;
+      }
+    }
+    return result ? &result->value : 0;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  const typename ImmutableTree<K,V,KOV,CMP>::value_type &
+  ImmutableTree<K,V,KOV,CMP>::min() const { 
+    Node *n = node;
+    assert(!n->isTerminator());
+    while (!n->left->isTerminator()) n = n->left;
+    return n->value;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  const typename ImmutableTree<K,V,KOV,CMP>::value_type &
+  ImmutableTree<K,V,KOV,CMP>::max() const {
+    Node *n = node;
+    assert(!n->isTerminator());
+    while (!n->right->isTerminator()) n = n->right;
+    return n->value;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  unsigned ImmutableTree<K,V,KOV,CMP>::size() const {
+    return node->size();
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP> 
+  ImmutableTree<K,V,KOV,CMP>::insert(const value_type &value) const { 
+    return ImmutableTree(node->insert(value)); 
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP> 
+  ImmutableTree<K,V,KOV,CMP>::replace(const value_type &value) const { 
+    return ImmutableTree(node->replace(value)); 
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP> 
+  ImmutableTree<K,V,KOV,CMP>::remove(const key_type &key) const { 
+    return ImmutableTree(node->remove(key)); 
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP> 
+  ImmutableTree<K,V,KOV,CMP>::popMin(value_type &valueOut) const { 
+    return ImmutableTree(node->popMin(valueOut)); 
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  ImmutableTree<K,V,KOV,CMP> 
+  ImmutableTree<K,V,KOV,CMP>::popMax(value_type &valueOut) const { 
+    return ImmutableTree(node->popMax(valueOut)); 
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  inline typename ImmutableTree<K,V,KOV,CMP>::iterator 
+  ImmutableTree<K,V,KOV,CMP>::begin() const {
+    return iterator(node, true);
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  inline typename ImmutableTree<K,V,KOV,CMP>::iterator 
+  ImmutableTree<K,V,KOV,CMP>::end() const {
+    return iterator(node, false);
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  inline typename ImmutableTree<K,V,KOV,CMP>::iterator 
+  ImmutableTree<K,V,KOV,CMP>::find(const key_type &key) const {
+    iterator end(node,false), it = lower_bound(key);
+    if (it==end || key_compare()(key,key_of_value()(*it))) {
+      return end;
+    } else {
+      return it;
+    }
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  inline typename ImmutableTree<K,V,KOV,CMP>::iterator 
+  ImmutableTree<K,V,KOV,CMP>::lower_bound(const key_type &k) const {
+    // XXX ugh this doesn't have to be so ugly does it?
+    iterator it(node,false);
+    for (Node *root=node; !root->isTerminator();) {
+      it.stack.push_back(root);
+      if (key_compare()(k, key_of_value()(root->value))) {
+        root = root->left;
+      } else if (key_compare()(key_of_value()(root->value), k)) {
+        root = root->right;
+      } else {
+        return it;
+      }
+    }
+    // it is now beginning or first element < k
+    if (!it.stack.empty()) {
+      Node *last = it.stack.back();
+      if (key_compare()(key_of_value()(last->value), k))
+        ++it;
+    }
+    return it;
+  }
+
+  template<class K, class V, class KOV, class CMP>
+  typename ImmutableTree<K,V,KOV,CMP>::iterator 
+  ImmutableTree<K,V,KOV,CMP>::upper_bound(const key_type &key) const {
+    iterator end(node,false),it = lower_bound(key);
+    if (it!=end && 
+        !key_compare()(key,key_of_value()(*it))) // no need to loop, no duplicates
+      ++it;
+    return it;
+  }
+
+}
+
+#endif
diff --git a/include/klee/Internal/ADT/MapOfSets.h b/include/klee/Internal/ADT/MapOfSets.h
new file mode 100644
index 00000000..25c5e2b9
--- /dev/null
+++ b/include/klee/Internal/ADT/MapOfSets.h
@@ -0,0 +1,385 @@
+//===-- MapOfSets.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_MAPOFSETS_H__
+#define __UTIL_MAPOFSETS_H__
+
+#include <cassert>
+#include <vector>
+#include <set>
+#include <map>
+
+// This should really be broken down into TreeOfSets on top of which
+// SetOfSets and MapOfSets are easily implemeted. It should also be
+// parameterized on the underlying set type. Neither are hard to do,
+// just not worth it at the moment.
+//
+// I also broke some STLish conventions because I was bored.
+
+namespace klee {
+
+  /** This implements the UBTree data structure (see Hoffmann and
+      Koehler, "A New Method to Index and Query Sets", IJCAI 1999) */
+  template<class K, class V>
+  class MapOfSets {
+  public:
+    class iterator;
+
+  public:
+    MapOfSets();
+
+    void clear();
+
+    void insert(const std::set<K> &set, const V &value);
+
+    V *lookup(const std::set<K> &set);
+
+    iterator begin();
+    iterator end();
+
+    void subsets(const std::set<K> &set, 
+                 std::vector< std::pair<std::set<K>, V> > &resultOut);
+    void supersets(const std::set<K> &set, 
+                   std::vector< std::pair<std::set<K>, V> > &resultOut);
+    
+    template<class Predicate>
+    V *findSuperset(const std::set<K> &set, const Predicate &p);
+    template<class Predicate>
+    V *findSubset(const std::set<K> &set, const Predicate &p);
+
+  private:
+    class Node;
+
+    Node root;
+
+    template<class Iterator, class Vector>
+    void findSubsets(Node *n, 
+                     const std::set<K> &accum,
+                     Iterator begin, 
+                     Iterator end,
+                     Vector &resultsOut);
+    template<class Iterator, class Vector>
+    void findSupersets(Node *n, 
+                       const std::set<K> &accum,
+                       Iterator begin, 
+                       Iterator end,
+                       Vector &resultsOut);
+    template<class Predicate>
+    V *findSuperset(Node *n, 
+                    typename std::set<K>::iterator begin, 
+                    typename std::set<K>::iterator end,
+                    const Predicate &p);
+    template<class Predicate>
+    V *findSubset(Node *n, 
+                  typename std::set<K>::iterator begin, 
+                  typename std::set<K>::iterator end,
+                  const Predicate &p);
+  };
+
+  /***/
+
+  template<class K, class V>
+  class MapOfSets<K,V>::Node {
+    friend class MapOfSets<K,V>;
+    friend class MapOfSets<K,V>::iterator;
+
+  public:
+    typedef std::map<K, Node> children_ty;
+
+    V value;
+
+  private:
+    bool isEndOfSet;
+    std::map<K, Node> children;
+    
+  public:
+    Node() : isEndOfSet(false) {}
+  };
+  
+  template<class K, class V>
+  class MapOfSets<K,V>::iterator {
+    typedef std::vector< typename std::map<K, Node>::iterator > stack_ty;
+    friend class MapOfSets<K,V>;
+  private:
+    Node *root;
+    bool onEntry;
+    stack_ty stack;
+
+    void step() {
+      if (onEntry) {
+        onEntry = false;
+        Node *n = stack.empty() ? root : &stack.back()->second;
+        while (!n->children.empty()) {
+          stack.push_back(n->children.begin());
+          n = &stack.back()->second;
+          if (n->isEndOfSet) {
+            onEntry = true;
+            return;
+          }
+        } 
+      }
+
+      while (!stack.empty()) {
+        unsigned size = stack.size();
+        Node *at = size==1 ? root : &stack[size-2]->second;
+        typename std::map<K,Node>::iterator &cur = stack.back();
+        ++cur;
+        if (cur==at->children.end()) {
+          stack.pop_back();
+        } else {
+          Node *n = &cur->second;
+
+          while (!n->isEndOfSet) {
+            assert(!n->children.empty());
+            stack.push_back(n->children.begin());
+            n = &stack.back()->second;
+          }
+
+          onEntry = true;
+          break;
+        }
+      } 
+    }
+
+  public:
+    // end()
+    iterator() : onEntry(false) {} 
+    // begin()
+    iterator(Node *_n) : root(_n), onEntry(true) {
+      if (!root->isEndOfSet)
+        step();
+    }
+
+    const std::pair<const std::set<K>, const V> operator*() {
+      assert(onEntry || !stack.empty());
+      std::set<K> s;
+      for (typename stack_ty::iterator it = stack.begin(), ie = stack.end();
+           it != ie; ++it)
+        s.insert((*it)->first);
+      Node *n = stack.empty() ? root : &stack.back()->second;
+      return std::make_pair(s, n->value);
+    }
+
+    bool operator==(const iterator &b) {
+      return onEntry==b.onEntry && stack==b.stack;
+    }
+    bool operator!=(const iterator &b) {
+      return !(*this==b);
+    }
+
+    iterator &operator++() {
+      step();
+      return *this;
+    }
+  };
+
+  /***/
+
+  template<class K, class V>
+  MapOfSets<K,V>::MapOfSets() {}  
+
+  template<class K, class V>
+  void MapOfSets<K,V>::insert(const std::set<K> &set, const V &value) {
+    Node *n = &root;
+    for (typename std::set<K>::const_iterator it = set.begin(), ie = set.end();
+         it != ie; ++it)
+      n = &n->children.insert(std::make_pair(*it, Node())).first->second;
+    n->isEndOfSet = true;
+    n->value = value;
+  }
+
+  template<class K, class V>
+  V *MapOfSets<K,V>::lookup(const std::set<K> &set) {
+    Node *n = &root;
+    for (typename std::set<K>::const_iterator it = set.begin(), ie = set.end();
+         it != ie; ++it) {
+      typename Node::children_ty::iterator kit = n->children.find(*it);
+      if (kit==n->children.end()) {
+        return 0;
+      } else {
+        n = &kit->second;
+      }
+    }
+    if (n->isEndOfSet) {
+      return &n->value;
+    } else {
+      return 0;
+    }
+  }
+
+  template<class K, class V>
+  typename MapOfSets<K,V>::iterator 
+  MapOfSets<K,V>::begin() { return iterator(&root); }
+  
+  template<class K, class V>
+  typename MapOfSets<K,V>::iterator 
+  MapOfSets<K,V>::end() { return iterator(); }
+
+  template<class K, class V>
+  template<class Iterator, class Vector>
+  void MapOfSets<K,V>::findSubsets(Node *n, 
+                                  const std::set<K> &accum,
+                                  Iterator begin, 
+                                  Iterator end,
+                                  Vector &resultsOut) {
+    if (n->isEndOfSet) {
+      resultsOut.push_back(std::make_pair(accum, n->value));
+    }
+    
+    for (Iterator it=begin; it!=end;) {
+      K elt = *it;
+      typename Node::children_ty::iterator kit = n->children.find(elt);
+      it++;
+      if (kit!=n->children.end()) {
+        std::set<K> nacc = accum;
+        nacc.insert(elt);
+        findSubsets(&kit->second, nacc, it, end, resultsOut);
+      }
+    }
+  }
+
+  template<class K, class V>
+  void MapOfSets<K,V>::subsets(const std::set<K> &set,
+                               std::vector< std::pair<std::set<K>, 
+                                                      V> > &resultOut) {
+    findSubsets(&root, std::set<K>(), set.begin(), set.end(), resultOut);
+  }
+
+  template<class K, class V>
+  template<class Iterator, class Vector>
+  void MapOfSets<K,V>::findSupersets(Node *n, 
+                                     const std::set<K> &accum,
+                                     Iterator begin, 
+                                     Iterator end,
+                                     Vector &resultsOut) {
+    if (begin==end) {
+      if (n->isEndOfSet)
+        resultsOut.push_back(std::make_pair(accum, n->value));
+      for (typename Node::children_ty::iterator it = n->children.begin(),
+             ie = n->children.end(); it != ie; ++it) {
+        std::set<K> nacc = accum;
+        nacc.insert(it->first);
+        findSupersets(&it->second, nacc, begin, end, resultsOut);
+      }
+    } else {
+      K elt = *begin;
+      Iterator next = begin;
+      ++next;
+      for (typename Node::children_ty::iterator it = n->children.begin(),
+             ie = n->children.end(); it != ie; ++it) {
+        std::set<K> nacc = accum;
+        nacc.insert(it->first);
+        if (elt==it->first) {
+          findSupersets(&it->second, nacc, next, end, resultsOut);
+        } else if (it->first<elt) {
+          findSupersets(&it->second, nacc, begin, end, resultsOut);
+        } else {
+          break;
+        }
+      }
+    }
+  }
+
+  template<class K, class V>
+  void MapOfSets<K,V>::supersets(const std::set<K> &set,
+                               std::vector< std::pair<std::set<K>, V> > &resultOut) {
+    findSupersets(&root, std::set<K>(), set.begin(), set.end(), resultOut);
+  }
+
+  template<class K, class V>
+  template<class Predicate>
+  V *MapOfSets<K,V>::findSubset(Node *n, 
+                                typename std::set<K>::iterator begin, 
+                                typename std::set<K>::iterator end,
+                                const Predicate &p) {   
+    if (n->isEndOfSet && p(n->value)) {
+      return &n->value;
+    } else if (begin==end) {
+      return 0;
+    } else {
+      typename Node::children_ty::iterator kend = n->children.end();
+      typename Node::children_ty::iterator 
+        kbegin = n->children.lower_bound(*begin);
+      typename std::set<K>::iterator it = begin;
+      if (kbegin==kend)
+        return 0;
+      for (;;) { // kbegin!=kend && *it <= kbegin->first
+        while (*it < kbegin->first) {
+          ++it;
+          if (it==end)
+            return 0;
+        }
+        if (*it == kbegin->first) {
+          ++it;
+          V *res = findSubset(&kbegin->second, it, end, p);
+          if (res || it==end)
+            return res;
+        }
+        while (kbegin->first < *it) {
+          ++kbegin;
+          if (kbegin==kend)
+            return 0;
+        }
+      }
+    }
+  }
+  
+  template<class K, class V>
+  template<class Predicate>
+  V *MapOfSets<K,V>::findSuperset(Node *n, 
+                                  typename std::set<K>::iterator begin, 
+                                  typename std::set<K>::iterator end,
+                                  const Predicate &p) {   
+    if (begin==end) {
+      if (n->isEndOfSet && p(n->value))
+        return &n->value;
+      for (typename Node::children_ty::iterator it = n->children.begin(),
+             ie = n->children.end(); it != ie; ++it) {
+        V *res = findSuperset(&it->second, begin, end, p);
+        if (res) return res;
+      }
+    } else {
+      typename Node::children_ty::iterator kbegin = n->children.begin();
+      typename Node::children_ty::iterator kmid = 
+        n->children.lower_bound(*begin);
+      for (typename Node::children_ty::iterator it = n->children.begin(),
+             ie = n->children.end(); it != ie; ++it) {
+        V *res = findSuperset(&it->second, begin, end, p);
+        if (res) return res;
+      }
+      if (kmid!=n->children.end() && *begin==kmid->first) {
+        V *res = findSuperset(&kmid->second, ++begin, end, p);
+        if (res) return res;
+      }
+    }
+    return 0;
+  }
+
+  template<class K, class V>
+  template<class Predicate>
+  V *MapOfSets<K,V>::findSuperset(const std::set<K> &set, const Predicate &p) {    
+    return findSuperset(&root, set.begin(), set.end(), p);
+  }
+
+  template<class K, class V>
+  template<class Predicate>
+  V *MapOfSets<K,V>::findSubset(const std::set<K> &set, const Predicate &p) {    
+    return findSubset(&root, set.begin(), set.end(), p);
+  }
+
+  template<class K, class V>
+  void MapOfSets<K,V>::clear() {
+    root.isEndOfSet = false;
+    root.value = V();
+    root.children.clear();
+  }
+
+}
+
+#endif
diff --git a/include/klee/Internal/ADT/RNG.h b/include/klee/Internal/ADT/RNG.h
new file mode 100644
index 00000000..b7f4906b
--- /dev/null
+++ b/include/klee/Internal/ADT/RNG.h
@@ -0,0 +1,50 @@
+//===-- RNG.h ---------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_UTIL_RNG_H
+#define KLEE_UTIL_RNG_H
+
+namespace klee {
+  class RNG {
+  private:
+    /* Period parameters */  
+    static const int N = 624;
+    static const int M = 397;
+    static const unsigned int MATRIX_A = 0x9908b0dfUL;   /* constant vector a */
+    static const unsigned int UPPER_MASK = 0x80000000UL; /* most significant w-r bits */
+    static const unsigned int LOWER_MASK = 0x7fffffffUL; /* least significant r bits */
+      
+  private:
+    unsigned int mt[N]; /* the array for the state vector  */
+    int mti;
+    
+  public:
+    RNG(unsigned int seed=5489UL);
+  
+    void seed(unsigned int seed);
+    
+    /* generates a random number on [0,0xffffffff]-interval */
+    unsigned int getInt32();
+    /* generates a random number on [0,0x7fffffff]-interval */
+    int getInt31();
+    /* generates a random number on [0,1]-real-interval */
+    double getDoubleLR();
+    float getFloatLR();
+    /* generates a random number on [0,1)-real-interval */
+    double getDoubleL();
+    float getFloatL();
+    /* generates a random number on (0,1)-real-interval */
+    double getDouble();
+    float getFloat();
+    /* generators a random flop */
+    bool getBool();
+  };
+}
+
+#endif
diff --git a/include/klee/Internal/ADT/TreeStream.h b/include/klee/Internal/ADT/TreeStream.h
new file mode 100644
index 00000000..63e49dbb
--- /dev/null
+++ b/include/klee/Internal/ADT/TreeStream.h
@@ -0,0 +1,77 @@
+//===-- TreeStream.h --------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_TREESTREAM_H__
+#define __UTIL_TREESTREAM_H__
+
+#include <string>
+#include <iostream>
+#include <vector>
+
+namespace klee {
+
+  typedef unsigned TreeStreamID;
+  class TreeOStream;
+
+  class TreeStreamWriter {
+    static const unsigned bufferSize = 4*4096;
+
+    friend class TreeOStream;
+
+  private:
+    char buffer[bufferSize];
+    unsigned lastID, bufferCount;
+
+    std::string path;
+    std::ofstream *output;
+    unsigned ids;
+
+    void write(TreeOStream &os, const char *s, unsigned size);
+    void flushBuffer();
+
+  public:
+    TreeStreamWriter(const std::string &_path);
+    ~TreeStreamWriter();
+
+    bool good();
+
+    TreeOStream open();
+    TreeOStream open(const TreeOStream &node);
+
+    void flush();
+
+    // hack, to be replace by proper stream capabilities
+    void readStream(TreeStreamID id,
+                    std::vector<unsigned char> &out);
+  };
+
+  class TreeOStream {
+    friend class TreeStreamWriter;
+
+  private:
+    TreeStreamWriter *writer;
+    unsigned id;
+    
+    TreeOStream(TreeStreamWriter &_writer, unsigned _id);
+
+  public:
+    TreeOStream();
+    ~TreeOStream();
+
+    unsigned getID() const;
+
+    void write(const char *buffer, unsigned size);
+
+    TreeOStream &operator<<(const std::string &s);
+
+    void flush();
+  };
+}
+
+#endif
diff --git a/include/klee/Internal/Module/Cell.h b/include/klee/Internal/Module/Cell.h
new file mode 100644
index 00000000..f54cd6eb
--- /dev/null
+++ b/include/klee/Internal/Module/Cell.h
@@ -0,0 +1,23 @@
+//===-- Cell.h --------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_CELL_H
+#define KLEE_CELL_H
+
+#include <klee/Expr.h>
+
+namespace klee {
+  class MemoryObject;
+
+  struct Cell {
+    ref<Expr> value;
+  };
+}
+
+#endif
diff --git a/include/klee/Internal/Module/InstructionInfoTable.h b/include/klee/Internal/Module/InstructionInfoTable.h
new file mode 100644
index 00000000..c93f5ddb
--- /dev/null
+++ b/include/klee/Internal/Module/InstructionInfoTable.h
@@ -0,0 +1,70 @@
+//===-- InstructionInfoTable.h ----------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_LIB_INSTRUCTIONINFOTABLE_H
+#define KLEE_LIB_INSTRUCTIONINFOTABLE_H
+
+#include <map>
+#include <string>
+#include <set>
+
+namespace llvm {
+  class Function;
+  class Instruction;
+  class Module; 
+}
+
+namespace klee {
+
+  /* Stores debug information for a KInstruction */
+  struct InstructionInfo {
+    unsigned id;
+    const std::string &file;
+    unsigned line;
+    unsigned assemblyLine;
+
+  public:
+    InstructionInfo(unsigned _id,
+                    const std::string &_file,
+                    unsigned _line,
+                    unsigned _assemblyLine)
+      : id(_id), 
+        file(_file),
+        line(_line),
+        assemblyLine(_assemblyLine) {
+    }
+  };
+
+  class InstructionInfoTable {
+    struct ltstr { 
+      bool operator()(const std::string *a, const std::string *b) const {
+        return *a<*b;
+      }
+    };
+
+    std::string dummyString;
+    InstructionInfo dummyInfo;
+    std::map<const llvm::Instruction*, InstructionInfo> infos;
+    std::set<const std::string *, ltstr> internedStrings;
+
+  private:
+    const std::string *internString(std::string s);
+
+  public:
+    InstructionInfoTable(llvm::Module *m);
+    ~InstructionInfoTable();
+
+    unsigned getMaxID() const;
+    const InstructionInfo &getInfo(const llvm::Instruction*) const;
+    const InstructionInfo &getFunctionInfo(const llvm::Function*) const;
+  };
+
+}
+
+#endif
diff --git a/include/klee/Internal/Module/KInstIterator.h b/include/klee/Internal/Module/KInstIterator.h
new file mode 100644
index 00000000..3890cc65
--- /dev/null
+++ b/include/klee/Internal/Module/KInstIterator.h
@@ -0,0 +1,49 @@
+//===-- KInstIterator.h -----------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_KINSTITERATOR_H
+#define KLEE_KINSTITERATOR_H
+
+namespace klee {
+  class KInstruction;
+
+  class KInstIterator {
+    KInstruction **it;
+
+  public:
+    KInstIterator() : it(0) {}
+    KInstIterator(KInstruction **_it) : it(_it) {}
+    KInstIterator(const KInstIterator &b) : it(b.it) {}
+    ~KInstIterator() {}
+
+    KInstIterator &operator=(const KInstIterator &b) {
+      it = b.it;
+      return *this;
+    }
+
+    bool operator==(const KInstIterator &b) const {
+      return it==b.it;
+    }
+    bool operator!=(const KInstIterator &b) const {
+      return !(*this == b);
+    }
+
+    KInstIterator &operator++() {
+      ++it;
+      return *this;
+    }
+
+    operator KInstruction*() const { return it ? *it : 0;}
+    operator bool() const { return it != 0; }
+
+    KInstruction *operator ->() const { return *it; }
+  };
+} // End klee namespace
+
+#endif
diff --git a/include/klee/Internal/Module/KInstruction.h b/include/klee/Internal/Module/KInstruction.h
new file mode 100644
index 00000000..c91d37ab
--- /dev/null
+++ b/include/klee/Internal/Module/KInstruction.h
@@ -0,0 +1,50 @@
+//===-- KInstruction.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_KINSTRUCTION_H
+#define KLEE_KINSTRUCTION_H
+
+#include <vector>
+
+namespace llvm {
+  class Instruction;
+}
+
+namespace klee {
+  class Executor;
+  struct InstructionInfo;
+  class KModule;
+
+
+  /// KInstruction - Intermediate instruction representation used
+  /// during execution.
+  struct KInstruction {
+    llvm::Instruction *inst;    
+    const InstructionInfo *info;
+
+    /// Value numbers for each operand. -1 is an invalid value,
+    /// otherwise negative numbers are indices (negated and offset by
+    /// 2) into the module constant table and positive numbers are
+    /// register indices.
+    int *operands;
+    /// Destination register index.
+    unsigned dest;
+
+  public:
+    virtual ~KInstruction(); 
+  };
+
+  struct KGEPInstruction : KInstruction {
+    std::vector< std::pair<unsigned, unsigned> > indices;
+    unsigned offset;
+  };
+}
+
+#endif
+
diff --git a/include/klee/Internal/Module/KModule.h b/include/klee/Internal/Module/KModule.h
new file mode 100644
index 00000000..690f079d
--- /dev/null
+++ b/include/klee/Internal/Module/KModule.h
@@ -0,0 +1,119 @@
+//===-- KModule.h -----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_KMODULE_H
+#define KLEE_KMODULE_H
+
+#include "klee/Interpreter.h"
+
+#include <map>
+#include <set>
+#include <vector>
+
+namespace llvm {
+  class BasicBlock;
+  class Constant;
+  class Function;
+  class Instruction;
+  class Module;
+  class TargetData;
+}
+
+namespace klee {
+  class Cell;
+  class Executor;
+  class Expr;
+  class InterpreterHandler;
+  class InstructionInfoTable;
+  class KInstruction;
+  class KModule;
+  template<class T> class ref;
+
+  struct KFunction {
+    llvm::Function *function;
+
+    unsigned numArgs, numRegisters;
+
+    unsigned numInstructions;
+    KInstruction **instructions;
+
+    std::map<llvm::BasicBlock*, unsigned> basicBlockEntry;
+
+    /// Whether instructions in this function should count as
+    /// "coverable" for statistics and search heuristics.
+    bool trackCoverage;
+
+  private:
+    KFunction(const KFunction&);
+    KFunction &operator=(const KFunction&);
+
+  public:
+    explicit KFunction(llvm::Function*, KModule *);
+    ~KFunction();
+
+    unsigned getArgRegister(unsigned index) { return index; }
+  };
+
+
+  class KConstant {
+  public:
+    /// Actual LLVM constant this represents.
+    llvm::Constant* ct;
+
+    /// The constant ID.
+    unsigned id;
+
+    /// First instruction where this constant was encountered, or NULL
+    /// if not applicable/unavailable.
+    KInstruction *ki;
+
+    KConstant(llvm::Constant*, unsigned, KInstruction*);
+  };
+
+
+  class KModule {
+  public:
+    llvm::Module *module;
+    llvm::TargetData *targetData;
+    
+    // Some useful functions to know the address of
+    llvm::Function *dbgStopPointFn, *kleeMergeFn;
+
+    // Our shadow versions of LLVM structures.
+    std::vector<KFunction*> functions;
+    std::map<llvm::Function*, KFunction*> functionMap;
+
+    // Functions which escape (may be called indirectly)
+    // XXX change to KFunction
+    std::set<llvm::Function*> escapingFunctions;
+
+    InstructionInfoTable *infos;
+
+    std::vector<llvm::Constant*> constants;
+    std::map<llvm::Constant*, KConstant*> constantMap;
+    KConstant* getKConstant(llvm::Constant *c);
+
+    Cell *constantTable;
+
+  public:
+    KModule(llvm::Module *_module);
+    ~KModule();
+
+    /// Initialize local data structures.
+    //
+    // FIXME: ihandler should not be here
+    void prepare(const Interpreter::ModuleOptions &opts, 
+                 InterpreterHandler *ihandler);
+
+    /// Return an id for the given constant, creating a new one if necessary.
+    unsigned getConstantID(llvm::Constant *c, KInstruction* ki);
+  };
+} // End klee namespace
+
+#endif
diff --git a/include/klee/Internal/README.txt b/include/klee/Internal/README.txt
new file mode 100644
index 00000000..9cedb653
--- /dev/null
+++ b/include/klee/Internal/README.txt
@@ -0,0 +1,3 @@
+This directory holds header files for things which are exposed as part
+of the internal API of a library, but shouldn't be exposed to
+externally.
diff --git a/include/klee/Internal/Support/FloatEvaluation.h b/include/klee/Internal/Support/FloatEvaluation.h
new file mode 100644
index 00000000..1d305374
--- /dev/null
+++ b/include/klee/Internal/Support/FloatEvaluation.h
@@ -0,0 +1,258 @@
+//===-- FloatEvaluation.h ---------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: Ditch this and use APFloat.
+
+#ifndef KLEE_UTIL_FLOATS_H
+#define KLEE_UTIL_FLOATS_H
+
+#include "klee/util/Bits.h"     //bits64::truncateToNBits
+#include "IntEvaluation.h" //ints::sext
+
+#include "llvm/Support/MathExtras.h"
+
+namespace klee {
+namespace floats {
+
+// ********************************** //
+// *** Pack uint64_t into FP types ** //
+// ********************************** //
+
+// interpret the 64 bits as a double instead of a uint64_t
+inline double UInt64AsDouble( uint64_t bits ) {
+  double ret;
+  assert( sizeof(bits) == sizeof(ret) );
+  memcpy( &ret, &bits, sizeof bits );
+  return ret;
+}
+
+// interpret the first 32 bits as a float instead of a uint64_t
+inline float UInt64AsFloat( uint64_t bits ) {
+  uint32_t tmp = bits; // ensure that we read correct bytes
+  float ret;
+  assert( sizeof(tmp) == sizeof(ret) );
+  memcpy( &ret, &tmp, sizeof tmp );
+  return ret;
+}
+
+
+// ********************************** //
+// *** Pack FP types into uint64_t ** //
+// ********************************** //
+
+// interpret the 64 bits as a uint64_t instead of a double
+inline uint64_t DoubleAsUInt64( double d ) {
+  uint64_t ret;
+  assert( sizeof(d) == sizeof(ret) );
+  memcpy( &ret, &d, sizeof d );
+  return ret;
+}
+
+// interpret the 32 bits as a uint64_t instead of as a float (add 32 0s)
+inline uint64_t FloatAsUInt64( float f ) {
+  uint32_t tmp;
+  assert( sizeof(tmp) == sizeof(f) );
+  memcpy( &tmp, &f, sizeof f );
+  return (uint64_t)tmp;
+}
+
+
+// ********************************** //
+// ************ Constants *********** //
+// ********************************** //
+
+const unsigned FLT_BITS = 32;
+const unsigned DBL_BITS = 64;
+
+
+
+// ********************************** //
+// ***** LLVM Binary Operations ***** //
+// ********************************** //
+
+// add of l and r
+inline uint64_t add(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits(FloatAsUInt64(UInt64AsFloat(l)  + UInt64AsFloat(r)),  FLT_BITS);
+  case DBL_BITS: return bits64::truncateToNBits(DoubleAsUInt64(UInt64AsDouble(l) + UInt64AsDouble(r)), DBL_BITS);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+// difference of l and r
+inline uint64_t sub(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits(FloatAsUInt64(UInt64AsFloat(l)  - UInt64AsFloat(r)),  FLT_BITS);
+  case DBL_BITS: return bits64::truncateToNBits(DoubleAsUInt64(UInt64AsDouble(l) - UInt64AsDouble(r)), DBL_BITS);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+// product of l and r
+inline uint64_t mul(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits(FloatAsUInt64(UInt64AsFloat(l)  * UInt64AsFloat(r)),  FLT_BITS);
+  case DBL_BITS: return bits64::truncateToNBits(DoubleAsUInt64(UInt64AsDouble(l) * UInt64AsDouble(r)), DBL_BITS);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+// signed divide of l by r
+inline uint64_t div(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits(FloatAsUInt64(UInt64AsFloat(l)  / UInt64AsFloat(r)),  FLT_BITS);
+  case DBL_BITS: return bits64::truncateToNBits(DoubleAsUInt64(UInt64AsDouble(l) / UInt64AsDouble(r)), DBL_BITS);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+// signed modulo of l by r
+inline uint64_t mod(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits(FloatAsUInt64( fmod(UInt64AsFloat(l),  UInt64AsFloat(r)) ), FLT_BITS);
+  case DBL_BITS: return bits64::truncateToNBits(DoubleAsUInt64( fmod(UInt64AsDouble(l), UInt64AsDouble(r)) ), DBL_BITS);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+
+// ********************************** //
+// *** LLVM Comparison Operations *** //
+// ********************************** //
+
+// determine if l represents NaN
+inline bool isNaN(uint64_t l, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return llvm::IsNAN( UInt64AsFloat(l) );
+  case DBL_BITS: return llvm::IsNAN( UInt64AsDouble(l) );
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+inline uint64_t eq(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return UInt64AsFloat(l)  == UInt64AsFloat(r);
+  case DBL_BITS: return UInt64AsDouble(l) == UInt64AsDouble(r);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+inline uint64_t ne(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return UInt64AsFloat(l)  != UInt64AsFloat(r);
+  case DBL_BITS: return UInt64AsDouble(l) != UInt64AsDouble(r);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+inline uint64_t lt(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return UInt64AsFloat(l)  < UInt64AsFloat(r);
+  case DBL_BITS: return UInt64AsDouble(l) < UInt64AsDouble(r);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+inline uint64_t le(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return UInt64AsFloat(l)  <= UInt64AsFloat(r);
+  case DBL_BITS: return UInt64AsDouble(l) <= UInt64AsDouble(r);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+inline uint64_t gt(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return UInt64AsFloat(l)  > UInt64AsFloat(r);
+  case DBL_BITS: return UInt64AsDouble(l) > UInt64AsDouble(r);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+inline uint64_t ge(uint64_t l, uint64_t r, unsigned inWidth) {
+  switch( inWidth ) {
+  case FLT_BITS: return UInt64AsFloat(l)  >= UInt64AsFloat(r);
+  case DBL_BITS: return UInt64AsDouble(l) >= UInt64AsDouble(r);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+
+// ********************************** //
+// *** LLVM Conversion Operations *** //
+// ********************************** //
+
+// truncation of l (which must be a double) to float (casts a double to a float)
+inline uint64_t trunc(uint64_t l, unsigned outWidth, unsigned inWidth) {
+  // FIXME: Investigate this, should this not happen? Was a quick
+  // patch for busybox.
+  if (inWidth==64 && outWidth==64) {
+    return l;
+  } else {
+    assert(inWidth==64 && "can only truncate from a 64-bit double");
+    assert(outWidth==32 && "can only truncate to a 32-bit float");
+    float trunc = (float)UInt64AsDouble(l);
+    return bits64::truncateToNBits(FloatAsUInt64(trunc), outWidth);
+  }
+}
+
+// extension of l (which must be a float) to double (casts a float to a double)
+inline uint64_t ext(uint64_t l, unsigned outWidth, unsigned inWidth) {
+  // FIXME: Investigate this, should this not happen? Was a quick
+  // patch for busybox.
+  if (inWidth==64 && outWidth==64) {
+    return l;
+  } else {
+    assert(inWidth==32 && "can only extend from a 32-bit float");
+    assert(outWidth==64 && "can only extend to a 64-bit double");
+    double ext = (double)UInt64AsFloat(l);
+    return bits64::truncateToNBits(DoubleAsUInt64(ext), outWidth);
+  }
+}
+
+// conversion of l to an unsigned integer, rounding towards zero
+inline uint64_t toUnsignedInt( uint64_t l, unsigned outWidth, unsigned inWidth ) {
+  switch( inWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits((uint64_t)UInt64AsFloat(l),  outWidth );
+  case DBL_BITS: return bits64::truncateToNBits((uint64_t)UInt64AsDouble(l), outWidth );
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+// conversion of l to a signed integer, rounding towards zero
+inline uint64_t toSignedInt( uint64_t l, unsigned outWidth, unsigned inWidth ) {
+  switch( inWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits((int64_t)UInt64AsFloat(l),  outWidth);
+  case DBL_BITS: return bits64::truncateToNBits((int64_t)UInt64AsDouble(l), outWidth);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+// conversion of l, interpreted as an unsigned int, to a floating point number
+inline uint64_t UnsignedIntToFP( uint64_t l, unsigned outWidth ) {
+  switch( outWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits(FloatAsUInt64((float)l),  outWidth);
+  case DBL_BITS: return bits64::truncateToNBits(DoubleAsUInt64((double)l), outWidth);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+// conversion of l, interpreted as a signed int, to a floating point number
+inline uint64_t SignedIntToFP( uint64_t l, unsigned outWidth, unsigned inWidth ) {
+  switch( outWidth ) {
+  case FLT_BITS: return bits64::truncateToNBits(FloatAsUInt64((float)(int64_t)ints::sext(l, 64, inWidth)), outWidth);
+  case DBL_BITS: return bits64::truncateToNBits(DoubleAsUInt64((double)(int64_t)ints::sext(l,64, inWidth)), outWidth);
+  default: assert(0 && "invalid floating point width");
+  }
+}
+
+} // end namespace ints
+} // end namespace klee
+
+#endif //KLEE_UTIL_FLOATS_H
diff --git a/include/klee/Internal/Support/IntEvaluation.h b/include/klee/Internal/Support/IntEvaluation.h
new file mode 100644
index 00000000..ed3ffc23
--- /dev/null
+++ b/include/klee/Internal/Support/IntEvaluation.h
@@ -0,0 +1,164 @@
+//===-- IntEvaluation.h -----------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_UTIL_INTEVALUATION_H
+#define KLEE_UTIL_INTEVALUATION_H
+
+#include "klee/util/Bits.h"
+
+#define MAX_BITS (sizeof(uint64_t) * 8)
+
+// ASSUMPTION: invalid bits in each uint64_t are 0. the trade-off here is
+// between making trunc/zext/sext fast and making operations that depend
+// on the invalid bits being 0 fast. 
+
+namespace klee {
+namespace ints {
+
+// add of l and r
+inline uint64_t add(uint64_t l, uint64_t r, unsigned inWidth) {
+  return bits64::truncateToNBits(l + r, inWidth);
+}
+
+// difference of l and r
+inline uint64_t sub(uint64_t l, uint64_t r, unsigned inWidth) {
+  return bits64::truncateToNBits(l - r, inWidth);
+}
+
+// product of l and r
+inline uint64_t mul(uint64_t l, uint64_t r, unsigned inWidth) {
+  return bits64::truncateToNBits(l * r, inWidth);
+}
+
+// truncation of l to outWidth bits
+inline uint64_t trunc(uint64_t l, unsigned outWidth, unsigned inWidth) {
+  return bits64::truncateToNBits(l, outWidth);
+}
+
+// zero-extension of l from inWidth to outWidth bits
+inline uint64_t zext(uint64_t l, unsigned outWidth, unsigned inWidth) {
+  return l;
+}
+
+// sign-extension of l from inWidth to outWidth bits
+inline uint64_t sext(uint64_t l, unsigned outWidth, unsigned inWidth) {
+  uint32_t numInvalidBits = MAX_BITS - inWidth;
+  return bits64::truncateToNBits(((int64_t)(l << numInvalidBits)) >> numInvalidBits, outWidth);
+}
+
+// unsigned divide of l by r
+inline uint64_t udiv(uint64_t l, uint64_t r, unsigned inWidth) {
+  return bits64::truncateToNBits(l / r, inWidth);
+}
+
+// unsigned mod of l by r
+inline uint64_t urem(uint64_t l, uint64_t r, unsigned inWidth) {
+  return bits64::truncateToNBits(l % r, inWidth);
+}
+
+// signed divide of l by r
+inline uint64_t sdiv(uint64_t l, uint64_t r, unsigned inWidth) {
+  // sign extend operands so that signed operation on 64-bits works correctly
+  int64_t sl = sext(l, MAX_BITS, inWidth);
+  int64_t sr = sext(r, MAX_BITS, inWidth);
+  return bits64::truncateToNBits(sl / sr, inWidth);
+}
+
+// signed mod of l by r
+inline uint64_t srem(uint64_t l, uint64_t r, unsigned inWidth) {
+  // sign extend operands so that signed operation on 64-bits works correctly
+  int64_t sl = sext(l, MAX_BITS, inWidth);
+  int64_t sr = sext(r, MAX_BITS, inWidth);
+  return bits64::truncateToNBits(sl % sr, inWidth);
+}
+
+// arithmetic shift right of l by r bits
+inline uint64_t ashr(uint64_t l, uint64_t shift, unsigned inWidth) {
+  int64_t sl = sext(l, MAX_BITS, inWidth);
+  return bits64::truncateToNBits(sl >> shift, inWidth);
+}
+
+// logical shift right of l by r bits
+inline uint64_t lshr(uint64_t l, uint64_t shift, unsigned inWidth) {
+  return l >> shift;
+}
+
+// shift left of l by r bits
+inline uint64_t shl(uint64_t l, uint64_t shift, unsigned inWidth) {
+  return bits64::truncateToNBits(l << shift, inWidth);
+}
+
+// logical AND of l and r
+inline uint64_t land(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l & r;
+}
+
+// logical OR of l and r
+inline uint64_t lor(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l | r;
+}
+
+// logical XOR of l and r
+inline uint64_t lxor(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l ^ r;
+}
+
+// comparison operations
+inline uint64_t eq(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l == r;
+}
+
+inline uint64_t ne(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l != r;
+}
+
+inline uint64_t ult(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l < r;
+}
+
+inline uint64_t ule(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l <= r;
+}
+
+inline uint64_t ugt(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l > r;
+}
+
+inline uint64_t uge(uint64_t l, uint64_t r, unsigned inWidth) {
+  return l >= r;
+}
+
+inline uint64_t slt(uint64_t l, uint64_t r, unsigned inWidth) {
+  int64_t sl = sext(l, MAX_BITS, inWidth);
+  int64_t sr = sext(r, MAX_BITS, inWidth);
+  return sl < sr;
+}
+
+inline uint64_t sle(uint64_t l, uint64_t r, unsigned inWidth) {
+  int64_t sl = sext(l, MAX_BITS, inWidth);
+  int64_t sr = sext(r, MAX_BITS, inWidth);
+  return sl <= sr;
+}
+
+inline uint64_t sgt(uint64_t l, uint64_t r, unsigned inWidth) {
+  int64_t sl = sext(l, MAX_BITS, inWidth);
+  int64_t sr = sext(r, MAX_BITS, inWidth);
+  return sl > sr;
+}
+
+inline uint64_t sge(uint64_t l, uint64_t r, unsigned inWidth) {
+  int64_t sl = sext(l, MAX_BITS, inWidth);
+  int64_t sr = sext(r, MAX_BITS, inWidth);
+  return sl >= sr;
+}
+
+} // end namespace ints
+} // end namespace klee
+
+#endif 
diff --git a/include/klee/Internal/Support/ModuleUtil.h b/include/klee/Internal/Support/ModuleUtil.h
new file mode 100644
index 00000000..6cf5fbee
--- /dev/null
+++ b/include/klee/Internal/Support/ModuleUtil.h
@@ -0,0 +1,40 @@
+//===-- ModuleUtil.h --------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_TRANSFORM_UTIL_H
+#define KLEE_TRANSFORM_UTIL_H
+
+#include <string>
+
+namespace llvm {
+  class Function;
+  class Instruction;
+  class Module; 
+}
+
+namespace klee {
+ 
+  /// Link a module with a specified bitcode archive.
+  llvm::Module *linkWithLibrary(llvm::Module *module, 
+                                const std::string &libraryName);
+
+  /// Return the Function* target of a Call or Invoke instruction, or
+  /// null if it cannot be determined (should be only for indirect
+  /// calls, although complicated constant expressions might be
+  /// another possibility).
+  llvm::Function *getDirectCallTarget(const llvm::Instruction*);
+
+  /// Return true iff the given Function value is used in something
+  /// other than a direct call (or a constant expression that
+  /// terminates in a direct call).
+  bool functionEscapes(const llvm::Function *f);
+
+}
+
+#endif
diff --git a/include/klee/Internal/Support/QueryLog.h b/include/klee/Internal/Support/QueryLog.h
new file mode 100644
index 00000000..b090d2d9
--- /dev/null
+++ b/include/klee/Internal/Support/QueryLog.h
@@ -0,0 +1,63 @@
+//===-- QueryLog.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_OPT_LOGGINGSOLVER_H
+#define KLEE_OPT_LOGGINGSOLVER_H
+
+#include "klee/Expr.h"
+
+#include <vector>
+
+namespace klee {
+  struct Query;
+
+  class QueryLogEntry {
+  public:
+    enum Type {
+      Validity,
+      Truth,
+      Value,
+      Cex
+    };
+    
+    typedef std::vector< ref<Expr> > exprs_ty;
+    exprs_ty exprs;
+
+    Type type;
+    ref<Expr> query;
+    unsigned instruction;
+    std::vector<const Array*> objects;
+    
+  public:
+    QueryLogEntry() : query(0,Expr::Bool) {}
+    QueryLogEntry(const QueryLogEntry &b);
+    QueryLogEntry(const Query &_query, 
+                  Type _type,
+                  const std::vector<const Array*> *objects = 0);
+  };
+
+  class QueryLogResult {
+  public:
+    uint64_t result;
+    double time;
+
+  public:
+    QueryLogResult() {}
+    QueryLogResult(bool _success, uint64_t _result, double _time) 
+      : result(_result), time(_time) {
+      if (!_success) { // la la la
+        result = 0;
+        time = -1;
+      }
+    }
+  };
+  
+}
+
+#endif
diff --git a/include/klee/Internal/Support/Timer.h b/include/klee/Internal/Support/Timer.h
new file mode 100644
index 00000000..a422abd0
--- /dev/null
+++ b/include/klee/Internal/Support/Timer.h
@@ -0,0 +1,28 @@
+//===-- Timer.h -------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_TIMER_H
+#define KLEE_TIMER_H
+
+#include <stdint.h>
+
+namespace klee {
+  class WallTimer {
+    uint64_t startMicroseconds;
+    
+  public:
+    WallTimer();
+
+    /// check - Return the delta since the timer was created, in microseconds.
+    uint64_t check();
+  };
+}
+
+#endif
+
diff --git a/include/klee/Internal/System/Time.h b/include/klee/Internal/System/Time.h
new file mode 100644
index 00000000..5229c8c9
--- /dev/null
+++ b/include/klee/Internal/System/Time.h
@@ -0,0 +1,20 @@
+//===-- Time.h --------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_UTIL_TIME_H
+#define KLEE_UTIL_TIME_H
+
+namespace klee {
+  namespace util {
+    double getUserTime();
+    double getWallTime();
+  }
+}
+
+#endif
diff --git a/include/klee/Interpreter.h b/include/klee/Interpreter.h
new file mode 100644
index 00000000..eca6e59e
--- /dev/null
+++ b/include/klee/Interpreter.h
@@ -0,0 +1,149 @@
+//===-- Interpreter.h - Abstract Execution Engine Interface -----*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_INTERPRETER_H
+#define KLEE_INTERPRETER_H
+
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+
+struct BOut;
+
+namespace llvm {
+class Function;
+class Module;
+}
+
+namespace klee {
+class ExecutionState;
+class Interpreter;
+class TreeStreamWriter;
+
+class InterpreterHandler {
+public:
+  InterpreterHandler() {}
+  virtual ~InterpreterHandler() {};
+
+  virtual std::ostream &getInfoStream() const = 0;
+
+  virtual std::string getOutputFilename(const std::string &filename) = 0;
+  virtual std::ostream *openOutputFile(const std::string &filename) = 0;
+
+  virtual void incPathsExplored() = 0;
+
+  virtual void processTestCase(const ExecutionState &state,
+                               const char *err, 
+                               const char *suffix) = 0;
+};
+
+class Interpreter {
+public:
+  /// ModuleOptions - Module level options which can be set when
+  /// registering a module with the interpreter.
+  struct ModuleOptions {
+    std::string LibraryDir;
+    bool Optimize;
+    bool CheckDivZero;
+
+    ModuleOptions(const std::string& _LibraryDir, 
+                  bool _Optimize, bool _CheckDivZero)
+      : LibraryDir(_LibraryDir), Optimize(_Optimize), 
+        CheckDivZero(_CheckDivZero) {}
+  };
+
+  /// InterpreterOptions - Options varying the runtime behavior during
+  /// interpretation.
+  struct InterpreterOptions {
+    /// A frequency at which to make concrete reads return constrained
+    /// symbolic values. This is used to test the correctness of the
+    /// symbolic execution on concrete programs.
+    unsigned MakeConcreteSymbolic;
+
+    InterpreterOptions()
+      : MakeConcreteSymbolic(false)
+    {}
+  };
+
+protected:
+  const InterpreterOptions interpreterOpts;
+
+  Interpreter(const InterpreterOptions &_interpreterOpts)
+    : interpreterOpts(_interpreterOpts)
+  {};
+
+public:
+  virtual ~Interpreter() {};
+
+  static Interpreter *create(const InterpreterOptions &_interpreterOpts,
+                             InterpreterHandler *ih);
+
+  /// Register the module to be executed.  
+  ///
+  /// \return The final module after it has been optimized, checks
+  /// inserted, and modified for interpretation.
+  virtual const llvm::Module * 
+  setModule(llvm::Module *module, 
+            const ModuleOptions &opts) = 0;
+
+  // supply a tree stream writer which the interpreter will use
+  // to record the concrete path (as a stream of '0' and '1' bytes).
+  virtual void setPathWriter(TreeStreamWriter *tsw) = 0;
+
+  // supply a tree stream writer which the interpreter will use
+  // to record the symbolic path (as a stream of '0' and '1' bytes).
+  virtual void setSymbolicPathWriter(TreeStreamWriter *tsw) = 0;
+
+  // supply a test case to replay from. this can be used to drive the
+  // interpretation down a user specified path. use null to reset.
+  virtual void setReplayOut(const struct BOut *out) = 0;
+
+  // supply a list of branch decisions specifying which direction to
+  // take on forks. this can be used to drive the interpretation down
+  // a user specified path. use null to reset.
+  virtual void setReplayPath(const std::vector<bool> *path) = 0;
+
+  // supply a set of symbolic bindings that will be used as "seeds"
+  // for the search. use null to reset.
+  virtual void useSeeds(const std::vector<struct BOut *> *seeds) = 0;
+
+  virtual void runFunctionAsMain(llvm::Function *f,
+                                 int argc,
+                                 char **argv,
+                                 char **envp) = 0;
+
+  /*** Runtime options ***/
+
+  virtual void setHaltExecution(bool value) = 0;
+
+  virtual void setInhibitForking(bool value) = 0;
+
+  /*** State accessor methods ***/
+
+  virtual unsigned getPathStreamID(const ExecutionState &state) = 0;
+
+  virtual unsigned getSymbolicPathStreamID(const ExecutionState &state) = 0;
+  
+  virtual void getConstraintLog(const ExecutionState &state,
+                                std::string &res,
+                                bool asCVC = false) = 0;
+
+  virtual bool getSymbolicSolution(const ExecutionState &state, 
+                                   std::vector< 
+                                   std::pair<std::string,
+                                   std::vector<unsigned char> > >
+                                   &res) = 0;
+
+  virtual void getCoveredLines(const ExecutionState &state,
+                               std::map<const std::string*, std::set<unsigned> > &res) = 0;
+};
+
+} // End klee namespace
+
+#endif
diff --git a/include/klee/Machine.h b/include/klee/Machine.h
new file mode 100644
index 00000000..b8a9e9ac
--- /dev/null
+++ b/include/klee/Machine.h
@@ -0,0 +1,28 @@
+//===-- Machine.h -----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __KLEE_MACHINE_H__
+#define __KLEE_MACHINE_H__
+
+#include "klee/Expr.h"
+
+namespace klee {
+  namespace machine {
+    enum ByteOrder {
+      LSB = 0,
+      MSB = 1
+    };
+  }
+}
+
+#define kMachineByteOrder      klee::machine::LSB
+#define kMachinePointerType    Expr::Int32
+#define kMachinePointerSize    4
+
+#endif /* __KLEE_MACHINE_H__ */
diff --git a/include/klee/Solver.h b/include/klee/Solver.h
new file mode 100644
index 00000000..2d4fa044
--- /dev/null
+++ b/include/klee/Solver.h
@@ -0,0 +1,216 @@
+//===-- Solver.h ------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_SOLVER_H
+#define KLEE_SOLVER_H
+
+#include "klee/Expr.h"
+
+#include <vector>
+
+namespace klee {
+  class ConstraintManager;
+  class Expr;
+  class SolverImpl;
+
+  struct Query {
+  public:
+    const ConstraintManager &constraints;
+    ref<Expr> expr;
+
+    Query(const ConstraintManager& _constraints, ref<Expr> _expr)
+      : constraints(_constraints), expr(_expr) {
+    }
+
+    /// withExpr - Return a copy of the query with the given expression.
+    Query withExpr(ref<Expr> _expr) const {
+      return Query(constraints, _expr);
+    }
+
+    /// withFalse - Return a copy of the query with a false expression.
+    Query withFalse() const {
+      return Query(constraints, ref<Expr>(0, Expr::Bool));
+    }
+
+    /// negateExpr - Return a copy of the query with the expression negated.
+    Query negateExpr() const {
+      return withExpr(Expr::createNot(expr));
+    }
+  };
+
+  class Solver {
+    // DO NOT IMPLEMENT.
+    Solver(const Solver&);
+    void operator=(const Solver&);
+
+  public:
+    enum Validity {
+      True = 1,
+      False = -1,
+      Unknown = 0
+    };
+  
+  public:
+    /// validity_to_str - Return the name of given Validity enum value.
+    static const char *validity_to_str(Validity v);
+
+  public:
+    SolverImpl *impl;
+
+  public:
+    Solver(SolverImpl *_impl) : impl(_impl) {};
+    ~Solver();
+
+    /// evaluate - Determine the full validity of an expression in particular
+    /// state.
+    ////
+    /// \param [out] result - The validity of the given expression (provably
+    /// true, provably false, or neither).
+    ///
+    /// \return True on success.
+    bool evaluate(const Query&, Validity &result);
+  
+    /// mustBeTrue - Determine if the expression is provably true.
+    ///
+    /// \param [out] result - On success, true iff the expresssion is provably
+    /// false.
+    ///
+    /// \return True on success.
+    bool mustBeTrue(const Query&, bool &result);
+
+    /// mustBeFalse - Determine if the expression is provably false.
+    ///
+    /// \param [out] result - On success, true iff the expresssion is provably
+    /// false.
+    ///
+    /// \return True on success.
+    bool mustBeFalse(const Query&, bool &result);
+
+    /// mayBeTrue - Determine if there is a valid assignment for the given state
+    /// in which the expression evaluates to false.
+    ///
+    /// \param [out] result - On success, true iff the expresssion is true for
+    /// some satisfying assignment.
+    ///
+    /// \return True on success.
+    bool mayBeTrue(const Query&, bool &result);
+
+    /// mayBeFalse - Determine if there is a valid assignment for the given
+    /// state in which the expression evaluates to false.
+    ///
+    /// \param [out] result - On success, true iff the expresssion is false for
+    /// some satisfying assignment.
+    ///
+    /// \return True on success.
+    bool mayBeFalse(const Query&, bool &result);
+
+    /// getValue - Compute one possible value for the given expression.
+    ///
+    /// \param [out] result - On success, a value for the expression in some
+    /// satisying assignment.
+    ///
+    /// \return True on success.
+    bool getValue(const Query&, ref<Expr> &result);
+
+    /// getInitialValues - Compute the initial values for a list of objects.
+    ///
+    /// \param [out] result - On success, this vector will be filled in with an
+    /// array of bytes for each given object (with length matching the object
+    /// size). The bytes correspond to the initial values for the objects for
+    /// some satisying assignment.
+    ///
+    /// \return True on success.
+    ///
+    /// NOTE: This function returns failure if there is no satisfying
+    /// assignment.
+    //
+    // FIXME: This API is lame. We should probably just provide an API which
+    // returns an Assignment object, then clients can get out whatever values
+    // they want. This also allows us to optimize the representation.
+    bool getInitialValues(const Query&, 
+                          const std::vector<const Array*> &objects,
+                          std::vector< std::vector<unsigned char> > &result);
+
+    /// getRange - Compute a tight range of possible values for a given
+    /// expression.
+    ///
+    /// \return - A pair with (min, max) values for the expression.
+    ///
+    /// \post(mustBeTrue(min <= e <= max) && 
+    ///       mayBeTrue(min == e) &&
+    ///       mayBeTrue(max == e))
+    //
+    // FIXME: This should go into a helper class, and should handle failure.
+    virtual std::pair< ref<Expr>, ref<Expr> > getRange(const Query&);
+  };
+
+  /// STPSolver - A complete solver based on STP.
+  class STPSolver : public Solver {
+  public:
+    /// STPSolver - Construct a new STPSolver.
+    ///
+    /// \param useForkedSTP - Whether STP should be run in a separate process
+    /// (required for using timeouts).
+    STPSolver(bool useForkedSTP);
+    
+    /// getConstraintLog - Return the constraint log for the given state in CVC
+    /// format.
+    char *getConstraintLog(const Query&);
+    
+    /// setTimeout - Set constraint solver timeout delay to the given value; 0
+    /// is off.
+    void setTimeout(double timeout);
+  };
+
+  /* *** */
+
+  /// createValidatingSolver - Create a solver which will validate all query
+  /// results against an oracle, used for testing that an optimized solver has
+  /// the same results as an unoptimized one. This solver will assert on any
+  /// mismatches.
+  ///
+  /// \param s - The primary underlying solver to use.
+  /// \param oracle - The solver to check query results against.
+  Solver *createValidatingSolver(Solver *s, Solver *oracle);
+
+  /// createCachingSolver - Create a solver which will cache the queries in
+  /// memory (without eviction).
+  ///
+  /// \param s - The underlying solver to use.
+  Solver *createCachingSolver(Solver *s);
+
+  /// createCexCachingSolver - Create a counterexample caching solver. This is a
+  /// more sophisticated cache which records counterexamples for a constraint
+  /// set and uses subset/superset relations among constraints to try and
+  /// quickly find satisfying assignments.
+  ///
+  /// \param s - The underlying solver to use.
+  Solver *createCexCachingSolver(Solver *s);
+
+  /// createFastCexSolver - Create a "fast counterexample solver", which tries
+  /// to quickly compute a satisfying assignment for a constraint set using
+  /// value propogation and range analysis.
+  ///
+  /// \param s - The underlying solver to use.
+  Solver *createFastCexSolver(Solver *s);
+
+  /// createIndependentSolver - Create a solver which will eliminate any
+  /// unnecessary constraints before propogating the query to the underlying
+  /// solver.
+  ///
+  /// \param s - The underlying solver to use.
+  Solver *createIndependentSolver(Solver *s);
+  
+  /// createPCLoggingSolver - Create a solver which will forward all queries
+  /// after writing them to the given path in .pc format.
+  Solver *createPCLoggingSolver(Solver *s, std::string path);
+
+}
+
+#endif
diff --git a/include/klee/SolverImpl.h b/include/klee/SolverImpl.h
new file mode 100644
index 00000000..29c356be
--- /dev/null
+++ b/include/klee/SolverImpl.h
@@ -0,0 +1,63 @@
+//===-- SolverImpl.h --------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_SOLVERIMPL_H
+#define KLEE_SOLVERIMPL_H
+
+#include <vector>
+
+namespace klee {
+  class Array;
+  class ExecutionState;
+  class Expr;
+  struct Query;
+
+  /// SolverImpl - Abstract base clase for solver implementations.
+  class SolverImpl {
+    // DO NOT IMPLEMENT.
+    SolverImpl(const SolverImpl&);
+    void operator=(const SolverImpl&);
+    
+  public:
+    SolverImpl() {}
+    virtual ~SolverImpl();
+
+    /// computeValidity - Compute a full validity result for the
+    /// query.
+    ///
+    /// The query expression is guaranteed to be non-constant and have
+    /// bool type.
+    ///
+    /// SolverImpl provides a default implementation which uses
+    /// computeTruth. Clients should override this if a more efficient
+    /// implementation is available.
+    virtual bool computeValidity(const Query& query, Solver::Validity &result);
+    
+    /// computeTruth - Determine whether the given query is provable.
+    ///
+    /// The query expression is guaranteed to be non-constant and have
+    /// bool type.
+    virtual bool computeTruth(const Query& query, bool &isValid) = 0;
+
+    /// computeValue - Compute a feasible value for the expression.
+    ///
+    /// The query expression is guaranteed to be non-constant.
+    virtual bool computeValue(const Query& query, ref<Expr> &result) = 0;
+    
+    virtual bool computeInitialValues(const Query& query,
+                                      const std::vector<const Array*> 
+                                        &objects,
+                                      std::vector< std::vector<unsigned char> > 
+                                        &values,
+                                      bool &hasSolution) = 0;  
+};
+
+}
+
+#endif
diff --git a/include/klee/Statistic.h b/include/klee/Statistic.h
new file mode 100644
index 00000000..e5aef6b1
--- /dev/null
+++ b/include/klee/Statistic.h
@@ -0,0 +1,65 @@
+//===-- Statistic.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_STATISTIC_H
+#define KLEE_STATISTIC_H
+
+#include <string>
+
+namespace klee {
+  class Statistic;
+  class StatisticManager;
+  class StatisticRecord;
+
+  /// Statistic - A named statistic instance.
+  ///
+  /// The Statistic class holds information about the statistic, but
+  /// not the actual values. Values are managed by the global
+  /// StatisticManager to enable transparent support for instruction
+  /// level and call path level statistics.
+  class Statistic {
+    friend class StatisticManager;
+    friend class StatisticRecord;
+
+  private:
+    unsigned id;
+    const std::string name;
+    const std::string shortName;
+
+  public:
+    Statistic(const std::string &_name, 
+              const std::string &_shortName);
+    ~Statistic();
+
+    /// getID - Get the unique statistic ID.
+    unsigned getID() { return id; }
+
+    /// getName - Get the statistic name.
+    const std::string &getName() const { return name; }
+
+    /// getShortName - Get the "short" statistic name, used in
+    /// callgrind output for example.
+    const std::string &getShortName() const { return shortName; }
+
+    /// getValue - Get the current primary statistic value.
+    uint64_t getValue() const;
+
+    /// operator uint64_t - Get the current primary statistic value.
+    operator uint64_t () const { return getValue(); }
+
+    /// operator++ - Increment the statistic by 1.
+    Statistic &operator ++() { return (*this += 1); }
+
+    /// operator+= - Increment the statistic by \arg addend.
+    Statistic &operator +=(const uint64_t addend);
+  };
+}
+
+#endif
+
diff --git a/include/klee/Statistics.h b/include/klee/Statistics.h
new file mode 100644
index 00000000..20ab2528
--- /dev/null
+++ b/include/klee/Statistics.h
@@ -0,0 +1,154 @@
+//===-- Statistics.h --------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_STATISTICS_H
+#define KLEE_STATISTICS_H
+
+#include "Statistic.h"
+
+#include <vector>
+#include <string>
+#include <string.h>
+
+namespace klee {
+  class Statistic;
+  class StatisticRecord {
+    friend class StatisticManager;
+
+  private:
+    uint64_t *data;
+
+  public:    
+    StatisticRecord();
+    StatisticRecord(const StatisticRecord &s);
+    ~StatisticRecord() { delete[] data; }
+    
+    void zero();
+
+    uint64_t getValue(const Statistic &s) const; 
+    void incrementValue(const Statistic &s, uint64_t addend) const;
+    StatisticRecord &operator =(const StatisticRecord &s);
+    StatisticRecord &operator +=(const StatisticRecord &sr);
+  };
+
+  class StatisticManager {
+  private:
+    bool enabled;
+    std::vector<Statistic*> stats;
+    uint64_t *globalStats;
+    uint64_t *indexedStats;
+    StatisticRecord *contextStats;
+    unsigned index;
+
+  public:
+    StatisticManager();
+    ~StatisticManager();
+
+    void useIndexedStats(unsigned totalIndices);
+
+    StatisticRecord *getContext();
+    void setContext(StatisticRecord *sr); /* null to reset */
+
+    void setIndex(unsigned i) { index = i; }
+    unsigned getIndex() { return index; }
+    unsigned getNumStatistics() { return stats.size(); }
+    Statistic &getStatistic(unsigned i) { return *stats[i]; }
+    
+    void registerStatistic(Statistic &s);
+    void incrementStatistic(Statistic &s, uint64_t addend);
+    uint64_t getValue(const Statistic &s) const;
+    void incrementIndexedValue(const Statistic &s, unsigned index, 
+                               uint64_t addend) const;
+    uint64_t getIndexedValue(const Statistic &s, unsigned index) const;
+    void setIndexedValue(const Statistic &s, unsigned index, uint64_t value);
+    int getStatisticID(const std::string &name) const;
+    Statistic *getStatisticByName(const std::string &name) const;
+  };
+
+  extern StatisticManager *theStatisticManager;
+
+  inline void StatisticManager::incrementStatistic(Statistic &s, 
+                                                   uint64_t addend) {
+    if (enabled) {
+      globalStats[s.id] += addend;
+      if (indexedStats) {
+        indexedStats[index*stats.size() + s.id] += addend;
+        if (contextStats)
+          contextStats->data[s.id] += addend;
+      }
+    }
+  }
+
+  inline StatisticRecord *StatisticManager::getContext() {
+    return contextStats;
+  }
+  inline void StatisticManager::setContext(StatisticRecord *sr) {
+    contextStats = sr;
+  }
+
+  inline void StatisticRecord::zero() {
+    ::memset(data, 0, sizeof(*data)*theStatisticManager->getNumStatistics());
+  }
+
+  inline StatisticRecord::StatisticRecord() 
+    : data(new uint64_t[theStatisticManager->getNumStatistics()]) {
+    zero();
+  }
+
+  inline StatisticRecord::StatisticRecord(const StatisticRecord &s) 
+    : data(new uint64_t[theStatisticManager->getNumStatistics()]) {
+    ::memcpy(data, s.data, 
+             sizeof(*data)*theStatisticManager->getNumStatistics());
+  }
+
+  inline StatisticRecord &StatisticRecord::operator=(const StatisticRecord &s) {
+    ::memcpy(data, s.data, 
+             sizeof(*data)*theStatisticManager->getNumStatistics());
+    return *this;
+  }
+
+  inline void StatisticRecord::incrementValue(const Statistic &s, 
+                                              uint64_t addend) const {
+    data[s.id] += addend;
+  }
+  inline uint64_t StatisticRecord::getValue(const Statistic &s) const { 
+    return data[s.id]; 
+  }
+
+  inline StatisticRecord &
+  StatisticRecord::operator +=(const StatisticRecord &sr) {
+    unsigned nStats = theStatisticManager->getNumStatistics();
+    for (unsigned i=0; i<nStats; i++)
+      data[i] += sr.data[i];
+    return *this;
+  }
+
+  inline uint64_t StatisticManager::getValue(const Statistic &s) const {
+    return globalStats[s.id];
+  }
+
+  inline void StatisticManager::incrementIndexedValue(const Statistic &s, 
+                                                      unsigned index,
+                                                      uint64_t addend) const {
+    indexedStats[index*stats.size() + s.id] += addend;
+  }
+
+  inline uint64_t StatisticManager::getIndexedValue(const Statistic &s, 
+                                                    unsigned index) const {
+    return indexedStats[index*stats.size() + s.id];
+  }
+
+  inline void StatisticManager::setIndexedValue(const Statistic &s, 
+                                                unsigned index,
+                                                uint64_t value) {
+    indexedStats[index*stats.size() + s.id] = value;
+  }
+}
+
+#endif
diff --git a/include/klee/TimerStatIncrementer.h b/include/klee/TimerStatIncrementer.h
new file mode 100644
index 00000000..35495d8b
--- /dev/null
+++ b/include/klee/TimerStatIncrementer.h
@@ -0,0 +1,32 @@
+//===-- TimerStatIncrementer.h ----------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_TIMERSTATINCREMENTER_H
+#define KLEE_TIMERSTATINCREMENTER_H
+
+#include "klee/Statistics.h"
+#include "klee/Internal/Support/Timer.h"
+
+namespace klee {
+  class TimerStatIncrementer {
+  private:
+    WallTimer timer;
+    Statistic &statistic;
+
+  public:
+    TimerStatIncrementer(Statistic &_statistic) : statistic(_statistic) {}
+    ~TimerStatIncrementer() {
+      statistic += timer.check(); 
+    };
+
+    uint64_t check() { return timer.check(); }
+  };
+}
+
+#endif
diff --git a/include/klee/klee.h b/include/klee/klee.h
new file mode 100644
index 00000000..698a61c4
--- /dev/null
+++ b/include/klee/klee.h
@@ -0,0 +1,120 @@
+//===-- klee.h --------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __KLEE_H__
+#define __KLEE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+  /* Add an accesible memory object at a user specified location. It
+     is the users responsibility to make sure that these memory
+     objects do not overlap. These memory objects will also
+     (obviously) not correctly interact with external function
+     calls. */
+  void klee_define_fixed_object(void *addr, unsigned nbytes);
+
+  /* make the contents of the object pointed to by addr symbolic. addr
+   * should always be the start of the object and nbytes must be its
+   * entire size. name is an optional name (can be the empty string)
+   */
+  void klee_make_symbolic_name(void *addr, unsigned nbytes, 
+			       const char *name);
+
+  void klee_make_symbolic(void *addr, unsigned nbytes);  
+  
+  /* Return symbolic value in the (signed) interval [begin,end) */
+  int klee_range(int begin, int end, const char *name);
+
+  /* Return a symbolic integer */
+  int klee_int(const char *name);
+
+  void *klee_malloc_n(unsigned nelems, unsigned size, unsigned alignment);
+
+  /* terminate the state without generating a test file */
+  __attribute__((noreturn))
+  void klee_silent_exit(int status);
+  
+  __attribute__((noreturn))
+  void klee_abort(void);  
+
+  /** Report an error and terminate the state. */
+  __attribute__((noreturn))
+  void klee_report_error(const char *file, 
+			 int line, 
+			 const char *message, 
+			 const char *suffix);
+  
+  /* called by checking code to get size of memory. */
+  unsigned klee_get_obj_size(void *ptr);
+  
+  /* print the tree associated w/ a given expression. */
+  void klee_print_expr(const char *msg, ...);
+  
+  /* NB: this *does not* fork n times and return [0,n) in children.
+   * It makes n be symbolic and returns: caller must compare N times.
+   */
+  unsigned klee_choose(unsigned n);
+  
+  /* special klee assert macro. this assert should be used when path consistency
+   * across platforms is desired (e.g., in tests).
+   * NB: __assert_fail is a klee "special" function
+   */
+# define klee_assert(expr)                                              \
+  ((expr)                                                               \
+   ? (void) (0)                                                         \
+   : __assert_fail (#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__))    \
+
+  /* Return true if the given value is symbolic (represented by an
+   * expression) in the current state. This is primarily for debugging
+   * and writing tests but can also be used to enable prints in replay
+   * mode.
+   */
+  unsigned klee_is_symbolic(unsigned n);
+
+
+  /* The following intrinsics are primarily intended for internal use
+     and may have peculiar semantics. */
+
+  void klee_assume(unsigned condition);
+  void klee_warning(const char *message);
+  void klee_warning_once(const char *message);
+  void klee_prefer_cex(void *object, unsigned condition);
+  void klee_mark_global(void *object);
+
+  /* Return a possible constant value for the input expression. This
+     allows programs to forcibly concretize values on their own. */
+  unsigned klee_get_value(unsigned expr);
+
+  /* Ensure that memory in the range [address, address+size) is
+     accessible to the program. If some byte in the range is not
+     accessible an error will be generated and the state
+     terminated. 
+  
+     The current implementation requires both address and size to be
+     constants and that the range lie within a single object. */
+  void klee_check_memory_access(const void *address, unsigned size);
+
+  /* Enable/disable forking. */
+  void klee_set_forking(unsigned enable);
+
+  /* klee_alias_function("foo", "bar") will replace, at runtime (on
+     the current path and all paths spawned on the current path), all
+     calls to foo() by calls to bar().  foo() and bar() have to exist
+     and have identical types.  Use klee_alias_function("foo", "foo")
+     to undo.  Be aware that some special functions, such as exit(),
+     may not always work. */
+  void klee_alias_function(const char* fn_name, const char* new_fn_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __KLEE_H__ */
diff --git a/include/klee/util/Assignment.h b/include/klee/util/Assignment.h
new file mode 100644
index 00000000..19f89a03
--- /dev/null
+++ b/include/klee/util/Assignment.h
@@ -0,0 +1,100 @@
+//===-- Assignment.h --------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_UTIL_ASSIGNMENT_H
+#define KLEE_UTIL_ASSIGNMENT_H
+
+#include <map>
+
+#include "klee/util/ExprEvaluator.h"
+
+// FIXME: Rename?
+
+namespace klee {
+  class Array;
+
+  class Assignment {
+  public:
+    typedef std::map<const Array*, std::vector<unsigned char> > bindings_ty;
+
+    bool allowFreeValues;
+    bindings_ty bindings;
+    
+  public:
+    Assignment(bool _allowFreeValues=false) 
+      : allowFreeValues(_allowFreeValues) {}
+    Assignment(std::vector<const Array*> &objects, 
+               std::vector< std::vector<unsigned char> > &values,
+               bool _allowFreeValues=false) 
+      : allowFreeValues(_allowFreeValues){
+      std::vector< std::vector<unsigned char> >::iterator valIt = 
+        values.begin();
+      for (std::vector<const Array*>::iterator it = objects.begin(),
+             ie = objects.end(); it != ie; ++it) {
+        const Array *os = *it;
+        std::vector<unsigned char> &arr = *valIt;
+        bindings.insert(std::make_pair(os, arr));
+        ++valIt;
+      }
+    }
+    
+    ref<Expr> evaluate(const Array *mo, unsigned index) const;
+    ref<Expr> evaluate(ref<Expr> e);
+
+    template<typename InputIterator>
+    bool satisfies(InputIterator begin, InputIterator end);
+  };
+  
+  class AssignmentEvaluator : public ExprEvaluator {
+    const Assignment &a;
+
+  protected:
+    ref<Expr> getInitialValue(const Array &mo, unsigned index) {
+      return a.evaluate(&mo, index);
+    }
+    
+  public:
+    AssignmentEvaluator(const Assignment &_a) : a(_a) {}    
+  };
+
+  /***/
+
+  inline ref<Expr> Assignment::evaluate(const Array *array, 
+                                        unsigned index) const {
+    bindings_ty::const_iterator it = bindings.find(array);
+    if (it!=bindings.end() && index<it->second.size()) {
+      return ref<Expr>(it->second[index], Expr::Int8);
+    } else {
+      if (allowFreeValues) {
+        return ReadExpr::create(UpdateList(array, true, 0), 
+                                ref<Expr>(index, Expr::Int32));
+      } else {
+        return ref<Expr>(0, Expr::Int8);
+      }
+    }
+  }
+
+  inline ref<Expr> Assignment::evaluate(ref<Expr> e) { 
+    AssignmentEvaluator v(*this);
+    return v.visit(e); 
+  }
+
+  template<typename InputIterator>
+  inline bool Assignment::satisfies(InputIterator begin, InputIterator end) {
+    AssignmentEvaluator v(*this);
+    for (; begin!=end; ++begin) {
+      ref<Expr> res = v.visit(*begin);
+      if (!res.isConstant() || !res.getConstantValue())
+        return false;
+    }
+    return true;
+  }
+}
+
+#endif
diff --git a/include/klee/util/BitArray.h b/include/klee/util/BitArray.h
new file mode 100644
index 00000000..6f887600
--- /dev/null
+++ b/include/klee/util/BitArray.h
@@ -0,0 +1,42 @@
+//===-- BitArray.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_UTIL_BITARRAY_H
+#define KLEE_UTIL_BITARRAY_H
+
+namespace klee {
+
+  // XXX would be nice not to have
+  // two allocations here for allocated
+  // BitArrays
+class BitArray {
+private:
+  uint32_t *bits;
+  
+protected:
+  static uint32_t length(unsigned size) { return (size+31)/32; }
+
+public:
+  BitArray(unsigned size, bool value = false) : bits(new uint32_t[length(size)]) {
+    memset(bits, value?0xFF:0, sizeof(*bits)*length(size));
+  }
+  BitArray(const BitArray &b, unsigned size) : bits(new uint32_t[length(size)]) {
+    memcpy(bits, b.bits, sizeof(*bits)*length(size));
+  }
+  ~BitArray() { delete[] bits; }
+
+  bool get(unsigned idx) { return (bool) ((bits[idx/32]>>(idx&0x1F))&1); }
+  void set(unsigned idx) { bits[idx/32] |= 1<<(idx&0x1F); }
+  void unset(unsigned idx) { bits[idx/32] &= ~(1<<(idx&0x1F)); }
+  void set(unsigned idx, bool value) { if (value) set(idx); else unset(idx); }
+};
+
+} // End klee namespace
+
+#endif
diff --git a/include/klee/util/Bits.h b/include/klee/util/Bits.h
new file mode 100644
index 00000000..ffbda09e
--- /dev/null
+++ b/include/klee/util/Bits.h
@@ -0,0 +1,102 @@
+//===-- Bits.h --------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_UTIL_BITS_H
+#define KLEE_UTIL_BITS_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace klee {
+  namespace bits32 {
+    // @pre(0 <= N <= 32)
+    // @post(retval = max([truncateToNBits(i,N) for i in naturals()]))
+    inline unsigned maxValueOfNBits(unsigned N) {
+      if (N==0)
+        return 0;
+      return ((unsigned) -1) >> (32 - N);
+    }
+
+    // @pre(0 < N <= 32)
+    inline unsigned truncateToNBits(unsigned x, unsigned N) {
+      return x&(((unsigned) -1) >> (32 - N));
+    }
+
+    inline unsigned withoutRightmostBit(unsigned x) {
+      return x&(x-1);
+    }
+
+    inline unsigned isolateRightmostBit(unsigned x) {
+      return x&-x;
+    }
+
+    inline unsigned isPowerOfTwo(unsigned x) {
+      if (x==0) return 0;
+      return !(x&(x-1));
+    }
+
+    // @pre(withoutRightmostBit(x) == 0)
+    // @post((1 << retval) == x)
+    inline unsigned indexOfSingleBit(unsigned x) {
+      unsigned res = 0;
+      if (x&0xFFFF0000) res += 16;
+      if (x&0xFF00FF00) res += 8;
+      if (x&0xF0F0F0F0) res += 4;
+      if (x&0xCCCCCCCC) res += 2;
+      if (x&0xAAAAAAAA) res += 1;
+      return res;
+    } 
+
+    inline unsigned indexOfRightmostBit(unsigned x) {
+      return indexOfSingleBit(isolateRightmostBit(x));
+    }
+  }
+
+  namespace bits64 {
+    // @pre(0 <= N <= 32)
+    // @post(retval = max([truncateToNBits(i,N) for i in naturals()]))
+    inline uint64_t maxValueOfNBits(unsigned N) {
+      if (N==0)
+        return 0;
+      return ((uint64_t) (int64_t) -1) >> (64 - N);
+    }
+    
+    // @pre(0 < N <= 64)
+    inline uint64_t truncateToNBits(uint64_t x, unsigned N) {
+      return x&(((uint64_t) (int64_t) -1) >> (64 - N));
+    }
+
+    inline uint64_t withoutRightmostBit(uint64_t x) {
+      return x&(x-1);
+    }
+
+    inline uint64_t isolateRightmostBit(uint64_t x) {
+      return x&-x;
+    }
+
+    inline uint64_t isPowerOfTwo(uint64_t x) {
+      if (x==0) return 0;
+      return !(x&(x-1));
+    }
+
+    // @pre((x&(x-1)) == 0)
+    // @post((1 << retval) == x)
+    inline unsigned indexOfSingleBit(uint64_t x) {
+      unsigned res = bits32::indexOfSingleBit((unsigned) (x | (x>>32)));
+      if (x&((uint64_t) 0xFFFFFFFF << 32))
+	  res += 32;
+      return res;
+    } 
+
+    inline uint64_t indexOfRightmostBit(uint64_t x) {
+      return indexOfSingleBit(isolateRightmostBit(x));
+    }
+  }
+} // End klee namespace
+
+#endif
diff --git a/include/klee/util/ExprEvaluator.h b/include/klee/util/ExprEvaluator.h
new file mode 100644
index 00000000..be98942d
--- /dev/null
+++ b/include/klee/util/ExprEvaluator.h
@@ -0,0 +1,39 @@
+//===-- ExprEvaluator.h -----------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPREVALUATOR_H
+#define KLEE_EXPREVALUATOR_H
+
+#include "klee/Expr.h"
+#include "klee/util/ExprVisitor.h"
+
+namespace klee {
+  class ExprEvaluator : public ExprVisitor {
+  protected:
+    Action evalRead(const UpdateList &ul, unsigned index);
+    Action visitRead(const ReadExpr &re);
+      
+    Action protectedDivOperation(const BinaryExpr &e);
+    Action visitUDiv(const UDivExpr &e);
+    Action visitSDiv(const SDivExpr &e);
+    Action visitURem(const URemExpr &e);
+    Action visitSRem(const SRemExpr &e);
+      
+  public:
+    ExprEvaluator() {}
+
+    // override to implement evaluation, this function is called to
+    // get the initial value for a symbolic byte. if the value is
+    // unknown then the user can simply return a ReadExpr at version 0
+    // of this MemoryObject.
+    virtual ref<Expr> getInitialValue(const Array& os, unsigned index) = 0;
+  };
+}
+
+#endif
diff --git a/include/klee/util/ExprHashMap.h b/include/klee/util/ExprHashMap.h
new file mode 100644
index 00000000..d9f95bff
--- /dev/null
+++ b/include/klee/util/ExprHashMap.h
@@ -0,0 +1,48 @@
+//===-- ExprHashMap.h -------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPRHASHMAP_H
+#define KLEE_EXPRHASHMAP_H
+
+#include "klee/Expr.h"
+#include <tr1/unordered_map>
+#include <tr1/unordered_set>
+
+namespace klee {
+
+  namespace util {
+    struct ExprHash  {
+      unsigned operator()(const ref<Expr> e) const {
+        return e.hash();
+      }
+    };
+    
+    struct ExprCmp {
+      bool operator()(const ref<Expr> &a, const ref<Expr> &b) const {
+        return a==b;
+      }
+    };
+  }
+  
+  template<class T> 
+  class ExprHashMap : 
+
+    public std::tr1::unordered_map<ref<Expr>,
+				   T,
+				   klee::util::ExprHash,
+				   klee::util::ExprCmp> {
+  };
+  
+  typedef std::tr1::unordered_set<ref<Expr>,
+				  klee::util::ExprHash,
+				  klee::util::ExprCmp> ExprHashSet;
+
+}
+
+#endif
diff --git a/include/klee/util/ExprPPrinter.h b/include/klee/util/ExprPPrinter.h
new file mode 100644
index 00000000..a1961e2b
--- /dev/null
+++ b/include/klee/util/ExprPPrinter.h
@@ -0,0 +1,58 @@
+//===-- ExprPPrinter.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPRPPRINTER_H
+#define KLEE_EXPRPPRINTER_H
+
+#include "klee/Expr.h"
+
+namespace klee {
+  class ConstraintManager;
+
+  class ExprPPrinter {
+  protected:
+    ExprPPrinter() {}
+    
+  public:
+    static ExprPPrinter *create(std::ostream &os);
+
+    virtual ~ExprPPrinter() {}
+
+    virtual void setNewline(const std::string &newline) = 0;
+    virtual void reset() = 0;
+    virtual void scan(const ref<Expr> &e) = 0;
+    virtual void print(const ref<Expr> &e, unsigned indent=0) = 0;
+
+    // utility methods
+
+    template<class Container>
+    void scan(Container c) {
+      scan(c.begin(), c.end());
+    }
+
+    template<class InputIterator>
+    void scan(InputIterator it, InputIterator end) {
+      for (; it!=end; ++it)
+        scan(*it);
+    }
+
+    static void printOne(std::ostream &os, const char *message, 
+                         const ref<Expr> &e);
+
+    static void printConstraints(std::ostream &os,
+                                 const ConstraintManager &constraints);
+
+    static void printQuery(std::ostream &os,
+                           const ConstraintManager &constraints,
+                           const ref<Expr> &q);
+  };
+
+}
+
+#endif
diff --git a/include/klee/util/ExprRangeEvaluator.h b/include/klee/util/ExprRangeEvaluator.h
new file mode 100644
index 00000000..3729b5c2
--- /dev/null
+++ b/include/klee/util/ExprRangeEvaluator.h
@@ -0,0 +1,283 @@
+//===-- ExprRangeEvaluator.h ------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPRRANGEEVALUATOR_H
+#define KLEE_EXPRRANGEEVALUATOR_H
+
+#include "klee/Expr.h"
+#include "klee/util/Bits.h"
+
+namespace klee {
+
+/*
+class ValueType {
+public:
+  ValueType(); // empty range
+  ValueType(uint64_t value);
+  ValueType(uint64_t min, uint64_t max);
+  
+  bool mustEqual(const uint64_t b);
+  bool mustEqual(const ValueType &b);
+  bool mayEqual(const uint64_t b);  
+  bool mayEqual(const ValueType &b);
+
+  bool isFullRange(unsigned width);
+
+  ValueType set_union(ValueType &);
+  ValueType set_intersection(ValueType &);
+  ValueType set_difference(ValueType &);
+
+  ValueType binaryAnd(ValueType &);
+  ValueType binaryOr(ValueType &);
+  ValueType binaryXor(ValueType &);
+  ValueType concat(ValueType &, unsigned width);
+  ValueType add(ValueType &, unsigned width);
+  ValueType sub(ValueType &, unsigned width);
+  ValueType mul(ValueType &, unsigned width);
+  ValueType udiv(ValueType &, unsigned width);
+  ValueType sdiv(ValueType &, unsigned width);
+  ValueType urem(ValueType &, unsigned width);
+  ValueType srem(ValueType &, unsigned width);
+
+  uint64_t min();
+  uint64_t max();
+  int64_t minSigned(unsigned width);
+  int64_t maxSigned(unsigned width);
+}
+*/
+
+template<class T>
+class ExprRangeEvaluator {
+protected:
+  virtual T getInitialReadRange(const Array &os, T index) = 0;
+
+  T evalRead(const UpdateList &ul, T index);
+
+public:
+  ExprRangeEvaluator() {}
+  virtual ~ExprRangeEvaluator() {}
+
+  T evaluate(const ref<Expr> &e);
+};
+
+template<class T>
+T ExprRangeEvaluator<T>::evalRead(const UpdateList &ul,
+                                  T index) {
+  T res;
+
+  for (const UpdateNode *un=ul.head; un; un=un->next) {
+    T ui = evaluate(un->index);
+
+    if (ui.mustEqual(index)) {
+      return res.set_union(evaluate(un->value));
+    } else if (ui.mayEqual(index)) {
+      res = res.set_union(evaluate(un->value));
+      if (res.isFullRange(8)) {
+        return res;
+      } 
+    }
+  }
+
+  return res.set_union(getInitialReadRange(*ul.root, index));
+}
+
+template<class T>
+T ExprRangeEvaluator<T>::evaluate(const ref<Expr> &e) {
+  switch (e.getKind()) {
+  case Expr::Constant:
+    return T(e.getConstantValue());
+
+  case Expr::NotOptimized: 
+    break;
+
+  case Expr::Read: {
+    const ReadExpr *re = static_ref_cast<const ReadExpr>(e);
+    T index = evaluate(re->index);
+
+    assert(re->getWidth()==Expr::Int8 && "unexpected multibyte read");
+
+    return evalRead(re->updates, index);
+  }
+
+  case Expr::Select: {
+    const SelectExpr *se = static_ref_cast<const SelectExpr>(e);
+    T cond = evaluate(se->cond);
+      
+    if (cond.mustEqual(1)) {
+      return evaluate(se->trueExpr);
+    } else if (cond.mustEqual(0)) {
+      return evaluate(se->falseExpr);
+    } else {
+      return evaluate(se->trueExpr).set_union(evaluate(se->falseExpr));
+    }
+  }
+
+    // XXX these should be unrolled to ensure nice inline
+  case Expr::Concat: {
+    const Expr *ep = e.get();
+    T res(0);
+    for (unsigned i=0; i<ep->getNumKids(); i++)
+      res = res.concat(evaluate(ep->getKid(i)),8);
+    return res;
+  }
+
+    // Arithmetic
+
+  case Expr::Add: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    unsigned width = be->left.getWidth();
+    return evaluate(be->left).add(evaluate(be->right), width);
+  }
+  case Expr::Sub: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    unsigned width = be->left.getWidth();
+    return evaluate(be->left).sub(evaluate(be->right), width);
+  }
+  case Expr::Mul: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    unsigned width = be->left.getWidth();
+    return evaluate(be->left).mul(evaluate(be->right), width);
+  }
+  case Expr::UDiv: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    unsigned width = be->left.getWidth();
+    return evaluate(be->left).udiv(evaluate(be->right), width);
+  }
+  case Expr::SDiv: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    unsigned width = be->left.getWidth();
+    return evaluate(be->left).sdiv(evaluate(be->right), width);
+  }
+  case Expr::URem: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    unsigned width = be->left.getWidth();
+    return evaluate(be->left).urem(evaluate(be->right), width);
+  }
+  case Expr::SRem: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    unsigned width = be->left.getWidth();
+    return evaluate(be->left).srem(evaluate(be->right), width);
+  }
+
+    // Binary
+
+  case Expr::And: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    return evaluate(be->left).binaryAnd(evaluate(be->right));
+  }
+  case Expr::Or: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    return evaluate(be->left).binaryOr(evaluate(be->right));
+  }
+  case Expr::Xor: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    return evaluate(be->left).binaryXor(evaluate(be->right));
+  }
+  case Expr::Shl: {
+    //    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    //    unsigned width = be->left.getWidth();
+    //    return evaluate(be->left).shl(evaluate(be->right), width);
+    break;
+  }
+  case Expr::LShr: {
+    //    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    //    unsigned width = be->left.getWidth();
+    //    return evaluate(be->left).lshr(evaluate(be->right), width);
+    break;
+  }
+  case Expr::AShr: {
+    //    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    //    unsigned width = be->left.getWidth();
+    //    return evaluate(be->left).ashr(evaluate(be->right), width);
+    break;
+  }
+
+    // Comparison
+
+  case Expr::Eq: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    T left = evaluate(be->left);
+    T right = evaluate(be->right);
+      
+    if (left.mustEqual(right)) {
+      return T(1);
+    } else if (!left.mayEqual(right)) {
+      return T(0);
+    }
+    break;
+  }
+
+  case Expr::Ult: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    T left = evaluate(be->left);
+    T right = evaluate(be->right);
+      
+    if (left.max() < right.min()) {
+      return T(1);
+    } else if (left.min() >= right.max()) {
+      return T(0);
+    }
+    break;
+  }
+  case Expr::Ule: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    T left = evaluate(be->left);
+    T right = evaluate(be->right);
+      
+    if (left.max() <= right.min()) {
+      return T(1);
+    } else if (left.min() > right.max()) {
+      return T(0);
+    }
+    break;
+  }
+  case Expr::Slt: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    T left = evaluate(be->left);
+    T right = evaluate(be->right);
+    unsigned bits = be->left.getWidth();
+
+    if (left.maxSigned(bits) < right.minSigned(bits)) {
+      return T(1);
+    } else if (left.minSigned(bits) >= right.maxSigned(bits)) {
+      return T(0);
+    }
+    break;
+  }
+  case Expr::Sle: {
+    const BinaryExpr *be = static_ref_cast<const BinaryExpr>(e);
+    T left = evaluate(be->left);
+    T right = evaluate(be->right);
+    unsigned bits = be->left.getWidth();
+      
+    if (left.maxSigned(bits) <= right.minSigned(bits)) {
+      return T(1);
+    } else if (left.minSigned(bits) > right.maxSigned(bits)) {
+      return T(0);
+    }
+    break;
+  }
+
+  case Expr::Ne:
+  case Expr::Ugt:
+  case Expr::Uge:
+  case Expr::Sgt:
+  case Expr::Sge:
+    assert(0 && "invalid expressions (uncanonicalized)");
+
+  default:
+    break;
+  }
+
+  return T(0, bits64::maxValueOfNBits(e.getWidth()));
+}
+
+}
+
+#endif
diff --git a/include/klee/util/ExprUtil.h b/include/klee/util/ExprUtil.h
new file mode 100644
index 00000000..a81c299f
--- /dev/null
+++ b/include/klee/util/ExprUtil.h
@@ -0,0 +1,43 @@
+//===-- ExprUtil.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPRUTIL_H
+#define KLEE_EXPRUTIL_H
+
+#include <vector>
+
+namespace klee {
+  class Array;
+  class Expr;
+  class ReadExpr;
+  template<typename T> class ref;
+
+  /// Find all ReadExprs used in the expression DAG. If visitUpdates
+  /// is true then this will including those reachable by traversing
+  /// update lists. Note that this may be slow and return a large
+  /// number of results.
+  void findReads(ref<Expr> e, 
+                 bool visitUpdates,
+                 std::vector< ref<ReadExpr> > &result);
+  
+  /// Return a list of all unique symbolic objects referenced by the given
+  /// expression.
+  void findSymbolicObjects(ref<Expr> e,
+                           std::vector<const Array*> &results);
+
+  /// Return a list of all unique symbolic objects referenced by the
+  /// given expression range.
+  template<typename InputIterator>
+  void findSymbolicObjects(InputIterator begin, 
+                           InputIterator end,
+                           std::vector<const Array*> &results);
+
+}
+
+#endif
diff --git a/include/klee/util/ExprVisitor.h b/include/klee/util/ExprVisitor.h
new file mode 100644
index 00000000..8f8617e3
--- /dev/null
+++ b/include/klee/util/ExprVisitor.h
@@ -0,0 +1,95 @@
+//===-- ExprVisitor.h -------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXPRVISITOR_H
+#define KLEE_EXPRVISITOR_H
+
+#include "ExprHashMap.h"
+
+namespace klee {
+  class ExprVisitor {
+  protected:
+    // typed variant, but non-virtual for efficiency
+    class Action {
+    public:
+      enum Kind { SkipChildren, DoChildren, ChangeTo };
+
+    private:
+      //      Action() {}
+      Action(Kind _kind) 
+        : kind(_kind), argument(0,Expr::Bool) {}
+      Action(Kind _kind, const ref<Expr> &_argument) 
+        : kind(_kind), argument(_argument) {}
+
+      friend class ExprVisitor;
+
+    public:
+      Kind kind;
+      ref<Expr> argument;
+
+      static Action changeTo(const ref<Expr> &expr) { return Action(ChangeTo,expr); }
+      static Action doChildren() { return Action(DoChildren); }
+      static Action skipChildren() { return Action(SkipChildren); }
+    };
+
+  protected:
+    explicit
+    ExprVisitor(bool _recursive=false) : recursive(_recursive) {}
+    virtual ~ExprVisitor() {}
+
+    virtual Action visitExpr(const Expr&);
+    virtual Action visitExprPost(const Expr&);
+
+    virtual Action visitNotOptimized(const NotOptimizedExpr&);
+    virtual Action visitRead(const ReadExpr&);
+    virtual Action visitSelect(const SelectExpr&);
+    virtual Action visitConcat(const ConcatExpr&);
+    virtual Action visitExtract(const ExtractExpr&);
+    virtual Action visitZExt(const ZExtExpr&);
+    virtual Action visitSExt(const SExtExpr&);
+    virtual Action visitAdd(const AddExpr&);
+    virtual Action visitSub(const SubExpr&);
+    virtual Action visitMul(const MulExpr&);
+    virtual Action visitUDiv(const UDivExpr&);
+    virtual Action visitSDiv(const SDivExpr&);
+    virtual Action visitURem(const URemExpr&);
+    virtual Action visitSRem(const SRemExpr&);
+    virtual Action visitAnd(const AndExpr&);
+    virtual Action visitOr(const OrExpr&);
+    virtual Action visitXor(const XorExpr&);
+    virtual Action visitShl(const ShlExpr&);
+    virtual Action visitLShr(const LShrExpr&);
+    virtual Action visitAShr(const AShrExpr&);
+    virtual Action visitEq(const EqExpr&);
+    virtual Action visitNe(const NeExpr&);
+    virtual Action visitUlt(const UltExpr&);
+    virtual Action visitUle(const UleExpr&);
+    virtual Action visitUgt(const UgtExpr&);
+    virtual Action visitUge(const UgeExpr&);
+    virtual Action visitSlt(const SltExpr&);
+    virtual Action visitSle(const SleExpr&);
+    virtual Action visitSgt(const SgtExpr&);
+    virtual Action visitSge(const SgeExpr&);
+
+  private:
+    typedef ExprHashMap< ref<Expr> > visited_ty;
+    visited_ty visited;
+    bool recursive;
+
+    ref<Expr> visitActual(const ref<Expr> &e);
+    
+  public:
+    // apply the visitor to the expression and return a possibly
+    // modified new expression.
+    ref<Expr> visit(const ref<Expr> &e);
+  };
+
+}
+
+#endif
diff --git a/include/klee/util/Ref.h b/include/klee/util/Ref.h
new file mode 100644
index 00000000..a70b09cf
--- /dev/null
+++ b/include/klee/util/Ref.h
@@ -0,0 +1,303 @@
+//===-- Ref.h ---------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_REF_H
+#define KLEE_REF_H
+
+#include <assert.h>
+
+class Expr;
+class BinaryExpr;
+class CastExpr;
+class CmpExpr;
+
+class ConstantExpr;
+class ReadExpr;
+class UpdateNode;
+class NotOptimizedExpr;
+class ReadExpr;
+class SelectExpr;
+class ConcatExpr;
+class ExtractExpr;
+class ZExtExpr;
+class SExtExpr;
+class AddExpr;
+class SubExpr;
+class MulExpr;
+class UDivExpr;
+class SDivExpr;
+class URemExpr;
+class SRemExpr;
+class AndExpr;
+class OrExpr;
+class XorExpr;
+class ShlExpr;
+class LShrExpr;
+class AShrExpr;
+class EqExpr;
+class NeExpr;
+class UltExpr;
+class UleExpr;
+class UgtExpr;
+class UgeExpr;
+class SltExpr;
+class SleExpr;
+class SgtExpr;
+class SgeExpr;
+class KModule;
+
+  class ExprVisitor;
+  class StackFrame;
+  class ObjectState;
+
+template<class T>
+class ref {
+public:
+  // default constructor: create a NULL reference
+  ref() : constantWidth(Expr::InvalidWidth) {
+    contents.ptr = 0;
+  }
+
+private:
+  // if NotConstant, not this ref is not a constant.
+  // otherwise, it's the width of the constant.
+  Expr::Width constantWidth;
+  static const Expr::Width NotConstant = (Expr::Width) 0;
+  
+  union {
+    T *ptr;
+    uint64_t val;
+  } contents;
+  
+  void inc() {
+    if (constantWidth == NotConstant &&
+        contents.ptr) {
+      contents.ptr->refCount++;
+    }
+  }
+  
+  void dec() {
+    if (constantWidth == NotConstant &&
+        contents.ptr &&
+        --contents.ptr->refCount == 0) {
+      delete contents.ptr;
+    }
+  }  
+
+  friend class ExprVisitor;
+  friend class Cell;
+  friend class ObjectState;
+  friend class KModule;
+
+public:
+  template<class U> friend class ref;
+  template<class U> friend U* dyn_ref_cast(ref &src);
+  template<class U> friend const U* dyn_ref_cast(const ref &src);
+  template<class U> friend U* static_ref_cast(ref &src);
+  template<class U> friend const U* static_ref_cast(const ref &src);
+
+  // constructor from pointer
+  ref(T *p) : constantWidth(NotConstant) {
+    contents.ptr = p;
+    inc();
+  }
+
+  // construct from constant
+  ref(uint64_t val, Expr::Width w) : constantWidth(w) {
+    contents.val = val;
+  }
+  
+  // normal copy constructor
+  ref (const ref<T> &r)
+    : constantWidth(r.constantWidth), contents(r.contents) {
+    inc();
+  }
+  
+  // conversion constructor
+  template<class U>
+  ref (const ref<U> &r) {
+    constantWidth = r.constantWidth;
+    contents.val = r.contents.val;
+    inc();
+  }
+  
+  // pointer operations
+  T *get () {
+    // demand(constantWidth == NotConstant, "deref of constant");
+
+    // allocate 
+    if (constantWidth != NotConstant) {
+      contents.ptr = dynamic_cast<T*>(Expr::createConstant(contents.val, constantWidth));
+      assert(contents.ptr && "error with lazy constant initialization");
+      constantWidth = NotConstant;
+      
+      inc();
+    }
+    return contents.ptr;
+  }
+
+  T *get () const {
+    assert(constantWidth == NotConstant && "deref of constant");
+    return contents.ptr;
+  }
+
+  // method calls for the constant optimization
+  bool isConstant() const {
+    if (constantWidth != NotConstant) {
+      return true;
+    } else if (contents.ptr) {
+      return contents.ptr->getKind() == Expr::Constant;
+    } else {
+      return false; // should never happen, but nice check
+    }
+  }
+
+  uint64_t getConstantValue() const {
+    if (constantWidth) {
+      return contents.val;
+    } else {
+      return contents.ptr->getConstantValue();
+    }
+  }
+
+  unsigned hash() const {
+    if (constantWidth) {
+      return Expr::hashConstant(contents.val, constantWidth);
+    } else {
+      return contents.ptr->hash();
+    }
+  }
+
+  unsigned computeHash() const {
+    if (isConstant()) {
+      return Expr::hashConstant(contents.val, constantWidth);
+    } else {
+      return contents.ptr->computeHash();
+    }
+  }
+
+  void rehash() const {
+    if (!isConstant())
+      contents.ptr->computeHash();
+  }
+  
+  Expr::Width getWidth() const {
+    if (constantWidth != NotConstant)
+      return constantWidth;
+    return contents.ptr->getWidth();
+  }
+
+  Expr::Kind getKind() const {
+    if (constantWidth != NotConstant)
+      return Expr::Constant;
+    return contents.ptr->getKind();
+  }
+
+  unsigned getNumKids() const {
+    if (constantWidth != NotConstant)
+      return 0;
+    return contents.ptr->getNumKids();
+  }
+
+  ref<Expr> getKid(unsigned k) {
+    if (constantWidth != NotConstant)
+      return 0;
+    return contents.ptr->getKid(k);
+  }
+
+  ~ref () { dec (); }
+
+  /* The copy assignment operator must also explicitly be defined,
+   * despite a redundant template. */
+  ref<T> &operator= (const ref<T> &r) {
+    dec();
+    constantWidth = r.constantWidth;
+    contents.val = r.contents.val;
+    inc();
+    
+    return *this;
+  }
+  
+  template<class U> ref<T> &operator= (const ref<U> &r) {
+    dec();
+    constantWidth = r.constantWidth;
+    contents.val = r.contents.val;
+    inc();
+    
+    return *this;
+  }
+
+  bool isNull() const { return !constantWidth && !contents.ptr; }
+
+  // assumes non-null arguments
+  int compare(const ref &rhs) const {
+    Expr::Kind ak = getKind(), bk = rhs.getKind();
+    if (ak!=bk) 
+      return (ak < bk) ? -1 : 1;
+    if (ak==Expr::Constant) {
+      Expr::Width at = getWidth(), bt = rhs.getWidth();
+      if (at!=bt) 
+        return (at < bt) ? -1 : 1;
+      uint64_t av = getConstantValue(), bv = rhs.getConstantValue();
+      if (av<bv) {
+        return -1;
+      } else if (av>bv) {
+        return 1;
+      } else {
+        return 0;
+      }
+    } else {
+      return get()->compare(*rhs.get());
+    }
+  }
+
+  // assumes non-null arguments
+  bool operator<(const ref &rhs) const { return compare(rhs)<0; }
+  bool operator==(const ref &rhs) const { return compare(rhs)==0; }
+  bool operator!=(const ref &rhs) const { return compare(rhs)!=0; }
+};
+
+
+template<class T>
+inline std::ostream &operator<<(std::ostream &os, const ref<T> &e) {
+  if (e.isConstant()) {
+    os << e.getConstantValue();
+  } else {
+    os << *e.get();
+  }
+  return os;
+}
+
+template<class U>
+U* dyn_ref_cast(ref<Expr> &src) {
+  if (src.constantWidth != ref<Expr>::NotConstant)
+    return 0;
+    
+  return dynamic_cast<U*>(src.contents.ptr);
+}
+
+template<class U>
+const U* dyn_ref_cast(const ref<Expr> &src) {
+  if (src.constantWidth != ref<Expr>::NotConstant)
+    return 0;
+    
+  return dynamic_cast<const U*>(src.contents.ptr);
+}
+
+template<class U>
+U* static_ref_cast(ref<Expr> &src) {
+  return static_cast<U*>(src.contents.ptr);
+}
+
+template<class U>
+const U* static_ref_cast(const ref<Expr> &src) {
+  return static_cast<const U*>(src.contents.ptr);
+}
+
+#endif /* KLEE_REF_H */
diff --git a/lib/Basic/BOut.cpp b/lib/Basic/BOut.cpp
new file mode 100644
index 00000000..42d17e27
--- /dev/null
+++ b/lib/Basic/BOut.cpp
@@ -0,0 +1,236 @@
+//===-- BOut.c ------------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Internal/ADT/BOut.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#define BOUT_MAGIC "BOUT\n"
+#define BOUT_MAGIC_SIZE 5
+#define BOUT_VERSION 2
+
+/***/
+
+static int read_uint32(FILE *f, unsigned *value_out) {
+  unsigned char data[4];
+  if (fread(data, 4, 1, f)!=1)
+    return 0;
+  *value_out = (((((data[0]<<8) + data[1])<<8) + data[2])<<8) + data[3];
+  return 1;
+}
+
+static int write_uint32(FILE *f, unsigned value) {
+  unsigned char data[4];
+  data[0] = value>>24;
+  data[1] = value>>16;
+  data[2] = value>> 8;
+  data[3] = value>> 0;
+  return fwrite(data, 1, 4, f)==4;
+}
+
+static int read_string(FILE *f, char **value_out) {
+  unsigned len;
+  if (!read_uint32(f, &len))
+    return 0;
+  *value_out = (char*) malloc(len+1);
+  if (!*value_out)
+    return 0;
+  if (fread(*value_out, len, 1, f)!=1)
+    return 0;
+  (*value_out)[len] = 0;
+  return 1;
+}
+
+static int write_string(FILE *f, const char *value) {
+  unsigned len = strlen(value);
+  if (!write_uint32(f, len))
+    return 0;
+  if (fwrite(value, len, 1, f)!=1)
+    return 0;
+  return 1;
+}
+
+/***/
+
+
+unsigned bOut_getCurrentVersion() {
+  return BOUT_VERSION;
+}
+
+
+static int bOut_checkHeader(FILE *f) {
+  char header[BOUT_MAGIC_SIZE];
+  if (fread(header, BOUT_MAGIC_SIZE, 1, f)!=1)
+    return 0;
+  if (memcmp(header, BOUT_MAGIC, BOUT_MAGIC_SIZE))
+    return 0;
+  return 1;
+}
+
+int bOut_isBOutFile(const char *path) {
+  FILE *f = fopen(path, "rb");
+  int res;
+
+  if (!f)
+    return 0;
+  res = bOut_checkHeader(f);
+  fclose(f);
+  
+  return res;
+}
+
+BOut *bOut_fromFile(const char *path) {
+  FILE *f = fopen(path, "rb");
+  BOut *res = 0;
+  unsigned i, version;
+
+  if (!f) 
+    goto error;
+  if (!bOut_checkHeader(f)) 
+    goto error;
+
+  res = (BOut*) calloc(1, sizeof(*res));
+  if (!res) 
+    goto error;
+
+  if (!read_uint32(f, &version)) 
+    goto error;
+  
+  if (version > bOut_getCurrentVersion())
+    goto error;
+
+  res->version = version;
+
+  if (!read_uint32(f, &res->numArgs)) 
+    goto error;
+  res->args = (char**) calloc(res->numArgs, sizeof(*res->args));
+  if (!res->args) 
+    goto error;
+  
+  for (i=0; i<res->numArgs; i++)
+    if (!read_string(f, &res->args[i]))
+      goto error;
+
+  if (version >= 2) {
+    if (!read_uint32(f, &res->symArgvs)) 
+      goto error;
+    if (!read_uint32(f, &res->symArgvLen)) 
+      goto error;
+  }
+
+  if (!read_uint32(f, &res->numObjects))
+    goto error;
+  res->objects = (BOutObject*) calloc(res->numObjects, sizeof(*res->objects));
+  if (!res->objects)
+    goto error;
+  for (i=0; i<res->numObjects; i++) {
+    BOutObject *o = &res->objects[i];
+    if (!read_string(f, &o->name))
+      goto error;
+    if (!read_uint32(f, &o->numBytes))
+      goto error;
+    o->bytes = (unsigned char*) malloc(o->numBytes);
+    if (fread(o->bytes, o->numBytes, 1, f)!=1)
+      goto error;
+  }
+
+  fclose(f);
+
+  return res;
+ error:
+  if (res) {
+    if (res->args) {
+      for (i=0; i<res->numArgs; i++)
+        if (res->args[i])
+          free(res->args[i]);
+      free(res->args);
+    }
+    if (res->objects) {
+      for (i=0; i<res->numObjects; i++) {
+        BOutObject *bo = &res->objects[i];
+        if (bo->name)
+          free(bo->name);
+        if (bo->bytes)
+          free(bo->bytes);
+      }
+      free(res->objects);
+    }
+    free(res);
+  }
+
+  if (f) fclose(f);
+
+  return 0;
+}
+
+int bOut_toFile(BOut *bo, const char *path) {
+  FILE *f = fopen(path, "wb");
+  unsigned i;
+
+  if (!f) 
+    goto error;
+  if (fwrite(BOUT_MAGIC, strlen(BOUT_MAGIC), 1, f)!=1)
+    goto error;
+  if (!write_uint32(f, BOUT_VERSION))
+    goto error;
+      
+  if (!write_uint32(f, bo->numArgs))
+    goto error;
+  for (i=0; i<bo->numArgs; i++) {
+    if (!write_string(f, bo->args[i]))
+      goto error;
+  }
+
+  if (!write_uint32(f, bo->symArgvs))
+    goto error;
+  if (!write_uint32(f, bo->symArgvLen))
+    goto error;
+  
+  if (!write_uint32(f, bo->numObjects))
+    goto error;
+  for (i=0; i<bo->numObjects; i++) {
+    BOutObject *o = &bo->objects[i];
+    if (!write_string(f, o->name))
+      goto error;
+    if (!write_uint32(f, o->numBytes))
+      goto error;
+    if (fwrite(o->bytes, o->numBytes, 1, f)!=1)
+      goto error;
+  }
+
+  fclose(f);
+
+  return 1;
+ error:
+  if (f) fclose(f);
+  
+  return 0;
+}
+
+unsigned bOut_numBytes(BOut *bo) {
+  unsigned i, res = 0;
+  for (i=0; i<bo->numObjects; i++)
+    res += bo->objects[i].numBytes;
+  return res;
+}
+
+void bOut_free(BOut *bo) {
+  unsigned i;
+  for (i=0; i<bo->numArgs; i++)
+    free(bo->args[i]);
+  free(bo->args);
+  for (i=0; i<bo->numObjects; i++) {
+    free(bo->objects[i].name);
+    free(bo->objects[i].bytes);
+  }
+  free(bo->objects);
+  free(bo);
+}
diff --git a/lib/Basic/Makefile b/lib/Basic/Makefile
new file mode 100644
index 00000000..d4481e7f
--- /dev/null
+++ b/lib/Basic/Makefile
@@ -0,0 +1,16 @@
+#===-- lib/Basic/Makefile ----------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleeBasic
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Basic/README.txt b/lib/Basic/README.txt
new file mode 100644
index 00000000..b13df6bd
--- /dev/null
+++ b/lib/Basic/README.txt
@@ -0,0 +1,3 @@
+This directory holds the most basic support facilities provided for
+both the klee and kleaver libraries. The code in this directory should
+have no dependencies on LLVM or any other klee libraries.
diff --git a/lib/Basic/Statistics.cpp b/lib/Basic/Statistics.cpp
new file mode 100644
index 00000000..9c95a891
--- /dev/null
+++ b/lib/Basic/Statistics.cpp
@@ -0,0 +1,84 @@
+//===-- Statistics.cpp ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Statistics.h"
+
+#include <vector>
+
+using namespace klee;
+
+StatisticManager::StatisticManager()
+  : enabled(true),
+    globalStats(0),
+    indexedStats(0),
+    contextStats(0),
+    index(0) {
+}
+
+StatisticManager::~StatisticManager() {
+  if (globalStats) delete[] globalStats;
+  if (indexedStats) delete[] indexedStats;
+}
+
+void StatisticManager::useIndexedStats(unsigned totalIndices) {  
+  if (indexedStats) delete[] indexedStats;
+  indexedStats = new uint64_t[totalIndices * stats.size()];
+  memset(indexedStats, 0, sizeof(*indexedStats) * totalIndices * stats.size());
+}
+
+void StatisticManager::registerStatistic(Statistic &s) {
+  if (globalStats) delete[] globalStats;
+  s.id = stats.size();
+  stats.push_back(&s);
+  globalStats = new uint64_t[stats.size()];
+  memset(globalStats, 0, sizeof(*globalStats)*stats.size());
+}
+
+int StatisticManager::getStatisticID(const std::string &name) const {
+  for (unsigned i=0; i<stats.size(); i++)
+    if (stats[i]->getName() == name)
+      return i;
+  return -1;
+}
+
+Statistic *StatisticManager::getStatisticByName(const std::string &name) const {
+  for (unsigned i=0; i<stats.size(); i++)
+    if (stats[i]->getName() == name)
+      return stats[i];
+  return 0;
+}
+
+StatisticManager *klee::theStatisticManager = 0;
+
+static StatisticManager &getStatisticManager() {
+  static StatisticManager sm;
+  theStatisticManager = &sm;
+  return sm;
+}
+
+/* *** */
+
+Statistic::Statistic(const std::string &_name, 
+                     const std::string &_shortName) 
+  : name(_name), 
+    shortName(_shortName) {
+  getStatisticManager().registerStatistic(*this);
+}
+
+Statistic::~Statistic() {
+}
+
+Statistic &Statistic::operator +=(const uint64_t addend) {
+  theStatisticManager->incrementStatistic(*this, addend);
+  return *this;
+}
+
+uint64_t Statistic::getValue() const {
+  return theStatisticManager->getValue(*this);
+}
diff --git a/lib/Core/AddressSpace.cpp b/lib/Core/AddressSpace.cpp
new file mode 100644
index 00000000..fb032fd5
--- /dev/null
+++ b/lib/Core/AddressSpace.cpp
@@ -0,0 +1,334 @@
+//===-- AddressSpace.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AddressSpace.h"
+#include "CoreStats.h"
+#include "Memory.h"
+#include "TimingSolver.h"
+
+#include "klee/Expr.h"
+#include "klee/TimerStatIncrementer.h"
+
+using namespace klee;
+
+///
+
+void AddressSpace::bindObject(const MemoryObject *mo, ObjectState *os) {
+  assert(os->copyOnWriteOwner==0 && "object already has owner");
+  os->copyOnWriteOwner = cowKey;
+  objects = objects.replace(std::make_pair(mo, os));
+}
+
+void AddressSpace::unbindObject(const MemoryObject *mo) {
+  objects = objects.remove(mo);
+}
+
+const ObjectState *AddressSpace::findObject(const MemoryObject *mo) const {
+  const MemoryMap::value_type *res = objects.lookup(mo);
+  
+  return res ? res->second : 0;
+}
+
+ObjectState *AddressSpace::getWriteable(const MemoryObject *mo,
+                                        const ObjectState *os) {
+  assert(!os->readOnly);
+
+  if (cowKey==os->copyOnWriteOwner) {
+    return const_cast<ObjectState*>(os);
+  } else {
+    ObjectState *n = new ObjectState(*os);
+    n->copyOnWriteOwner = cowKey;
+    objects = objects.replace(std::make_pair(mo, n));
+    return n;    
+  }
+}
+
+/// 
+
+bool AddressSpace::resolveOne(uint64_t addr64, ObjectPair &result) {
+  unsigned address = (unsigned) addr64;
+  MemoryObject hack(address);
+
+  if (const MemoryMap::value_type *res = objects.lookup_previous(&hack)) {
+    const MemoryObject *mo = res->first;
+    if ((mo->size==0 && address==mo->address) ||
+        (address - mo->address < mo->size)) {
+      result = *res;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool AddressSpace::resolveOne(ExecutionState &state,
+                              TimingSolver *solver,
+                              ref<Expr> address,
+                              ObjectPair &result,
+                              bool &success) {
+  if (address.isConstant()) {
+    success = resolveOne(address.getConstantValue(), result);
+    return true;
+  } else {
+    TimerStatIncrementer timer(stats::resolveTime);
+
+    // try cheap search, will succeed for any inbounds pointer
+
+    ref<Expr> cex(0);
+    if (!solver->getValue(state, address, cex))
+      return false;
+    unsigned example = (unsigned) cex.getConstantValue();
+    MemoryObject hack(example);
+    const MemoryMap::value_type *res = objects.lookup_previous(&hack);
+    
+    if (res) {
+      const MemoryObject *mo = res->first;
+      if (example - mo->address < mo->size) {
+        result = *res;
+        success = true;
+        return true;
+      }
+    }
+
+    // didn't work, now we have to search
+       
+    MemoryMap::iterator oi = objects.upper_bound(&hack);
+    MemoryMap::iterator begin = objects.begin();
+    MemoryMap::iterator end = objects.end();
+      
+    MemoryMap::iterator start = oi;
+    while (oi!=begin) {
+      --oi;
+      const MemoryObject *mo = oi->first;
+        
+      bool mayBeTrue;
+      if (!solver->mayBeTrue(state, 
+                             mo->getBoundsCheckPointer(address), mayBeTrue))
+        return false;
+      if (mayBeTrue) {
+        result = *oi;
+        success = true;
+        return true;
+      } else {
+        bool mustBeTrue;
+        if (!solver->mustBeTrue(state, 
+                                UgeExpr::create(address, mo->getBaseExpr()),
+                                mustBeTrue))
+          return false;
+        if (mustBeTrue)
+          break;
+      }
+    }
+
+    // search forwards
+    for (oi=start; oi!=end; ++oi) {
+      const MemoryObject *mo = oi->first;
+
+      bool mustBeTrue;
+      if (!solver->mustBeTrue(state, 
+                              UltExpr::create(address, mo->getBaseExpr()),
+                              mustBeTrue))
+        return false;
+      if (mustBeTrue) {
+        break;
+      } else {
+        bool mayBeTrue;
+
+        if (!solver->mayBeTrue(state, 
+                               mo->getBoundsCheckPointer(address),
+                               mayBeTrue))
+          return false;
+        if (mayBeTrue) {
+          result = *oi;
+          success = true;
+          return true;
+        }
+      }
+    }
+
+    success = false;
+    return true;
+  }
+}
+
+bool AddressSpace::resolve(ExecutionState &state,
+                           TimingSolver *solver, 
+                           ref<Expr> p, 
+                           ResolutionList &rl, 
+                           unsigned maxResolutions,
+                           double timeout) {
+  if (p.isConstant()) {
+    ObjectPair res;
+    if (resolveOne(p.getConstantValue(), res))
+      rl.push_back(res);
+    return false;
+  } else {
+    TimerStatIncrementer timer(stats::resolveTime);
+    uint64_t timeout_us = (uint64_t) (timeout*1000000.);
+
+    // XXX in general this isn't exactly what we want... for
+    // a multiple resolution case (or for example, a \in {b,c,0})
+    // we want to find the first object, find a cex assuming
+    // not the first, find a cex assuming not the second...
+    // etc.
+    
+    // XXX how do we smartly amortize the cost of checking to
+    // see if we need to keep searching up/down, in bad cases?
+    // maybe we don't care?
+    
+    // XXX we really just need a smart place to start (although
+    // if its a known solution then the code below is guaranteed
+    // to hit the fast path with exactly 2 queries). we could also
+    // just get this by inspection of the expr.
+    
+    ref<Expr> cex(0);
+    if (!solver->getValue(state, p, cex))
+      return true;
+    unsigned example = (unsigned) cex.getConstantValue();
+    MemoryObject hack(example);
+    
+    MemoryMap::iterator oi = objects.upper_bound(&hack);
+    MemoryMap::iterator begin = objects.begin();
+    MemoryMap::iterator end = objects.end();
+      
+    MemoryMap::iterator start = oi;
+      
+    // XXX in the common case we can save one query if we ask
+    // mustBeTrue before mayBeTrue for the first result. easy
+    // to add I just want to have a nice symbolic test case first.
+      
+    // search backwards, start with one minus because this
+    // is the object that p *should* be within, which means we
+    // get write off the end with 4 queries (XXX can be better,
+    // no?)
+    while (oi!=begin) {
+      --oi;
+      const MemoryObject *mo = oi->first;
+      if (timeout_us && timeout_us < timer.check())
+        return true;
+
+      // XXX I think there is some query wasteage here?
+      ref<Expr> inBounds = mo->getBoundsCheckPointer(p);
+      bool mayBeTrue;
+      if (!solver->mayBeTrue(state, inBounds, mayBeTrue))
+        return true;
+      if (mayBeTrue) {
+        rl.push_back(*oi);
+        
+        // fast path check
+        unsigned size = rl.size();
+        if (size==1) {
+          bool mustBeTrue;
+          if (!solver->mustBeTrue(state, inBounds, mustBeTrue))
+            return true;
+          if (mustBeTrue)
+            return false;
+        } else if (size==maxResolutions) {
+          return true;
+        }
+      }
+        
+      bool mustBeTrue;
+      if (!solver->mustBeTrue(state, 
+                              UgeExpr::create(p, mo->getBaseExpr()),
+                              mustBeTrue))
+        return true;
+      if (mustBeTrue)
+        break;
+    }
+    // search forwards
+    for (oi=start; oi!=end; ++oi) {
+      const MemoryObject *mo = oi->first;
+      if (timeout_us && timeout_us < timer.check())
+        return true;
+
+      bool mustBeTrue;
+      if (!solver->mustBeTrue(state, 
+                              UltExpr::create(p, mo->getBaseExpr()),
+                              mustBeTrue))
+        return true;
+      if (mustBeTrue)
+        break;
+      
+      // XXX I think there is some query wasteage here?
+      ref<Expr> inBounds = mo->getBoundsCheckPointer(p);
+      bool mayBeTrue;
+      if (!solver->mayBeTrue(state, inBounds, mayBeTrue))
+        return true;
+      if (mayBeTrue) {
+        rl.push_back(*oi);
+        
+        // fast path check
+        unsigned size = rl.size();
+        if (size==1) {
+          bool mustBeTrue;
+          if (!solver->mustBeTrue(state, inBounds, mustBeTrue))
+            return true;
+          if (mustBeTrue)
+            return false;
+        } else if (size==maxResolutions) {
+          return true;
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
+// These two are pretty big hack so we can sort of pass memory back
+// and forth to externals. They work by abusing the concrete cache
+// store inside of the object states, which allows them to
+// transparently avoid screwing up symbolics (if the byte is symbolic
+// then its concrete cache byte isn't being used) but is just a hack.
+
+void AddressSpace::copyOutConcretes() {
+  for (MemoryMap::iterator it = objects.begin(), ie = objects.end(); 
+       it != ie; ++it) {
+    const MemoryObject *mo = it->first;
+
+    if (!mo->isUserSpecified) {
+      ObjectState *os = it->second;
+      uint8_t *address = (uint8_t*) (unsigned long) mo->address;
+
+      if (!os->readOnly)
+        memcpy(address, os->concreteStore, mo->size);
+    }
+  }
+}
+
+bool AddressSpace::copyInConcretes() {
+  for (MemoryMap::iterator it = objects.begin(), ie = objects.end(); 
+       it != ie; ++it) {
+    const MemoryObject *mo = it->first;
+
+    if (!mo->isUserSpecified) {
+      const ObjectState *os = it->second;
+      uint8_t *address = (uint8_t*) (unsigned long) mo->address;
+
+      if (memcmp(address, os->concreteStore, mo->size)!=0) {
+        if (os->readOnly) {
+          return false;
+        } else {
+          ObjectState *wos = getWriteable(mo, os);
+          memcpy(wos->concreteStore, address, mo->size);
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+/***/
+
+bool MemoryObjectLT::operator()(const MemoryObject *a, const MemoryObject *b) const {
+  return a->address < b->address;
+}
+
diff --git a/lib/Core/AddressSpace.h b/lib/Core/AddressSpace.h
new file mode 100644
index 00000000..a281714c
--- /dev/null
+++ b/lib/Core/AddressSpace.h
@@ -0,0 +1,131 @@
+//===-- AddressSpace.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_ADDRESSSPACE_H
+#define KLEE_ADDRESSSPACE_H
+
+#include "ObjectHolder.h"
+
+#include "klee/Expr.h"
+#include "klee/Internal/ADT/ImmutableMap.h"
+
+namespace klee {
+  class ExecutionState;
+  class MemoryObject;
+  class ObjectState;
+  class TimingSolver;
+
+  template<class T> class ref;
+
+  typedef std::pair<const MemoryObject*, const ObjectState*> ObjectPair;
+  typedef std::vector<ObjectPair> ResolutionList;  
+
+  /// Function object ordering MemoryObject's by address.
+  struct MemoryObjectLT {
+    bool operator()(const MemoryObject *a, const MemoryObject *b) const;
+  };
+  
+  typedef ImmutableMap<const MemoryObject*, ObjectHolder, MemoryObjectLT> MemoryMap;
+  
+  class AddressSpace {
+  private:
+    /// Epoch counter used to control ownership of objects.
+    mutable unsigned cowKey;
+
+    /// Unsupported, use copy constructor
+    AddressSpace &operator=(const AddressSpace&); 
+    
+  public:
+    /// The MemoryObject -> ObjectState map that constitutes the
+    /// address space.
+    ///
+    /// The set of objects where o->copyOnWriteOwner == cowKey are the
+    /// objects that we own.
+    ///
+    /// \invariant forall o in objects, o->copyOnWriteOwner <= cowKey
+    MemoryMap objects;
+    
+  public:
+    AddressSpace() : cowKey(1) {}
+    AddressSpace(const AddressSpace &b) : cowKey(++b.cowKey), objects(b.objects) { }
+    ~AddressSpace() {}
+
+    /// Resolve address to an ObjectPair in result.
+    /// \return true iff an object was found.
+    bool resolveOne(uint64_t address, 
+                    ObjectPair &result);
+
+    /// Resolve address to an ObjectPair in result.
+    ///
+    /// \param state The state this address space is part of.
+    /// \param solver A solver used to determine possible 
+    ///               locations of the \a address.
+    /// \param address The address to search for.
+    /// \param[out] result An ObjectPair this address can resolve to 
+    ///               (when returning true).
+    /// \return true iff an object was found at \a address.
+    bool resolveOne(ExecutionState &state, 
+                    TimingSolver *solver,
+                    ref<Expr> address,
+                    ObjectPair &result,
+                    bool &success);
+
+    /// Resolve address to a list of ObjectPairs it can point to. If
+    /// maxResolutions is non-zero then no more than that many pairs
+    /// will be returned. 
+    ///
+    /// \return true iff the resolution is incomplete (maxResolutions
+    /// is non-zero and the search terminated early, or a query timed out).
+    bool resolve(ExecutionState &state,
+                 TimingSolver *solver,
+                 ref<Expr> address, 
+                 ResolutionList &rl, 
+                 unsigned maxResolutions=0,
+                 double timeout=0.);
+
+    /***/
+
+    /// Add a binding to the address space.
+    void bindObject(const MemoryObject *mo, ObjectState *os);
+
+    /// Remove a binding from the address space.
+    void unbindObject(const MemoryObject *mo);
+
+    /// Lookup a binding from a MemoryObject.
+    const ObjectState *findObject(const MemoryObject *mo) const;
+
+    /// \brief Obtain an ObjectState suitable for writing.
+    ///
+    /// This returns a writeable object state, creating a new copy of
+    /// the given ObjectState if necessary. If the address space owns
+    /// the ObjectState then this routine effectively just strips the
+    /// const qualifier it.
+    ///
+    /// \param mo The MemoryObject to get a writeable ObjectState for.
+    /// \param os The current binding of the MemoryObject.
+    /// \return A writeable ObjectState (\a os or a copy).
+    ObjectState *getWriteable(const MemoryObject *mo, const ObjectState *os);
+
+    /// Copy the concrete values of all managed ObjectStates into the
+    /// actual system memory location they were allocated at.
+    void copyOutConcretes();
+
+    /// Copy the concrete values of all managed ObjectStates back from
+    /// the actual system memory location they were allocated
+    /// at. ObjectStates will only be written to (and thus,
+    /// potentially copied) if the memory values are different from
+    /// the current concrete values.
+    ///
+    /// \retval true The copy succeeded. 
+    /// \retval false The copy failed because a read-only object was modified.
+    bool copyInConcretes();
+  };
+} // End klee namespace
+
+#endif
diff --git a/lib/Core/CallPathManager.cpp b/lib/Core/CallPathManager.cpp
new file mode 100644
index 00000000..d0a61b31
--- /dev/null
+++ b/lib/Core/CallPathManager.cpp
@@ -0,0 +1,103 @@
+//===-- CallPathManager.cpp -----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CallPathManager.h"
+
+#include "klee/Statistics.h"
+
+#include <map>
+#include <vector>
+#include "llvm/Function.h"
+#include "llvm/Support/Streams.h"
+
+using namespace llvm;
+using namespace klee;
+
+///
+
+CallPathNode::CallPathNode(CallPathNode *_parent, 
+                           Instruction *_callSite,
+                           Function *_function)
+  : parent(_parent),
+    callSite(_callSite),
+    function(_function),
+    count(0) {
+}
+
+void CallPathNode::print() {
+  llvm::cerr << "  (Function: " << this->function->getName() << ", "
+	     << "Callsite: " << callSite << ", "
+	     << "Count: " << this->count << ")";
+  if (parent && parent->callSite) {
+    llvm::cerr << ";\n";
+    parent->print();
+  }
+  else llvm::cerr << "\n";
+}
+
+///
+
+CallPathManager::CallPathManager() : root(0, 0, 0) {
+}
+
+CallPathManager::~CallPathManager() {
+  for (std::vector<CallPathNode*>::iterator it = paths.begin(),
+         ie = paths.end(); it != ie; ++it)
+    delete *it;
+}
+
+void CallPathManager::getSummaryStatistics(CallSiteSummaryTable &results) {
+  results.clear();
+
+  for (std::vector<CallPathNode*>::iterator it = paths.begin(),
+         ie = paths.end(); it != ie; ++it)
+    (*it)->summaryStatistics = (*it)->statistics;
+
+  // compute summary bottom up, while building result table
+  for (std::vector<CallPathNode*>::reverse_iterator it = paths.rbegin(),
+         ie = paths.rend(); it != ie; ++it) {
+    CallPathNode *cp = *it;
+    cp->parent->summaryStatistics += cp->summaryStatistics;
+
+    CallSiteInfo &csi = results[cp->callSite][cp->function];
+    csi.count += cp->count;
+    csi.statistics += cp->summaryStatistics;
+  }
+}
+
+
+CallPathNode *CallPathManager::computeCallPath(CallPathNode *parent, 
+                                               Instruction *cs,
+                                               Function *f) {
+  for (CallPathNode *p=parent; p; p=p->parent)
+    if (cs==p->callSite && f==p->function)
+      return p;
+  
+  CallPathNode *cp = new CallPathNode(parent, cs, f);
+  paths.push_back(cp);
+  return cp;
+}
+
+CallPathNode *CallPathManager::getCallPath(CallPathNode *parent, 
+                                           Instruction *cs,
+                                           Function *f) {
+  std::pair<Instruction*,Function*> key(cs, f);
+  if (!parent)
+    parent = &root;
+  
+  CallPathNode::children_ty::iterator it = parent->children.find(key);
+  if (it==parent->children.end()) {
+    CallPathNode *cp = computeCallPath(parent, cs, f);
+    parent->children.insert(std::make_pair(key, cp));
+    return cp;
+  } else {
+    return it->second;
+  }
+}
+
diff --git a/lib/Core/CallPathManager.h b/lib/Core/CallPathManager.h
new file mode 100644
index 00000000..2e16d72b
--- /dev/null
+++ b/lib/Core/CallPathManager.h
@@ -0,0 +1,83 @@
+//===-- CallPathManager.h ---------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_CALLPATHMANAGER_H__
+#define __UTIL_CALLPATHMANAGER_H__
+
+#include "klee/Statistics.h"
+
+#include <map>
+#include <vector>
+
+namespace llvm {
+  class Instruction;
+  class Function;
+}
+
+namespace klee {
+  class StatisticRecord;
+
+  struct CallSiteInfo {
+    unsigned count;
+    StatisticRecord statistics;
+
+  public:
+    CallSiteInfo() : count(0) {}
+  };
+
+  typedef std::map<llvm::Instruction*,
+                   std::map<llvm::Function*, CallSiteInfo> > CallSiteSummaryTable;    
+  
+  class CallPathNode {
+    friend class CallPathManager;
+
+  public:
+    typedef std::map<std::pair<llvm::Instruction*, 
+                               llvm::Function*>, CallPathNode*> children_ty;
+
+    // form list of (callSite,function) path
+    CallPathNode *parent;
+    llvm::Instruction *callSite;
+    llvm::Function *function;
+    children_ty children;
+
+    StatisticRecord statistics;
+    StatisticRecord summaryStatistics;
+    unsigned count;
+
+  public:
+    CallPathNode(CallPathNode *parent, 
+                 llvm::Instruction *callSite,
+                 llvm::Function *function);
+
+    void print();
+  };
+
+  class CallPathManager {
+    CallPathNode root;
+    std::vector<CallPathNode*> paths;
+
+  private:
+    CallPathNode *computeCallPath(CallPathNode *parent, 
+                                  llvm::Instruction *callSite,
+                                  llvm::Function *f);
+    
+  public:
+    CallPathManager();
+    ~CallPathManager();
+
+    void getSummaryStatistics(CallSiteSummaryTable &result);
+    
+    CallPathNode *getCallPath(CallPathNode *parent, 
+                              llvm::Instruction *callSite,
+                              llvm::Function *f);
+  };
+}
+
+#endif
diff --git a/lib/Core/Common.cpp b/lib/Core/Common.cpp
new file mode 100644
index 00000000..479c4465
--- /dev/null
+++ b/lib/Core/Common.cpp
@@ -0,0 +1,110 @@
+//===-- Common.cpp --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+
+#include <set>
+
+using namespace klee;
+
+FILE* klee::klee_warning_file = NULL;
+FILE* klee::klee_message_file = NULL;
+
+
+/* Prints a message/warning.
+   
+   If pfx is NULL, this is a regular message, and it's sent to
+   klee_message_file (messages.txt).  Otherwise, it is sent to 
+   klee_warning_file (warnings.txt).
+
+   Iff onlyToFile is false, the message is also printed on stderr.
+*/
+static void klee_vmessage(const char *pfx, bool onlyToFile, const char *msg, va_list ap) {
+  FILE *f = stderr;
+  if (!onlyToFile) {
+    fprintf(f, "KLEE: ");
+    if (pfx) fprintf(f, "%s: ", pfx);
+    vfprintf(f, msg, ap);
+    fprintf(f, "\n");
+    fflush(f);
+  }
+
+  if (pfx == NULL)
+    f = klee_message_file;
+  else f = klee_warning_file;
+    
+  if (f) {
+    fprintf(f, "KLEE: ");
+    if (pfx) fprintf(f, "%s: ", pfx);
+    vfprintf(f, msg, ap);
+    fprintf(f, "\n");
+    fflush(f);
+  }
+}
+
+
+void klee::klee_message(const char *msg, ...) {
+  va_list ap;
+  va_start(ap, msg);
+  klee_vmessage(NULL, false, msg, ap);
+  va_end(ap);
+}
+
+/* Message to be written only to file */
+void klee::klee_message_to_file(const char *msg, ...) {
+  va_list ap;
+  va_start(ap, msg);
+  klee_vmessage(NULL, true, msg, ap);
+  va_end(ap);
+}
+
+void klee::klee_error(const char *msg, ...) {
+  va_list ap;
+  va_start(ap, msg);
+  klee_vmessage("ERROR", false, msg, ap);
+  va_end(ap);
+  exit(1);
+}
+
+void klee::klee_warning(const char *msg, ...) {
+  va_list ap;
+  va_start(ap, msg);
+  klee_vmessage("WARNING", false, msg, ap);
+  va_end(ap);
+}
+
+
+/* Prints a warning once per message. */
+void klee::klee_warning_once(const void *id, const char *msg, ...) {
+  static std::set< std::pair<const void*, const char*> > keys;
+  std::pair<const void*, const char*> key;
+
+
+  /* "calling external" messages contain the actual arguments with
+     which we called the external function, so we need to ignore them
+     when computing the key. */
+  if (strncmp(msg, "calling external", strlen("calling external")) != 0)
+    key = std::make_pair(id, msg);
+  else key = std::make_pair(id, "calling external");
+  
+  if (!keys.count(key)) {
+    keys.insert(key);
+    
+    va_list ap;
+    va_start(ap, msg);
+    klee_vmessage("WARNING", false, msg, ap);
+    va_end(ap);
+  }
+}
diff --git a/lib/Core/Common.h b/lib/Core/Common.h
new file mode 100644
index 00000000..ce05b536
--- /dev/null
+++ b/lib/Core/Common.h
@@ -0,0 +1,56 @@
+//===-- Common.h ------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __KLEE_COMMON_H__
+#define __KLEE_COMMON_H__
+
+#ifdef __CYGWIN__
+#ifndef WINDOWS
+#define WINDOWS
+#endif
+#endif
+
+#include <stdio.h>
+
+// XXX ugh
+namespace klee {
+  class Solver;
+
+  extern FILE* klee_warning_file;
+  extern FILE* klee_message_file;
+
+  /// Print "KLEE: ERROR" followed by the msg in printf format and a
+  /// newline on stderr and to warnings.txt, then exit with an error.
+  void klee_error(const char *msg, ...)
+    __attribute__ ((format (printf, 1, 2), noreturn));
+
+  /// Print "KLEE: " followed by the msg in printf format and a
+  /// newline on stderr and to messages.txt.
+  void klee_message(const char *msg, ...)
+    __attribute__ ((format (printf, 1, 2)));
+
+  /// Print "KLEE: " followed by the msg in printf format and a
+  /// newline to messages.txt.
+  void klee_message_to_file(const char *msg, ...)
+    __attribute__ ((format (printf, 1, 2)));
+
+  /// Print "KLEE: WARNING" followed by the msg in printf format and a
+  /// newline on stderr and to warnings.txt.
+  void klee_warning(const char *msg, ...)
+    __attribute__ ((format (printf, 1, 2)));
+
+  /// Print "KLEE: WARNING" followed by the msg in printf format and a
+  /// newline on stderr and to warnings.txt. However, the warning is only 
+  /// printed once for each unique (id, msg) pair (as pointers).
+  void klee_warning_once(const void *id,
+                         const char *msg, ...)
+    __attribute__ ((format (printf, 2, 3)));
+}
+
+#endif /* __KLEE_COMMON_H__ */
diff --git a/lib/Core/CoreStats.cpp b/lib/Core/CoreStats.cpp
new file mode 100644
index 00000000..ca2ef1c9
--- /dev/null
+++ b/lib/Core/CoreStats.cpp
@@ -0,0 +1,29 @@
+//===-- CoreStats.cpp -----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CoreStats.h"
+
+using namespace klee;
+
+Statistic stats::allocations("Allocations", "Alloc");
+Statistic stats::coveredInstructions("CoveredInstructions", "Icov");
+Statistic stats::falseBranches("FalseBranches", "Bf");
+Statistic stats::forkTime("ForkTime", "Ftime");
+Statistic stats::forks("Forks", "Forks");
+Statistic stats::instructionRealTime("InstructionRealTimes", "Ireal");
+Statistic stats::instructionTime("InstructionTimes", "Itime");
+Statistic stats::instructions("Instructions", "I");
+Statistic stats::minDistToReturn("MinDistToReturn", "Rdist");
+Statistic stats::minDistToUncovered("MinDistToUncovered", "UCdist");
+Statistic stats::reachableUncovered("ReachableUncovered", "IuncovReach");
+Statistic stats::resolveTime("ResolveTime", "Rtime");
+Statistic stats::solverTime("SolverTime", "Stime");
+Statistic stats::states("States", "States");
+Statistic stats::trueBranches("TrueBranches", "Bt");
+Statistic stats::uncoveredInstructions("UncoveredInstructions", "Iuncov");
diff --git a/lib/Core/CoreStats.h b/lib/Core/CoreStats.h
new file mode 100644
index 00000000..09845a89
--- /dev/null
+++ b/lib/Core/CoreStats.h
@@ -0,0 +1,53 @@
+//===-- CoreStats.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_CORESTATS_H
+#define KLEE_CORESTATS_H
+
+#include "klee/Statistic.h"
+
+namespace klee {
+namespace stats {
+
+  extern Statistic allocations;
+  extern Statistic resolveTime;
+  extern Statistic instructions;
+  extern Statistic instructionTime;
+  extern Statistic instructionRealTime;
+  extern Statistic coveredInstructions;
+  extern Statistic uncoveredInstructions;  
+  extern Statistic trueBranches;
+  extern Statistic falseBranches;
+  extern Statistic forkTime;
+  extern Statistic solverTime;
+
+  /// The number of process forks.
+  extern Statistic forks;
+
+  /// Number of states, this is a "fake" statistic used by istats, it
+  /// isn't normally up-to-date.
+  extern Statistic states;
+
+  /// Instruction level statistic for tracking number of reachable
+  /// uncovered instructions.
+  extern Statistic reachableUncovered;
+
+  /// Instruction level statistic tracking the minimum intraprocedural
+  /// distance to an uncovered instruction; this is only periodically
+  /// updated.
+  extern Statistic minDistToUncovered;
+
+  /// Instruction level statistic tracking the minimum intraprocedural
+  /// distance to a function return.
+  extern Statistic minDistToReturn;
+
+}
+}
+
+#endif
diff --git a/lib/Core/ExecutionState.cpp b/lib/Core/ExecutionState.cpp
new file mode 100644
index 00000000..dd6d4647
--- /dev/null
+++ b/lib/Core/ExecutionState.cpp
@@ -0,0 +1,417 @@
+//===-- ExecutionState.cpp ------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/ExecutionState.h"
+
+#include "klee/Internal/Module/Cell.h"
+#include "klee/Internal/Module/InstructionInfoTable.h"
+#include "klee/Internal/Module/KInstruction.h"
+#include "klee/Internal/Module/KModule.h"
+
+#include "klee/Expr.h"
+
+#include "Memory.h"
+
+#include "llvm/Function.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <iostream>
+#include <cassert>
+#include <map>
+#include <set>
+#include <stdarg.h>
+
+using namespace llvm;
+using namespace klee;
+
+namespace { 
+  cl::opt<bool>
+  DebugLogStateMerge("debug-log-state-merge");
+}
+
+/***/
+
+StackFrame::StackFrame(KInstIterator _caller, KFunction *_kf)
+  : caller(_caller), kf(_kf), callPathNode(0), 
+    minDistToUncoveredOnReturn(0), varargs(0) {
+  locals = new Cell[kf->numRegisters];
+}
+
+StackFrame::StackFrame(const StackFrame &s) 
+  : caller(s.caller),
+    kf(s.kf),
+    callPathNode(s.callPathNode),
+    allocas(s.allocas),
+    minDistToUncoveredOnReturn(s.minDistToUncoveredOnReturn),
+    varargs(s.varargs) {
+  locals = new Cell[s.kf->numRegisters];
+  for (unsigned i=0; i<s.kf->numRegisters; i++)
+    locals[i] = s.locals[i];
+}
+
+StackFrame::~StackFrame() { 
+  delete[] locals; 
+}
+
+/***/
+
+ExecutionState::ExecutionState(KFunction *kf) 
+  : fakeState(false),
+    underConstrained(false),
+    depth(0),
+    pc(kf->instructions),
+    prevPC(pc),
+    queryCost(0.), 
+    weight(1),
+    instsSinceCovNew(0),
+    coveredNew(false),
+    forkDisabled(false),
+    ptreeNode(0) {
+  pushFrame(0, kf);
+}
+
+ExecutionState::ExecutionState(const std::vector<ref<Expr> > &assumptions) 
+  : fakeState(true),
+    underConstrained(false),
+    constraints(assumptions),
+    queryCost(0.),
+    ptreeNode(0) {
+}
+
+ExecutionState::~ExecutionState() {
+  while (!stack.empty()) popFrame();
+}
+
+ExecutionState *ExecutionState::branch() {
+  depth++;
+
+  ExecutionState *falseState = new ExecutionState(*this);
+  falseState->coveredNew = false;
+  falseState->coveredLines.clear();
+
+  weight *= .5;
+  falseState->weight -= weight;
+
+  return falseState;
+}
+
+void ExecutionState::pushFrame(KInstIterator caller, KFunction *kf) {
+  stack.push_back(StackFrame(caller,kf));
+}
+
+void ExecutionState::popFrame() {
+  StackFrame &sf = stack.back();
+  for (std::vector<const MemoryObject*>::iterator it = sf.allocas.begin(), 
+         ie = sf.allocas.end(); it != ie; ++it)
+    addressSpace.unbindObject(*it);
+  stack.pop_back();
+}
+
+///
+
+std::string ExecutionState::getFnAlias(std::string fn) {
+  std::map < std::string, std::string >::iterator it = fnAliases.find(fn);
+  if (it != fnAliases.end())
+    return it->second;
+  else return "";
+}
+
+void ExecutionState::addFnAlias(std::string old_fn, std::string new_fn) {
+  fnAliases[old_fn] = new_fn;
+}
+
+void ExecutionState::removeFnAlias(std::string fn) {
+  fnAliases.erase(fn);
+}
+
+/**/
+
+std::ostream &klee::operator<<(std::ostream &os, const MemoryMap &mm) {
+  os << "{";
+  MemoryMap::iterator it = mm.begin();
+  MemoryMap::iterator ie = mm.end();
+  if (it!=ie) {
+    os << "MO" << it->first->id << ":" << it->second;
+    for (++it; it!=ie; ++it)
+      os << ", MO" << it->first->id << ":" << it->second;
+  }
+  os << "}";
+  return os;
+}
+
+bool ExecutionState::merge(const ExecutionState &b) {
+  if (DebugLogStateMerge)
+    llvm::cerr << "-- attempting merge of A:" 
+               << this << " with B:" << &b << "--\n";
+  if (pc != b.pc)
+    return false;
+
+  // XXX is it even possible for these to differ? does it matter? probably
+  // implies difference in object states?
+  if (symbolics!=b.symbolics)
+    return false;
+
+  {
+    std::vector<StackFrame>::const_iterator itA = stack.begin();
+    std::vector<StackFrame>::const_iterator itB = b.stack.begin();
+    while (itA!=stack.end() && itB!=b.stack.end()) {
+      // XXX vaargs?
+      if (itA->caller!=itB->caller || itA->kf!=itB->kf)
+        return false;
+      ++itA;
+      ++itB;
+    }
+    if (itA!=stack.end() || itB!=b.stack.end())
+      return false;
+  }
+
+  std::set< ref<Expr> > aConstraints(constraints.begin(), constraints.end());
+  std::set< ref<Expr> > bConstraints(b.constraints.begin(), 
+                                     b.constraints.end());
+  std::set< ref<Expr> > commonConstraints, aSuffix, bSuffix;
+  std::set_intersection(aConstraints.begin(), aConstraints.end(),
+                        bConstraints.begin(), bConstraints.end(),
+                        std::inserter(commonConstraints, commonConstraints.begin()));
+  std::set_difference(aConstraints.begin(), aConstraints.end(),
+                      commonConstraints.begin(), commonConstraints.end(),
+                      std::inserter(aSuffix, aSuffix.end()));
+  std::set_difference(bConstraints.begin(), bConstraints.end(),
+                      commonConstraints.begin(), commonConstraints.end(),
+                      std::inserter(bSuffix, bSuffix.end()));
+  if (DebugLogStateMerge) {
+    llvm::cerr << "\tconstraint prefix: [";
+    for (std::set< ref<Expr> >::iterator it = commonConstraints.begin(), 
+           ie = commonConstraints.end(); it != ie; ++it)
+      llvm::cerr << *it << ", ";
+    llvm::cerr << "]\n";
+    llvm::cerr << "\tA suffix: [";
+    for (std::set< ref<Expr> >::iterator it = aSuffix.begin(), 
+           ie = aSuffix.end(); it != ie; ++it)
+      llvm::cerr << *it << ", ";
+    llvm::cerr << "]\n";
+    llvm::cerr << "\tB suffix: [";
+    for (std::set< ref<Expr> >::iterator it = bSuffix.begin(), 
+           ie = bSuffix.end(); it != ie; ++it)
+      llvm::cerr << *it << ", ";
+    llvm::cerr << "]\n";
+  }
+
+  // We cannot merge if addresses would resolve differently in the
+  // states. This means:
+  // 
+  // 1. Any objects created since the branch in either object must
+  // have been free'd.
+  //
+  // 2. We cannot have free'd any pre-existing object in one state
+  // and not the other
+
+  if (DebugLogStateMerge) {
+    llvm::cerr << "\tchecking object states\n";
+    llvm::cerr << "A: " << addressSpace.objects << "\n";
+    llvm::cerr << "B: " << b.addressSpace.objects << "\n";
+  }
+    
+  std::set<const MemoryObject*> mutated;
+  MemoryMap::iterator ai = addressSpace.objects.begin();
+  MemoryMap::iterator bi = b.addressSpace.objects.begin();
+  MemoryMap::iterator ae = addressSpace.objects.end();
+  MemoryMap::iterator be = b.addressSpace.objects.end();
+  for (; ai!=ae && bi!=be; ++ai, ++bi) {
+    if (ai->first != bi->first) {
+      if (DebugLogStateMerge) {
+        if (ai->first < bi->first) {
+          llvm::cerr << "\t\tB misses binding for: " << ai->first->id << "\n";
+        } else {
+          llvm::cerr << "\t\tA misses binding for: " << bi->first->id << "\n";
+        }
+      }
+      return false;
+    }
+    if (ai->second != bi->second) {
+      if (DebugLogStateMerge)
+        llvm::cerr << "\t\tmutated: " << ai->first->id << "\n";
+      mutated.insert(ai->first);
+    }
+  }
+  if (ai!=ae || bi!=be) {
+    if (DebugLogStateMerge)
+      llvm::cerr << "\t\tmappings differ\n";
+    return false;
+  }
+  
+  // merge stack
+
+  ref<Expr> inA(1, Expr::Bool), inB(1, Expr::Bool);
+  for (std::set< ref<Expr> >::iterator it = aSuffix.begin(), 
+         ie = aSuffix.end(); it != ie; ++it)
+    inA = AndExpr::create(inA, *it);
+  for (std::set< ref<Expr> >::iterator it = bSuffix.begin(), 
+         ie = bSuffix.end(); it != ie; ++it)
+    inB = AndExpr::create(inB, *it);
+
+  // XXX should we have a preference as to which predicate to use?
+  // it seems like it can make a difference, even though logically
+  // they must contradict each other and so inA => !inB
+
+  std::vector<StackFrame>::iterator itA = stack.begin();
+  std::vector<StackFrame>::const_iterator itB = b.stack.begin();
+  for (; itA!=stack.end(); ++itA, ++itB) {
+    StackFrame &af = *itA;
+    const StackFrame &bf = *itB;
+    for (unsigned i=0; i<af.kf->numRegisters; i++) {
+      ref<Expr> &av = af.locals[i].value;
+      const ref<Expr> &bv = bf.locals[i].value;
+      if (av.isNull() || bv.isNull()) {
+        // if one is null then by implication (we are at same pc)
+        // we cannot reuse this local, so just ignore
+      } else {
+        av = SelectExpr::create(inA, av, bv);
+      }
+    }
+  }
+
+  for (std::set<const MemoryObject*>::iterator it = mutated.begin(), 
+         ie = mutated.end(); it != ie; ++it) {
+    const MemoryObject *mo = *it;
+    const ObjectState *os = addressSpace.findObject(mo);
+    const ObjectState *otherOS = b.addressSpace.findObject(mo);
+    assert(os && !os->readOnly && 
+           "objects mutated but not writable in merging state");
+    assert(otherOS);
+
+    ObjectState *wos = addressSpace.getWriteable(mo, os);
+    for (unsigned i=0; i<mo->size; i++) {
+      ref<Expr> av = wos->read8(i);
+      ref<Expr> bv = otherOS->read8(i);
+      wos->write(i, SelectExpr::create(inA, av, bv));
+    }
+  }
+
+  constraints = ConstraintManager();
+  for (std::set< ref<Expr> >::iterator it = commonConstraints.begin(), 
+         ie = commonConstraints.end(); it != ie; ++it)
+    constraints.addConstraint(*it);
+  constraints.addConstraint(OrExpr::create(inA, inB));
+
+  return true;
+}
+
+/**/
+
+/*
+   Used for tainting: create a clone of os that we can revirt to with
+   the behavior that all constraints are preserved, but writes are 
+   discarded.  When we revirt it will be at the same address.
+ */
+ObjectState *ExecutionState::cloneObject(ObjectState *os, 
+                                         MemoryObject *mo) {
+  MemoryMap::iterator it = shadowObjects.find(mo);
+  if (it != shadowObjects.end())
+    assert(0 && "Cannot exist already!");
+
+  llvm::cerr << "DRE: Inserting a cloned object: " << mo << "\n";
+  shadowObjects = shadowObjects.replace(std::make_pair(mo, os));
+  os = new ObjectState(*os);
+  addressSpace.bindObject(mo, os);
+  return os;
+}
+
+/***/
+
+
+ExecutionTraceEvent::ExecutionTraceEvent(ExecutionState& state, 
+                                         KInstruction* ki)
+  : consecutiveCount(1) 
+{
+  file = ki->info->file;
+  line = ki->info->line;
+  funcName = state.stack.back().kf->function->getName();
+  stackDepth = state.stack.size();
+}
+
+bool ExecutionTraceEvent::ignoreMe() const {
+  // ignore all events occurring in certain pesky uclibc files:
+  if (file.find("libc/stdio/") != std::string::npos) {
+    return true;
+  }
+
+  return false;
+}
+
+void ExecutionTraceEvent::print(std::ostream &os) const {
+  os.width(stackDepth);
+  os << ' ';
+  printDetails(os);
+  os << ' ' << file << ':' << line << ':' << funcName;
+  if (consecutiveCount > 1)
+    os << " (" << consecutiveCount << "x)\n";
+  else
+    os << '\n';
+}
+
+
+bool ExecutionTraceEventEquals(ExecutionTraceEvent* e1, ExecutionTraceEvent* e2) {
+  // first see if their base class members are identical:
+  if (!((e1->file == e2->file) &&
+        (e1->line == e2->line) &&
+        (e1->funcName == e2->funcName)))
+    return false;
+
+  // fairly ugly, but i'm no OOP master, so this is the way i'm
+  // doing it for now ... lemme know if there's a cleaner way:
+  BranchTraceEvent* be1 = dynamic_cast<BranchTraceEvent*>(e1);
+  BranchTraceEvent* be2 = dynamic_cast<BranchTraceEvent*>(e2);
+  if (be1 && be2) {
+    return ((be1->trueTaken == be2->trueTaken) &&
+            (be1->canForkGoBothWays == be2->canForkGoBothWays));
+  }
+
+  // don't tolerate duplicates in anything else:
+  return false;
+}
+
+
+void BranchTraceEvent::printDetails(std::ostream &os) const {
+  os << "BRANCH " << (trueTaken ? "T" : "F") << ' ' <<
+        (canForkGoBothWays ? "2-way" : "1-way");
+}
+
+void ExecutionTraceManager::addEvent(ExecutionTraceEvent* evt) {
+  // don't trace anything before __user_main, except for global events
+  if (!hasSeenUserMain) {
+    if (evt->funcName == "__user_main") {
+      hasSeenUserMain = true;
+    }
+    else if (evt->funcName != "global_def") {
+      return;
+    }
+  }
+
+  // custom ignore events:
+  if (evt->ignoreMe())
+    return;
+
+  if (events.size() > 0) {
+    // compress consecutive duplicates:
+    ExecutionTraceEvent* last = events.back();
+    if (ExecutionTraceEventEquals(last, evt)) {
+      last->consecutiveCount++;
+      return;
+    }
+  }
+
+  events.push_back(evt);
+}
+
+void ExecutionTraceManager::printAllEvents(std::ostream &os) const {
+  for (unsigned i = 0; i != events.size(); ++i)
+    events[i]->print(os);
+}
+
+/***/
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
new file mode 100644
index 00000000..d3409908
--- /dev/null
+++ b/lib/Core/Executor.cpp
@@ -0,0 +1,3260 @@
+//===-- Executor.cpp ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "Executor.h"
+ 
+#include "CoreStats.h"
+#include "ExternalDispatcher.h"
+#include "ImpliedValue.h"
+#include "Memory.h"
+#include "MemoryManager.h"
+#include "PTree.h"
+#include "Searcher.h"
+#include "SeedInfo.h"
+#include "SpecialFunctionHandler.h"
+#include "StatsTracker.h"
+#include "TimingSolver.h"
+#include "UserSearcher.h"
+#include "../Solver/SolverStats.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Expr.h"
+#include "klee/Interpreter.h"
+#include "klee/Machine.h"
+#include "klee/TimerStatIncrementer.h"
+#include "klee/util/Assignment.h"
+#include "klee/util/ExprPPrinter.h"
+#include "klee/util/ExprUtil.h"
+#include "klee/Config/config.h"
+#include "klee/Internal/ADT/BOut.h"
+#include "klee/Internal/ADT/RNG.h"
+#include "klee/Internal/Module/Cell.h"
+#include "klee/Internal/Module/InstructionInfoTable.h"
+#include "klee/Internal/Module/KInstruction.h"
+#include "klee/Internal/Module/KModule.h"
+#include "klee/Internal/Support/FloatEvaluation.h"
+#include "klee/Internal/System/Time.h"
+
+#include "llvm/Attributes.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/System/Process.h"
+#include "llvm/Target/TargetData.h"
+
+#include <cassert>
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <string>
+
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <cxxabi.h>
+
+using namespace llvm;
+using namespace klee;
+
+// omg really hard to share cl opts across files ...
+bool WriteTraces = false;
+
+namespace {
+  cl::opt<bool>
+  DumpStatesOnHalt("dump-states-on-halt",
+                   cl::init(true));
+ 
+  cl::opt<bool>
+  NoPreferCex("no-prefer-cex",
+              cl::init(false));
+ 
+  cl::opt<bool>
+  UseAsmAddresses("use-asm-addresses",
+                  cl::init(false));
+ 
+  cl::opt<bool>
+  RandomizeFork("randomize-fork",
+                cl::init(false));
+ 
+  cl::opt<bool>
+  AllowExternalSymCalls("allow-external-sym-calls",
+                        cl::init(false));
+
+  cl::opt<bool>
+  DebugPrintInstructions("debug-print-instructions", 
+                         cl::desc("Print instructions during execution."));
+
+  cl::opt<bool>
+  DebugCheckForImpliedValues("debug-check-for-implied-values");
+
+
+  cl::opt<bool>
+  SimplifySymIndices("simplify-sym-indices",
+                     cl::init(false));
+
+  cl::opt<unsigned>
+  MaxSymArraySize("max-sym-array-size",
+                  cl::init(0));
+
+  cl::opt<bool>
+  DebugValidateSolver("debug-validate-solver",
+		      cl::init(false));
+
+  cl::opt<bool>
+  SuppressExternalWarnings("suppress-external-warnings");
+
+  cl::opt<bool>
+  AllExternalWarnings("all-external-warnings");
+
+  cl::opt<bool>
+  OnlyOutputStatesCoveringNew("only-output-states-covering-new",
+                              cl::init(false));
+
+  cl::opt<bool>
+  AlwaysOutputSeeds("always-output-seeds",
+                              cl::init(true));
+
+  cl::opt<bool>
+  UseFastCexSolver("use-fast-cex-solver",
+		   cl::init(false));
+
+  cl::opt<bool>
+  UseIndependentSolver("use-independent-solver",
+                       cl::init(true),
+		       cl::desc("Use constraint independence"));
+
+  cl::opt<bool>
+  EmitAllErrors("emit-all-errors",
+                cl::init(false),
+                cl::desc("Generate tests cases for all errors "
+                         "(default=one per (error,instruction) pair)"));
+
+  cl::opt<bool>
+  UseCexCache("use-cex-cache",
+              cl::init(true),
+	      cl::desc("Use counterexample caching"));
+
+  cl::opt<bool>
+  UseQueryLog("use-query-log",
+              cl::init(false));
+
+  cl::opt<bool>
+  UseQueryPCLog("use-query-pc-log",
+                cl::init(false));
+  
+  cl::opt<bool>
+  UseSTPQueryPCLog("use-stp-query-pc-log",
+                   cl::init(false));
+
+  cl::opt<bool>
+  NoExternals("no-externals", 
+           cl::desc("Do not allow external functin calls"));
+
+  cl::opt<bool>
+  UseCache("use-cache",
+	   cl::init(true),
+	   cl::desc("Use validity caching"));
+
+  cl::opt<bool>
+  OnlyReplaySeeds("only-replay-seeds", 
+                  cl::desc("Discard states that do not have a seed."));
+ 
+  cl::opt<bool>
+  OnlySeed("only-seed", 
+           cl::desc("Stop execution after seeding is done without doing regular search."));
+ 
+  cl::opt<bool>
+  AllowSeedExtension("allow-seed-extension", 
+                     cl::desc("Allow extra (unbound) values to become symbolic during seeding."));
+ 
+  cl::opt<bool>
+  ZeroSeedExtension("zero-seed-extension");
+ 
+  cl::opt<bool>
+  AllowSeedTruncation("allow-seed-truncation", 
+                      cl::desc("Allow smaller buffers than in seeds."));
+ 
+  cl::opt<bool>
+  NamedSeedMatching("named-seed-matching",
+                    cl::desc("Use names to match symbolic objects to inputs."));
+
+  cl::opt<double>
+  MaxStaticForkPct("max-static-fork-pct", cl::init(1.));
+  cl::opt<double>
+  MaxStaticSolvePct("max-static-solve-pct", cl::init(1.));
+  cl::opt<double>
+  MaxStaticCPForkPct("max-static-cpfork-pct", cl::init(1.));
+  cl::opt<double>
+  MaxStaticCPSolvePct("max-static-cpsolve-pct", cl::init(1.));
+
+  cl::opt<double>
+  MaxInstructionTime("max-instruction-time",
+                     cl::desc("Only allow a single instruction to take this much time (default=0 (off))"),
+                     cl::init(0));
+  
+  cl::opt<double>
+  SeedTime("seed-time",
+           cl::desc("Amount of time to dedicate to seeds, before normal search (default=0 (off))"),
+           cl::init(0));
+  
+  cl::opt<double>
+  MaxSTPTime("max-stp-time",
+             cl::desc("Maximum amount of time for a single query (default=120s)"),
+             cl::init(120.0));
+  
+  cl::opt<unsigned int>
+  StopAfterNInstructions("stop-after-n-instructions",
+                         cl::desc("Stop execution after specified number of instructions (0=off)"),
+                         cl::init(0));
+  
+  cl::opt<unsigned>
+  MaxForks("max-forks",
+           cl::desc("Only fork this many times (-1=off)"),
+           cl::init(~0u));
+  
+  cl::opt<unsigned>
+  MaxDepth("max-depth",
+           cl::desc("Only allow this many symbolic branches (0=off)"),
+           cl::init(0));
+  
+  cl::opt<unsigned>
+  MaxMemory("max-memory",
+            cl::desc("Refuse to fork when more above this about of memory (in MB, 0=off)"),
+            cl::init(0));
+
+  cl::opt<bool>
+  MaxMemoryInhibit("max-memory-inhibit",
+            cl::desc("Inhibit forking at memory cap (vs. random terminat)"),
+            cl::init(true));
+
+  // use 'external storage' because also needed by tools/klee/main.cpp
+  cl::opt<bool, true>
+  WriteTracesProxy("write-traces", 
+           cl::desc("Write .trace file for each terminated state"),
+           cl::location(WriteTraces),
+           cl::init(false));
+
+  cl::opt<bool>
+  UseForkedSTP("use-forked-stp", 
+                 cl::desc("Run STP in forked process"));
+}
+
+
+static void *theMMap = 0;
+static unsigned theMMapSize = 0;
+
+namespace klee {
+  RNG theRNG;
+}
+
+Solver *constructSolverChain(STPSolver *stpSolver,
+                             std::string queryLogPath,
+                             std::string stpQueryLogPath,
+                             std::string queryPCLogPath,
+                             std::string stpQueryPCLogPath) {
+  Solver *solver = stpSolver;
+
+  if (UseSTPQueryPCLog)
+    solver = createPCLoggingSolver(solver, 
+                                   stpQueryLogPath);
+
+  if (UseFastCexSolver)
+    solver = createFastCexSolver(solver);
+
+  if (UseCexCache)
+    solver = createCexCachingSolver(solver);
+
+  if (UseCache)
+    solver = createCachingSolver(solver);
+
+  if (UseIndependentSolver)
+    solver = createIndependentSolver(solver);
+
+  if (DebugValidateSolver)
+    solver = createValidatingSolver(solver, stpSolver);
+
+  if (UseQueryPCLog)
+    solver = createPCLoggingSolver(solver, 
+                                   queryPCLogPath);
+  
+  return solver;
+}
+
+Executor::Executor(const InterpreterOptions &opts,
+                   InterpreterHandler *ih) 
+  : Interpreter(opts),
+    kmodule(0),
+    interpreterHandler(ih),
+    searcher(0),
+    externalDispatcher(new ExternalDispatcher()),
+    statsTracker(0),
+    pathWriter(0),
+    symPathWriter(0),
+    specialFunctionHandler(0),
+    processTree(0),
+    replayOut(0),
+    replayPath(0),    
+    usingSeeds(0),
+    atMemoryLimit(false),
+    inhibitForking(false),
+    haltExecution(false),
+    ivcEnabled(false),
+    stpTimeout(std::min(MaxSTPTime,MaxInstructionTime)) {
+  STPSolver *stpSolver = new STPSolver(UseForkedSTP);
+  Solver *solver = 
+    constructSolverChain(stpSolver,
+                         interpreterHandler->getOutputFilename("queries.qlog"),
+                         interpreterHandler->getOutputFilename("stp-queries.qlog"),
+                         interpreterHandler->getOutputFilename("queries.pc"),
+                         interpreterHandler->getOutputFilename("stp-queries.pc"));
+  
+  this->solver = new TimingSolver(solver, stpSolver);
+
+  memory = new MemoryManager();
+}
+
+
+const Module *Executor::setModule(llvm::Module *module, 
+                                  const ModuleOptions &opts) {
+  assert(!kmodule && module && "can only register one module"); // XXX gross
+
+  kmodule = new KModule(module);
+
+  specialFunctionHandler = new SpecialFunctionHandler(*this);
+
+  specialFunctionHandler->prepare();
+  kmodule->prepare(opts, interpreterHandler);
+  specialFunctionHandler->bind();
+
+  if (StatsTracker::useStatistics()) {
+    statsTracker = 
+      new StatsTracker(*this,
+                       interpreterHandler->getOutputFilename("assembly.ll"),
+                       userSearcherRequiresMD2U());
+  }
+  
+  return module;
+}
+
+Executor::~Executor() {
+  delete memory;
+  delete externalDispatcher;
+  if (processTree)
+    delete processTree;
+  if (specialFunctionHandler)
+    delete specialFunctionHandler;
+  if (statsTracker)
+    delete statsTracker;
+  delete solver;
+  delete kmodule;
+}
+
+/***/
+
+void Executor::initializeGlobalObject(ExecutionState &state, ObjectState *os,
+                                      Constant *c, 
+                                      unsigned offset) {
+  TargetData *targetData = kmodule->targetData;
+  if (ConstantVector *cp = dyn_cast<ConstantVector>(c)) {
+    unsigned elementSize =
+      targetData->getTypeStoreSize(cp->getType()->getElementType());
+    for (unsigned i=0, e=cp->getNumOperands(); i != e; ++i)
+      initializeGlobalObject(state, os, cp->getOperand(i), 
+			     offset + i*elementSize);
+  } else if (isa<ConstantAggregateZero>(c)) {
+    unsigned i, size = targetData->getTypeStoreSize(c->getType());
+    for (i=0; i<size; i++)
+      os->write8(offset+i, (uint8_t) 0);
+  } else if (ConstantArray *ca = dyn_cast<ConstantArray>(c)) {
+    unsigned elementSize =
+      targetData->getTypeStoreSize(ca->getType()->getElementType());
+    for (unsigned i=0, e=ca->getNumOperands(); i != e; ++i)
+      initializeGlobalObject(state, os, ca->getOperand(i), 
+			     offset + i*elementSize);
+  } else if (ConstantStruct *cs = dyn_cast<ConstantStruct>(c)) {
+    const StructLayout *sl =
+      targetData->getStructLayout(cast<StructType>(cs->getType()));
+    for (unsigned i=0, e=cs->getNumOperands(); i != e; ++i)
+      initializeGlobalObject(state, os, cs->getOperand(i), 
+			     offset + sl->getElementOffset(i));
+  } else {
+    os->write(offset, evalConstant(c));
+  }
+}
+
+MemoryObject * Executor::addExternalObject(ExecutionState &state, 
+                                           void *addr, unsigned size, 
+                                           bool isReadOnly) {
+  MemoryObject *mo = memory->allocateFixed((uint64_t) (unsigned long) addr, 
+                                           size, 0);
+  ObjectState *os = bindObjectInState(state, mo, false);
+  for(unsigned i = 0; i < size; i++)
+    os->write8(i, ((uint8_t*)addr)[i]);
+  if(isReadOnly)
+    os->setReadOnly(true);  
+  return mo;
+}
+
+void Executor::initializeGlobals(ExecutionState &state) {
+  Module *m = kmodule->module;
+
+  if (m->getModuleInlineAsm() != "")
+    klee_warning("executable has module level assembly (ignoring)");
+
+  assert(m->lib_begin() == m->lib_end() &&
+         "XXX do not support dependent libraries");
+
+  // represent function globals using the address of the actual llvm function
+  // object. given that we use malloc to allocate memory in states this also
+  // ensures that we won't conflict. we don't need to allocate a memory object
+  // since reading/writing via a function pointer is unsupported anyway.
+  for (Module::iterator i = m->begin(), ie = m->end(); i != ie; ++i) {
+    Function *f = i;
+    ref<Expr> addr(0);
+
+    // If the symbol has external weak linkage then it is implicitly
+    // not defined in this module; if it isn't resolvable then it
+    // should be null.
+    if (f->hasExternalWeakLinkage() && 
+        !externalDispatcher->resolveSymbol(f->getName())) {
+      addr = Expr::createPointer(0);
+    } else {
+      addr = Expr::createPointer((unsigned long) (void*) f);
+      legalFunctions.insert(f);
+    }
+    
+    globalAddresses.insert(std::make_pair(f, addr));
+  }
+
+  // Disabled, we don't want to promote use of live externals.
+#ifdef HAVE_CTYPE_EXTERNALS
+#ifndef WINDOWS
+#ifndef DARWIN
+  /* From /usr/include/errno.h: it [errno] is a per-thread variable. */
+  int *errno_addr = __errno_location();
+  addExternalObject(state, (void *)errno_addr, sizeof *errno_addr, false);
+
+  /* from /usr/include/ctype.h:
+       These point into arrays of 384, so they can be indexed by any `unsigned
+       char' value [0,255]; by EOF (-1); or by any `signed char' value
+       [-128,-1).  ISO C requires that the ctype functions work for `unsigned */
+  const uint16_t **addr = __ctype_b_loc();
+  addExternalObject(state, (void *)(*addr-128), 
+                    384 * sizeof **addr, true);
+  addExternalObject(state, addr, 4, true);
+    
+  const int32_t **lower_addr = __ctype_tolower_loc();
+  addExternalObject(state, (void *)(*lower_addr-128), 
+                    384 * sizeof **lower_addr, true);
+  addExternalObject(state, lower_addr, 4, true);
+  
+  const int32_t **upper_addr = __ctype_toupper_loc();
+  addExternalObject(state, (void *)(*upper_addr-128), 
+                    384 * sizeof **upper_addr, true);
+  addExternalObject(state, upper_addr, 4, true);
+#endif
+#endif
+#endif
+
+  // allocate and initialize globals, done in two passes since we may
+  // need address of a global in order to initialize some other one.
+
+  // allocate memory objects for all globals
+  for (Module::const_global_iterator i = m->global_begin(),
+         e = m->global_end();
+       i != e; ++i) {
+    if (i->isDeclaration()) {
+      // FIXME: We have no general way of handling unknown external
+      // symbols. If we really cared about making external stuff work
+      // better we could support user definition, or use the EXE style
+      // hack where we check the object file information.
+
+      const Type *ty = i->getType()->getElementType();
+      const std::string &name = i->getName();
+      uint64_t size = kmodule->targetData->getTypeStoreSize(ty);
+
+      // XXX - DWD - hardcode some things until we decide how to fix.
+#ifndef WINDOWS
+      if (name == "_ZTVN10__cxxabiv117__class_type_infoE") {
+        size = 0x2C;
+      } else if (name == "_ZTVN10__cxxabiv120__si_class_type_infoE") {
+        size = 0x2C;
+      } else if (name == "_ZTVN10__cxxabiv121__vmi_class_type_infoE") {
+        size = 0x2C;
+      }
+#endif
+
+      if (size == 0) {
+        llvm::cerr << "Unable to find size for global variable: " << i->getName() 
+                   << " (use will result in out of bounds access)\n";
+      }
+
+      MemoryObject *mo = memory->allocate(size, false, true, i);
+      ObjectState *os = bindObjectInState(state, mo, false);
+      globalObjects.insert(std::make_pair(i, mo));
+      globalAddresses.insert(std::make_pair(i, mo->getBaseExpr()));
+
+      // Program already running = object already initialized.  Read
+      // concrete value and write it to our copy.
+      if (size) {
+        void *addr;
+        if (name=="__dso_handle") {
+          extern void *__dso_handle __attribute__ ((__weak__));
+          addr = &__dso_handle; // wtf ?
+        } else {
+          addr = externalDispatcher->resolveSymbol(name);
+        }
+        if (!addr)
+          klee_error("unable to load symbol(%s) while initializing globals.", 
+                     name.c_str());
+
+        for (unsigned offset=0; offset<mo->size; offset++)
+          os->write8(offset, ((unsigned char*)addr)[offset]);
+      }
+    } else {
+      const std::string &name = i->getName();
+      const Type *ty = i->getType()->getElementType();
+      uint64_t size = kmodule->targetData->getTypeStoreSize(ty);
+      MemoryObject *mo = 0;
+
+      if (UseAsmAddresses && name[0]=='\01') {
+        char *end;
+        uint64_t address = ::strtoll(name.c_str()+1, &end, 0);
+
+        if (end && *end == '\0') {
+          klee_message("NOTE: allocated global at asm specified address: %#08llx"
+                       " (%llu bytes)",
+                       address, size);
+          mo = memory->allocateFixed(address, size, &*i);
+          mo->isUserSpecified = true; // XXX hack;
+        }
+      }
+
+      if (!mo)
+        mo = memory->allocate(size, false, true, &*i);
+      assert(mo && "out of memory");
+      ObjectState *os = bindObjectInState(state, mo, false);
+      globalObjects.insert(std::make_pair(i, mo));
+      globalAddresses.insert(std::make_pair(i, mo->getBaseExpr()));
+
+      if (!i->hasInitializer())
+          os->initializeToRandom();
+    }
+  }
+  
+  // link aliases to their definitions (if bound)
+  for (Module::alias_iterator i = m->alias_begin(), ie = m->alias_end(); 
+       i != ie; ++i) {
+    // Map the alias to its aliasee's address. This works because we have
+    // addresses for everything, even undefined functions. 
+    globalAddresses.insert(std::make_pair(i, evalConstant(i->getAliasee())));
+  }
+
+  // once all objects are allocated, do the actual initialization
+  for (Module::const_global_iterator i = m->global_begin(),
+         e = m->global_end();
+       i != e; ++i) {
+    if (i->hasInitializer()) {
+      MemoryObject *mo = globalObjects.find(i)->second;
+      const ObjectState *os = state.addressSpace.findObject(mo);
+      assert(os);
+      ObjectState *wos = state.addressSpace.getWriteable(mo, os);
+      
+      initializeGlobalObject(state, wos, i->getInitializer(), 0);
+      // if(i->isConstant()) os->setReadOnly(true);
+    }
+  }
+}
+
+void Executor::branch(ExecutionState &state, 
+                      const std::vector< ref<Expr> > &conditions,
+                      std::vector<ExecutionState*> &result) {
+  TimerStatIncrementer timer(stats::forkTime);
+  unsigned N = conditions.size();
+  assert(N);
+
+  stats::forks += N-1;
+
+  // XXX do proper balance or keep random?
+  result.push_back(&state);
+  for (unsigned i=1; i<N; ++i) {
+    ExecutionState *es = result[theRNG.getInt32() % i];
+    ExecutionState *ns = es->branch();
+    addedStates.insert(ns);
+    result.push_back(ns);
+    es->ptreeNode->data = 0;
+    std::pair<PTree::Node*,PTree::Node*> res = 
+      processTree->split(es->ptreeNode, ns, es);
+    ns->ptreeNode = res.first;
+    es->ptreeNode = res.second;
+  }
+
+  // If necessary redistribute seeds to match conditions, killing
+  // states if necessary due to OnlyReplaySeeds (inefficient but
+  // simple).
+  
+  std::map< ExecutionState*, std::vector<SeedInfo> >::iterator it = 
+    seedMap.find(&state);
+  if (it != seedMap.end()) {
+    std::vector<SeedInfo> seeds = it->second;
+    seedMap.erase(it);
+
+    // Assume each seed only satisfies one condition (necessarily true
+    // when conditions are mutually exclusive and their conjunction is
+    // a tautology).
+    for (std::vector<SeedInfo>::iterator siit = seeds.begin(), 
+           siie = seeds.end(); siit != siie; ++siit) {
+      unsigned i;
+      for (i=0; i<N; ++i) {
+        ref<Expr> res;
+        bool success = 
+          solver->getValue(state, siit->assignment.evaluate(conditions[i]), 
+                           res);
+        assert(success && "FIXME: Unhandled solver failure");
+        if (res.getConstantValue())
+          break;
+      }
+      
+      // If we didn't find a satisfying condition randomly pick one
+      // (the seed will be patched).
+      if (i==N)
+        i = theRNG.getInt32() % N;
+
+      seedMap[result[i]].push_back(*siit);
+    }
+
+    if (OnlyReplaySeeds) {
+      for (unsigned i=0; i<N; ++i) {
+        if (!seedMap.count(result[i])) {
+          terminateState(*result[i]);
+          result[i] = NULL;
+        }
+      } 
+    }
+  }
+
+  for (unsigned i=0; i<N; ++i)
+    if (result[i])
+      addConstraint(*result[i], conditions[i]);
+}
+
+Executor::StatePair 
+Executor::fork(ExecutionState &current, ref<Expr> condition, bool isInternal) {
+  Solver::Validity res;
+  std::map< ExecutionState*, std::vector<SeedInfo> >::iterator it = 
+    seedMap.find(&current);
+  bool isSeeding = it != seedMap.end();
+
+  if (!isSeeding &&
+      !condition.isConstant() && 
+      (MaxStaticForkPct!=1. || MaxStaticSolvePct != 1. ||
+       MaxStaticCPForkPct!=1. || MaxStaticCPSolvePct != 1.) &&
+      statsTracker->elapsed() > 60.) {
+    StatisticManager &sm = *theStatisticManager;
+    CallPathNode *cpn = current.stack.back().callPathNode;
+    if ((MaxStaticForkPct<1. &&
+         sm.getIndexedValue(stats::forks, sm.getIndex()) > 
+         stats::forks*MaxStaticForkPct) ||
+        (MaxStaticCPForkPct<1. &&
+         cpn && (cpn->statistics.getValue(stats::forks) > 
+                 stats::forks*MaxStaticCPForkPct)) ||
+        (MaxStaticSolvePct<1 &&
+         sm.getIndexedValue(stats::solverTime, sm.getIndex()) > 
+         stats::solverTime*MaxStaticSolvePct) ||
+        (MaxStaticCPForkPct<1. &&
+         cpn && (cpn->statistics.getValue(stats::solverTime) > 
+                 stats::solverTime*MaxStaticCPSolvePct))) {
+      ref<Expr> value; 
+      bool success = solver->getValue(current, condition, value);
+      assert(success && "FIXME: Unhandled solver failure");
+      addConstraint(current, EqExpr::create(value, condition));
+      condition = value;
+    }      
+  }
+
+  double timeout = stpTimeout;
+  if (isSeeding)
+    timeout *= it->second.size();
+  solver->setTimeout(timeout);
+  bool success = solver->evaluate(current, condition, res);
+  solver->setTimeout(0);
+  if (!success) {
+    current.pc = current.prevPC;
+    terminateStateEarly(current, "query timed out");
+    return StatePair(0, 0);
+  }
+
+  if (!isSeeding) {
+    if (replayPath && !isInternal) {
+      assert(replayPosition<replayPath->size() &&
+             "ran out of branches in replay path mode");
+      bool branch = (*replayPath)[replayPosition++];
+      
+      if (res==Solver::True) {
+        assert(branch && "hit invalid branch in replay path mode");
+      } else if (res==Solver::False) {
+        assert(!branch && "hit invalid branch in replay path mode");
+      } else {
+        // add constraints
+        if(branch) {
+          res = Solver::True;
+          addConstraint(current, condition);
+        } else  {
+          res = Solver::False;
+          addConstraint(current, Expr::createNot(condition));
+        }
+      }
+    } else if (res==Solver::Unknown) {
+      assert(!replayOut && "in replay mode, only one branch can be true.");
+      
+      if ((MaxMemoryInhibit && atMemoryLimit) || 
+          current.forkDisabled ||
+          inhibitForking || 
+          (MaxForks!=~0u && stats::forks >= MaxForks)) {
+        TimerStatIncrementer timer(stats::forkTime);
+        if (theRNG.getBool()) {
+          addConstraint(current, condition);
+          res = Solver::True;        
+        } else {
+          addConstraint(current, Expr::createNot(condition));
+          res = Solver::False;
+        }
+      }
+    }
+  }
+
+  // Fix branch in only-replay-seed mode, if we don't have both true
+  // and false seeds.
+  if (isSeeding && 
+      (current.forkDisabled || OnlyReplaySeeds) && 
+      res == Solver::Unknown) {
+    bool trueSeed=false, falseSeed=false;
+    // Is seed extension still ok here?
+    for (std::vector<SeedInfo>::iterator siit = it->second.begin(), 
+           siie = it->second.end(); siit != siie; ++siit) {
+      ref<Expr> res;
+      bool success = 
+        solver->getValue(current, siit->assignment.evaluate(condition), res);
+      assert(success && "FIXME: Unhandled solver failure");
+      if (res.isConstant()) {
+        if (res.getConstantValue()) {
+          trueSeed = true;
+        } else {
+          falseSeed = true;
+        }
+        if (trueSeed && falseSeed)
+          break;
+      }
+    }
+    if (!(trueSeed && falseSeed)) {
+      assert(trueSeed || falseSeed);
+      
+      res = trueSeed ? Solver::True : Solver::False;
+      addConstraint(current, trueSeed ? condition : Expr::createNot(condition));
+    }
+  }
+
+
+  // XXX - even if the constraint is provable one way or the other we
+  // can probably benefit by adding this constraint and allowing it to
+  // reduce the other constraints. For example, if we do a binary
+  // search on a particular value, and then see a comparison against
+  // the value it has been fixed at, we should take this as a nice
+  // hint to just use the single constraint instead of all the binary
+  // search ones. If that makes sense.
+  if (res==Solver::True) {
+    if (!isInternal) {
+      if (pathWriter) {
+        current.pathOS << "1";
+      }
+    }
+
+    return StatePair(&current, 0);
+  } else if (res==Solver::False) {
+    if (!isInternal) {
+      if (pathWriter) {
+        current.pathOS << "0";
+      }
+    }
+
+    return StatePair(0, &current);
+  } else {
+    TimerStatIncrementer timer(stats::forkTime);
+    ExecutionState *falseState, *trueState = &current;
+
+    ++stats::forks;
+
+    falseState = trueState->branch();
+    addedStates.insert(falseState);
+
+    if (RandomizeFork && theRNG.getBool())
+      std::swap(trueState, falseState);
+
+    if (it != seedMap.end()) {
+      std::vector<SeedInfo> seeds = it->second;
+      it->second.clear();
+      std::vector<SeedInfo> &trueSeeds = seedMap[trueState];
+      std::vector<SeedInfo> &falseSeeds = seedMap[falseState];
+      for (std::vector<SeedInfo>::iterator siit = seeds.begin(), 
+             siie = seeds.end(); siit != siie; ++siit) {
+        ref<Expr> res;
+        bool success = 
+          solver->getValue(current, siit->assignment.evaluate(condition), res);
+        assert(success && "FIXME: Unhandled solver failure");
+        if (res.getConstantValue()) {
+          trueSeeds.push_back(*siit);
+        } else {
+          falseSeeds.push_back(*siit);
+        }
+      }
+      
+      bool swapInfo = false;
+      if (trueSeeds.empty()) {
+        if (&current == trueState) swapInfo = true;
+        seedMap.erase(trueState);
+      }
+      if (falseSeeds.empty()) {
+        if (&current == falseState) swapInfo = true;
+        seedMap.erase(falseState);
+      }
+      if (swapInfo) {
+        std::swap(trueState->coveredNew, falseState->coveredNew);
+        std::swap(trueState->coveredLines, falseState->coveredLines);
+      }
+    }
+
+    current.ptreeNode->data = 0;
+    std::pair<PTree::Node*, PTree::Node*> res =
+      processTree->split(current.ptreeNode, falseState, trueState);
+    falseState->ptreeNode = res.first;
+    trueState->ptreeNode = res.second;
+
+    if (!isInternal) {
+      if (pathWriter) {
+        falseState->pathOS = pathWriter->open(current.pathOS);
+        trueState->pathOS << "1";
+        falseState->pathOS << "0";
+      }      
+      if (symPathWriter) {
+        falseState->symPathOS = symPathWriter->open(current.symPathOS);
+        trueState->symPathOS << "1";
+        falseState->symPathOS << "0";
+      }
+    }
+
+    addConstraint(*trueState, condition);
+    addConstraint(*falseState, Expr::createNot(condition));
+
+    // Kinda gross, do we even really still want this option?
+    if (MaxDepth && MaxDepth<=trueState->depth) {
+      terminateStateEarly(*trueState, "max-depth exceeded");
+      terminateStateEarly(*falseState, "max-depth exceeded");
+      return StatePair(0, 0);
+    }
+
+    return StatePair(trueState, falseState);
+  }
+}
+
+void Executor::addConstraint(ExecutionState &state, ref<Expr> condition) {
+  if (condition.isConstant()) {
+    assert(condition.getConstantValue() &&
+           "attempt to add invalid constraint");
+    return;
+  }
+
+  // Check to see if this constraint violates seeds.
+  std::map< ExecutionState*, std::vector<SeedInfo> >::iterator it = 
+    seedMap.find(&state);
+  if (it != seedMap.end()) {
+    bool warn = false;
+    for (std::vector<SeedInfo>::iterator siit = it->second.begin(), 
+           siie = it->second.end(); siit != siie; ++siit) {
+      bool res;
+      bool success = 
+        solver->mustBeFalse(state, siit->assignment.evaluate(condition), res);
+      assert(success && "FIXME: Unhandled solver failure");
+      if (res) {
+        siit->patchSeed(state, condition, solver);
+        warn = true;
+      }
+    }
+    if (warn)
+      klee_warning("seeds patched for violating constraint"); 
+  }
+
+  state.addConstraint(condition);
+  if (ivcEnabled)
+    doImpliedValueConcretization(state, condition, ref<Expr>(1, Expr::Bool));
+}
+
+ref<Expr> Executor::evalConstant(Constant *c) {
+  if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(c)) {
+    return evalConstantExpr(ce);
+  } else {
+    if (const ConstantInt *ci = dyn_cast<ConstantInt>(c)) {
+      switch(ci->getBitWidth()) {
+      case  1: return ConstantExpr::create(ci->getZExtValue(), Expr::Bool);
+      case  8: return ConstantExpr::create(ci->getZExtValue(), Expr::Int8);
+      case 16: return ConstantExpr::create(ci->getZExtValue(), Expr::Int16);
+      case 32: return ConstantExpr::create(ci->getZExtValue(), Expr::Int32);
+      case 64: return ConstantExpr::create(ci->getZExtValue(), Expr::Int64);
+      default:
+        assert(0 && "XXX arbitrary bit width constants unhandled");
+      }
+    } else if (const ConstantFP *cf = dyn_cast<ConstantFP>(c)) {      
+      switch(cf->getType()->getTypeID()) {
+      case Type::FloatTyID: {
+	float f = cf->getValueAPF().convertToFloat();
+	return ConstantExpr::create(floats::FloatAsUInt64(f), Expr::Int32);
+      }
+      case Type::DoubleTyID: {
+	double d = cf->getValueAPF().convertToDouble();
+	return ConstantExpr::create(floats::DoubleAsUInt64(d), Expr::Int64);
+      }	
+      case Type::X86_FP80TyID: {
+        // FIXME: This is really broken, but for now we just convert
+	// to a double. This isn't going to work at all in general,
+	// but we need support for wide constants.
+	APFloat apf = cf->getValueAPF();
+        bool ignored;
+	APFloat::opStatus r = apf.convert(APFloat::IEEEdouble, 
+                                          APFloat::rmNearestTiesToAway,
+                                          &ignored);
+        (void) r;
+        //assert(!(r & APFloat::opOverflow) && !(r & APFloat::opUnderflow) &&
+        //       "Overflow/underflow while converting from FP80 (x87) to 64-bit double");
+	double d = apf.convertToDouble();
+	return ConstantExpr::create(floats::DoubleAsUInt64(d), Expr::Int64);
+      }
+      default:		
+	llvm::cerr << "Constant of type " << cf->getType()->getDescription() 
+                   << " not supported\n";
+	llvm::cerr << "Constant used at ";
+	KConstant *kc = kmodule->getKConstant((Constant*) cf);
+	if (kc && kc->ki && kc->ki->info)
+	  llvm::cerr << kc->ki->info->file << ":" << kc->ki->info->line << "\n";
+	else llvm::cerr << "<unknown>\n";
+	  
+	assert(0 && "Arbitrary bit width floating point constants unsupported");
+      }
+    } else if (const GlobalValue *gv = dyn_cast<GlobalValue>(c)) {
+      return globalAddresses.find(gv)->second;
+    } else if (isa<ConstantPointerNull>(c)) {
+      return Expr::createPointer(0);
+    } else if (isa<UndefValue>(c)) {
+      return ConstantExpr::create(0, Expr::getWidthForLLVMType(c->getType()));
+    } else {
+      // Constant{AggregateZero,Array,Struct,Vector}
+      assert(0 && "invalid argument to evalConstant()");
+    }
+  }
+}
+
+ref<Expr> Executor::eval(KInstruction *ki,
+                         unsigned index,
+                         ExecutionState &state) {
+  assert(index < ki->inst->getNumOperands());
+  int vnumber = ki->operands[index];
+
+  // Determine if this is a constant or not.
+  if (vnumber < 0) {
+    unsigned index = -vnumber - 2;
+    Cell &c = kmodule->constantTable[index];
+    return c.value;
+  } else {
+    unsigned index = vnumber;
+    StackFrame &sf = state.stack.back();
+    Cell &c = sf.locals[index];
+    return c.value;
+  }
+}
+
+void Executor::bindLocal(KInstruction *target, ExecutionState &state, 
+                         ref<Expr> value) {
+  StackFrame &sf = state.stack.back();
+  unsigned reg = target->dest;
+  Cell &c = sf.locals[reg];
+  c.value = value;  
+}
+
+void Executor::bindArgument(KFunction *kf, unsigned index, 
+                            ExecutionState &state, ref<Expr> value) {
+  StackFrame &sf = state.stack.back();
+  unsigned reg = kf->getArgRegister(index);
+  Cell &c = sf.locals[reg];
+  c.value = value;
+}
+
+ref<Expr> Executor::toUnique(const ExecutionState &state, 
+                             ref<Expr> &e) {
+  ref<Expr> result = e;
+
+  if (!e.isConstant()) {
+    ref<Expr> value(0);
+    bool isTrue = false;
+
+    solver->setTimeout(stpTimeout);      
+    if (solver->getValue(state, e, value) &&
+        solver->mustBeTrue(state, EqExpr::create(e, value), isTrue) &&
+        isTrue)
+      result = value;
+    solver->setTimeout(0);
+  }
+  
+  return result;
+}
+
+
+/* Concretize the given expression, and return a possible constant value. 
+   'reason' is just a documentation string stating the reason for concretization. */
+ref<Expr> Executor::toConstant(ExecutionState &state, 
+                               ref<Expr> e,
+                               const char *reason) {
+  e = state.constraints.simplifyExpr(e);
+  if (!e.isConstant()) {
+    ref<Expr> value;
+    bool success = solver->getValue(state, e, value);
+    assert(success && "FIXME: Unhandled solver failure");
+    
+    std::ostringstream os;
+    os << "silently concretizing (reason: " << reason << ") expression " << e 
+       << " to value " << value 
+       << " (" << (*(state.pc)).info->file << ":" << (*(state.pc)).info->line << ")";
+      
+    if (AllExternalWarnings)
+      klee_warning(reason, os.str().c_str());
+    else
+      klee_warning_once(reason, "%s", os.str().c_str());
+
+    addConstraint(state, EqExpr::create(e, value));
+    
+    return value;
+  } else {
+    return e;
+  }
+}
+
+void Executor::executeGetValue(ExecutionState &state,
+                               ref<Expr> e,
+                               KInstruction *target) {
+  e = state.constraints.simplifyExpr(e);
+  std::map< ExecutionState*, std::vector<SeedInfo> >::iterator it = 
+    seedMap.find(&state);
+  if (it==seedMap.end() || e.isConstant()) {
+    ref<Expr> value;
+    bool success = solver->getValue(state, e, value);
+    assert(success && "FIXME: Unhandled solver failure");
+    bindLocal(target, state, value);
+  } else {
+    std::set< ref<Expr> > values;
+    for (std::vector<SeedInfo>::iterator siit = it->second.begin(), 
+           siie = it->second.end(); siit != siie; ++siit) {
+      ref<Expr> value;
+      bool success = 
+        solver->getValue(state, siit->assignment.evaluate(e), value);
+      assert(success && "FIXME: Unhandled solver failure");
+      values.insert(value);
+    }
+    
+    std::vector< ref<Expr> > conditions;
+    for (std::set< ref<Expr> >::iterator vit = values.begin(), 
+           vie = values.end(); vit != vie; ++vit)
+      conditions.push_back(EqExpr::create(e, *vit));
+
+    std::vector<ExecutionState*> branches;
+    branch(state, conditions, branches);
+    
+    std::vector<ExecutionState*>::iterator bit = branches.begin();
+    for (std::set< ref<Expr> >::iterator vit = values.begin(), 
+           vie = values.end(); vit != vie; ++vit) {
+      ExecutionState *es = *bit;
+      if (es)
+        bindLocal(target, *es, *vit);
+      ++bit;
+    }
+  }
+}
+
+void Executor::stepInstruction(ExecutionState &state) {
+  if (DebugPrintInstructions) {
+    printFileLine(state, state.pc);
+    llvm::cerr << std::setw(10) << stats::instructions << " " << *state.pc->inst;
+  }
+
+  if (statsTracker)
+    statsTracker->stepInstruction(state);
+
+  ++stats::instructions;
+  state.prevPC = state.pc;
+  ++state.pc;
+
+  if (stats::instructions==StopAfterNInstructions)
+    haltExecution = true;
+}
+
+void Executor::executeCall(ExecutionState &state, 
+                           KInstruction *ki,
+                           Function *f,
+                           std::vector< ref<Expr> > &arguments) {
+  if (WriteTraces) {
+    // don't print out special debug stop point 'function' calls
+    if (f->getIntrinsicID() != Intrinsic::dbg_stoppoint) {
+      const std::string& calleeFuncName = f->getName();
+      state.exeTraceMgr.addEvent(new FunctionCallTraceEvent(state, ki, calleeFuncName));
+    }
+  }
+
+  Instruction *i = ki->inst;
+  if (f && f->isDeclaration()) {
+    if (f!=kmodule->dbgStopPointFn) { // special case speed hack
+      switch(f->getIntrinsicID()) {
+      case Intrinsic::dbg_stoppoint:
+      case Intrinsic::dbg_region_start:
+      case Intrinsic::dbg_region_end:
+      case Intrinsic::dbg_func_start:
+      case Intrinsic::dbg_declare:
+      case Intrinsic::not_intrinsic:
+        // state may be destroyed by this call, cannot touch
+        callExternalFunction(state, ki, f, arguments);
+        break;
+          
+        // vararg is handled by caller and intrinsic lowering,
+        // see comment for ExecutionState::varargs
+      case Intrinsic::vastart:  {
+        StackFrame &sf = state.stack.back();
+        assert(sf.varargs && 
+               "vastart called in function with no vararg object");
+        executeMemoryOperation(state, true, arguments[0], 
+                               sf.varargs->getBaseExpr(), 0);
+        break;
+      }
+      case Intrinsic::vaend:    // va_end is a noop for the interpreter
+        break;
+          
+      case Intrinsic::vacopy: // should be lowered
+      default:
+        klee_error("unknown intrinsic: %s", f->getName().c_str());
+      }
+    }
+
+    if (InvokeInst *ii = dyn_cast<InvokeInst>(i)) {
+      transferToBasicBlock(ii->getNormalDest(), i->getParent(), state);
+    }
+  } else {
+    // XXX not really happy about this reliance on prevPC but is ok I
+    // guess. This just done to avoid having to pass KInstIterator
+    // everywhere instead of the actual instruction, since we can't
+    // make a KInstIterator from just an instruction (unlike LLVM).
+    KFunction *kf = kmodule->functionMap[f];
+    state.pushFrame(state.prevPC, kf);
+    state.pc = kf->instructions;
+        
+    if (statsTracker)
+      statsTracker->framePushed(state, &state.stack[state.stack.size()-2]);
+        
+    unsigned callingArgs = arguments.size();
+    unsigned funcArgs = f->arg_size();
+    if (!f->isVarArg()) {
+      if (callingArgs > funcArgs) {
+        klee_warning_once(f, "calling %s with extra arguments.", 
+                          f->getName().c_str());
+      } else if (callingArgs < funcArgs) {
+        terminateStateOnError(state, "calling function with too few arguments", 
+                              "user.err");
+        return;
+      }
+    } else {
+      if (callingArgs < funcArgs) {
+        terminateStateOnError(state, "calling function with too few arguments", 
+                              "user.err");
+        return;
+      }
+            
+      StackFrame &sf = state.stack.back();
+      unsigned size = 0;
+      for (unsigned i = funcArgs; i < callingArgs; i++)
+        size += Expr::getMinBytesForWidth(arguments[i].getWidth());
+
+      MemoryObject *mo = sf.varargs = memory->allocate(size, true, false, 
+                                                       state.prevPC->inst);
+      if (!mo) {
+        terminateStateOnExecError(state, "out of memory (varargs)");
+        return;
+      }
+      ObjectState *os = bindObjectInState(state, mo, true);
+      unsigned offset = 0;
+      for (unsigned i = funcArgs; i < callingArgs; i++) {
+        // XXX: DRE: i think we bind memory objects here?
+        os->write(offset, arguments[i]);
+        offset += Expr::getMinBytesForWidth(arguments[i].getWidth());
+      }
+    }
+
+    unsigned numFormals = f->arg_size();
+    for (unsigned i=0; i<numFormals; ++i) 
+      bindArgument(kf, i, state, arguments[i]);
+  }
+}
+
+void Executor::transferToBasicBlock(BasicBlock *dst, BasicBlock *src, 
+                                    ExecutionState &state) {
+  // Note that in general phi nodes can reuse phi values from the same
+  // block but the incoming value is the eval() result *before* the
+  // execution of any phi nodes. this is pathological and doesn't
+  // really seem to occur, but just in case we run the PhiCleanerPass
+  // which makes sure this cannot happen and so it is safe to just
+  // eval things in order. The PhiCleanerPass also makes sure that all
+  // incoming blocks have the same order for each PHINode so we only
+  // have to compute the index once.
+  //
+  // With that done we simply set an index in the state so that PHI
+  // instructions know which argument to eval, set the pc, and continue.
+  
+  // XXX this lookup has to go ?
+  KFunction *kf = state.stack.back().kf;
+  unsigned entry = kf->basicBlockEntry[dst];
+  state.pc = &kf->instructions[entry];
+  if (state.pc->inst->getOpcode() == Instruction::PHI) {
+    PHINode *first = static_cast<PHINode*>(state.pc->inst);
+    state.incomingBBIndex = first->getBasicBlockIndex(src);
+  }
+}
+
+void Executor::printFileLine(ExecutionState &state, KInstruction *ki) {
+  const InstructionInfo &ii = *ki->info;
+  if (ii.file != "") 
+    llvm::cerr << "     " << ii.file << ":" << ii.line << ":";
+  else
+    llvm::cerr << "     [no debug info]:";
+}
+
+
+Function* Executor::getCalledFunction(CallSite &cs, ExecutionState &state) {
+  Function *f = cs.getCalledFunction();
+  
+  if (f) {
+    std::string alias = state.getFnAlias(f->getName());
+    if (alias != "") {
+      //llvm::cerr << f->getName() << "() is aliased with " << alias << "()\n";
+      llvm::Module* currModule = kmodule->module;
+      Function* old_f = f;
+      f = currModule->getFunction(alias);
+      if (!f) {
+	llvm::cerr << "Function " << alias << "(), alias for " << old_f->getName() << " not found!\n";
+	assert(f && "function alias not found");
+      }
+    }
+  }
+  
+  return f;
+}
+
+
+void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
+  Instruction *i = ki->inst;
+  switch (i->getOpcode()) {
+    // Control flow
+  case Instruction::Ret: {
+    ReturnInst *ri = cast<ReturnInst>(i);
+    KInstIterator kcaller = state.stack.back().caller;
+    Instruction *caller = kcaller ? kcaller->inst : 0;
+    bool isVoidReturn = (ri->getNumOperands() == 0);
+    ref<Expr> result(0,Expr::Bool);
+
+    if (WriteTraces) {
+      state.exeTraceMgr.addEvent(new FunctionReturnTraceEvent(state, ki));
+    }
+    
+    if (!isVoidReturn) {
+      result = eval(ki, 0, state);
+    }
+    
+    if (state.stack.size() <= 1) {
+      assert(!caller && "caller set on initial stack frame");
+      terminateStateOnExit(state);
+    } else {
+      state.popFrame();
+
+      if (statsTracker)
+        statsTracker->framePopped(state);
+
+      if (InvokeInst *ii = dyn_cast<InvokeInst>(caller)) {
+        transferToBasicBlock(ii->getNormalDest(), caller->getParent(), state);
+      } else {
+        state.pc = kcaller;
+        ++state.pc;
+      }
+
+      if (!isVoidReturn) {
+        const Type *t = caller->getType();
+        if (t != Type::VoidTy) {
+          // may need to do coercion due to bitcasts
+          Expr::Width from = result.getWidth();
+          Expr::Width to = Expr::getWidthForLLVMType(t);
+            
+          if (from != to) {
+            CallSite cs = (isa<InvokeInst>(caller) ? CallSite(cast<InvokeInst>(caller)) : 
+                           CallSite(cast<CallInst>(caller)));
+
+            // XXX need to check other param attrs ?
+            if (cs.paramHasAttr(0, llvm::Attribute::SExt)) {
+              result = SExtExpr::create(result, to);
+            } else {
+              result = ZExtExpr::create(result, to);
+            }
+          }
+
+          bindLocal(kcaller, state, result);
+        }
+      } else {
+        // We check that the return value has no users instead of
+        // checking the type, since C defaults to returning int for
+        // undeclared functions.
+        if (!caller->use_empty()) {
+          terminateStateOnExecError(state, "return void when caller expected a result");
+        }
+      }
+    }      
+    break;
+  }
+  case Instruction::Unwind: {
+    for (;;) {
+      KInstruction *kcaller = state.stack.back().caller;
+      state.popFrame();
+
+      if (statsTracker)
+        statsTracker->framePopped(state);
+
+      if (state.stack.empty()) {
+        terminateStateOnExecError(state, "unwind from initial stack frame");
+        break;
+      } else {
+        Instruction *caller = kcaller->inst;
+        if (InvokeInst *ii = dyn_cast<InvokeInst>(caller)) {
+          transferToBasicBlock(ii->getUnwindDest(), caller->getParent(), state);
+          break;
+        }
+      }
+    }
+    break;
+  }
+  case Instruction::Br: {
+    BranchInst *bi = cast<BranchInst>(i);
+    if (bi->isUnconditional()) {
+      transferToBasicBlock(bi->getSuccessor(0), bi->getParent(), state);
+    } else {
+      // FIXME: Find a way that we don't have this hidden dependency.
+      assert(bi->getCondition() == bi->getOperand(0) &&
+             "Wrong operand index!");
+      ref<Expr> cond = eval(ki, 0, state);
+      Executor::StatePair branches = fork(state, cond, false);
+
+      if (WriteTraces) {
+        bool isTwoWay = (branches.first && branches.second);
+
+        if (branches.first) {
+          branches.first->exeTraceMgr.addEvent(
+            new BranchTraceEvent(state, ki, true, isTwoWay));
+        }
+
+        if (branches.second) {
+          branches.second->exeTraceMgr.addEvent(
+            new BranchTraceEvent(state, ki, false, isTwoWay));
+        }
+      }
+
+      // NOTE: There is a hidden dependency here, markBranchVisited
+      // requires that we still be in the context of the branch
+      // instruction (it reuses its statistic id). Should be cleaned
+      // up with convenient instruction specific data.
+      if (statsTracker && state.stack.back().kf->trackCoverage)
+        statsTracker->markBranchVisited(branches.first, branches.second);
+
+      if (branches.first)
+        transferToBasicBlock(bi->getSuccessor(0), bi->getParent(), *branches.first);
+      if (branches.second)
+        transferToBasicBlock(bi->getSuccessor(1), bi->getParent(), *branches.second);
+    }
+    break;
+  }
+  case Instruction::Switch: {
+    SwitchInst *si = cast<SwitchInst>(i);
+    ref<Expr> cond = eval(ki, 0, state);
+    unsigned cases = si->getNumCases();
+    BasicBlock *bb = si->getParent();
+
+    cond = toUnique(state, cond);
+    if (cond.isConstant()) {
+      // Somewhat gross to create these all the time, but fine till we
+      // switch to an internal rep.
+      ConstantInt *ci = ConstantInt::get(si->getCondition()->getType(),
+                                         cond.getConstantValue());
+      unsigned index = si->findCaseValue(ci);
+      transferToBasicBlock(si->getSuccessor(index), si->getParent(), state);
+    } else {
+      std::map<BasicBlock*, ref<Expr> > targets;
+      ref<Expr> isDefault(1,Expr::Bool);
+      for (unsigned i=1; i<cases; ++i) {
+        ref<Expr> value = evalConstant(si->getCaseValue(i));
+        ref<Expr> match = EqExpr::create(cond, value);
+        isDefault = AndExpr::create(isDefault, Expr::createNot(match));
+        bool result;
+        bool success = solver->mayBeTrue(state, match, result);
+        assert(success && "FIXME: Unhandled solver failure");
+        if (result) {
+          std::map<BasicBlock*, ref<Expr> >::iterator it =
+            targets.insert(std::make_pair(si->getSuccessor(i),
+                                          ref<Expr>(0,Expr::Bool))).first;
+          it->second = OrExpr::create(match, it->second);
+        }
+      }
+      bool res;
+      bool success = solver->mayBeTrue(state, isDefault, res);
+      assert(success && "FIXME: Unhandled solver failure");
+      if (res)
+        targets.insert(std::make_pair(si->getSuccessor(0), isDefault));
+      
+      std::vector< ref<Expr> > conditions;
+      for (std::map<BasicBlock*, ref<Expr> >::iterator it = 
+             targets.begin(), ie = targets.end();
+           it != ie; ++it)
+        conditions.push_back(it->second);
+      
+      std::vector<ExecutionState*> branches;
+      branch(state, conditions, branches);
+        
+      std::vector<ExecutionState*>::iterator bit = branches.begin();
+      for (std::map<BasicBlock*, ref<Expr> >::iterator it = 
+             targets.begin(), ie = targets.end();
+           it != ie; ++it) {
+        ExecutionState *es = *bit;
+        if (es)
+          transferToBasicBlock(it->first, bb, *es);
+        ++bit;
+      }
+    }
+    break;
+ }
+  case Instruction::Unreachable:
+    // Note that this is not necessarily an internal bug, llvm will
+    // generate unreachable instructions in cases where it knows the
+    // program will crash. So it is effectively a SEGV or internal
+    // error.
+    terminateStateOnExecError(state, "reached \"unreachable\" instruction");
+    break;
+
+  case Instruction::Invoke:
+  case Instruction::Call: {
+    CallSite cs;
+    unsigned argStart;
+    if (i->getOpcode()==Instruction::Call) {
+      cs = CallSite(cast<CallInst>(i));
+      argStart = 1;
+    } else {
+      cs = CallSite(cast<InvokeInst>(i));
+      argStart = 3;
+    }
+
+    unsigned numArgs = cs.arg_size();
+    Function *f = getCalledFunction(cs, state);
+      
+    // evaluate arguments
+    std::vector< ref<Expr> > arguments;
+    arguments.reserve(numArgs);
+
+    for (unsigned j=0; j<numArgs; ++j)
+      arguments.push_back(eval(ki, argStart+j, state));
+
+    if (!f) {
+      // special case the call with a bitcast case
+      Value *fp = cs.getCalledValue();
+      llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(fp);
+        
+      if (ce && ce->getOpcode()==Instruction::BitCast) {
+        f = dyn_cast<Function>(ce->getOperand(0));
+        assert(f && "XXX unrecognized constant expression in call");
+        const FunctionType *fType = 
+          dyn_cast<FunctionType>(cast<PointerType>(f->getType())->getElementType());
+        const FunctionType *ceType =
+          dyn_cast<FunctionType>(cast<PointerType>(ce->getType())->getElementType());
+        assert(fType && ceType && "unable to get function type");
+
+        // XXX check result coercion
+
+        // XXX this really needs thought and validation
+        unsigned i=0;
+        for (std::vector< ref<Expr> >::iterator
+               ai = arguments.begin(), ie = arguments.end();
+             ai != ie; ++ai) {
+          Expr::Width to, from = (*ai).getWidth();
+            
+          if (i<fType->getNumParams()) {
+            to = Expr::getWidthForLLVMType(fType->getParamType(i));
+
+            if (from != to) {
+              // XXX need to check other param attrs ?
+              if (cs.paramHasAttr(i+1, llvm::Attribute::SExt)) {
+                arguments[i] = SExtExpr::create(arguments[i], to);
+              } else {
+                arguments[i] = ZExtExpr::create(arguments[i], to);
+              }
+            }
+          }
+            
+          i++;
+        }
+      } else if (isa<InlineAsm>(fp)) {
+        terminateStateOnExecError(state, "inline assembly is unsupported");
+        break;
+      }
+    }
+
+    if (f) {
+      executeCall(state, ki, f, arguments);
+    } else {
+      ref<Expr> v = eval(ki, 0, state);
+
+      ExecutionState *free = &state;
+      bool hasInvalid = false, first = true;
+
+      /* XXX This is wasteful, no need to do a full evaluate since we
+         have already got a value. But in the end the caches should
+         handle it for us, albeit with some overhead. */
+      do {
+        ref<Expr> value;
+        bool success = solver->getValue(*free, v, value);
+        assert(success && "FIXME: Unhandled solver failure");
+        StatePair res = fork(*free, EqExpr::create(v, value), true);
+        if (res.first) {
+          void *addr = (void*) (unsigned long) value.getConstantValue();
+          std::set<void*>::iterator it = legalFunctions.find(addr);
+          if (it != legalFunctions.end()) {
+            f = (Function*) addr;
+
+            // Don't give warning on unique resolution
+            if (res.second || !first)
+              klee_warning_once(addr, 
+                                "resolved symbolic function pointer to: %s",
+                                f->getName().c_str());
+
+            executeCall(*res.first, ki, f, arguments);
+          } else {
+            if (!hasInvalid) {
+              terminateStateOnExecError(state, "invalid function pointer");
+              hasInvalid = true;
+            }
+          }
+        }
+
+        first = false;
+        free = res.second;
+      } while (free);
+    }
+    break;
+  }
+  case Instruction::PHI: {
+    ref<Expr> result = eval(ki, state.incomingBBIndex * 2, state);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+    // Special instructions
+  case Instruction::Select: {
+    SelectInst *SI = cast<SelectInst>(ki->inst);
+    assert(SI->getCondition() == SI->getOperand(0) &&
+           "Wrong operand index!");
+    ref<Expr> cond = eval(ki, 0, state);
+    ref<Expr> tExpr = eval(ki, 1, state);
+    ref<Expr> fExpr = eval(ki, 2, state);
+    ref<Expr> result = SelectExpr::create(cond, tExpr, fExpr);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::VAArg:
+    terminateStateOnExecError(state, "unexpected VAArg instruction");
+    break;
+
+    // Arithmetic / logical
+#define FP_CONSTANT_BINOP(op, type, l, r, target, state) \
+        bindLocal(target, state, \
+                  ref<Expr>(op(toConstant(state, l, "floating point").getConstantValue(), \
+                               toConstant(state, r, "floating point").getConstantValue(), \
+                               type), type))
+  case Instruction::Add: {
+    BinaryOperator *bi = cast<BinaryOperator>(i);
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+
+    if( bi->getType()->getTypeID() == llvm::Type::IntegerTyID ) {
+      bindLocal(ki, state, AddExpr::create(left, right));
+    } else {
+      Expr::Width type = Expr::getWidthForLLVMType(bi->getType());
+      FP_CONSTANT_BINOP(floats::add, type, left, right, ki, state);
+    }
+
+    break;
+  }
+
+  case Instruction::Sub: {
+    BinaryOperator *bi = cast<BinaryOperator>(i);
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+
+    if( bi->getType()->getTypeID() == llvm::Type::IntegerTyID ) {
+      bindLocal(ki, state, SubExpr::create(left, right));
+    } else {
+      Expr::Width type = Expr::getWidthForLLVMType(bi->getType());
+      FP_CONSTANT_BINOP(floats::sub, type, left, right, ki, state);
+    }
+
+    break;
+  }
+ 
+  case Instruction::Mul: {
+    BinaryOperator *bi = cast<BinaryOperator>(i);
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+
+    if( bi->getType()->getTypeID() == llvm::Type::IntegerTyID ) {
+      bindLocal(ki, state, MulExpr::create(left, right));
+    } else {
+      Expr::Width type = Expr::getWidthForLLVMType(bi->getType());
+      FP_CONSTANT_BINOP(floats::mul, type, left, right, ki, state);
+    }
+
+    break;
+  }
+
+  case Instruction::UDiv: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = UDivExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::SDiv: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = SDivExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::URem: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = URemExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+ 
+  case Instruction::SRem: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = SRemExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::And: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = AndExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::Or: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = OrExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::Xor: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = XorExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::Shl: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = ShlExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::LShr: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = LShrExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::AShr: {
+    ref<Expr> left = eval(ki, 0, state);
+    ref<Expr> right = eval(ki, 1, state);
+    ref<Expr> result = AShrExpr::create(left, right);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+    // Compare
+
+  case Instruction::ICmp: {
+    CmpInst *ci = cast<CmpInst>(i);
+    ICmpInst *ii = cast<ICmpInst>(ci);
+ 
+    switch(ii->getPredicate()) {
+    case ICmpInst::ICMP_EQ: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = EqExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_NE: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = NeExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_UGT: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = UgtExpr::create(left, right);
+      bindLocal(ki, state,result);
+      break;
+    }
+
+    case ICmpInst::ICMP_UGE: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = UgeExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_ULT: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = UltExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_ULE: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = UleExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_SGT: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = SgtExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_SGE: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = SgeExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_SLT: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = SltExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    case ICmpInst::ICMP_SLE: {
+      ref<Expr> left = eval(ki, 0, state);
+      ref<Expr> right = eval(ki, 1, state);
+      ref<Expr> result = SleExpr::create(left, right);
+      bindLocal(ki, state, result);
+      break;
+    }
+
+    default:
+      terminateStateOnExecError(state, "invalid ICmp predicate");
+    }
+    break;
+  }
+ 
+    // Memory instructions...
+  case Instruction::Alloca:
+  case Instruction::Malloc: {
+    AllocationInst *ai = cast<AllocationInst>(i);
+    unsigned elementSize = 
+      kmodule->targetData->getTypeStoreSize(ai->getAllocatedType());
+    ref<Expr> size = Expr::createPointer(elementSize);
+    if (ai->isArrayAllocation()) {
+      // XXX coerce?
+      ref<Expr> count = eval(ki, 0, state);
+      size = MulExpr::create(count, size);
+    }
+    bool isLocal = i->getOpcode()==Instruction::Alloca;
+    executeAlloc(state, size, isLocal, ki);
+    break;
+  }
+  case Instruction::Free: {
+    executeFree(state, eval(ki, 0, state));
+    break;
+  }
+
+  case Instruction::Load: {
+    ref<Expr> base = eval(ki, 0, state);
+    executeMemoryOperation(state, false, base, 0, ki);
+    break;
+  }
+  case Instruction::Store: {
+    ref<Expr> base = eval(ki, 1, state);
+    ref<Expr> value = eval(ki, 0, state);
+    executeMemoryOperation(state, true, base, value, 0);
+    break;
+  }
+
+  case Instruction::GetElementPtr: {
+    KGEPInstruction *kgepi = static_cast<KGEPInstruction*>(ki);
+    ref<Expr> base = eval(ki, 0, state);
+
+    for (std::vector< std::pair<unsigned, unsigned> >::iterator 
+           it = kgepi->indices.begin(), ie = kgepi->indices.end(); 
+         it != ie; ++it) {
+      unsigned elementSize = it->second;
+      ref<Expr> index = eval(ki, it->first, state);
+      base = AddExpr::create(base,
+                             MulExpr::create(Expr::createCoerceToPointerType(index),
+                                             Expr::createPointer(elementSize)));
+    }
+    if (kgepi->offset)
+      base = AddExpr::create(base,
+                             Expr::createPointer(kgepi->offset));
+    bindLocal(ki, state, base);
+    break;
+  }
+
+    // Conversion
+  case Instruction::Trunc: {
+    CastInst *ci = cast<CastInst>(i);
+    ref<Expr> result = ExtractExpr::createByteOff(eval(ki, 0, state),
+						  0,
+						  Expr::getWidthForLLVMType(ci->getType()));
+    bindLocal(ki, state, result);
+    break;
+  }
+  case Instruction::ZExt: {
+    CastInst *ci = cast<CastInst>(i);
+    ref<Expr> result = ZExtExpr::create(eval(ki, 0, state),
+                                        Expr::getWidthForLLVMType(ci->getType()));
+    bindLocal(ki, state, result);
+    break;
+  }
+  case Instruction::SExt: {
+    CastInst *ci = cast<CastInst>(i);
+    ref<Expr> result = SExtExpr::create(eval(ki, 0, state),
+                                        Expr::getWidthForLLVMType(ci->getType()));
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::IntToPtr: {
+    CastInst *ci = cast<CastInst>(i);
+    Expr::Width pType = Expr::getWidthForLLVMType(ci->getType());
+    ref<Expr> arg = eval(ki, 0, state);
+    bindLocal(ki, state, ZExtExpr::create(arg, pType));
+    break;
+  } 
+  case Instruction::PtrToInt: {
+    CastInst *ci = cast<CastInst>(i);
+    Expr::Width iType = Expr::getWidthForLLVMType(ci->getType());
+    ref<Expr> arg = eval(ki, 0, state);
+    bindLocal(ki, state, ZExtExpr::create(arg, iType));
+    break;
+  }
+
+  case Instruction::BitCast: {
+    ref<Expr> result = eval(ki, 0, state);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+    // Floating Point specific instructions
+  case Instruction::FPTrunc: {
+    FPTruncInst *fi = cast<FPTruncInst>(i);
+    Expr::Width resultType = Expr::getWidthForLLVMType(fi->getType());
+    ref<Expr> arg = toConstant(state, eval(ki, 0, state),
+                               "floating point");
+    uint64_t value = floats::trunc(arg.getConstantValue(),
+                                   resultType,
+                                   arg.getWidth());
+    ref<Expr> result(value, resultType);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::FPExt: {
+    FPExtInst *fi = cast<FPExtInst>(i);
+    Expr::Width resultType = Expr::getWidthForLLVMType(fi->getType());
+    ref<Expr> arg = toConstant(state, eval(ki, 0, state),
+                               "floating point");
+    uint64_t value = floats::ext(arg.getConstantValue(),
+                                 resultType,
+                                 arg.getWidth());
+    ref<Expr> result(value, resultType);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::FPToUI: {
+    FPToUIInst *fi = cast<FPToUIInst>(i);
+    Expr::Width resultType = Expr::getWidthForLLVMType(fi->getType());
+    ref<Expr> arg = toConstant(state, eval(ki, 0, state),
+                               "floating point");
+    uint64_t value = floats::toUnsignedInt(arg.getConstantValue(),
+                                           resultType,
+                                           arg.getWidth());
+    ref<Expr> result(value, resultType);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::FPToSI: {
+    FPToSIInst *fi = cast<FPToSIInst>(i);
+    Expr::Width resultType = Expr::getWidthForLLVMType(fi->getType());
+    ref<Expr> arg = toConstant(state, eval(ki, 0, state),
+                               "floating point");
+    uint64_t value = floats::toSignedInt(arg.getConstantValue(),
+                                         resultType,
+                                         arg.getWidth());
+    ref<Expr> result(value, resultType);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::UIToFP: {
+    UIToFPInst *fi = cast<UIToFPInst>(i);
+    Expr::Width resultType = Expr::getWidthForLLVMType(fi->getType());
+    ref<Expr> arg = toConstant(state, eval(ki, 0, state),
+                               "floating point");
+    uint64_t value = floats::UnsignedIntToFP(arg.getConstantValue(),
+                                             resultType);
+    ref<Expr> result(value, resultType);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::SIToFP: {
+    SIToFPInst *fi = cast<SIToFPInst>(i);
+    Expr::Width resultType = Expr::getWidthForLLVMType(fi->getType());
+    ref<Expr> arg = toConstant(state, eval(ki, 0, state),
+                               "floating point");
+    uint64_t value = floats::SignedIntToFP(arg.getConstantValue(),
+                                           resultType,
+                                           arg.getWidth());
+    ref<Expr> result(value, resultType);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::FCmp: {
+    FCmpInst *fi = cast<FCmpInst>(i);
+    Expr::Width resultType = Expr::getWidthForLLVMType(fi->getType());
+    ref<Expr> left  = toConstant(state, eval(ki, 0, state), 
+                                 "floating point");
+    ref<Expr> right = toConstant(state, eval(ki, 1, state),
+                                 "floating point");
+    uint64_t leftVal = left.getConstantValue();
+    uint64_t rightVal = right.getConstantValue();
+ 
+    //determine whether the operands are NANs
+    unsigned inWidth = left.getWidth();
+    bool leftIsNaN   = floats::isNaN( leftVal,  inWidth );
+    bool rightIsNaN  = floats::isNaN( rightVal, inWidth );
+
+    //handle NAN based on whether the predicate is "ordered" or "unordered"
+    uint64_t ret = (uint64_t)-1;
+    bool done = false;
+    switch( fi->getPredicate() ) {
+      //predicates which only care about whether or not the operands are NaNs
+    case FCmpInst::FCMP_ORD:
+      done = true;
+      ret = !leftIsNaN && !rightIsNaN;
+      break;
+
+    case FCmpInst::FCMP_UNO:
+      done = true;
+      ret = leftIsNaN || rightIsNaN;
+      break;
+
+      //ordered comparisons return false if either operand is NaN
+    case FCmpInst::FCMP_OEQ:
+    case FCmpInst::FCMP_OGT:
+    case FCmpInst::FCMP_OGE:
+    case FCmpInst::FCMP_OLT:
+    case FCmpInst::FCMP_OLE:
+    case FCmpInst::FCMP_ONE:
+      if( !leftIsNaN && !rightIsNaN) //only fall through and return false if there are NaN(s)
+        break;
+
+    case FCmpInst::FCMP_FALSE: { //always return false for this predicate
+      done = true;
+      ret  = false;
+      break;
+    }
+
+      //unordered comparisons return true if either operand is NaN
+    case FCmpInst::FCMP_UEQ:
+    case FCmpInst::FCMP_UGT:
+    case FCmpInst::FCMP_UGE:
+    case FCmpInst::FCMP_ULT:
+    case FCmpInst::FCMP_ULE:
+    case FCmpInst::FCMP_UNE:
+      if( !leftIsNaN && !rightIsNaN) //only fall through and return true if there are NaN(s)
+        break;
+
+    case FCmpInst::FCMP_TRUE: //always return true for this predicate
+      done = true;
+      ret  = true;
+
+    default:
+    case FCmpInst::BAD_FCMP_PREDICATE: /* will fall through and trigger fatal in the next switch */
+      break;
+    }
+
+    //if not done, then we need to actually do a comparison to get the result
+    if( !done ) {
+      switch( fi->getPredicate() ) {
+        //ordered comparisons return false if either operand is NaN
+      case FCmpInst::FCMP_OEQ:
+      case FCmpInst::FCMP_UEQ:
+        ret = floats::eq( leftVal, rightVal, inWidth );
+        break;
+
+      case FCmpInst::FCMP_OGT:
+      case FCmpInst::FCMP_UGT:
+        ret = floats::gt( leftVal, rightVal, inWidth );
+        break;
+
+      case FCmpInst::FCMP_OGE:
+      case FCmpInst::FCMP_UGE:
+        ret = floats::ge( leftVal, rightVal, inWidth );
+        break;
+
+      case FCmpInst::FCMP_OLT:
+      case FCmpInst::FCMP_ULT:
+        ret = floats::lt( leftVal, rightVal, inWidth );
+        break;
+
+      case FCmpInst::FCMP_OLE:
+      case FCmpInst::FCMP_ULE:
+        ret = floats::le( leftVal, rightVal, inWidth );
+        break;
+
+      case FCmpInst::FCMP_ONE:
+      case FCmpInst::FCMP_UNE:
+        ret = floats::ne( leftVal, rightVal, inWidth );
+        break;
+      
+      default:
+        terminateStateOnExecError(state, "invalid FCmp predicate");
+      }
+    }
+
+    ref<Expr> result(ret, resultType);
+    bindLocal(ki, state, result);
+    break;
+  }
+
+  case Instruction::FDiv: {
+    BinaryOperator *bi = cast<BinaryOperator>(i);
+
+    ref<Expr> dividend = eval(ki, 0, state);
+    ref<Expr> divisor = eval(ki, 1, state);
+    Expr::Width type = Expr::getWidthForLLVMType(bi->getType());
+    FP_CONSTANT_BINOP(floats::div, type, dividend, divisor, ki, state);
+    break;
+  }
+
+  case Instruction::FRem: {
+    BinaryOperator *bi = cast<BinaryOperator>(i);
+
+    ref<Expr> dividend = eval(ki, 0, state);
+    ref<Expr> divisor = eval(ki, 1, state);
+    Expr::Width type = Expr::getWidthForLLVMType(bi->getType());
+    FP_CONSTANT_BINOP(floats::mod, type, dividend, divisor, ki, state);
+    break;
+  }
+
+ 
+    // Other instructions...
+    // Unhandled
+  case Instruction::ExtractElement:
+  case Instruction::InsertElement:
+  case Instruction::ShuffleVector:
+    terminateStateOnError(state, "XXX vector instructions unhandled",
+                          "xxx.err");
+    break;
+ 
+  default:
+    terminateStateOnExecError(state, "invalid instruction");
+    break;
+  }
+}
+
+void Executor::updateStates(ExecutionState *current) {
+  if (searcher) {
+    searcher->update(current, addedStates, removedStates);
+  }
+  
+  states.insert(addedStates.begin(), addedStates.end());
+  addedStates.clear();
+  
+  for (std::set<ExecutionState*>::iterator
+         it = removedStates.begin(), ie = removedStates.end();
+       it != ie; ++it) {
+    ExecutionState *es = *it;
+    std::set<ExecutionState*>::iterator it2 = states.find(es);
+    assert(it2!=states.end());
+    states.erase(it2);
+    std::map<ExecutionState*, std::vector<SeedInfo> >::iterator it3 = 
+      seedMap.find(es);
+    if (it3 != seedMap.end())
+      seedMap.erase(it3);
+    processTree->remove(es->ptreeNode);
+    delete es;
+  }
+  removedStates.clear();
+}
+
+void Executor::bindInstructionConstants(KInstruction *KI) {
+  GetElementPtrInst *gepi = dyn_cast<GetElementPtrInst>(KI->inst);
+  if (!gepi)
+    return;
+
+  KGEPInstruction *kgepi = static_cast<KGEPInstruction*>(KI);
+  ref<Expr> constantOffset = Expr::createPointer(0);
+  unsigned index = 1;
+  for (gep_type_iterator ii = gep_type_begin(gepi), ie = gep_type_end(gepi);
+       ii != ie; ++ii) {
+    if (const StructType *st = dyn_cast<StructType>(*ii)) {
+      const StructLayout *sl = 
+        kmodule->targetData->getStructLayout(st);
+      const ConstantInt *ci = cast<ConstantInt>(ii.getOperand());
+      ref<Expr> addend = Expr::createPointer(sl->getElementOffset((unsigned) 
+                                                                  ci->getZExtValue()));
+      constantOffset = AddExpr::create(constantOffset, addend);
+    } else {
+      const SequentialType *st = cast<SequentialType>(*ii);
+      unsigned elementSize = 
+        kmodule->targetData->getTypeStoreSize(st->getElementType());
+      Value *operand = ii.getOperand();
+      if (Constant *c = dyn_cast<Constant>(operand)) {
+        ref<Expr> index = evalConstant(c);
+        ref<Expr> addend = MulExpr::create(Expr::createCoerceToPointerType(index), 
+                                           Expr::createPointer(elementSize));
+        constantOffset = AddExpr::create(constantOffset, addend);
+      } else {
+        kgepi->indices.push_back(std::make_pair(index, elementSize));
+      }
+    }
+    index++;
+  }
+  assert(constantOffset.isConstant());
+  kgepi->offset = constantOffset.getConstantValue();
+}
+
+void Executor::bindModuleConstants() {
+  for (std::vector<KFunction*>::iterator it = kmodule->functions.begin(), 
+         ie = kmodule->functions.end(); it != ie; ++it) {
+    KFunction *kf = *it;
+    for (unsigned i=0; i<kf->numInstructions; ++i)
+      bindInstructionConstants(kf->instructions[i]);
+  }
+
+  kmodule->constantTable = new Cell[kmodule->constants.size()];
+  for (unsigned i=0; i<kmodule->constants.size(); ++i) {
+    Cell &c = kmodule->constantTable[i];
+    c.value = evalConstant(kmodule->constants[i]);
+  }
+}
+
+void Executor::run(ExecutionState &initialState) {
+  bindModuleConstants();
+
+  // Delay init till now so that ticks don't accrue during
+  // optimization and such.
+  initTimers();
+
+  states.insert(&initialState);
+
+  if (usingSeeds) {
+    std::vector<SeedInfo> &v = seedMap[&initialState];
+    
+    for (std::vector<BOut*>::const_iterator it = usingSeeds->begin(), 
+           ie = usingSeeds->end(); it != ie; ++it)
+      v.push_back(SeedInfo(*it));
+
+    int lastNumSeeds = usingSeeds->size()+10;
+    double lastTime, startTime = lastTime = util::getWallTime();
+    ExecutionState *lastState = 0;
+    while (!seedMap.empty()) {
+      if (haltExecution) goto dump;
+
+      std::map<ExecutionState*, std::vector<SeedInfo> >::iterator it = 
+        seedMap.upper_bound(lastState);
+      if (it == seedMap.end())
+        it = seedMap.begin();
+      lastState = it->first;
+      unsigned numSeeds = it->second.size();
+      ExecutionState &state = *lastState;
+      KInstruction *ki = state.pc;
+      stepInstruction(state);
+
+      executeInstruction(state, ki);
+      processTimers(&state, MaxInstructionTime * numSeeds);
+      updateStates(&state);
+
+      if ((stats::instructions % 1000) == 0) {
+        int numSeeds = 0, numStates = 0;
+        for (std::map<ExecutionState*, std::vector<SeedInfo> >::iterator
+               it = seedMap.begin(), ie = seedMap.end();
+             it != ie; ++it) {
+          numSeeds += it->second.size();
+          numStates++;
+        }
+        double time = util::getWallTime();
+        if (SeedTime>0. && time > startTime + SeedTime) {
+          klee_warning("seed time expired, %d seeds remain over %d states",
+                       numSeeds, numStates);
+          break;
+        } else if (numSeeds<=lastNumSeeds-10 ||
+                   time >= lastTime+10) {
+          lastTime = time;
+          lastNumSeeds = numSeeds;          
+          klee_message("%d seeds remaining over: %d states", 
+                       numSeeds, numStates);
+        }
+      }
+    }
+
+    klee_message("seeding done (%d states remain)", (int) states.size());
+
+    // XXX total hack, just because I like non uniform better but want
+    // seed results to be equally weighted.
+    for (std::set<ExecutionState*>::iterator
+           it = states.begin(), ie = states.end();
+         it != ie; ++it) {
+      (*it)->weight = 1.;
+    }
+
+    if (OnlySeed)
+      goto dump;
+  }
+
+  searcher = constructUserSearcher(*this);
+
+  searcher->update(0, states, std::set<ExecutionState*>());
+
+  while (!states.empty() && !haltExecution) {
+    ExecutionState &state = searcher->selectState();
+    KInstruction *ki = state.pc;
+    stepInstruction(state);
+
+    executeInstruction(state, ki);
+    processTimers(&state, MaxInstructionTime);
+
+    if (MaxMemory) {
+      if ((stats::instructions & 0xFFFF) == 0) {
+        // We need to avoid calling GetMallocUsage() often because it
+        // is O(elts on freelist). This is really bad since we start
+        // to pummel the freelist once we hit the memory cap.
+        unsigned mbs = sys::Process::GetTotalMemoryUsage() >> 20;
+        
+        if (mbs > MaxMemory) {
+          if (mbs > MaxMemory + 100) {
+            // just guess at how many to kill
+            unsigned numStates = states.size();
+            unsigned toKill = std::max(1U, numStates - numStates*MaxMemory/mbs);
+
+            if (MaxMemoryInhibit)
+              klee_warning("killing %d states (over memory cap)",
+                           toKill);
+
+            std::vector<ExecutionState*> arr(states.begin(), states.end());
+            for (unsigned i=0,N=arr.size(); N && i<toKill; ++i,--N) {
+              unsigned idx = rand() % N;
+
+              // Make two pulls to try and not hit a state that
+              // covered new code.
+              if (arr[idx]->coveredNew)
+                idx = rand() % N;
+
+              std::swap(arr[idx], arr[N-1]);
+              terminateStateEarly(*arr[N-1], "memory limit");
+            }
+          }
+          atMemoryLimit = true;
+        } else {
+          atMemoryLimit = false;
+        }
+      }
+    }
+
+    updateStates(&state);
+  }
+
+  delete searcher;
+  searcher = 0;
+  
+ dump:
+  if (DumpStatesOnHalt && !states.empty()) {
+    llvm::cerr << "KLEE: halting execution, dumping remaining states\n";
+    for (std::set<ExecutionState*>::iterator
+           it = states.begin(), ie = states.end();
+         it != ie; ++it) {
+      ExecutionState &state = **it;
+      stepInstruction(state); // keep stats rolling
+      terminateStateEarly(state, "execution halting");
+    }
+    updateStates(0);
+  }
+}
+
+std::string Executor::getAddressInfo(ExecutionState &state, 
+                                     ref<Expr> address) const{
+  std::ostringstream info;
+  info << "\taddress: " << address << "\n";
+  uint64_t example;
+  if (address.isConstant()) {
+    example = address.getConstantValue();
+  } else {
+    ref<Expr> value;
+    bool success = solver->getValue(state, address, value);
+    assert(success && "FIXME: Unhandled solver failure");
+    example = value.getConstantValue();
+    info << "\texample: " << example << "\n";
+    std::pair< ref<Expr>, ref<Expr> > res = solver->getRange(state, address);
+    info << "\trange: [" << res.first << ", " << res.second <<"]\n";
+  }
+  
+  MemoryObject hack((unsigned) example);    
+  MemoryMap::iterator lower = state.addressSpace.objects.upper_bound(&hack);
+  info << "\tnext: ";
+  if (lower==state.addressSpace.objects.end()) {
+    info << "none\n";
+  } else {
+    const MemoryObject *mo = lower->first;
+    info << "object at " << mo->address
+         << " of size " << mo->size << "\n";
+  }
+  if (lower!=state.addressSpace.objects.begin()) {
+    --lower;
+    info << "\tprev: ";
+    if (lower==state.addressSpace.objects.end()) {
+      info << "none\n";
+    } else {
+      const MemoryObject *mo = lower->first;
+      info << "object at " << mo->address 
+           << " of size " << mo->size << "\n";
+    }
+  }
+
+  return info.str();
+}
+
+void Executor::terminateState(ExecutionState &state) {
+  if (replayOut && replayPosition!=replayOut->numObjects) {
+    klee_warning_once(replayOut, "replay did not consume all objects in .bout input.");
+  }
+
+  interpreterHandler->incPathsExplored();
+
+  std::set<ExecutionState*>::iterator it = addedStates.find(&state);
+  if (it==addedStates.end()) {
+    state.pc = state.prevPC;
+
+    removedStates.insert(&state);
+  } else {
+    // never reached searcher, just delete immediately
+    std::map< ExecutionState*, std::vector<SeedInfo> >::iterator it3 = 
+      seedMap.find(&state);
+    if (it3 != seedMap.end())
+      seedMap.erase(it3);
+    addedStates.erase(it);
+    processTree->remove(state.ptreeNode);
+    delete &state;
+  }
+}
+
+void Executor::terminateStateEarly(ExecutionState &state, std::string message) {
+  if (!OnlyOutputStatesCoveringNew || state.coveredNew ||
+      (AlwaysOutputSeeds && seedMap.count(&state)))
+    interpreterHandler->processTestCase(state, (message + "\n").c_str(), "early");
+  terminateState(state);
+}
+
+void Executor::terminateStateOnExit(ExecutionState &state) {
+  if (!OnlyOutputStatesCoveringNew || state.coveredNew || 
+      (AlwaysOutputSeeds && seedMap.count(&state)))
+    interpreterHandler->processTestCase(state, 0, 0);
+  terminateState(state);
+}
+
+void Executor::terminateStateOnError(ExecutionState &state,
+                                     const std::string &message,
+                                     const std::string &suffix,
+                                     const std::string &info) {
+  static std::set< std::pair<Instruction*, std::string> > emittedErrors;
+  const InstructionInfo &ii = *state.prevPC->info;
+  
+  if (EmitAllErrors ||
+      emittedErrors.insert(std::make_pair(state.prevPC->inst,message)).second) {
+    if (ii.file != "") {
+      klee_message("ERROR: %s:%d: %s", ii.file.c_str(), ii.line, message.c_str());
+    } else {
+      klee_message("ERROR: %s", message.c_str());
+    }
+    if (!EmitAllErrors)
+      klee_message("NOTE: now ignoring this error at this location");
+    
+    std::ostringstream msg;
+    msg << "Error: " << message << "\n";
+    if (ii.file != "") {
+      msg << "File: " << ii.file << "\n";
+      msg << "Line: " << ii.line << "\n";
+    }
+    msg << "Stack: \n";
+    unsigned idx = 0;
+    const KInstruction *target = state.prevPC;
+    for (ExecutionState::stack_ty::reverse_iterator
+           it = state.stack.rbegin(), ie = state.stack.rend();
+         it != ie; ++it) {
+      StackFrame &sf = *it;
+      Function *f = sf.kf->function;
+      const InstructionInfo &ii = *target->info;
+      msg << "\t#" << idx++ 
+          << " " << std::setw(8) << std::setfill('0') << ii.assemblyLine
+          << " in " << f->getName() << " (";
+      // Yawn, we could go up and print varargs if we wanted to.
+      unsigned index = 0;
+      for (Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end();
+           ai != ae; ++ai) {
+        if (ai!=f->arg_begin()) msg << ", ";
+
+        msg << ai->getName();
+        // XXX should go through function
+        ref<Expr> value = sf.locals[sf.kf->getArgRegister(index++)].value; 
+        if (value.isConstant())
+          msg << "=" << value;
+      }
+      msg << ")";
+      if (ii.file != "")
+        msg << " at " << ii.file << ":" << ii.line;
+      msg << "\n";
+      target = sf.caller;
+    }
+
+    if (info != "")
+      msg << "Info: \n" << info;
+    interpreterHandler->processTestCase(state, msg.str().c_str(), suffix.c_str());
+  }
+    
+  terminateState(state);
+}
+
+// XXX shoot me
+static const char *okExternalsList[] = { "printf", 
+                                         "fprintf", 
+                                         "puts",
+                                         "getpid" };
+static std::set<std::string> okExternals(okExternalsList,
+                                         okExternalsList + 
+                                         (sizeof(okExternalsList)/sizeof(okExternalsList[0])));
+
+void Executor::callExternalFunction(ExecutionState &state,
+                                    KInstruction *target,
+                                    Function *function,
+                                    std::vector< ref<Expr> > &arguments) {
+  // check if specialFunctionHandler wants it
+  if (specialFunctionHandler->handle(state, function, target, arguments))
+    return;
+  
+  if (NoExternals && !okExternals.count(function->getName())) {
+    llvm::cerr << "KLEE:ERROR: Calling not-OK external function : " << function->getName() << "\n";
+    terminateStateOnError(state, "externals disallowed", "user.err");
+    return;
+  }
+
+  // normal external function handling path
+  uint64_t *args = (uint64_t*) alloca(sizeof(*args) * (arguments.size() + 1));
+  memset(args, 0, sizeof(*args) * (arguments.size() + 1));
+
+  unsigned i = 1;
+  for (std::vector<ref<Expr> >::iterator ai = arguments.begin(), ae = arguments.end();
+       ai!=ae; ++ai, ++i) {
+    if (AllowExternalSymCalls) { // don't bother checking uniqueness
+      ref<Expr> ce;
+      bool success = solver->getValue(state, *ai, ce);
+      assert(success && "FIXME: Unhandled solver failure");
+      static_cast<ConstantExpr*>(ce.get())->toMemory((void*) &args[i]);
+    } else {
+      ref<Expr> arg = toUnique(state, *ai);
+      if (arg.isConstant()) {
+        // XXX kick toMemory functions from here
+        static_cast<ConstantExpr*>(arg.get())->toMemory((void*) &args[i]);
+      } else {
+        std::string msg = "external call with symbolic argument: " + function->getName();
+        terminateStateOnExecError(state, msg);
+        return;
+      }
+    }
+  }
+
+  state.addressSpace.copyOutConcretes();
+
+  if (!SuppressExternalWarnings) {
+    std::ostringstream os;
+    os << "calling external: " << function->getName().c_str() << "(";
+    for (unsigned i=0; i<arguments.size(); i++) {
+      os << arguments[i];
+      if (i != arguments.size()-1)
+	os << ", ";
+    }
+    os << ")";
+    
+    if (AllExternalWarnings)
+      klee_warning("%s", os.str().c_str());
+    else
+      klee_warning_once(function, "%s", os.str().c_str());
+  }
+  
+  bool success = externalDispatcher->executeCall(function, target->inst, args);
+  if (!success) {
+    terminateStateOnError(state, "failed external call: " + function->getName(), "external.err");
+    return;
+  }
+
+  if (!state.addressSpace.copyInConcretes()) {
+    terminateStateOnError(state, "external modified read-only object", "external.err");
+    return;
+  }
+
+  const Type *resultType = target->inst->getType();
+  if (resultType != Type::VoidTy) {
+    ref<Expr> e = ConstantExpr::fromMemory((void*) args, 
+                                           Expr::getWidthForLLVMType(resultType));
+    bindLocal(target, state, e);
+  }
+}
+
+/***/
+
+ref<Expr> Executor::replaceReadWithSymbolic(ExecutionState &state, 
+                                            ref<Expr> e) {
+  unsigned n = interpreterOpts.MakeConcreteSymbolic;
+  if (!n || replayOut || replayPath)
+    return e;
+
+  // right now, we don't replace symbolics (is there any reason too?)
+  if (!e.isConstant())
+    return e;
+
+  if (n != 1 && random() %  n)
+    return e;
+
+  // create a new fresh location, assert it is equal to concrete value in e
+  // and return it.
+  
+  const MemoryObject *mo = memory->allocate(Expr::getMinBytesForWidth(e.getWidth()), 
+                                            false, false,
+                                            state.prevPC->inst);
+  assert(mo && "out of memory");
+  ref<Expr> res = Expr::createTempRead(mo->array, e.getWidth());
+  ref<Expr> eq = NotOptimizedExpr::create(EqExpr::create(e, res));
+  llvm::cerr << "Making symbolic: " << eq << "\n";
+  state.addConstraint(eq);
+  return res;
+}
+
+ObjectState *Executor::bindObjectInState(ExecutionState &state, const MemoryObject *mo,
+                                         bool isLocal) {
+  ObjectState *os = new ObjectState(mo, mo->size);
+  state.addressSpace.bindObject(mo, os);
+
+  // Its possible that multiple bindings of the same mo in the state
+  // will put multiple copies on this list, but it doesn't really
+  // matter because all we use this list for is to unbind the object
+  // on function return.
+  if (isLocal)
+    state.stack.back().allocas.push_back(mo);
+
+  return os;
+}
+
+void Executor::executeAllocN(ExecutionState &state,
+                             uint64_t nelems,
+                             uint64_t size,
+                             uint64_t alignment,
+                             bool isLocal,
+                             KInstruction *target) {
+#if 0  
+  // over-allocate so that we can properly align the whole buffer
+  uint64_t address = (uint64_t) (unsigned) malloc(nelems * size + alignment - 1);
+  address += (alignment - address % alignment);
+#else
+  theMMap =   
+    mmap((void*) 0x90000000, 
+         nelems*size, PROT_READ|PROT_WRITE, 
+         MAP_PRIVATE
+#ifdef MAP_ANONYMOUS
+         |MAP_ANONYMOUS
+#endif
+         , 0, 0);
+  uint64_t address = (uintptr_t) theMMap;
+  theMMapSize = nelems*size;
+#endif
+
+  for (unsigned i = 0; i < nelems; i++) {
+    MemoryObject *mo = memory->allocateFixed(address + i*size, size, state.prevPC->inst);
+    ObjectState *os = bindObjectInState(state, mo, isLocal);
+    os->initializeToRandom();
+
+    // bind the local to the first memory object in the whole array
+    if (i == 0)
+      bindLocal(target, state, mo->getBaseExpr());
+  }
+
+  llvm::cerr << "KLEE: allocN at: " << address << "\n";
+}
+
+void Executor::executeAlloc(ExecutionState &state,
+                            ref<Expr> size,
+                            bool isLocal,
+                            KInstruction *target,
+                            bool zeroMemory,
+                            const ObjectState *reallocFrom) {
+  size = toUnique(state, size);
+  if (size.isConstant()) {
+    MemoryObject *mo = memory->allocate(size.getConstantValue(), isLocal, false,
+                                        state.prevPC->inst);
+    if (!mo) {
+      bindLocal(target, state, ref<Expr>(0, kMachinePointerType));
+    } else {
+      ObjectState *os = bindObjectInState(state, mo, isLocal);
+      if (zeroMemory) {
+        os->initializeToZero();
+      } else {
+        os->initializeToRandom();
+      }
+      bindLocal(target, state, mo->getBaseExpr());
+      
+      if (reallocFrom) {
+        unsigned count = std::min(reallocFrom->size, os->size);
+        for (unsigned i=0; i<count; i++)
+          os->write(i, reallocFrom->read8(i));
+        state.addressSpace.unbindObject(reallocFrom->getObject());
+      }
+    }
+  } else {
+    // XXX For now we just pick a size. Ideally we would support
+    // symbolic sizes fully but even if we don't it would be better to
+    // "smartly" pick a value, for example we could fork and pick the
+    // min and max values and perhaps some intermediate (reasonable
+    // value).
+    // 
+    // It would also be nice to recognize the case when size has
+    // exactly two values and just fork (but we need to get rid of
+    // return argument first). This shows up in pcre when llvm
+    // collapses the size expression with a select.
+
+    ref<Expr> example;
+    bool success = solver->getValue(state, size, example);
+    assert(success && "FIXME: Unhandled solver failure");
+    
+    // Try and start with a small example
+    while (example.getConstantValue()>128) {
+      ref<Expr> tmp = ref<Expr>(example.getConstantValue() >> 1, 
+                                example.getWidth());
+      bool res;
+      bool success = solver->mayBeTrue(state, EqExpr::create(tmp, size), res);
+      assert(success && "FIXME: Unhandled solver failure");      
+      if (!res)
+        break;
+      example = tmp;
+    }
+
+    StatePair fixedSize = fork(state, EqExpr::create(example, size), true);
+    
+    if (fixedSize.second) { 
+      // Check for exactly two values
+      ref<Expr> tmp;
+      bool success = solver->getValue(*fixedSize.second, size, tmp);
+      assert(success && "FIXME: Unhandled solver failure");      
+      bool res;
+      success = solver->mustBeTrue(*fixedSize.second, 
+                                   EqExpr::create(tmp, size),
+                                   res);
+      assert(success && "FIXME: Unhandled solver failure");      
+      if (res) {
+        executeAlloc(*fixedSize.second, tmp, isLocal,
+                     target, zeroMemory, reallocFrom);
+      } else {
+        // See if a *really* big value is possible. If so assume
+        // malloc will fail for it, so lets fork and return 0.
+        StatePair hugeSize = fork(*fixedSize.second, 
+                                  UltExpr::create(ref<Expr>(1<<31, Expr::Int32), size), 
+                                  true);
+        if (hugeSize.first) {
+          klee_message("NOTE: found huge malloc, returing 0");
+          bindLocal(target, *hugeSize.first, ref<Expr>(0,kMachinePointerType));
+        }
+        
+        if (hugeSize.second) {
+          std::ostringstream info;
+          ExprPPrinter::printOne(info, "  size expr", size);
+          info << "  concretization : " << example << "\n";
+          info << "  unbound example: " << tmp << "\n";
+          terminateStateOnError(*hugeSize.second, 
+                                "concretized symbolic size", 
+                                "model.err", 
+                                info.str());
+        }
+      }
+    }
+
+    if (fixedSize.first) // can be zero when fork fails
+      executeAlloc(*fixedSize.first, example, isLocal, 
+                   target, zeroMemory, reallocFrom);
+  }
+}
+
+void Executor::executeFree(ExecutionState &state,
+                           ref<Expr> address,
+                           KInstruction *target) {
+  StatePair zeroPointer = fork(state, Expr::createIsZero(address), true);
+  if (zeroPointer.first) {
+    if (target)
+      bindLocal(target, *zeroPointer.first, Expr::createPointer(0));
+  }
+  if (zeroPointer.second) { // address != 0
+    ExactResolutionList rl;
+    resolveExact(*zeroPointer.second, address, rl, "free");
+    
+    for (Executor::ExactResolutionList::iterator it = rl.begin(), 
+           ie = rl.end(); it != ie; ++it) {
+      const MemoryObject *mo = it->first.first;
+      if (mo->isLocal) {
+        terminateStateOnError(*it->second, 
+                              "free of alloca", 
+                              "free.err",
+                              getAddressInfo(*it->second, address));
+      } else if (mo->isGlobal) {
+        terminateStateOnError(*it->second, 
+                              "free of global", 
+                              "free.err",
+                              getAddressInfo(*it->second, address));
+      } else {
+        it->second->addressSpace.unbindObject(mo);
+        if (target)
+          bindLocal(target, *it->second, Expr::createPointer(0));
+      }
+    }
+  }
+}
+
+void Executor::resolveExact(ExecutionState &state,
+                            ref<Expr> p,
+                            ExactResolutionList &results, 
+                            const std::string &name) {
+  // XXX we may want to be capping this?
+  ResolutionList rl;
+  state.addressSpace.resolve(state, solver, p, rl);
+  
+  ExecutionState *unbound = &state;
+  for (ResolutionList::iterator it = rl.begin(), ie = rl.end(); 
+       it != ie; ++it) {
+    ref<Expr> inBounds = EqExpr::create(p, it->first->getBaseExpr());
+    
+    StatePair branches = fork(*unbound, inBounds, true);
+    
+    if (branches.first)
+      results.push_back(std::make_pair(*it, branches.first));
+
+    unbound = branches.second;
+    if (!unbound) // Fork failure
+      break;
+  }
+
+  if (unbound) {
+    terminateStateOnError(*unbound,
+                          "memory error: invalid pointer: " + name,
+                          "ptr.err",
+                          getAddressInfo(*unbound, p));
+  }
+}
+
+void Executor::executeMemoryOperation(ExecutionState &state,
+                                      bool isWrite,
+                                      ref<Expr> address,
+                                      ref<Expr> value /* undef if read */,
+                                      KInstruction *target /* undef if write */) {
+  Expr::Width type = (isWrite ? value.getWidth() : 
+                     Expr::getWidthForLLVMType(target->inst->getType()));
+  unsigned bytes = Expr::getMinBytesForWidth(type);
+
+  if (SimplifySymIndices) {
+    if (!address.isConstant())
+      address = state.constraints.simplifyExpr(address);
+    if (isWrite && !value.isConstant())
+      value = state.constraints.simplifyExpr(value);
+  }
+
+  // fast path: single in-bounds resolution
+  ObjectPair op;
+  bool success;
+  solver->setTimeout(stpTimeout);
+  if (!state.addressSpace.resolveOne(state, solver, address, op, success)) {
+    address = toConstant(state, address, "resolveOne failure");
+    success = state.addressSpace.resolveOne(address.getConstantValue(), op);
+  }
+  solver->setTimeout(0);
+
+  if (success) {
+    const MemoryObject *mo = op.first;
+
+    if (MaxSymArraySize && mo->size>=MaxSymArraySize) {
+      address = toConstant(state, address, "max-sym-array-size");
+    }
+    
+    ref<Expr> offset = mo->getOffsetExpr(address);
+
+    bool inBounds;
+    solver->setTimeout(stpTimeout);
+    bool success = solver->mustBeTrue(state, 
+                                      mo->getBoundsCheckOffset(offset, bytes),
+                                      inBounds);
+    solver->setTimeout(0);
+    if (!success) {
+      state.pc = state.prevPC;
+      terminateStateEarly(state, "query timed out");
+      return;
+    }
+
+    if (inBounds) {
+      const ObjectState *os = op.second;
+      if (isWrite) {
+        if (os->readOnly) {
+          terminateStateOnError(state,
+                                "memory error: object read only",
+                                "readonly.err");
+        } else {
+          ObjectState *wos = state.addressSpace.getWriteable(mo, os);
+          wos->write(offset, value);
+        }          
+      } else {
+        ref<Expr> result = os->read(offset, type);
+        
+        if (interpreterOpts.MakeConcreteSymbolic)
+          result = replaceReadWithSymbolic(state, result);
+        
+        bindLocal(target, state, result);
+      }
+
+      return;
+    }
+  } 
+
+  // we are on an error path (no resolution, multiple resolution, one
+  // resolution with out of bounds)
+  
+  ResolutionList rl;  
+  solver->setTimeout(stpTimeout);
+  bool incomplete = state.addressSpace.resolve(state, solver, address, rl,
+                                               0, stpTimeout);
+  solver->setTimeout(0);
+  
+  // XXX there is some query wasteage here. who cares?
+  ExecutionState *unbound = &state;
+  
+  for (ResolutionList::iterator i = rl.begin(), ie = rl.end(); i != ie; ++i) {
+    const MemoryObject *mo = i->first;
+    const ObjectState *os = i->second;
+    ref<Expr> inBounds = mo->getBoundsCheckPointer(address, bytes);
+    
+    StatePair branches = fork(*unbound, inBounds, true);
+    ExecutionState *bound = branches.first;
+
+    // bound can be 0 on failure or overlapped 
+    if (bound) {
+      if (isWrite) {
+        if (os->readOnly) {
+          terminateStateOnError(*bound,
+                                "memory error: object read only",
+                                "readonly.err");
+        } else {
+          ObjectState *wos = bound->addressSpace.getWriteable(mo, os);
+          wos->write(mo->getOffsetExpr(address), value);
+        }
+      } else {
+        ref<Expr> result = os->read(mo->getOffsetExpr(address), type);
+        bindLocal(target, *bound, result);
+      }
+    }
+
+    unbound = branches.second;
+    if (!unbound)
+      break;
+  }
+  
+  // XXX should we distinguish out of bounds and overlapped cases?
+  if (unbound) {
+    if (incomplete) {
+      terminateStateEarly(*unbound, "query timed out (resolve)");
+    } else {
+      terminateStateOnError(*unbound,
+                            "memory error: out of bound pointer",
+                            "ptr.err",
+                            getAddressInfo(*unbound, address));
+    }
+  }
+}
+
+void Executor::executeMakeSymbolic(ExecutionState &state, 
+                                   const MemoryObject *mo) {
+  // make a new one and rebind, we use bind here because we want to
+  // create a flat out new state, not a copy. although I'm not really
+  // sure it matters.
+  ObjectState *os = bindObjectInState(state, mo, false);
+  if (!replayOut) {
+    os->makeSymbolic();
+    state.addSymbolic(mo);
+    
+    std::map< ExecutionState*, std::vector<SeedInfo> >::iterator it = 
+      seedMap.find(&state);
+    if (it!=seedMap.end()) { // In seed mode we need to add this as a
+                             // binding.
+      for (std::vector<SeedInfo>::iterator siit = it->second.begin(), 
+             siie = it->second.end(); siit != siie; ++siit) {
+        SeedInfo &si = *siit;
+        BOutObject *obj = si.getNextInput(mo,
+                                          NamedSeedMatching);
+
+        if (!obj) {
+          if (ZeroSeedExtension) {
+            std::vector<unsigned char> &values = 
+              si.assignment.bindings[mo->array];
+            values = std::vector<unsigned char>(mo->size, '\0');
+          } else if (!AllowSeedExtension) {
+            terminateStateOnError(state, 
+                                  "ran out of inputs during seeding",
+                                  "user.err");
+            break;
+          }
+        } else {
+          if (obj->numBytes != mo->size &&
+              ((!(AllowSeedExtension || ZeroSeedExtension)
+                && obj->numBytes < mo->size) ||
+               (!AllowSeedTruncation && obj->numBytes > mo->size))) {
+	    std::stringstream msg;
+	    msg << "replace size mismatch: "
+		<< mo->name << "[" << mo->size << "]"
+		<< " vs " << obj->name << "[" << obj->numBytes << "]"
+		<< " in bout\n";
+
+            terminateStateOnError(state,
+                                  msg.str(),
+                                  "user.err");
+            break;
+          } else {
+            std::vector<unsigned char> &values = 
+              si.assignment.bindings[mo->array];
+            values.insert(values.begin(), obj->bytes, 
+                          obj->bytes + std::min(obj->numBytes, mo->size));            
+            if (ZeroSeedExtension) {
+              for (unsigned i=obj->numBytes; i<mo->size; ++i)
+                values.push_back('\0');
+            }
+          }
+        }
+      }
+    }
+  } else {
+    if (replayPosition >= replayOut->numObjects) {
+      terminateStateOnError(state, "replay count mismatch", "user.err");
+    } else {
+      BOutObject *obj = &replayOut->objects[replayPosition++];
+      if (obj->numBytes != mo->size) {
+        terminateStateOnError(state, "replay size mismatch", "user.err");
+      } else {
+        for (unsigned i=0; i<mo->size; i++)
+          os->write8(i, obj->bytes[i]);
+      }
+    }
+  }
+}
+
+/***/
+
+void Executor::runFunctionAsMain(Function *f,
+				 int argc,
+				 char **argv,
+				 char **envp) {
+  std::vector<ref<Expr> > arguments;
+
+  // force deterministic initialization of memory objects
+  srand(1);
+  srandom(1);
+  
+  MemoryObject *argvMO = 0;
+
+  // In order to make uclibc happy and be closer to what the system is
+  // doing we lay out the environments at the end of the argv array
+  // (both are terminated by a null). There is also a final terminating
+  // null that uclibc seems to expect, possibly the ELF header?
+
+  int envc;
+  for (envc=0; envp[envc]; ++envc) ;
+
+  KFunction *kf = kmodule->functionMap[f];
+  assert(kf);
+  Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end();
+  if (ai!=ae) {
+    arguments.push_back(ref<Expr>(argc, Expr::Int32));
+
+    if (++ai!=ae) {
+      argvMO = memory->allocate((argc+1+envc+1+1) * kMachinePointerSize, false, true,
+                                f->begin()->begin());
+      
+      arguments.push_back(argvMO->getBaseExpr());
+
+      if (++ai!=ae) {
+        uint64_t envp_start = argvMO->address + (argc+1)*kMachinePointerSize;
+        arguments.push_back(Expr::createPointer(envp_start));
+
+        if (++ai!=ae)
+          klee_error("invalid main function (expect 0-3 arguments)");
+      }
+    }
+  }
+
+  ExecutionState *state = new ExecutionState(kmodule->functionMap[f]);
+  
+  if (pathWriter) 
+    state->pathOS = pathWriter->open();
+  if (symPathWriter) 
+    state->symPathOS = symPathWriter->open();
+
+
+  if (statsTracker)
+    statsTracker->framePushed(*state, 0);
+
+  assert(arguments.size() == f->arg_size() && "wrong number of arguments");
+  for (unsigned i = 0, e = f->arg_size(); i != e; ++i)
+    bindArgument(kf, i, *state, arguments[i]);
+
+  if (argvMO) {
+    ObjectState *argvOS = bindObjectInState(*state, argvMO, false);
+
+    for (int i=0; i<argc+1+envc+1+1; i++) {
+      MemoryObject *arg;
+      
+      if (i==argc || i>=argc+1+envc) {
+        arg = 0;
+      } else {
+        char *s = i<argc ? argv[i] : envp[i-(argc+1)];
+        int j, len = strlen(s);
+        
+        arg = memory->allocate(len+1, false, true, state->pc->inst);
+        ObjectState *os = bindObjectInState(*state, arg, false);
+        for (j=0; j<len+1; j++)
+          os->write8(j, s[j]);
+      }
+
+      if (arg) {
+        argvOS->write(i * kMachinePointerSize, arg->getBaseExpr());
+      } else {
+        argvOS->write(i * kMachinePointerSize, Expr::createPointer(0));
+      }
+    }
+  }
+  
+  initializeGlobals(*state);
+
+  processTree = new PTree(state);
+  state->ptreeNode = processTree->root;
+  run(*state);
+  delete processTree;
+  processTree = 0;
+
+  // hack to clear memory objects
+  delete memory;
+  memory = new MemoryManager();
+  
+  globalObjects.clear();
+  globalAddresses.clear();
+
+  if (statsTracker)
+    statsTracker->done();
+
+  if (theMMap) {
+    munmap(theMMap, theMMapSize);
+    theMMap = 0;
+  }
+}
+
+unsigned Executor::getPathStreamID(const ExecutionState &state) {
+  assert(pathWriter);
+  return state.pathOS.getID();
+}
+
+unsigned Executor::getSymbolicPathStreamID(const ExecutionState &state) {
+  assert(symPathWriter);
+  return state.symPathOS.getID();
+}
+
+void Executor::getConstraintLog(const ExecutionState &state,
+                                std::string &res,
+                                bool asCVC) {
+  if (asCVC) {
+    Query query(state.constraints, ref<Expr>(0, Expr::Bool));
+    char *log = solver->stpSolver->getConstraintLog(query);
+    res = std::string(log);
+    free(log);
+  } else {
+    std::ostringstream info;
+    ExprPPrinter::printConstraints(info, state.constraints);
+    res = info.str();    
+  }
+}
+
+bool Executor::getSymbolicSolution(const ExecutionState &state,
+                                   std::vector< 
+                                   std::pair<std::string,
+                                   std::vector<unsigned char> > >
+                                   &res) {
+  solver->setTimeout(stpTimeout);
+
+  ExecutionState tmp(state);
+  if (!NoPreferCex) {
+    for (std::vector<const MemoryObject*>::const_iterator 
+           it = state.symbolics.begin(), ie = state.symbolics.end(); 
+         it != ie; ++it) {
+      const MemoryObject *mo = *it;
+      std::vector< ref<Expr> >::const_iterator pi = 
+        mo->cexPreferences.begin(), pie = mo->cexPreferences.end();
+      for (; pi != pie; ++pi) {
+        bool mustBeTrue;
+        bool success = solver->mustBeTrue(tmp, Expr::createNot(*pi), 
+                                          mustBeTrue);
+        if (!success) break;
+        if (!mustBeTrue) tmp.addConstraint(*pi);
+      }
+      if (pi!=pie) break;
+    }
+  }
+
+  std::vector< std::vector<unsigned char> > values;
+  std::vector<const Array*> objects;
+  for (unsigned i = 0; i != state.symbolics.size(); ++i)
+    objects.push_back(state.symbolics[i]->array);
+  bool success = solver->getInitialValues(tmp, objects, values);
+  solver->setTimeout(0);
+  if (!success) {
+    klee_warning("unable to compute initial values (invalid constraints?)!");
+    ExprPPrinter::printQuery(std::cerr,
+                             state.constraints, 
+                             ref<Expr>(0,Expr::Bool));
+    return false;
+  }
+  
+  unsigned i = 0;
+  for (std::vector<const MemoryObject*>::const_iterator 
+         it = state.symbolics.begin(), ie = state.symbolics.end(); 
+       it != ie; ++it) {
+    res.push_back(std::make_pair((*it)->name, values[i]));
+    ++i;
+  }
+  return true;
+}
+
+void Executor::getCoveredLines(const ExecutionState &state,
+                               std::map<const std::string*, std::set<unsigned> > &res) {
+  res = state.coveredLines;
+}
+
+void Executor::doImpliedValueConcretization(ExecutionState &state,
+                                            ref<Expr> e,
+                                            ref<Expr> value) {
+  assert(value.isConstant() && "non-constant passed in place of constant");
+  
+  if (DebugCheckForImpliedValues)
+    ImpliedValue::checkForImpliedValues(solver->solver, e, value);
+
+  ImpliedValueList results;
+  ImpliedValue::getImpliedValues(e, value, results);
+  for (ImpliedValueList::iterator it = results.begin(), ie = results.end();
+       it != ie; ++it) {
+    ReadExpr *re = it->first.get();
+    
+    if (re->index.isConstant()) {
+      // FIXME: This is the sole remaining usage of the Array object
+      // variable. Kill me.
+      const MemoryObject *mo = re->updates.root->object;
+      const ObjectState *os = state.addressSpace.findObject(mo);
+
+      if (!os) {
+        // object has been free'd, no need to concretize (although as
+        // in other cases we would like to concretize the outstanding
+        // reads, but we have no facility for that yet)
+      } else {
+        assert(!os->readOnly && "not possible? read only object with static read?");
+        ObjectState *wos = state.addressSpace.getWriteable(mo, os);
+        wos->write(re->index.getConstantValue(), it->second);
+      }
+    }
+  }
+}
+
+///
+
+Interpreter *Interpreter::create(const InterpreterOptions &opts,
+                                 InterpreterHandler *ih) {
+  return new Executor(opts, ih);
+}
diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h
new file mode 100644
index 00000000..76868291
--- /dev/null
+++ b/lib/Core/Executor.h
@@ -0,0 +1,445 @@
+//===-- Executor.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Class to perform actual execution, hides implementation details from external
+// interpreter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXECUTOR_H
+#define KLEE_EXECUTOR_H
+
+#include "klee/Interpreter.h"
+#include "llvm/Support/CallSite.h"
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+
+struct BOut;
+
+namespace llvm {
+  class BasicBlock;
+  class BranchInst;
+  class CallInst;
+  class Constant;
+  class ConstantExpr;
+  class Function;
+  class GlobalValue;
+  class Instruction;
+  class TargetData;
+  class Value;
+}
+
+namespace klee {  
+  class ExecutionState;
+  class ExternalDispatcher;
+  class Expr;
+  class InstructionInfoTable;
+  class KFunction;
+  class KInstruction;
+  class KInstIterator;
+  class KModule;
+  class MemoryManager;
+  class MemoryObject;
+  class ObjectState;
+  class PTree;
+  class Searcher;
+  class SeedInfo;
+  class SpecialFunctionHandler;
+  class StackFrame;
+  class StatsTracker;
+  class TimingSolver;
+  class TreeStreamWriter;
+  template<class T> class ref;
+
+  /// \todo Add a context object to keep track of data only live
+  /// during an instruction step. Should contain addedStates,
+  /// removedStates, and haltExecution, among others.
+
+class Executor : public Interpreter {
+  friend class BumpMergingSearcher;
+  friend class MergingSearcher;
+  friend class RandomPathSearcher;
+  friend class OwningSearcher;
+  friend class WeightedRandomSearcher;
+  friend class SpecialFunctionHandler;
+  friend class StatsTracker;
+
+public:
+  class Timer {
+  public:
+    Timer();
+    virtual ~Timer();
+
+    /// The event callback.
+    virtual void run() = 0;
+  };
+
+  typedef std::pair<ExecutionState*,ExecutionState*> StatePair;
+
+private:
+  class TimerInfo;
+
+  KModule *kmodule;
+  InterpreterHandler *interpreterHandler;
+  Searcher *searcher;
+
+  ExternalDispatcher *externalDispatcher;
+  TimingSolver *solver;
+  MemoryManager *memory;
+  std::set<ExecutionState*> states;
+  StatsTracker *statsTracker;
+  TreeStreamWriter *pathWriter, *symPathWriter;
+  SpecialFunctionHandler *specialFunctionHandler;
+  std::vector<TimerInfo*> timers;
+  PTree *processTree;
+
+  /// Used to track states that have been added during the current
+  /// instructions step. 
+  /// \invariant \ref addedStates is a subset of \ref states. 
+  /// \invariant \ref addedStates and \ref removedStates are disjoint.
+  std::set<ExecutionState*> addedStates;
+  /// Used to track states that have been removed during the current
+  /// instructions step. 
+  /// \invariant \ref removedStates is a subset of \ref states. 
+  /// \invariant \ref addedStates and \ref removedStates are disjoint.
+  std::set<ExecutionState*> removedStates;
+
+  /// When non-empty the Executor is running in "seed" mode. The
+  /// states in this map will be executed in an arbitrary order
+  /// (outside the normal search interface) until they terminate. When
+  /// the states reach a symbolic branch then either direction that
+  /// satisfies one or more seeds will be added to this map. What
+  /// happens with other states (that don't satisfy the seeds) depends
+  /// on as-yet-to-be-determined flags.
+  std::map<ExecutionState*, std::vector<SeedInfo> > seedMap;
+  
+  /// Map of globals to their representative memory object.
+  std::map<const llvm::GlobalValue*, MemoryObject*> globalObjects;
+
+  /// Map of globals to their bound address. This also includes
+  /// globals that have no representative object (i.e. functions).
+  std::map<const llvm::GlobalValue*, ref<Expr> > globalAddresses;
+
+  /// The set of legal function addresses, used to validate function
+  /// pointers.
+  std::set<void*> legalFunctions;
+
+  /// When non-null the bindings that will be used for calls to
+  /// klee_make_symbolic in order replay.
+  const struct BOut *replayOut;
+  /// When non-null a list of branch decisions to be used for replay.
+  const std::vector<bool> *replayPath;
+  /// The index into the current \ref replayOut or \ref replayPath
+  /// object.
+  unsigned replayPosition;
+
+  /// When non-null a list of "seed" inputs which will be used to
+  /// drive execution.
+  const std::vector<struct BOut *> *usingSeeds;  
+
+  /// Disables forking, instead a random path is chosen. Enabled as
+  /// needed to control memory usage. \see fork()
+  bool atMemoryLimit;
+
+  /// Disables forking, set by client. \see setInhibitForking()
+  bool inhibitForking;
+
+  /// Signals the executor to halt execution at the next instruction
+  /// step.
+  bool haltExecution;  
+
+  /// Whether implied-value concretization is enabled. Currently
+  /// false, it is buggy (it needs to validate its writes).
+  bool ivcEnabled;
+
+  /// The maximum time to allow for a single stp query.
+  double stpTimeout;  
+
+  llvm::Function* getCalledFunction(llvm::CallSite &cs, ExecutionState &state);
+  
+  void executeInstruction(ExecutionState &state, KInstruction *ki);
+
+  void printFileLine(ExecutionState &state, KInstruction *ki);
+
+  void run(ExecutionState &initialState);
+
+  // Given a concrete object in our [klee's] address space, add it to 
+  // objects checked code can reference.
+  MemoryObject *addExternalObject(ExecutionState &state, void *addr, 
+                                  unsigned size, bool isReadOnly);
+
+  void initializeGlobalObject(ExecutionState &state, ObjectState *os, 
+			      llvm::Constant *c,
+			      unsigned offset);
+  void initializeGlobals(ExecutionState &state);
+
+  void stepInstruction(ExecutionState &state);
+  void updateStates(ExecutionState *current);
+  void transferToBasicBlock(llvm::BasicBlock *dst, 
+			    llvm::BasicBlock *src,
+			    ExecutionState &state);
+
+  void callExternalFunction(ExecutionState &state,
+                            KInstruction *target,
+                            llvm::Function *function,
+                            std::vector< ref<Expr> > &arguments);
+
+  ObjectState *bindObjectInState(ExecutionState &state, const MemoryObject *mo,
+                                 bool isLocal);
+
+  /// Resolve a pointer to the memory objects it could point to the
+  /// start of, forking execution when necessary and generating errors
+  /// for pointers to invalid locations (either out of bounds or
+  /// address inside the middle of objects).
+  ///
+  /// \param results[out] A list of ((MemoryObject,ObjectState),
+  /// state) pairs for each object the given address can point to the
+  /// beginning of.
+  typedef std::vector< std::pair<std::pair<const MemoryObject*, const ObjectState*>, 
+                                 ExecutionState*> > ExactResolutionList;
+  void resolveExact(ExecutionState &state,
+                    ref<Expr> p,
+                    ExactResolutionList &results,
+                    const std::string &name);
+
+  /// Allocate and bind a new object in a particular state. NOTE: This
+  /// function may fork.
+  ///
+  /// \param isLocal Flag to indicate if the object should be
+  /// automatically deallocated on function return (this also makes it
+  /// illegal to free directly).
+  ///
+  /// \param target Value at which to bind the base address of the new
+  /// object.
+  ///
+  /// \param reallocFrom If non-zero and the allocation succeeds,
+  /// initialize the new object from the given one and unbind it when
+  /// done (realloc semantics). The initialized bytes will be the
+  /// minimum of the size of the old and new objects, with remaining
+  /// bytes initialized as specified by zeroMemory.
+  void executeAlloc(ExecutionState &state,
+                    ref<Expr> size,
+                    bool isLocal,
+                    KInstruction *target,
+                    bool zeroMemory=false,
+                    const ObjectState *reallocFrom=0);
+
+  /// XXX not for public use (this is for histar, it allocations a
+  /// contiguous set of objects, while guaranteeing page alignment)
+  void executeAllocN(ExecutionState &state,
+                     uint64_t nelems,
+                     uint64_t size,
+                     uint64_t alignment,
+                     bool isLocal,
+                     KInstruction *target);
+
+  /// Free the given address with checking for errors. If target is
+  /// given it will be bound to 0 in the resulting states (this is a
+  /// convenience for realloc). Note that this function can cause the
+  /// state to fork and that \ref state cannot be safely accessed
+  /// afterwards.
+  void executeFree(ExecutionState &state,
+                   ref<Expr> address,
+                   KInstruction *target = 0);
+  
+  void executeCall(ExecutionState &state, 
+                   KInstruction *ki,
+                   llvm::Function *f,
+                   std::vector< ref<Expr> > &arguments);
+                   
+  // do address resolution / object binding / out of bounds checking
+  // and perform the operation
+  void executeMemoryOperation(ExecutionState &state,
+                              bool isWrite,
+                              ref<Expr> address,
+                              ref<Expr> value /* undef if read */,
+                              KInstruction *target /* undef if write */);
+
+  void executeMakeSymbolic(ExecutionState &state, const MemoryObject *mo);
+
+  /// Create a new state where each input condition has been added as
+  /// a constraint and return the results. The input state is included
+  /// as one of the results. Note that the output vector may included
+  /// NULL pointers for states which were unable to be created.
+  void branch(ExecutionState &state, 
+              const std::vector< ref<Expr> > &conditions,
+              std::vector<ExecutionState*> &result);
+
+  // Fork current and return states in which condition holds / does
+  // not hold, respectively. One of the states is necessarily the
+  // current state, and one of the states may be null.
+  StatePair fork(ExecutionState &current, ref<Expr> condition, bool isInternal);
+
+  /// Add the given (boolean) condition as a constraint on state. This
+  /// function is a wrapper around the state's addConstraint function
+  /// which also manages manages propogation of implied values,
+  /// validity checks, and seed patching.
+  void addConstraint(ExecutionState &state, ref<Expr> condition);
+
+  // Called on [for now] concrete reads, replaces constant with a symbolic
+  // Used for testing.
+  ref<Expr> replaceReadWithSymbolic(ExecutionState &state, ref<Expr> e);
+
+  ref<Expr> eval(KInstruction *ki,
+                 unsigned index, 
+                 ExecutionState &state);
+  
+  void bindLocal(KInstruction *target, 
+                 ExecutionState &state, 
+                 ref<Expr> value);
+  void bindArgument(KFunction *kf, 
+                    unsigned index,
+                    ExecutionState &state,
+                    ref<Expr> value);
+
+  ref<Expr> evalConstantExpr(llvm::ConstantExpr *ce);
+
+  /// Return a unique constant value for the given expression in the
+  /// given state, if it has one (i.e. it provably only has a single
+  /// value). Otherwise return the original expression.
+  ref<Expr> toUnique(const ExecutionState &state, ref<Expr> &e);
+
+  /// Return a constant value for the given expression, forcing it to
+  /// be constant in the given state by adding a constraint if
+  /// necessary. Note that this function breaks completeness and
+  /// should generally be avoided.
+  ///
+  /// \param purpose An identify string to printed in case of concretization.
+  ref<Expr> toConstant(ExecutionState &state, ref<Expr> e, const char *purpose);
+
+  /// Bind a constant value for e to the given target. NOTE: This
+  /// function may fork state if the state has multiple seeds.
+  void executeGetValue(ExecutionState &state, ref<Expr> e, KInstruction *target);
+
+  /// Get textual information regarding a memory address.
+  std::string getAddressInfo(ExecutionState &state, ref<Expr> address) const;
+
+  // remove state from queue and delete
+  void terminateState(ExecutionState &state);
+  // call exit handler and terminate state
+  void terminateStateEarly(ExecutionState &state, std::string message);
+  // call exit handler and terminate state
+  void terminateStateOnExit(ExecutionState &state);
+  // call error handler and terminate state
+  void terminateStateOnError(ExecutionState &state, 
+                             const std::string &message,
+                             const std::string &suffix,
+                             const std::string &longMessage="");
+
+  // call error handler and terminate state, for execution errors
+  // (things that should not be possible, like illegal instruction or
+  // unlowered instrinsic, or are unsupported, like inline assembly)
+  void terminateStateOnExecError(ExecutionState &state, 
+                                 const std::string &message,
+                                 const std::string &info="") {
+    terminateStateOnError(state, message, "exec.err", info);
+  }
+
+  /// bindModuleConstants - Initialize the module constant table.
+  void bindModuleConstants();
+
+  /// bindInstructionConstants - Initialize any necessary per instruction
+  /// constant values.
+  void bindInstructionConstants(KInstruction *KI);
+
+  void handlePointsToObj(ExecutionState &state, 
+                         KInstruction *target, 
+                         const std::vector<ref<Expr> > &arguments);
+
+  void doImpliedValueConcretization(ExecutionState &state,
+                                    ref<Expr> e,
+                                    ref<Expr> value);
+
+  /// Add a timer to be executed periodically.
+  ///
+  /// \param timer The timer object to run on firings.
+  /// \param rate The approximate delay (in seconds) between firings.
+  void addTimer(Timer *timer, double rate);
+
+  void initTimers();
+  void processTimers(ExecutionState *current,
+                     double maxInstTime);
+                
+public:
+  Executor(const InterpreterOptions &opts, InterpreterHandler *ie);
+  virtual ~Executor();
+
+  const InterpreterHandler& getHandler() {
+    return *interpreterHandler;
+  }
+
+  // XXX should just be moved out to utility module
+  ref<Expr> evalConstant(llvm::Constant *c);
+
+  virtual void setPathWriter(TreeStreamWriter *tsw) {
+    pathWriter = tsw;
+  }
+  virtual void setSymbolicPathWriter(TreeStreamWriter *tsw) {
+    symPathWriter = tsw;
+  }      
+
+  virtual void setReplayOut(const struct BOut *out) {
+    assert(!replayPath && "cannot replay both buffer and path");
+    replayOut = out;
+    replayPosition = 0;
+  }
+
+  virtual void setReplayPath(const std::vector<bool> *path) {
+    assert(!replayOut && "cannot replay both buffer and path");
+    replayPath = path;
+    replayPosition = 0;
+  }
+
+  virtual const llvm::Module *
+  setModule(llvm::Module *module, const ModuleOptions &opts);
+
+  virtual void useSeeds(const std::vector<struct BOut *> *seeds) { 
+    usingSeeds = seeds;
+  }
+
+  virtual void runFunctionAsMain(llvm::Function *f,
+                                 int argc,
+                                 char **argv,
+                                 char **envp);
+
+  /*** Runtime options ***/
+  
+  virtual void setHaltExecution(bool value) {
+    haltExecution = value;
+  }
+
+  virtual void setInhibitForking(bool value) {
+    inhibitForking = value;
+  }
+
+  /*** State accessor methods ***/
+
+  virtual unsigned getPathStreamID(const ExecutionState &state);
+
+  virtual unsigned getSymbolicPathStreamID(const ExecutionState &state);
+
+  virtual void getConstraintLog(const ExecutionState &state,
+                                std::string &res,
+                                bool asCVC = false);
+
+  virtual bool getSymbolicSolution(const ExecutionState &state, 
+                                   std::vector< 
+                                   std::pair<std::string,
+                                   std::vector<unsigned char> > >
+                                   &res);
+
+  virtual void getCoveredLines(const ExecutionState &state,
+                               std::map<const std::string*, std::set<unsigned> > &res);
+};
+  
+} // End klee namespace
+
+#endif
diff --git a/lib/Core/ExecutorTimers.cpp b/lib/Core/ExecutorTimers.cpp
new file mode 100644
index 00000000..51792e0d
--- /dev/null
+++ b/lib/Core/ExecutorTimers.cpp
@@ -0,0 +1,220 @@
+//===-- ExecutorTimers.cpp ------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "CoreStats.h"
+#include "Executor.h"
+#include "PTree.h"
+#include "StatsTracker.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Internal/Module/InstructionInfoTable.h"
+#include "klee/Internal/Module/KInstruction.h"
+#include "klee/Internal/Module/KModule.h"
+#include "klee/Internal/System/Time.h"
+
+#include "llvm/Function.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <math.h>
+
+
+using namespace llvm;
+using namespace klee;
+
+cl::opt<double>
+MaxTime("max-time",
+        cl::desc("Halt execution after the specified number of seconds (0=off)"),
+        cl::init(0));
+
+///
+
+class HaltTimer : public Executor::Timer {
+  Executor *executor;
+
+public:
+  HaltTimer(Executor *_executor) : executor(_executor) {}
+  ~HaltTimer() {}
+
+  void run() {
+    llvm::cerr << "KLEE: HaltTimer invoked\n";
+    executor->setHaltExecution(true);
+  }
+};
+
+///
+
+static const double kSecondsPerTick = .1;
+static volatile unsigned timerTicks = 0;
+
+// XXX hack
+extern "C" unsigned dumpStates, dumpPTree;
+unsigned dumpStates = 0, dumpPTree = 0;
+
+static void onAlarm(int) {
+  ++timerTicks;
+}
+
+// oooogalay
+static void setupHandler() {
+  struct itimerval t;
+  struct timeval tv;
+  
+  tv.tv_sec = (long) kSecondsPerTick;
+  tv.tv_usec = (long) (fmod(kSecondsPerTick, 1.)*1000000);
+  
+  t.it_interval = t.it_value = tv;
+  
+  ::setitimer(ITIMER_REAL, &t, 0);
+  ::signal(SIGALRM, onAlarm);
+}
+
+void Executor::initTimers() {
+  static bool first = true;
+
+  if (first) {
+    first = false;
+    setupHandler();
+  }
+
+  if (MaxTime) {
+    addTimer(new HaltTimer(this), MaxTime);
+  }
+}
+
+///
+
+Executor::Timer::Timer() {}
+
+Executor::Timer::~Timer() {}
+
+class Executor::TimerInfo {
+public:
+  Timer *timer;
+  
+  /// Approximate delay per timer firing.
+  double rate;
+  /// Wall time for next firing.
+  double nextFireTime;
+  
+public:
+  TimerInfo(Timer *_timer, double _rate) 
+    : timer(_timer),
+      rate(_rate),
+      nextFireTime(util::getWallTime() + rate) {}
+  ~TimerInfo() { delete timer; }
+};
+
+void Executor::addTimer(Timer *timer, double rate) {
+  timers.push_back(new TimerInfo(timer, rate));
+}
+
+void Executor::processTimers(ExecutionState *current,
+                             double maxInstTime) {
+  static unsigned callsWithoutCheck = 0;
+  unsigned ticks = timerTicks;
+
+  if (!ticks && ++callsWithoutCheck > 1000) {
+    setupHandler();
+    ticks = 1;
+  }
+
+  if (ticks || dumpPTree || dumpStates) {
+    if (dumpPTree) {
+      char name[32];
+      sprintf(name, "ptree%08d.dot", (int) stats::instructions);
+      std::ostream *os = interpreterHandler->openOutputFile(name);
+      if (os) {
+        processTree->dump(*os);
+        delete os;
+      }
+      
+      dumpPTree = 0;
+    }
+
+    if (dumpStates) {
+      std::ostream *os = interpreterHandler->openOutputFile("states.txt");
+      
+      if (os) {
+        for (std::set<ExecutionState*>::const_iterator it = states.begin(), 
+               ie = states.end(); it != ie; ++it) {
+          ExecutionState *es = *it;
+          *os << "(" << es << ",";
+          *os << "[";
+          ExecutionState::stack_ty::iterator next = es->stack.begin();
+          ++next;
+          for (ExecutionState::stack_ty::iterator sfIt = es->stack.begin(),
+                 sf_ie = es->stack.end(); sfIt != sf_ie; ++sfIt) {
+            *os << "('" << sfIt->kf->function->getName() << "',";
+            if (next == es->stack.end()) {
+              *os << es->prevPC->info->line << "), ";
+            } else {
+              *os << next->caller->info->line << "), ";
+              ++next;
+            }
+          }
+          *os << "], ";
+
+          StackFrame &sf = es->stack.back();
+          uint64_t md2u = computeMinDistToUncovered(es->pc,
+                                                    sf.minDistToUncoveredOnReturn);
+          uint64_t icnt = theStatisticManager->getIndexedValue(stats::instructions,
+                                                               es->pc->info->id);
+          uint64_t cpicnt = sf.callPathNode->statistics.getValue(stats::instructions);
+
+          *os << "{";
+          *os << "'depth' : " << es->depth << ", ";
+          *os << "'weight' : " << es->weight << ", ";
+          *os << "'queryCost' : " << es->queryCost << ", ";
+          *os << "'coveredNew' : " << es->coveredNew << ", ";
+          *os << "'instsSinceCovNew' : " << es->instsSinceCovNew << ", ";
+          *os << "'md2u' : " << md2u << ", ";
+          *os << "'icnt' : " << icnt << ", ";
+          *os << "'CPicnt' : " << cpicnt << ", ";
+          *os << "}";
+          *os << ")\n";
+        }
+        
+        delete os;
+      }
+
+      dumpStates = 0;
+    }
+
+    if (maxInstTime>0 && current && !removedStates.count(current)) {
+      if (timerTicks*kSecondsPerTick > maxInstTime) {
+        klee_warning("max-instruction-time exceeded: %.2fs",
+                     timerTicks*kSecondsPerTick);
+        terminateStateEarly(*current, "max-instruction-time exceeded");
+      }
+    }
+
+    if (!timers.empty()) {
+      double time = util::getWallTime();
+
+      for (std::vector<TimerInfo*>::iterator it = timers.begin(), 
+             ie = timers.end(); it != ie; ++it) {
+        TimerInfo *ti = *it;
+        
+        if (time >= ti->nextFireTime) {
+          ti->timer->run();
+          ti->nextFireTime = time + ti->rate;
+        }
+      }
+    }
+
+    timerTicks = 0;
+    callsWithoutCheck = 0;
+  }
+}
+
diff --git a/lib/Core/ExecutorUtil.cpp b/lib/Core/ExecutorUtil.cpp
new file mode 100644
index 00000000..3b11dd42
--- /dev/null
+++ b/lib/Core/ExecutorUtil.cpp
@@ -0,0 +1,144 @@
+//===-- ExecutorUtil.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Executor.h"
+
+#include "klee/Expr.h"
+#include "klee/Interpreter.h"
+#include "klee/Machine.h"
+#include "klee/Solver.h"
+
+#include "klee/Internal/Module/KModule.h"
+
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Target/TargetData.h"
+#include <iostream>
+#include <cassert>
+
+using namespace klee;
+using namespace llvm;
+
+namespace klee {
+
+ref<Expr> 
+Executor::evalConstantExpr(llvm::ConstantExpr *ce) {
+  const llvm::Type *type = ce->getType();
+
+  ref<Expr> op1(0,Expr::Bool), op2(0,Expr::Bool), op3(0,Expr::Bool);
+  int numOperands = ce->getNumOperands();
+
+  if (numOperands > 0) op1 = evalConstant(ce->getOperand(0));
+  if (numOperands > 1) op2 = evalConstant(ce->getOperand(1));
+  if (numOperands > 2) op3 = evalConstant(ce->getOperand(2));
+  
+  switch (ce->getOpcode()) {
+    case Instruction::Trunc: return ExtractExpr::createByteOff(op1, 
+							       0,
+							       Expr::getWidthForLLVMType(type));
+    case Instruction::ZExt:  return  ZExtExpr::create(op1, 
+                                                      Expr::getWidthForLLVMType(type));
+    case Instruction::SExt:  return  SExtExpr::create(op1, 
+                                                      Expr::getWidthForLLVMType(type));
+    case Instruction::Add:   return   AddExpr::create(op1, op2);
+    case Instruction::Sub:   return   SubExpr::create(op1, op2);
+    case Instruction::Mul:   return   MulExpr::create(op1, op2);
+    case Instruction::SDiv:  return  SDivExpr::create(op1, op2);
+    case Instruction::UDiv:  return  UDivExpr::create(op1, op2);
+    case Instruction::SRem:  return  SRemExpr::create(op1, op2);
+    case Instruction::URem:  return  URemExpr::create(op1, op2);
+    case Instruction::And:   return   AndExpr::create(op1, op2);
+    case Instruction::Or:    return    OrExpr::create(op1, op2);
+    case Instruction::Xor:   return   XorExpr::create(op1, op2);
+    case Instruction::Shl:   return   ShlExpr::create(op1, op2);
+    case Instruction::LShr:  return  LShrExpr::create(op1, op2);
+    case Instruction::AShr:  return  AShrExpr::create(op1, op2);
+    case Instruction::BitCast:  return op1;
+
+    case Instruction::IntToPtr: {
+      return ZExtExpr::create(op1, Expr::getWidthForLLVMType(type));
+    } 
+
+    case Instruction::PtrToInt: {
+      return ZExtExpr::create(op1, Expr::getWidthForLLVMType(type));
+    }
+      
+    case Instruction::GetElementPtr: {
+      ref<Expr> base = op1;
+
+      for (gep_type_iterator ii = gep_type_begin(ce), ie = gep_type_end(ce);
+           ii != ie; ++ii) {
+        ref<Expr> addend(0, kMachinePointerType);
+        
+        if (const StructType *st = dyn_cast<StructType>(*ii)) {
+          const StructLayout *sl = kmodule->targetData->getStructLayout(st);
+          const ConstantInt *ci = cast<ConstantInt>(ii.getOperand());
+          
+          addend = Expr::createPointer(sl->getElementOffset((unsigned)
+                                                            ci->getZExtValue()));
+        } else {
+          const SequentialType *st = cast<SequentialType>(*ii);
+          ref<Expr> index = evalConstant(cast<Constant>(ii.getOperand()));
+          unsigned elementSize = kmodule->targetData->getTypeStoreSize(st->getElementType());
+          
+          index = Expr::createCoerceToPointerType(index);
+          addend = MulExpr::create(index,
+                                   Expr::createPointer(elementSize));
+        }
+        
+        base = AddExpr::create(base, addend);
+      }
+      
+      return base;
+    }
+      
+    case Instruction::ICmp: {
+      switch(ce->getPredicate()) {
+        case ICmpInst::ICMP_EQ:  return  EqExpr::create(op1, op2);
+        case ICmpInst::ICMP_NE:  return  NeExpr::create(op1, op2);
+        case ICmpInst::ICMP_UGT: return UgtExpr::create(op1, op2);
+        case ICmpInst::ICMP_UGE: return UgeExpr::create(op1, op2);
+        case ICmpInst::ICMP_ULT: return UltExpr::create(op1, op2);
+        case ICmpInst::ICMP_ULE: return UleExpr::create(op1, op2);
+        case ICmpInst::ICMP_SGT: return SgtExpr::create(op1, op2);
+        case ICmpInst::ICMP_SGE: return SgeExpr::create(op1, op2);
+        case ICmpInst::ICMP_SLT: return SltExpr::create(op1, op2);
+        case ICmpInst::ICMP_SLE: return SleExpr::create(op1, op2);
+        default:
+          assert(0 && "unhandled ICmp predicate");
+      }
+    }
+      
+    case Instruction::Select: {
+      return SelectExpr::create(op1, op2, op3);
+    }
+
+    case Instruction::FDiv:
+    case Instruction::FRem:
+    case Instruction::FPTrunc:
+    case Instruction::FPExt:
+    case Instruction::UIToFP:
+    case Instruction::SIToFP:
+    case Instruction::FPToUI:
+    case Instruction::FPToSI:
+    case Instruction::FCmp:
+      assert(0 && "floating point ConstantExprs unsupported");
+
+    default :
+      assert(0 && "unknown ConstantExpr type");
+  }
+}
+
+}
diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp
new file mode 100644
index 00000000..9e3b0a49
--- /dev/null
+++ b/lib/Core/ExternalDispatcher.cpp
@@ -0,0 +1,230 @@
+//===-- ExternalDispatcher.cpp --------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ExternalDispatcher.h"
+
+#include "llvm/Module.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
+#include <setjmp.h>
+#include <signal.h>
+
+using namespace llvm;
+using namespace klee;
+
+/***/
+
+static jmp_buf escapeCallJmpBuf;
+
+extern "C" {
+
+static void sigsegv_handler(int signal, siginfo_t *info, void *context) {
+  longjmp(escapeCallJmpBuf, 1);
+}
+
+}
+
+void *ExternalDispatcher::resolveSymbol(const std::string &name) {
+  assert(executionEngine);
+  
+  const char *str = name.c_str();
+
+  // We use this to validate that function names can be resolved so we
+  // need to match how the JIT does it. Unfortunately we can't
+  // directly access the JIT resolution function
+  // JIT::getPointerToNamedFunction so we emulate the important points.
+
+  if (str[0] == 1) // asm specifier, skipped
+    ++str;
+
+  void *addr = dl_symbols.SearchForAddressOfSymbol(str);
+  if (addr)
+    return addr;
+  
+  // If it has an asm specifier and starts with an underscore we retry
+  // without the underscore. I (DWD) don't know why.
+  if (name[0] == 1 && str[0]=='_') { 
+    ++str;
+    addr = dl_symbols.SearchForAddressOfSymbol(str);
+  }
+
+  return addr;
+}
+
+ExternalDispatcher::ExternalDispatcher() {
+  dispatchModule = new Module("ExternalDispatcher");
+  ExistingModuleProvider* MP = new ExistingModuleProvider(dispatchModule);
+  
+  std::string error;
+  executionEngine = ExecutionEngine::createJIT(MP, &error);
+  if (!executionEngine) {
+    llvm::cerr << "unable to make jit: " << error << "\n";
+    abort();
+  }
+
+  // from ExecutionEngine::create
+  if (executionEngine) {
+    // Make sure we can resolve symbols in the program as well. The zero arg
+    // to the function tells DynamicLibrary to load the program, not a library.
+    try {
+      dl_symbols.LoadLibraryPermanently(0);
+    } catch (...) {
+      assert(0 && "Exception in LoadLibraryPermantently.\n");
+    }
+  }
+
+#ifdef WINDOWS
+  preboundFunctions["getpid"] = (void*) (long) getpid;
+  preboundFunctions["putchar"] = (void*) (long) putchar;
+  preboundFunctions["printf"] = (void*) (long) printf;
+  preboundFunctions["fprintf"] = (void*) (long) fprintf;
+  preboundFunctions["sprintf"] = (void*) (long) sprintf;
+#endif
+}
+
+ExternalDispatcher::~ExternalDispatcher() {
+  delete executionEngine;
+}
+
+bool ExternalDispatcher::executeCall(Function *f, Instruction *i, uint64_t *args) {
+  dispatchers_ty::iterator it = dispatchers.find(i);
+  Function *dispatcher;
+
+  if (it == dispatchers.end()) {
+#ifdef WINDOWS
+    std::map<std::string, void*>::iterator it2 = 
+      preboundFunctions.find(f->getName()));
+
+    if (it2 != preboundFunctions.end()) {
+      // only bind once
+      if (it2->second) {
+        executionEngine->addGlobalMapping(f, it2->second);
+        it2->second = 0;
+      }
+    }
+#endif
+
+    dispatcher = createDispatcher(f,i);
+
+    dispatchers.insert(std::make_pair(i, dispatcher));
+
+    if (dispatcher) {
+      // force the JIT execution engine to go ahead and build the
+      // function. this ensures that any errors or assertions in the
+      // compilation process will trigger crashes instead of being
+      // caught as aborts in the external function.
+      executionEngine->recompileAndRelinkFunction(dispatcher);
+    }
+  } else {
+    dispatcher = it->second;
+  }
+
+  return runProtectedCall(dispatcher, args);
+}
+
+// XXX not reentrant
+static uint64_t *gTheArgsP;
+
+bool ExternalDispatcher::runProtectedCall(Function *f, uint64_t *args) {
+  struct sigaction segvAction, segvActionOld;
+  bool res;
+  
+  if (!f)
+    return false;
+
+  std::vector<GenericValue> gvArgs;
+  gTheArgsP = args;
+
+  segvAction.sa_handler = 0;
+  memset(&segvAction.sa_mask, 0, sizeof(segvAction.sa_mask));
+  segvAction.sa_flags = SA_SIGINFO;
+  segvAction.sa_sigaction = ::sigsegv_handler;
+  sigaction(SIGSEGV, &segvAction, &segvActionOld);
+
+  if (setjmp(escapeCallJmpBuf)) {
+    res = false;
+  } else {
+    executionEngine->runFunction(f, gvArgs);
+    res = true;
+  }
+
+  sigaction(SIGSEGV, &segvActionOld, 0);
+  return res;
+}
+
+// for performance purposes we construct the stub in such a way that
+// the arguments pointer is passed through the static global variable
+// gTheArgsP in this file. This is done so that the stub function
+// prototype trivially matches the special cases that the JIT knows
+// how to directly call. If this is not done, then the jit will end up
+// generating a nullary stub just to call our stub, for every single
+// function call.
+Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *inst) {
+  if (!resolveSymbol(target->getName()))
+    return 0;
+
+  CallSite cs;
+  if (inst->getOpcode()==Instruction::Call) {
+    cs = CallSite(cast<CallInst>(inst));
+  } else {
+    cs = CallSite(cast<InvokeInst>(inst));
+  }
+
+  Value **args = new Value*[cs.arg_size()];
+
+  std::vector<const Type*> nullary;
+  
+  Function *dispatcher = Function::Create(FunctionType::get(Type::VoidTy, 
+							    nullary, false),
+					  GlobalVariable::ExternalLinkage, 
+					  "",
+					  dispatchModule);
+
+
+  BasicBlock *dBB = BasicBlock::Create("entry", dispatcher);
+
+  Instruction *argI64sp = new IntToPtrInst(ConstantInt::get(Type::Int64Ty, (long) (void*) &gTheArgsP),
+					   PointerType::getUnqual(PointerType::getUnqual(Type::Int64Ty)),
+					   "argsp",
+					   dBB);
+  Instruction *argI64s = new LoadInst(argI64sp, "args", dBB); 
+
+  unsigned i = 0;
+  for (CallSite::arg_iterator ai = cs.arg_begin(), ae = cs.arg_end();
+       ai!=ae; ++ai, ++i) {
+    Value *index = ConstantInt::get(Type::Int32Ty, i+1);
+
+    Instruction *argI64p = GetElementPtrInst::Create(argI64s, index, "", dBB);
+    Instruction *argp = new BitCastInst(argI64p, 
+                                        PointerType::getUnqual((*ai)->getType()), "", dBB);
+    args[i] = new LoadInst(argp, "", dBB);
+  }
+
+  Instruction *result = CallInst::Create(target, args, args+i, "", dBB);
+
+  if (result->getType() != Type::VoidTy) {
+    Instruction *resp = new BitCastInst(argI64s, 
+                                        PointerType::getUnqual(result->getType()), "", dBB);
+    new StoreInst(result, resp, dBB);
+  }
+
+  ReturnInst::Create(dBB);
+
+  delete[] args;
+
+  return dispatcher;
+}
diff --git a/lib/Core/ExternalDispatcher.h b/lib/Core/ExternalDispatcher.h
new file mode 100644
index 00000000..fc8f80f4
--- /dev/null
+++ b/lib/Core/ExternalDispatcher.h
@@ -0,0 +1,50 @@
+//===-- ExternalDispatcher.h ------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_EXTERNALDISPATCHER_H
+#define KLEE_EXTERNALDISPATCHER_H
+
+#include <map>
+#include "llvm/System/DynamicLibrary.h"
+
+namespace llvm {
+  class ExecutionEngine;
+  class Instruction;
+  class Function;
+  class FunctionType;
+  class Module;
+}
+
+namespace klee {
+  class ExternalDispatcher {
+  private:
+    typedef std::map<const llvm::Instruction*,llvm::Function*> dispatchers_ty;
+    dispatchers_ty dispatchers;
+    llvm::Module *dispatchModule;
+    llvm::ExecutionEngine *executionEngine;
+    llvm::sys::DynamicLibrary dl_symbols;
+    std::map<std::string, void*> preboundFunctions;
+    
+    llvm::Function *createDispatcher(llvm::Function *f, llvm::Instruction *i);
+    bool runProtectedCall(llvm::Function *f, uint64_t *args);
+    
+  public:
+    ExternalDispatcher();
+    ~ExternalDispatcher();
+
+    /* Call the given function using the parameter passing convention of
+     * ci with arguments in args[1], args[2], ... and writing the result
+     * into args[0].
+     */
+    bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args);
+    void *resolveSymbol(const std::string &name);
+  };  
+}
+
+#endif
diff --git a/lib/Core/ImpliedValue.cpp b/lib/Core/ImpliedValue.cpp
new file mode 100644
index 00000000..386c8d80
--- /dev/null
+++ b/lib/Core/ImpliedValue.cpp
@@ -0,0 +1,274 @@
+//===-- ImpliedValue.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ImpliedValue.h"
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+// FIXME: Use APInt.
+#include "klee/Internal/Support/IntEvaluation.h"
+
+#include "klee/util/ExprUtil.h"
+
+#include <iostream>
+#include <map>
+#include <set>
+
+using namespace klee;
+
+// XXX we really want to do some sort of canonicalization of exprs
+// globally so that cases below become simpler
+static void _getImpliedValue(ref<Expr> e,
+                             uint64_t value,
+                             ImpliedValueList &results) {
+  switch (e.getKind()) {
+    
+  case Expr::Constant: {
+    assert(value == e.getConstantValue() && "error in implied value calculation");
+    break;
+  }
+
+    // Special
+
+  case Expr::NotOptimized: break;
+
+  case Expr::Read: {
+    // XXX in theory it is possible to descend into a symbolic index
+    // under certain circumstances (all values known, known value
+    // unique, or range known, max / min hit). Seems unlikely this
+    // would work often enough to be worth the effort.
+    ReadExpr *re = static_ref_cast<ReadExpr>(e);
+    results.push_back(std::make_pair(re, 
+                                     ConstantExpr::create(value, e.getWidth())));
+    break;
+  }
+    
+  case Expr::Select: {
+    // not much to do, could improve with range analysis
+    SelectExpr *se = static_ref_cast<SelectExpr>(e);
+    
+    if (se->trueExpr.isConstant()) {
+      if (se->falseExpr.isConstant()) {
+        if (se->trueExpr.getConstantValue() != se->falseExpr.getConstantValue()) {
+          if (value == se->trueExpr.getConstantValue()) {
+            _getImpliedValue(se->cond, 1, results);
+          } else {
+            assert(value == se->falseExpr.getConstantValue() &&
+                   "err in implied value calculation");
+            _getImpliedValue(se->cond, 0, results);
+          }
+        }
+      }
+    }
+    break;
+  }
+
+  case Expr::Concat: {
+    ConcatExpr *ce = static_ref_cast<ConcatExpr>(e);
+    _getImpliedValue(ce->getKid(0), (value >> ce->getKid(1).getWidth()) & ((1 << ce->getKid(0).getWidth()) - 1), results);
+    _getImpliedValue(ce->getKid(1), value & ((1 << ce->getKid(1).getWidth()) - 1), results);
+    break;
+  }
+    
+  case Expr::Extract: {
+    // XXX, could do more here with "some bits" mask
+    break;
+  }
+
+    // Casting
+
+  case Expr::ZExt: 
+  case Expr::SExt: {
+    CastExpr *ce = static_ref_cast<CastExpr>(e);
+    _getImpliedValue(ce->src, 
+                     bits64::truncateToNBits(value, 
+					     ce->src.getWidth()),
+                     results);
+    break;
+  }
+
+    // Arithmetic
+
+  case Expr::Add: { // constants on left
+    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    if (be->left.isConstant()) {
+      uint64_t nvalue = ints::sub(value,
+                                  be->left.getConstantValue(),
+                                  be->left.getWidth());
+      _getImpliedValue(be->right, nvalue, results);
+    }
+    break;
+  }
+  case Expr::Sub: { // constants on left
+    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    if (be->left.isConstant()) {
+      uint64_t nvalue = ints::sub(be->left.getConstantValue(),
+                                  value,
+                                  be->left.getWidth());
+      _getImpliedValue(be->right, nvalue, results);
+    }
+    break;
+  }
+  case Expr::Mul: {
+    // XXX can do stuff here, but need valid mask and other things
+    // because of bits that might be lost
+    break;
+  }
+
+  case Expr::UDiv:
+  case Expr::SDiv:
+  case Expr::URem:
+  case Expr::SRem:
+    // no, no, no
+    break;
+
+    // Binary
+
+  case Expr::And: {
+    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    if (be->getWidth() == Expr::Bool) {
+      if (value) {
+        _getImpliedValue(be->left, value, results);
+        _getImpliedValue(be->right, value, results);
+      }
+    } else {
+      // XXX, we can basically propogate a mask here
+      // where we know "some bits". may or may not be
+      // useful.
+    }
+    break;
+  }
+  case Expr::Or: {
+    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    if (!value) {
+      _getImpliedValue(be->left, 0, results);
+      _getImpliedValue(be->right, 0, results);
+    } else {
+      // XXX, can do more?
+    }
+    break;
+  }
+  case Expr::Xor: { // constants on left
+    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    if (be->left.isConstant()) {
+      _getImpliedValue(be->right, value ^ be->left.getConstantValue(), results);
+    }
+    break;
+  }
+
+    // Comparison
+  case Expr::Ne: 
+    value = !value;
+    /* fallthru */
+  case Expr::Eq: {
+    EqExpr *ee = static_ref_cast<EqExpr>(e);
+    if (value) {
+      if (ee->left.isConstant())
+        _getImpliedValue(ee->right, ee->left.getConstantValue(), results);
+    } else {
+      // look for limited value range, woohoo
+      //
+      // in general anytime one side was restricted to two values we
+      // can apply this trick. the only obvious case where this
+      // occurs, aside from booleans, is as the result of a select
+      // expression where the true and false branches are single
+      // valued and distinct.
+      
+      if (ee->left.isConstant()) {
+        if (ee->left.getWidth() == Expr::Bool) {
+          _getImpliedValue(ee->right, !ee->left.getConstantValue(), results);
+        }
+      }
+    }
+    break;
+  }
+    
+  default:
+    break;
+  }
+}
+    
+void ImpliedValue::getImpliedValues(ref<Expr> e, 
+                                    ref<Expr> value, 
+                                    ImpliedValueList &results) {
+  assert(value.isConstant() && "non-constant in place of constant");
+  _getImpliedValue(e, value.getConstantValue(), results);
+}
+
+void ImpliedValue::checkForImpliedValues(Solver *S, ref<Expr> e, 
+                                         ref<Expr> value) {
+  assert(value.isConstant() && "non-constant in place of constant");
+
+  std::vector<ref<ReadExpr> > reads;
+  std::map<ref<ReadExpr>, ref<Expr> > found;
+  ImpliedValueList results;
+
+  getImpliedValues(e, value, results);
+
+  for (ImpliedValueList::iterator i = results.begin(), ie = results.end();
+       i != ie; ++i) {
+    std::map<ref<ReadExpr>, ref<Expr> >::iterator it = found.find(i->first);
+    if (it != found.end()) {
+      assert(it->second.getConstantValue() == i->second.getConstantValue() &&
+             "I don't think so Scott");
+    } else {
+      found.insert(std::make_pair(i->first, i->second));
+    }
+  }
+
+  findReads(e, false, reads);
+  std::set< ref<ReadExpr> > readsSet(reads.begin(), reads.end());
+  reads = std::vector< ref<ReadExpr> >(readsSet.begin(), readsSet.end());
+
+  std::vector<ref<Expr> > assumption;
+  assumption.push_back(EqExpr::create(e, value));
+
+  // obscure... we need to make sure that all the read indices are
+  // bounds checked. if we don't do this we can end up constructing
+  // invalid counterexamples because STP will happily make out of
+  // bounds indices which will not get picked up. this is of utmost
+  // importance if we are being backed by the CexCachingSolver.
+
+  for (std::vector< ref<ReadExpr> >::iterator i = reads.begin(), 
+         ie = reads.end(); i != ie; ++i) {
+    ReadExpr *re = i->get();
+    ref<Expr> size = ref<Expr>(re->updates.root->size, kMachinePointerType);
+    assumption.push_back(UltExpr::create(re->index, size));
+  }
+
+  ConstraintManager assume(assumption);
+  for (std::vector< ref<ReadExpr> >::iterator i = reads.begin(), 
+         ie = reads.end(); i != ie; ++i) {
+    ref<ReadExpr> var = *i;
+    ref<Expr> possible;
+    bool success = S->getValue(Query(assume, var), possible);
+    assert(success && "FIXME: Unhandled solver failure");    
+    std::map<ref<ReadExpr>, ref<Expr> >::iterator it = found.find(var);
+    bool res;
+    success = S->mustBeTrue(Query(assume, EqExpr::create(var, possible)), res);
+    assert(success && "FIXME: Unhandled solver failure");    
+    if (res) {
+      if (it != found.end()) {
+        assert(possible.getConstantValue() == it->second.getConstantValue());
+        found.erase(it);
+      }
+    } else {
+      if (it!=found.end()) {
+        ref<Expr> binding = it->second;
+        llvm::cerr << "checkForImpliedValues: " << e  << " = " << value << "\n"
+                   << "\t\t implies " << var << " == " << binding
+                   << " (error)\n";
+        assert(0);
+      }
+    }
+  }
+
+  assert(found.empty());
+}
diff --git a/lib/Core/ImpliedValue.h b/lib/Core/ImpliedValue.h
new file mode 100644
index 00000000..51ec6e9b
--- /dev/null
+++ b/lib/Core/ImpliedValue.h
@@ -0,0 +1,38 @@
+//===-- ImpliedValue.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_IMPLIEDVALUE_H
+#define KLEE_IMPLIEDVALUE_H
+
+#include "klee/Expr.h"
+
+#include <vector>
+
+// The idea of implied values is that often we know the result of some
+// expression e is a concrete value C. In many cases this directly
+// implies that some variable x embedded in e is also a concrete value
+// (derived from C). This module is used for finding such variables
+// and their computed values.
+
+namespace klee {
+  class ConstantExpr;
+  class Expr;
+  class ReadExpr;
+  class Solver;
+
+  typedef std::vector< std::pair<ref<ReadExpr>, ref<Expr> > > ImpliedValueList;
+  
+  namespace ImpliedValue {        
+    void getImpliedValues(ref<Expr> e, ref<Expr> cvalue, ImpliedValueList &result);
+    void checkForImpliedValues(Solver *S, ref<Expr> e, ref<Expr> cvalue);    
+  }
+
+}
+
+#endif
diff --git a/lib/Core/Makefile b/lib/Core/Makefile
new file mode 100755
index 00000000..4da3c7ea
--- /dev/null
+++ b/lib/Core/Makefile
@@ -0,0 +1,16 @@
+#===-- lib/Core/Makefile -----------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleeCore
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Core/Memory.cpp b/lib/Core/Memory.cpp
new file mode 100644
index 00000000..cd563551
--- /dev/null
+++ b/lib/Core/Memory.cpp
@@ -0,0 +1,812 @@
+//===-- Memory.cpp --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "Memory.h"
+
+#include "klee/Expr.h"
+#include "klee/Machine.h"
+#include "klee/Solver.h"
+#include "klee/util/BitArray.h"
+
+#include "ObjectHolder.h"
+
+#include <llvm/Function.h>
+#include <llvm/Instruction.h>
+#include <llvm/Value.h>
+
+#include <iostream>
+#include <cassert>
+#include <sstream>
+
+using namespace llvm;
+using namespace klee;
+
+/***/
+
+ObjectHolder::ObjectHolder(const ObjectHolder &b) : os(b.os) { 
+  if (os) ++os->refCount; 
+}
+
+ObjectHolder::ObjectHolder(ObjectState *_os) : os(_os) { 
+  if (os) ++os->refCount; 
+}
+
+ObjectHolder::~ObjectHolder() { 
+  if (os && --os->refCount==0) delete os; 
+}
+  
+ObjectHolder &ObjectHolder::operator=(const ObjectHolder &b) {
+  if (b.os) ++b.os->refCount;
+  if (os && --os->refCount==0) delete os;
+  os = b.os;
+  return *this;
+}
+
+/***/
+
+int MemoryObject::counter = 0;
+
+extern "C" void vc_DeleteExpr(void*);
+
+MemoryObject::~MemoryObject() {
+  // FIXME: This shouldn't be necessary. Array's should be ref-counted
+  // just like everything else, and the interaction with the STP array
+  // should hide at least inside the Expr/Solver layers.
+  if (array) {
+    if (array->stpInitialArray) {
+      ::vc_DeleteExpr(array->stpInitialArray);
+      array->stpInitialArray = 0;
+    }
+    delete array;
+  }
+}
+
+void MemoryObject::getAllocInfo(std::string &result) const {
+  std::ostringstream info;
+
+  info << "MO" << id << "[" << size << "]";
+
+  if (allocSite) {
+    info << " allocated at ";
+    if (const Instruction *i = dyn_cast<Instruction>(allocSite)) {
+      info << i->getParent()->getParent()->getName() << "():";
+      info << *i;
+    } else if (const GlobalValue *gv = dyn_cast<GlobalValue>(allocSite)) {
+      info << "global:" << gv->getName();
+    } else {
+      info << "value:" << *allocSite;
+    }
+  } else {
+    info << " (no allocation info)";
+  }
+  
+  result = info.str();
+}
+
+/***/
+
+ObjectState::ObjectState(const MemoryObject *mo, unsigned _size)
+  : copyOnWriteOwner(0),
+    refCount(0),
+    object(mo),
+    concreteStore(new uint8_t[_size]),
+    concreteMask(0),
+    flushMask(0),
+    knownSymbolics(0),
+    size(_size),
+    updates(mo->array, false, 0),
+    readOnly(false) {
+}
+
+ObjectState::ObjectState(const ObjectState &os) 
+  : copyOnWriteOwner(0),
+    refCount(0),
+    object(os.object),
+    concreteStore(new uint8_t[os.size]),
+    concreteMask(os.concreteMask ? new BitArray(*os.concreteMask, os.size) : 0),
+    flushMask(os.flushMask ? new BitArray(*os.flushMask, os.size) : 0),
+    knownSymbolics(0),
+    size(os.size),
+    updates(os.updates),
+    readOnly(false) {
+  assert(!os.readOnly && "no need to copy read only object?");
+
+  if (os.knownSymbolics) {
+    knownSymbolics = new ref<Expr>[size];
+    for (unsigned i=0; i<size; i++)
+      knownSymbolics[i] = os.knownSymbolics[i];
+  }
+
+  memcpy(concreteStore, os.concreteStore, size*sizeof(*concreteStore));
+}
+
+ObjectState::~ObjectState() {
+  if (concreteMask) delete concreteMask;
+  if (flushMask) delete flushMask;
+  if (knownSymbolics) delete[] knownSymbolics;
+  delete[] concreteStore;
+}
+
+/***/
+
+void ObjectState::makeConcrete() {
+  if (concreteMask) delete concreteMask;
+  if (flushMask) delete flushMask;
+  if (knownSymbolics) delete[] knownSymbolics;
+  concreteMask = 0;
+  flushMask = 0;
+  knownSymbolics = 0;
+}
+
+void ObjectState::makeSymbolic() {
+  assert(!updates.head &&
+         "XXX makeSymbolic of objects with symbolic values is unsupported");
+  updates.isRooted = true;
+
+  // XXX simplify this, can just delete various arrays I guess
+  for (unsigned i=0; i<size; i++) {
+    markByteSymbolic(i);
+    setKnownSymbolic(i, 0);
+    markByteFlushed(i);
+  }
+}
+
+void ObjectState::initializeToZero() {
+  makeConcrete();
+  memset(concreteStore, 0, size);
+}
+
+void ObjectState::initializeToRandom() {  
+  makeConcrete();
+  for (unsigned i=0; i<size; i++) {
+    // randomly selected by 256 sided die
+    concreteStore[i] = 0xAB;
+  }
+}
+
+/*
+Cache Invariants
+--
+isByteKnownSymbolic(i) => !isByteConcrete(i)
+isByteConcrete(i) => !isByteKnownSymbolic(i)
+!isByteFlushed(i) => (isByteConcrete(i) || isByteKnownSymbolic(i))
+ */
+
+void ObjectState::fastRangeCheckOffset(ref<Expr> offset,
+                                       unsigned *base_r,
+                                       unsigned *size_r) const {
+  *base_r = 0;
+  *size_r = size;
+}
+
+void ObjectState::flushRangeForRead(unsigned rangeBase, 
+                                    unsigned rangeSize) const {
+  if (!flushMask) flushMask = new BitArray(size, true);
+ 
+  for (unsigned offset=rangeBase; offset<rangeBase+rangeSize; offset++) {
+    if (!isByteFlushed(offset)) {
+      if (isByteConcrete(offset)) {
+        updates.extend(ConstantExpr::create(offset, kMachinePointerType),
+                       ConstantExpr::create(concreteStore[offset], Expr::Int8));
+      } else {
+        assert(isByteKnownSymbolic(offset) && "invalid bit set in flushMask");
+        updates.extend(ConstantExpr::create(offset, kMachinePointerType),
+                       knownSymbolics[offset]);
+      }
+
+      flushMask->unset(offset);
+    }
+  } 
+}
+
+void ObjectState::flushRangeForWrite(unsigned rangeBase, 
+                                     unsigned rangeSize) {
+  if (!flushMask) flushMask = new BitArray(size, true);
+
+  for (unsigned offset=rangeBase; offset<rangeBase+rangeSize; offset++) {
+    if (!isByteFlushed(offset)) {
+      if (isByteConcrete(offset)) {
+        updates.extend(ConstantExpr::create(offset, kMachinePointerType),
+                       ConstantExpr::create(concreteStore[offset], Expr::Int8));
+        markByteSymbolic(offset);
+      } else {
+        assert(isByteKnownSymbolic(offset) && "invalid bit set in flushMask");
+        updates.extend(ConstantExpr::create(offset, kMachinePointerType),
+                       knownSymbolics[offset]);
+        setKnownSymbolic(offset, 0);
+      }
+
+      flushMask->unset(offset);
+    } else {
+      // flushed bytes that are written over still need
+      // to be marked out
+      if (isByteConcrete(offset)) {
+        markByteSymbolic(offset);
+      } else if (isByteKnownSymbolic(offset)) {
+        setKnownSymbolic(offset, 0);
+      }
+    }
+  } 
+}
+
+bool ObjectState::isByteConcrete(unsigned offset) const {
+  return !concreteMask || concreteMask->get(offset);
+}
+
+bool ObjectState::isByteFlushed(unsigned offset) const {
+  return flushMask && !flushMask->get(offset);
+}
+
+bool ObjectState::isByteKnownSymbolic(unsigned offset) const {
+  return knownSymbolics && knownSymbolics[offset].get();
+}
+
+void ObjectState::markByteConcrete(unsigned offset) {
+  if (concreteMask)
+    concreteMask->set(offset);
+}
+
+void ObjectState::markByteSymbolic(unsigned offset) {
+  if (!concreteMask)
+    concreteMask = new BitArray(size, true);
+  concreteMask->unset(offset);
+}
+
+void ObjectState::markByteUnflushed(unsigned offset) {
+  if (flushMask)
+    flushMask->set(offset);
+}
+
+void ObjectState::markByteFlushed(unsigned offset) {
+  if (!flushMask) {
+    flushMask = new BitArray(size, false);
+  } else {
+    flushMask->unset(offset);
+  }
+}
+
+void ObjectState::setKnownSymbolic(unsigned offset, 
+                                   Expr *value /* can be null */) {
+  if (knownSymbolics) {
+    knownSymbolics[offset] = value;
+  } else {
+    if (value) {
+      knownSymbolics = new ref<Expr>[size];
+      knownSymbolics[offset] = value;
+    }
+  }
+}
+
+/***/
+
+ref<Expr> ObjectState::read8(unsigned offset) const {
+  if (isByteConcrete(offset)) {
+    return ConstantExpr::create(concreteStore[offset], Expr::Int8);
+  } else if (isByteKnownSymbolic(offset)) {
+    return knownSymbolics[offset];
+  } else {
+    assert(isByteFlushed(offset) && "unflushed byte without cache value");
+    
+    return ReadExpr::create(updates, 
+                            ConstantExpr::create(offset, kMachinePointerType));
+  }    
+}
+
+ref<Expr> ObjectState::read8(ref<Expr> offset) const {
+  assert(!offset.isConstant() && "constant offset passed to symbolic read8");
+  unsigned base, size;
+  fastRangeCheckOffset(offset, &base, &size);
+  flushRangeForRead(base, size);
+
+  if (size>4096) {
+    std::string allocInfo;
+    object->getAllocInfo(allocInfo);
+    klee_warning_once(0, "flushing %d bytes on read, may be slow and/or crash: %s", 
+                      size,
+                      allocInfo.c_str());
+  }
+  
+  return ReadExpr::create(updates, offset);
+}
+
+void ObjectState::write8(unsigned offset, uint8_t value) {
+  //assert(read_only == false && "writing to read-only object!");
+  concreteStore[offset] = value;
+  setKnownSymbolic(offset, 0);
+
+  markByteConcrete(offset);
+  markByteUnflushed(offset);
+}
+
+void ObjectState::write8(unsigned offset, ref<Expr> value) {
+  // can happen when ExtractExpr special cases
+  if (value.isConstant()) {
+    write8(offset, (uint8_t) value.getConstantValue());
+  } else {
+    setKnownSymbolic(offset, value.get());
+      
+    markByteSymbolic(offset);
+    markByteUnflushed(offset);
+  }
+}
+
+void ObjectState::write8(ref<Expr> offset, ref<Expr> value) {
+  assert(!offset.isConstant() && "constant offset passed to symbolic write8");
+  unsigned base, size;
+  fastRangeCheckOffset(offset, &base, &size);
+  flushRangeForWrite(base, size);
+
+  if (size>4096) {
+    std::string allocInfo;
+    object->getAllocInfo(allocInfo);
+    klee_warning_once(0, "flushing %d bytes on read, may be slow and/or crash: %s", 
+                      size,
+                      allocInfo.c_str());
+  }
+  
+  updates.extend(offset, value);
+}
+
+/***/
+
+ref<Expr> ObjectState::read(ref<Expr> offset, Expr::Width width) const {
+  if (offset.isConstant()) {
+    return read((unsigned) offset.getConstantValue(), width);
+  } else { 
+    switch (width) {
+    case  Expr::Bool: return  read1(offset);
+    case  Expr::Int8: return  read8(offset);
+    case Expr::Int16: return read16(offset);
+    case Expr::Int32: return read32(offset);
+    case Expr::Int64: return read64(offset);
+    default: assert(0 && "invalid type");
+    }
+  }
+}
+
+ref<Expr> ObjectState::read(unsigned offset, Expr::Width width) const {
+  switch (width) {
+  case  Expr::Bool: return  read1(offset);
+  case  Expr::Int8: return  read8(offset);
+  case Expr::Int16: return read16(offset);
+  case Expr::Int32: return read32(offset);
+  case Expr::Int64: return read64(offset);
+  default: assert(0 && "invalid type");
+  }
+}
+
+ref<Expr> ObjectState::read1(unsigned offset) const {
+  return ExtractExpr::createByteOff(read8(offset), 0, Expr::Bool);
+}
+
+ref<Expr> ObjectState::read1(ref<Expr> offset) const {
+  return ExtractExpr::createByteOff(read8(offset), 0, Expr::Bool);
+}
+
+ref<Expr> ObjectState::read16(unsigned offset) const {
+  if (kMachineByteOrder == machine::MSB) {
+    return ConcatExpr::create(read8(offset+0),
+			      read8(offset+1));
+  } else {
+    return ConcatExpr::create(read8(offset+1),
+			      read8(offset+0));
+  }
+}
+
+ref<Expr> ObjectState::read16(ref<Expr> offset) const {
+  if (kMachineByteOrder == machine::MSB) {
+    return ConcatExpr::create
+      (read8(AddExpr::create(offset,
+                             ConstantExpr::create(0,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(1,
+                                                  kMachinePointerType))));
+  } else {
+    return ConcatExpr::create
+      (read8(AddExpr::create(offset,
+                             ConstantExpr::create(1,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(0,
+                                                  kMachinePointerType))));
+  }
+}
+
+ref<Expr> ObjectState::read32(unsigned offset) const {
+  if (kMachineByteOrder == machine::MSB) {
+    return ConcatExpr::create4(read8(offset+0),
+                               read8(offset+1),
+                               read8(offset+2),
+                               read8(offset+3));
+  } else {
+    return ConcatExpr::create4(read8(offset+3),
+                               read8(offset+2),
+                               read8(offset+1),
+                               read8(offset+0));
+  }
+}
+
+ref<Expr> ObjectState::read32(ref<Expr> offset) const {
+  if (kMachineByteOrder == machine::MSB) {
+    return ConcatExpr::create4
+      (read8(AddExpr::create(offset,
+                             ConstantExpr::create(0,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(1,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(2,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(3,
+                                                  kMachinePointerType))));
+  } else {
+    return ConcatExpr::create4
+      (read8(AddExpr::create(offset,
+                             ConstantExpr::create(3,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(2,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(1,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(0,
+                                                  kMachinePointerType))));
+  }
+}
+
+ref<Expr> ObjectState::read64(unsigned offset) const {
+  if (kMachineByteOrder == machine::MSB) {
+    return ConcatExpr::create8(read8(offset+0),
+                               read8(offset+1),
+                               read8(offset+2),
+                               read8(offset+3),
+                               read8(offset+4),
+                               read8(offset+5),
+                               read8(offset+6),
+                               read8(offset+7));
+  } else {
+    return ConcatExpr::create8(read8(offset+7),
+                               read8(offset+6),
+                               read8(offset+5),
+                               read8(offset+4),
+                               read8(offset+3),
+                               read8(offset+2),
+                               read8(offset+1),
+                               read8(offset+0));
+  }
+}
+
+ref<Expr> ObjectState::read64(ref<Expr> offset) const {
+  if (kMachineByteOrder == machine::MSB) {
+    return ConcatExpr::create8
+      (read8(AddExpr::create(offset,
+                             ConstantExpr::create(0,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(1,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(2,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(3,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(4,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(5,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(6,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(7,
+                                                  kMachinePointerType))));
+  } else {
+    return ConcatExpr::create8
+      (read8(AddExpr::create(offset,
+                             ConstantExpr::create(7,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(6,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(5,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(4,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(3,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(2,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(1,
+                                                  kMachinePointerType))),
+       read8(AddExpr::create(offset,
+                             ConstantExpr::create(0,
+                                                  kMachinePointerType))));
+  }
+}
+
+void ObjectState::write(ref<Expr> offset, ref<Expr> value) {
+  Expr::Width w = value.getWidth();
+  if (offset.isConstant()) {
+    write(offset.getConstantValue(), value);
+  } else {
+    switch(w) {
+    case  Expr::Bool:  write1(offset, value); break;
+    case  Expr::Int8:  write8(offset, value); break;
+    case Expr::Int16: write16(offset, value); break;
+    case Expr::Int32: write32(offset, value); break;
+    case Expr::Int64: write64(offset, value); break;
+    default: assert(0 && "invalid number of bytes in write");
+    }
+  }
+}
+
+void ObjectState::write(unsigned offset, ref<Expr> value) {
+  Expr::Width w = value.getWidth();
+  if (value.isConstant()) {
+    uint64_t val = value.getConstantValue();
+    switch(w) {
+    case  Expr::Bool:
+    case  Expr::Int8:  write8(offset, val); break;
+    case Expr::Int16: write16(offset, val); break;
+    case Expr::Int32: write32(offset, val); break;
+    case Expr::Int64: write64(offset, val); break;
+    default: assert(0 && "invalid number of bytes in write");
+    }
+  } else {
+    switch(w) {
+    case  Expr::Bool:  write1(offset, value); break;
+    case  Expr::Int8:  write8(offset, value); break;
+    case Expr::Int16: write16(offset, value); break;
+    case Expr::Int32: write32(offset, value); break;
+    case Expr::Int64: write64(offset, value); break;
+    default: assert(0 && "invalid number of bytes in write");
+    }
+  }
+}
+
+void ObjectState::write1(unsigned offset, ref<Expr> value) {
+  write8(offset, ZExtExpr::create(value, Expr::Int8));
+}
+
+void ObjectState::write1(ref<Expr> offset, ref<Expr> value) {
+  write8(offset, ZExtExpr::create(value, Expr::Int8));
+}
+
+void ObjectState::write16(unsigned offset, uint16_t value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(offset+0, (uint8_t) (value >>  8));
+    write8(offset+1, (uint8_t) (value >>  0));
+  } else {
+    write8(offset+1, (uint8_t) (value >>  8));
+    write8(offset+0, (uint8_t) (value >>  0));
+  }
+}
+
+void ObjectState::write16(unsigned offset, ref<Expr> value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(offset+0, ExtractExpr::createByteOff(value, 1));
+    write8(offset+1, ExtractExpr::createByteOff(value, 0));
+  } else {
+    write8(offset+1, ExtractExpr::createByteOff(value, 1));
+    write8(offset+0, ExtractExpr::createByteOff(value, 0));
+  }
+}
+
+
+void ObjectState::write16(ref<Expr> offset, ref<Expr> value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(0, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,1));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(0, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,0));
+  } else {
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(1, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,1));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(0, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,0));
+  }
+}
+
+void ObjectState::write32(unsigned offset, uint32_t value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(offset+0, (uint8_t) (value >>  24));
+    write8(offset+1, (uint8_t) (value >>  16));
+    write8(offset+2, (uint8_t) (value >>  8));
+    write8(offset+3, (uint8_t) (value >>  0));
+  } else {
+    write8(offset+3, (uint8_t) (value >>  24));
+    write8(offset+2, (uint8_t) (value >>  16));
+    write8(offset+1, (uint8_t) (value >>  8));
+    write8(offset+0, (uint8_t) (value >>  0));
+  }
+}
+
+void ObjectState::write32(unsigned offset, ref<Expr> value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(offset+0, ExtractExpr::createByteOff(value, 3));
+    write8(offset+1, ExtractExpr::createByteOff(value, 2));
+    write8(offset+2, ExtractExpr::createByteOff(value, 1));
+    write8(offset+3, ExtractExpr::createByteOff(value, 0));
+  } else {
+    write8(offset+3, ExtractExpr::createByteOff(value, 3));
+    write8(offset+2, ExtractExpr::createByteOff(value, 2));
+    write8(offset+1, ExtractExpr::createByteOff(value, 1));
+    write8(offset+0, ExtractExpr::createByteOff(value, 0));
+  }
+}
+
+void ObjectState::write32(ref<Expr> offset, ref<Expr> value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(0, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,3));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(1, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,2));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(2, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,1));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(3, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,0));
+  } else {
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(3, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,3));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(2, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,2));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(1, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,1));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(0, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,0));
+  }
+}
+
+void ObjectState::write64(unsigned offset, uint64_t value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(offset+0, (uint8_t) (value >>  56));
+    write8(offset+1, (uint8_t) (value >>  48));
+    write8(offset+2, (uint8_t) (value >>  40));
+    write8(offset+3, (uint8_t) (value >>  32));
+    write8(offset+4, (uint8_t) (value >>  24));
+    write8(offset+5, (uint8_t) (value >>  16));
+    write8(offset+6, (uint8_t) (value >>  8));
+    write8(offset+7, (uint8_t) (value >>  0));
+  } else {
+    write8(offset+7, (uint8_t) (value >>  56));
+    write8(offset+6, (uint8_t) (value >>  48));
+    write8(offset+5, (uint8_t) (value >>  40));
+    write8(offset+4, (uint8_t) (value >>  32));
+    write8(offset+3, (uint8_t) (value >>  24));
+    write8(offset+2, (uint8_t) (value >>  16));
+    write8(offset+1, (uint8_t) (value >>  8));
+    write8(offset+0, (uint8_t) (value >>  0));
+  }
+}
+
+void ObjectState::write64(unsigned offset, ref<Expr> value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(offset+0, ExtractExpr::createByteOff(value, 7));
+    write8(offset+1, ExtractExpr::createByteOff(value, 6));
+    write8(offset+2, ExtractExpr::createByteOff(value, 5));
+    write8(offset+3, ExtractExpr::createByteOff(value, 4));
+    write8(offset+4, ExtractExpr::createByteOff(value, 3));
+    write8(offset+5, ExtractExpr::createByteOff(value, 2));
+    write8(offset+6, ExtractExpr::createByteOff(value, 1));
+    write8(offset+7, ExtractExpr::createByteOff(value, 0));
+  } else {
+    write8(offset+7, ExtractExpr::createByteOff(value, 7));
+    write8(offset+6, ExtractExpr::createByteOff(value, 6));
+    write8(offset+5, ExtractExpr::createByteOff(value, 5));
+    write8(offset+4, ExtractExpr::createByteOff(value, 4));
+    write8(offset+3, ExtractExpr::createByteOff(value, 3));
+    write8(offset+2, ExtractExpr::createByteOff(value, 2));
+    write8(offset+1, ExtractExpr::createByteOff(value, 1));
+    write8(offset+0, ExtractExpr::createByteOff(value, 0));
+  }
+}
+
+void ObjectState::write64(ref<Expr> offset, ref<Expr> value) {
+  if (kMachineByteOrder == machine::MSB) {
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(0, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,7));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(1, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,6));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(2, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,5));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(3, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,4));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(4, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,3));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(5, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,2));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(6, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,1));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(7, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,0));
+  } else {
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(7, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,7));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(6, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,6));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(5, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,5));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(4, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,4));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(3, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,3));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(2, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,2));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(1, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,1));
+    write8(AddExpr::create(offset,
+                           ConstantExpr::create(0, kMachinePointerType)), 
+           ExtractExpr::createByteOff(value,0));
+  }
+}
+
+void ObjectState::print() {
+  llvm::cerr << "-- ObjectState --\n";
+  llvm::cerr << "\tMemoryObject ID: " << object->id << "\n";
+  llvm::cerr << "\tRoot Object: " << updates.root << "\n";
+  llvm::cerr << "\tIs Rooted? " << updates.isRooted << "\n";
+  llvm::cerr << "\tSize: " << size << "\n";
+
+  llvm::cerr << "\tBytes:\n";
+  for (unsigned i=0; i<size; i++) {
+    llvm::cerr << "\t\t["<<i<<"]"
+               << " concrete? " << isByteConcrete(i)
+               << " known-sym? " << isByteKnownSymbolic(i)
+               << " flushed? " << isByteFlushed(i) << " = ";
+    ref<Expr> e = read8(i);
+    llvm::cerr << e << "\n";
+  }
+
+  llvm::cerr << "\tUpdates:\n";
+  for (const UpdateNode *un=updates.head; un; un=un->next) {
+    llvm::cerr << "\t\t[" << un->index << "] = " << un->value << "\n";
+  }
+}
diff --git a/lib/Core/Memory.h b/lib/Core/Memory.h
new file mode 100644
index 00000000..0f09b162
--- /dev/null
+++ b/lib/Core/Memory.h
@@ -0,0 +1,239 @@
+//===-- Memory.h ------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_MEMORY_H
+#define KLEE_MEMORY_H
+
+#include "klee/Expr.h"
+
+#include <vector>
+#include <string>
+
+namespace llvm {
+  class Value;
+}
+
+namespace klee {
+
+class BitArray;
+class MemoryManager;
+class Solver;
+
+class MemoryObject {
+  friend class STPBuilder;
+
+private:
+  static int counter;
+
+public:
+  unsigned id;
+  uint64_t address;
+  Array *array;
+
+  /// size in bytes
+  unsigned size;
+  std::string name;
+
+  bool isLocal;
+  bool isGlobal;
+  bool isFixed;
+
+  /// true if created by us.
+  bool fake_object;
+  bool isUserSpecified;
+
+  /// "Location" for which this memory object was allocated. This
+  /// should be either the allocating instruction or the global object
+  /// it was allocated for (or whatever else makes sense).
+  const llvm::Value *allocSite;
+  
+  /// A list of boolean expressions the user has requested be true of
+  /// a counterexample. Mutable since we play a little fast and loose
+  /// with allowing it to be added to during execution (although
+  /// should sensibly be only at creation time).
+  mutable std::vector< ref<Expr> > cexPreferences;
+
+  // DO NOT IMPLEMENT
+  MemoryObject(const MemoryObject &b);
+  MemoryObject &operator=(const MemoryObject &b);
+
+public:
+  // XXX this is just a temp hack, should be removed
+  explicit
+  MemoryObject(uint64_t _address) 
+    : id(counter++),
+      address(_address),
+      array(new Array(this, 0, id)),
+      size(0),
+      isFixed(true),
+      allocSite(0) {
+  }
+
+  MemoryObject(uint64_t _address, unsigned _size, 
+               bool _isLocal, bool _isGlobal, bool _isFixed,
+               const llvm::Value *_allocSite) 
+    : id(counter++),
+      address(_address),
+      array(new Array(this, id, _size)),
+      size(_size),
+      name("unnamed"),
+      isLocal(_isLocal),
+      isGlobal(_isGlobal),
+      isFixed(_isFixed),
+      fake_object(false),
+      isUserSpecified(false),
+      allocSite(_allocSite) {
+  }
+
+  ~MemoryObject();
+
+  /// Get an identifying string for this allocation.
+  void getAllocInfo(std::string &result) const;
+
+  void setName(std::string name) {
+    this->name = name;
+  }
+
+  ref<Expr> getBaseExpr() const { 
+    return ConstantExpr::create(address, kMachinePointerType);
+  }
+  ref<Expr> getSizeExpr() const { 
+    return ConstantExpr::create(size, kMachinePointerType);
+  }
+  ref<Expr> getOffsetExpr(ref<Expr> pointer) const {
+    return SubExpr::create(pointer, getBaseExpr());
+  }
+  ref<Expr> getBoundsCheckPointer(ref<Expr> pointer) const {
+    return getBoundsCheckOffset(getOffsetExpr(pointer));
+  }
+  ref<Expr> getBoundsCheckPointer(ref<Expr> pointer, unsigned bytes) const {
+    return getBoundsCheckOffset(getOffsetExpr(pointer), bytes);
+  }
+
+  ref<Expr> getBoundsCheckOffset(ref<Expr> offset) const {
+    if (size==0) {
+      return EqExpr::create(offset, ref<Expr>(0, kMachinePointerType));
+    } else {
+      return UltExpr::create(offset, getSizeExpr());
+    }
+  }
+  ref<Expr> getBoundsCheckOffset(ref<Expr> offset, unsigned bytes) const {
+    if (bytes<=size) {
+      return UltExpr::create(offset, 
+                             ref<Expr>(size - bytes + 1, kMachinePointerType));
+    } else {
+      return ref<Expr>(0, Expr::Bool);
+    }
+  }
+};
+
+class ObjectState {
+private:
+  friend class AddressSpace;
+  unsigned copyOnWriteOwner; // exclusively for AddressSpace
+
+  friend class ObjectHolder;
+  unsigned refCount;
+
+  const MemoryObject *object;
+
+  uint8_t *concreteStore;
+  // XXX cleanup name of flushMask (its backwards or something)
+  BitArray *concreteMask;
+
+  // mutable because may need flushed during read of const
+  mutable BitArray *flushMask;
+
+  ref<Expr> *knownSymbolics;
+
+public:
+  unsigned size;
+
+  // mutable because we may need flush during read of const
+  mutable UpdateList updates;
+
+  bool readOnly;
+
+public:
+  // initial contents are undefined but concrete, it is the creators
+  // responsibility to initialize the object contents appropriate
+  ObjectState(const MemoryObject *mo, unsigned size);
+  ObjectState(const ObjectState &os);
+  ~ObjectState();
+
+  const MemoryObject *getObject() const { return object; }
+
+  void setReadOnly(bool ro) { readOnly = ro; }
+
+  // make all bytes are concrete with undefined values
+  void makeConcrete();
+
+  void makeSymbolic();
+
+  // make contents all concrete and zero
+  void initializeToZero();
+  // make contents all concrete and random
+  void initializeToRandom();
+
+  ref<Expr> read(ref<Expr> offset, Expr::Width width) const;
+  ref<Expr> read(unsigned offset, Expr::Width width) const;
+  ref<Expr> read1(unsigned offset) const;
+  ref<Expr> read8(unsigned offset) const;
+  ref<Expr> read16(unsigned offset) const;
+  ref<Expr> read32(unsigned offset) const;
+  ref<Expr> read64(unsigned offset) const;
+
+  // return bytes written.
+  void write(unsigned offset, ref<Expr> value);
+  void write(ref<Expr> offset, ref<Expr> value);
+
+  void write8(unsigned offset, uint8_t value);
+  void write16(unsigned offset, uint16_t value);
+  void write32(unsigned offset, uint32_t value);
+  void write64(unsigned offset, uint64_t value);
+
+private:
+  ref<Expr> read1(ref<Expr> offset) const;
+  ref<Expr> read8(ref<Expr> offset) const;
+  ref<Expr> read16(ref<Expr> offset) const;
+  ref<Expr> read32(ref<Expr> offset) const;
+  ref<Expr> read64(ref<Expr> offset) const;
+
+  void write1(unsigned offset, ref<Expr> value);
+  void write1(ref<Expr> offset, ref<Expr> value);
+  void write8(unsigned offset, ref<Expr> value);
+  void write8(ref<Expr> offset, ref<Expr> value);
+  void write16(unsigned offset, ref<Expr> value);
+  void write16(ref<Expr> offset, ref<Expr> value);
+  void write32(unsigned offset, ref<Expr> value);
+  void write32(ref<Expr> offset, ref<Expr> value);
+  void write64(unsigned offset, ref<Expr> value);
+  void write64(ref<Expr> offset, ref<Expr> value);
+
+  
+  void fastRangeCheckOffset(ref<Expr> offset, unsigned *base_r, unsigned *size_r) const;
+  void flushRangeForRead(unsigned rangeBase, unsigned rangeSize) const;
+  void flushRangeForWrite(unsigned rangeBase, unsigned rangeSize);
+
+  bool isByteConcrete(unsigned offset) const;
+  bool isByteFlushed(unsigned offset) const;
+  bool isByteKnownSymbolic(unsigned offset) const;
+
+  void markByteConcrete(unsigned offset);
+  void markByteSymbolic(unsigned offset);
+  void markByteFlushed(unsigned offset);
+  void markByteUnflushed(unsigned offset);
+  void setKnownSymbolic(unsigned offset, Expr *value);
+
+  void print();
+};
+  
+} // End klee namespace
+
+#endif
diff --git a/lib/Core/MemoryManager.cpp b/lib/Core/MemoryManager.cpp
new file mode 100644
index 00000000..cec7b7d1
--- /dev/null
+++ b/lib/Core/MemoryManager.cpp
@@ -0,0 +1,69 @@
+//===-- MemoryManager.cpp -------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "CoreStats.h"
+#include "Memory.h"
+#include "MemoryManager.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+
+#include "llvm/Support/CommandLine.h"
+
+using namespace klee;
+
+/***/
+
+MemoryManager::~MemoryManager() { 
+  while (!objects.empty()) {
+    MemoryObject *mo = objects.back();
+    objects.pop_back();
+    delete mo;
+  }
+}
+
+MemoryObject *MemoryManager::allocate(uint64_t size, bool isLocal, bool isGlobal,
+                                      const llvm::Value *allocSite) {
+  if (size>10*1024*1024) {
+    klee_warning_once(0, "failing large alloc: %u bytes", (unsigned) size);
+    return 0;
+  }
+  uint64_t address = (uint64_t) (unsigned long) malloc((unsigned) size);
+  if (!address)
+    return 0;
+  
+  ++stats::allocations;
+  MemoryObject *res = new MemoryObject(address, size, isLocal, isGlobal, false,
+                                       allocSite);
+  objects.push_back(res);
+  return res;
+}
+
+MemoryObject *MemoryManager::allocateFixed(uint64_t address, uint64_t size,
+                                           const llvm::Value *allocSite) {
+  for (objects_ty::iterator it = objects.begin(), ie = objects.end();
+       it != ie; ++it) {
+    MemoryObject *mo = *it;
+    assert(!(address+size > mo->address && address < mo->address+mo->size) &&
+           "allocated an overlapping object");
+  }
+
+  ++stats::allocations;
+  MemoryObject *res = new MemoryObject(address, size, false, true, true,
+                                       allocSite);
+  objects.push_back(res);
+  return res;
+}
+
+void MemoryManager::deallocate(const MemoryObject *mo) {
+  assert(0);
+}
diff --git a/lib/Core/MemoryManager.h b/lib/Core/MemoryManager.h
new file mode 100644
index 00000000..adb2ba22
--- /dev/null
+++ b/lib/Core/MemoryManager.h
@@ -0,0 +1,41 @@
+//===-- MemoryManager.h -----------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_MEMORYMANAGER_H
+#define KLEE_MEMORYMANAGER_H
+
+#include <vector>
+#include <stdint.h>
+
+namespace llvm {
+  class Value;
+}
+
+namespace klee {
+  class MemoryObject;
+
+  class MemoryManager {
+  private:
+    typedef std::vector<MemoryObject*> objects_ty;
+    objects_ty objects;
+
+  public:
+    MemoryManager() {}
+    ~MemoryManager();
+
+    MemoryObject *allocate(uint64_t size, bool isLocal, bool isGlobal,
+                           const llvm::Value *allocSite);
+    MemoryObject *allocateFixed(uint64_t address, uint64_t size,
+                                const llvm::Value *allocSite);
+    void deallocate(const MemoryObject *mo);
+  };
+
+} // End klee namespace
+
+#endif
diff --git a/lib/Core/ObjectHolder.h b/lib/Core/ObjectHolder.h
new file mode 100644
index 00000000..abf2c6f0
--- /dev/null
+++ b/lib/Core/ObjectHolder.h
@@ -0,0 +1,33 @@
+//===-- ObjectHolder.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_OBJECTHOLDER_H
+#define KLEE_OBJECTHOLDER_H
+
+namespace klee {
+  class ObjectState;
+
+  class ObjectHolder {
+    ObjectState *os;
+    
+  public:
+    ObjectHolder() : os(0) {}
+    ObjectHolder(ObjectState *_os);
+    ObjectHolder(const ObjectHolder &b);
+    ~ObjectHolder(); 
+    
+    ObjectHolder &operator=(const ObjectHolder &b);
+
+    operator class ObjectState *() { return os; }
+    operator class ObjectState *() const { return (ObjectState*) os; }
+  };
+}
+
+#endif
+
diff --git a/lib/Core/PTree.cpp b/lib/Core/PTree.cpp
new file mode 100644
index 00000000..349761cd
--- /dev/null
+++ b/lib/Core/PTree.cpp
@@ -0,0 +1,103 @@
+//===-- PTree.cpp ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PTree.h"
+
+#include <klee/Expr.h>
+#include <klee/util/ExprPPrinter.h>
+
+#include <vector>
+#include <iostream>
+
+using namespace klee;
+
+  /* *** */
+
+PTree::PTree(const data_type &_root) : root(new Node(0,_root)) {
+}
+
+PTree::~PTree() {}
+
+std::pair<PTreeNode*, PTreeNode*>
+PTree::split(Node *n, 
+             const data_type &leftData, 
+             const data_type &rightData) {
+  assert(n && !n->left && !n->right);
+  n->left = new Node(n, leftData);
+  n->right = new Node(n, rightData);
+  return std::make_pair(n->left, n->right);
+}
+
+void PTree::remove(Node *n) {
+  assert(!n->left && !n->right);
+  do {
+    Node *p = n->parent;
+    delete n;
+    if (p) {
+      if (n == p->left) {
+        p->left = 0;
+      } else {
+        assert(n == p->right);
+        p->right = 0;
+      }
+    }
+    n = p;
+  } while (n && !n->left && !n->right);
+}
+
+void PTree::dump(std::ostream &os) {
+  ExprPPrinter *pp = ExprPPrinter::create(os);
+  pp->setNewline("\\l");
+  os << "digraph G {\n";
+  os << "\tsize=\"10,7.5\";\n";
+  os << "\tratio=fill;\n";
+  os << "\trotate=90;\n";
+  os << "\tcenter = \"true\";\n";
+  os << "\tnode [style=\"filled\",width=.1,height=.1,fontname=\"Terminus\"]\n";
+  os << "\tedge [arrowsize=.3]\n";
+  std::vector<PTree::Node*> stack;
+  stack.push_back(root);
+  while (!stack.empty()) {
+    PTree::Node *n = stack.back();
+    stack.pop_back();
+    if (n->condition.isNull()) {
+      os << "\tn" << n << " [label=\"\"";
+    } else {
+      os << "\tn" << n << " [label=\"";
+      pp->print(n->condition);
+      os << "\",shape=diamond";
+    }
+    if (n->data)
+      os << ",fillcolor=green";
+    os << "];\n";
+    if (n->left) {
+      os << "\tn" << n << " -> n" << n->left << ";\n";
+      stack.push_back(n->left);
+    }
+    if (n->right) {
+      os << "\tn" << n << " -> n" << n->right << ";\n";
+      stack.push_back(n->right);
+    }
+  }
+  os << "}\n";
+  delete pp;
+}
+
+PTreeNode::PTreeNode(PTreeNode *_parent, 
+                     ExecutionState *_data) 
+  : parent(_parent),
+    left(0),
+    right(0),
+    data(_data),
+    condition(0) {
+}
+
+PTreeNode::~PTreeNode() {
+}
+
diff --git a/lib/Core/PTree.h b/lib/Core/PTree.h
new file mode 100644
index 00000000..6accc8e2
--- /dev/null
+++ b/lib/Core/PTree.h
@@ -0,0 +1,53 @@
+//===-- PTree.h -------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_PTREE_H__
+#define __UTIL_PTREE_H__
+
+#include <klee/Expr.h>
+
+#include <utility>
+#include <cassert>
+#include <iostream>
+
+namespace klee {
+  class ExecutionState;
+
+  class PTree { 
+    typedef ExecutionState* data_type;
+
+  public:
+    typedef class PTreeNode Node;
+    Node *root;
+
+    PTree(const data_type &_root);
+    ~PTree();
+    
+    std::pair<Node*,Node*> split(Node *n,
+                                 const data_type &leftData,
+                                 const data_type &rightData);
+    void remove(Node *n);
+
+    void dump(std::ostream &os);
+  };
+
+  class PTreeNode {
+    friend class PTree;
+  public:
+    PTreeNode *parent, *left, *right;
+    ExecutionState *data;
+    ref<Expr> condition;
+
+  private:
+    PTreeNode(PTreeNode *_parent, ExecutionState *_data);
+    ~PTreeNode();
+  };
+}
+
+#endif
diff --git a/lib/Core/Searcher.cpp b/lib/Core/Searcher.cpp
new file mode 100644
index 00000000..4c94c59b
--- /dev/null
+++ b/lib/Core/Searcher.cpp
@@ -0,0 +1,575 @@
+//===-- Searcher.cpp ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "Searcher.h"
+
+#include "CoreStats.h"
+#include "Executor.h"
+#include "PTree.h"
+#include "StatsTracker.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Statistics.h"
+#include "klee/Internal/Module/InstructionInfoTable.h"
+#include "klee/Internal/Module/KInstruction.h"
+#include "klee/Internal/Module/KModule.h"
+#include "klee/Internal/ADT/DiscretePDF.h"
+#include "klee/Internal/ADT/RNG.h"
+#include "klee/Internal/Support/ModuleUtil.h"
+#include "klee/Internal/System/Time.h"
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <cassert>
+#include <fstream>
+#include <climits>
+
+using namespace klee;
+using namespace llvm;
+
+namespace {
+  cl::opt<bool>
+  DebugLogMerge("debug-log-merge");
+}
+
+namespace klee {
+  extern RNG theRNG;
+}
+
+Searcher::~Searcher() {
+}
+
+///
+
+ExecutionState &DFSSearcher::selectState() {
+  return *states.back();
+}
+
+void DFSSearcher::update(ExecutionState *current,
+                         const std::set<ExecutionState*> &addedStates,
+                         const std::set<ExecutionState*> &removedStates) {
+  states.insert(states.end(),
+                addedStates.begin(),
+                addedStates.end());
+  for (std::set<ExecutionState*>::const_iterator it = removedStates.begin(),
+         ie = removedStates.end(); it != ie; ++it) {
+    ExecutionState *es = *it;
+    if (es == states.back()) {
+      states.pop_back();
+    } else {
+      bool ok = false;
+
+      for (std::vector<ExecutionState*>::iterator it = states.begin(),
+             ie = states.end(); it != ie; ++it) {
+        if (es==*it) {
+          states.erase(it);
+          ok = true;
+          break;
+        }
+      }
+
+      assert(ok && "invalid state removed");
+    }
+  }
+}
+
+///
+
+ExecutionState &RandomSearcher::selectState() {
+  return *states[theRNG.getInt32()%states.size()];
+}
+
+void RandomSearcher::update(ExecutionState *current,
+                            const std::set<ExecutionState*> &addedStates,
+                            const std::set<ExecutionState*> &removedStates) {
+  states.insert(states.end(),
+                addedStates.begin(),
+                addedStates.end());
+  for (std::set<ExecutionState*>::const_iterator it = removedStates.begin(),
+         ie = removedStates.end(); it != ie; ++it) {
+    ExecutionState *es = *it;
+    bool ok = false;
+
+    for (std::vector<ExecutionState*>::iterator it = states.begin(),
+           ie = states.end(); it != ie; ++it) {
+      if (es==*it) {
+        states.erase(it);
+        ok = true;
+        break;
+      }
+    }
+    
+    assert(ok && "invalid state removed");
+  }
+}
+
+///
+
+WeightedRandomSearcher::WeightedRandomSearcher(Executor &_executor,
+                                               WeightType _type) 
+  : executor(_executor),
+    states(new DiscretePDF<ExecutionState*>()),
+    type(_type) {
+  switch(type) {
+  case Depth: 
+    updateWeights = false;
+    break;
+  case InstCount:
+  case CPInstCount:
+  case QueryCost:
+  case MinDistToUncovered:
+  case CoveringNew:
+    updateWeights = true;
+    break;
+  default:
+    assert(0 && "invalid weight type");
+  }
+}
+
+WeightedRandomSearcher::~WeightedRandomSearcher() {
+  delete states;
+}
+
+ExecutionState &WeightedRandomSearcher::selectState() {
+  return *states->choose(theRNG.getDoubleL());
+}
+
+double WeightedRandomSearcher::getWeight(ExecutionState *es) {
+  switch(type) {
+  default:
+  case Depth: 
+    return es->weight;
+  case InstCount: {
+    uint64_t count = theStatisticManager->getIndexedValue(stats::instructions,
+                                                          es->pc->info->id);
+    double inv = 1. / std::max((uint64_t) 1, count);
+    return inv * inv;
+  }
+  case CPInstCount: {
+    StackFrame &sf = es->stack.back();
+    uint64_t count = sf.callPathNode->statistics.getValue(stats::instructions);
+    double inv = 1. / std::max((uint64_t) 1, count);
+    return inv;
+  }
+  case QueryCost:
+    return (es->queryCost < .1) ? 1. : 1./es->queryCost;
+  case CoveringNew:
+  case MinDistToUncovered: {
+    uint64_t md2u = computeMinDistToUncovered(es->pc,
+                                              es->stack.back().minDistToUncoveredOnReturn);
+
+    double invMD2U = 1. / (md2u ? md2u : 10000);
+    if (type==CoveringNew) {
+      double invCovNew = 0.;
+      if (es->instsSinceCovNew)
+        invCovNew = 1. / std::max(1, (int) es->instsSinceCovNew - 1000);
+      return (invCovNew * invCovNew + invMD2U * invMD2U);
+    } else {
+      return invMD2U * invMD2U;
+    }
+  }
+  }
+}
+
+void WeightedRandomSearcher::update(ExecutionState *current,
+                                    const std::set<ExecutionState*> &addedStates,
+                                    const std::set<ExecutionState*> &removedStates) {
+  if (current && updateWeights && !removedStates.count(current))
+    states->update(current, getWeight(current));
+  
+  for (std::set<ExecutionState*>::const_iterator it = addedStates.begin(),
+         ie = addedStates.end(); it != ie; ++it) {
+    ExecutionState *es = *it;
+    states->insert(es, getWeight(es));
+  }
+
+  for (std::set<ExecutionState*>::const_iterator it = removedStates.begin(),
+         ie = removedStates.end(); it != ie; ++it) {
+    states->remove(*it);
+  }
+}
+
+bool WeightedRandomSearcher::empty() { 
+  return states->empty(); 
+}
+
+///
+
+RandomPathSearcher::RandomPathSearcher(Executor &_executor)
+  : executor(_executor) {
+}
+
+RandomPathSearcher::~RandomPathSearcher() {
+}
+
+ExecutionState &RandomPathSearcher::selectState() {
+  unsigned flips=0, bits=0;
+  PTree::Node *n = executor.processTree->root;
+  
+  while (!n->data) {
+    if (!n->left) {
+      n = n->right;
+    } else if (!n->right) {
+      n = n->left;
+    } else {
+      if (bits==0) {
+        flips = theRNG.getInt32();
+        bits = 32;
+      }
+      --bits;
+      n = (flips&(1<<bits)) ? n->left : n->right;
+    }
+  }
+
+  return *n->data;
+}
+
+void RandomPathSearcher::update(ExecutionState *current,
+                                const std::set<ExecutionState*> &addedStates,
+                                const std::set<ExecutionState*> &removedStates) {
+}
+
+bool RandomPathSearcher::empty() { 
+  return executor.states.empty(); 
+}
+
+///
+
+BumpMergingSearcher::BumpMergingSearcher(Executor &_executor, Searcher *_baseSearcher) 
+  : executor(_executor),
+    baseSearcher(_baseSearcher),
+    mergeFunction(executor.kmodule->kleeMergeFn) {
+}
+
+BumpMergingSearcher::~BumpMergingSearcher() {
+  delete baseSearcher;
+}
+
+///
+
+Instruction *BumpMergingSearcher::getMergePoint(ExecutionState &es) {  
+  if (mergeFunction) {
+    Instruction *i = es.pc->inst;
+
+    if (i->getOpcode()==Instruction::Call) {
+      CallSite cs(cast<CallInst>(i));
+      if (mergeFunction==cs.getCalledFunction())
+        return i;
+    }
+  }
+
+  return 0;
+}
+
+ExecutionState &BumpMergingSearcher::selectState() {
+entry:
+  // out of base states, pick one to pop
+  if (baseSearcher->empty()) {
+    std::map<llvm::Instruction*, ExecutionState*>::iterator it = 
+      statesAtMerge.begin();
+    ExecutionState *es = it->second;
+    statesAtMerge.erase(it);
+    ++es->pc;
+
+    baseSearcher->addState(es);
+  }
+
+  ExecutionState &es = baseSearcher->selectState();
+
+  if (Instruction *mp = getMergePoint(es)) {
+    std::map<llvm::Instruction*, ExecutionState*>::iterator it = 
+      statesAtMerge.find(mp);
+
+    baseSearcher->removeState(&es);
+
+    if (it==statesAtMerge.end()) {
+      statesAtMerge.insert(std::make_pair(mp, &es));
+    } else {
+      ExecutionState *mergeWith = it->second;
+      if (mergeWith->merge(es)) {
+        // hack, because we are terminating the state we need to let
+        // the baseSearcher know about it again
+        baseSearcher->addState(&es);
+        executor.terminateState(es);
+      } else {
+        it->second = &es; // the bump
+        ++mergeWith->pc;
+
+        baseSearcher->addState(mergeWith);
+      }
+    }
+
+    goto entry;
+  } else {
+    return es;
+  }
+}
+
+void BumpMergingSearcher::update(ExecutionState *current,
+                                 const std::set<ExecutionState*> &addedStates,
+                                 const std::set<ExecutionState*> &removedStates) {
+  baseSearcher->update(current, addedStates, removedStates);
+}
+
+///
+
+MergingSearcher::MergingSearcher(Executor &_executor, Searcher *_baseSearcher) 
+  : executor(_executor),
+    baseSearcher(_baseSearcher),
+    mergeFunction(executor.kmodule->kleeMergeFn) {
+}
+
+MergingSearcher::~MergingSearcher() {
+  delete baseSearcher;
+}
+
+///
+
+Instruction *MergingSearcher::getMergePoint(ExecutionState &es) {
+  if (mergeFunction) {
+    Instruction *i = es.pc->inst;
+
+    if (i->getOpcode()==Instruction::Call) {
+      CallSite cs(cast<CallInst>(i));
+      if (mergeFunction==cs.getCalledFunction())
+        return i;
+    }
+  }
+
+  return 0;
+}
+
+ExecutionState &MergingSearcher::selectState() {
+  while (!baseSearcher->empty()) {
+    ExecutionState &es = baseSearcher->selectState();
+    if (getMergePoint(es)) {
+      baseSearcher->removeState(&es, &es);
+      statesAtMerge.insert(&es);
+    } else {
+      return es;
+    }
+  }
+  
+  // build map of merge point -> state list
+  std::map<Instruction*, std::vector<ExecutionState*> > merges;
+  for (std::set<ExecutionState*>::const_iterator it = statesAtMerge.begin(),
+         ie = statesAtMerge.end(); it != ie; ++it) {
+    ExecutionState &state = **it;
+    Instruction *mp = getMergePoint(state);
+    
+    merges[mp].push_back(&state);
+  }
+  
+  if (DebugLogMerge)
+    llvm::cerr << "-- all at merge --\n";
+  for (std::map<Instruction*, std::vector<ExecutionState*> >::iterator
+         it = merges.begin(), ie = merges.end(); it != ie; ++it) {
+    if (DebugLogMerge) {
+      llvm::cerr << "\tmerge: " << it->first << " [";
+      for (std::vector<ExecutionState*>::iterator it2 = it->second.begin(),
+             ie2 = it->second.end(); it2 != ie2; ++it2) {
+        ExecutionState *state = *it2;
+        llvm::cerr << state << ", ";
+      }
+      llvm::cerr << "]\n";
+    }
+
+    // merge states
+    std::set<ExecutionState*> toMerge(it->second.begin(), it->second.end());
+    while (!toMerge.empty()) {
+      ExecutionState *base = *toMerge.begin();
+      toMerge.erase(toMerge.begin());
+      
+      std::set<ExecutionState*> toErase;
+      for (std::set<ExecutionState*>::iterator it = toMerge.begin(),
+             ie = toMerge.end(); it != ie; ++it) {
+        ExecutionState *mergeWith = *it;
+        
+        if (base->merge(*mergeWith)) {
+          toErase.insert(mergeWith);
+        }
+      }
+      if (DebugLogMerge && !toErase.empty()) {
+        llvm::cerr << "\t\tmerged: " << base << " with [";
+        for (std::set<ExecutionState*>::iterator it = toErase.begin(),
+               ie = toErase.end(); it != ie; ++it) {
+          if (it!=toErase.begin()) llvm::cerr << ", ";
+          llvm::cerr << *it;
+        }
+        llvm::cerr << "]\n";
+      }
+      for (std::set<ExecutionState*>::iterator it = toErase.begin(),
+             ie = toErase.end(); it != ie; ++it) {
+        std::set<ExecutionState*>::iterator it2 = toMerge.find(*it);
+        assert(it2!=toMerge.end());
+        executor.terminateState(**it);
+        toMerge.erase(it2);
+      }
+
+      // step past merge and toss base back in pool
+      statesAtMerge.erase(statesAtMerge.find(base));
+      ++base->pc;
+      baseSearcher->addState(base);
+    }  
+  }
+  
+  if (DebugLogMerge)
+    llvm::cerr << "-- merge complete, continuing --\n";
+  
+  return selectState();
+}
+
+void MergingSearcher::update(ExecutionState *current,
+                             const std::set<ExecutionState*> &addedStates,
+                             const std::set<ExecutionState*> &removedStates) {
+  if (!removedStates.empty()) {
+    std::set<ExecutionState *> alt = removedStates;
+    for (std::set<ExecutionState*>::const_iterator it = removedStates.begin(),
+           ie = removedStates.end(); it != ie; ++it) {
+      ExecutionState *es = *it;
+      std::set<ExecutionState*>::const_iterator it = statesAtMerge.find(es);
+      if (it!=statesAtMerge.end()) {
+        statesAtMerge.erase(it);
+        alt.erase(alt.find(es));
+      }
+    }    
+    baseSearcher->update(current, addedStates, alt);
+  } else {
+    baseSearcher->update(current, addedStates, removedStates);
+  }
+}
+
+///
+
+BatchingSearcher::BatchingSearcher(Searcher *_baseSearcher,
+                                   double _timeBudget,
+                                   unsigned _instructionBudget) 
+  : baseSearcher(_baseSearcher),
+    timeBudget(_timeBudget),
+    instructionBudget(_instructionBudget),
+    lastState(0) {
+  
+}
+
+BatchingSearcher::~BatchingSearcher() {
+  delete baseSearcher;
+}
+
+ExecutionState &BatchingSearcher::selectState() {
+  if (!lastState || 
+      (util::getWallTime()-lastStartTime)>timeBudget ||
+      (stats::instructions-lastStartInstructions)>instructionBudget) {
+    if (lastState) {
+      double delta = util::getWallTime()-lastStartTime;
+      if (delta>timeBudget*1.1) {
+        llvm::cerr << "KLEE: increased time budget from " << timeBudget << " to " << delta << "\n";
+        timeBudget = delta;
+      }
+    }
+    lastState = &baseSearcher->selectState();
+    lastStartTime = util::getWallTime();
+    lastStartInstructions = stats::instructions;
+    return *lastState;
+  } else {
+    return *lastState;
+  }
+}
+
+void BatchingSearcher::update(ExecutionState *current,
+                              const std::set<ExecutionState*> &addedStates,
+                              const std::set<ExecutionState*> &removedStates) {
+  if (removedStates.count(lastState))
+    lastState = 0;
+  baseSearcher->update(current, addedStates, removedStates);
+}
+
+/***/
+
+IterativeDeepeningTimeSearcher::IterativeDeepeningTimeSearcher(Searcher *_baseSearcher)
+  : baseSearcher(_baseSearcher),
+    time(1.) {
+}
+
+IterativeDeepeningTimeSearcher::~IterativeDeepeningTimeSearcher() {
+  delete baseSearcher;
+}
+
+ExecutionState &IterativeDeepeningTimeSearcher::selectState() {
+  ExecutionState &res = baseSearcher->selectState();
+  startTime = util::getWallTime();
+  return res;
+}
+
+void IterativeDeepeningTimeSearcher::update(ExecutionState *current,
+                                            const std::set<ExecutionState*> &addedStates,
+                                            const std::set<ExecutionState*> &removedStates) {
+  double elapsed = util::getWallTime() - startTime;
+
+  if (!removedStates.empty()) {
+    std::set<ExecutionState *> alt = removedStates;
+    for (std::set<ExecutionState*>::const_iterator it = removedStates.begin(),
+           ie = removedStates.end(); it != ie; ++it) {
+      ExecutionState *es = *it;
+      std::set<ExecutionState*>::const_iterator it = pausedStates.find(es);
+      if (it!=pausedStates.end()) {
+        pausedStates.erase(it);
+        alt.erase(alt.find(es));
+      }
+    }    
+    baseSearcher->update(current, addedStates, alt);
+  } else {
+    baseSearcher->update(current, addedStates, removedStates);
+  }
+
+  if (current && !removedStates.count(current) && elapsed>time) {
+    pausedStates.insert(current);
+    baseSearcher->removeState(current);
+  }
+
+  if (baseSearcher->empty()) {
+    time *= 2;
+    llvm::cerr << "KLEE: increasing time budget to: " << time << "\n";
+    baseSearcher->update(0, pausedStates, std::set<ExecutionState*>());
+    pausedStates.clear();
+  }
+}
+
+/***/
+
+InterleavedSearcher::InterleavedSearcher(const std::vector<Searcher*> &_searchers)
+  : searchers(_searchers),
+    index(1) {
+}
+
+InterleavedSearcher::~InterleavedSearcher() {
+  for (std::vector<Searcher*>::const_iterator it = searchers.begin(),
+         ie = searchers.end(); it != ie; ++it)
+    delete *it;
+}
+
+ExecutionState &InterleavedSearcher::selectState() {
+  Searcher *s = searchers[--index];
+  if (index==0) index = searchers.size();
+  return s->selectState();
+}
+
+void InterleavedSearcher::update(ExecutionState *current,
+                                 const std::set<ExecutionState*> &addedStates,
+                                 const std::set<ExecutionState*> &removedStates) {
+  for (std::vector<Searcher*>::const_iterator it = searchers.begin(),
+         ie = searchers.end(); it != ie; ++it)
+    (*it)->update(current, addedStates, removedStates);
+}
diff --git a/lib/Core/Searcher.h b/lib/Core/Searcher.h
new file mode 100644
index 00000000..455a7679
--- /dev/null
+++ b/lib/Core/Searcher.h
@@ -0,0 +1,279 @@
+//===-- Searcher.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_SEARCHER_H
+#define KLEE_SEARCHER_H
+
+#include <vector>
+#include <set>
+#include <map>
+#include <queue>
+
+// FIXME: Move out of header, use llvm streams.
+#include <ostream>
+
+namespace llvm {
+  class BasicBlock;
+  class Function;
+  class Instruction;
+}
+
+namespace klee {
+  template<class T> class DiscretePDF;
+  class ExecutionState;
+  class Executor;
+
+  class Searcher {
+  public:
+    virtual ~Searcher();
+
+    virtual ExecutionState &selectState() = 0;
+
+    virtual void update(ExecutionState *current,
+                        const std::set<ExecutionState*> &addedStates,
+                        const std::set<ExecutionState*> &removedStates) = 0;
+
+    virtual bool empty() = 0;
+
+    // prints name of searcher as a klee_message()
+    // TODO: could probably make prettier or more flexible
+    virtual void printName(std::ostream &os) { 
+      os << "<unnamed searcher>\n";
+    }
+
+    // pgbovine - to be called when a searcher gets activated and
+    // deactivated, say, by a higher-level searcher; most searchers
+    // don't need this functionality, so don't have to override.
+    virtual void activate() {};
+    virtual void deactivate() {};
+
+    // utility functions
+
+    void addState(ExecutionState *es, ExecutionState *current = 0) {
+      std::set<ExecutionState*> tmp;
+      tmp.insert(es);
+      update(current, tmp, std::set<ExecutionState*>());
+    }
+
+    void removeState(ExecutionState *es, ExecutionState *current = 0) {
+      std::set<ExecutionState*> tmp;
+      tmp.insert(es);
+      update(current, std::set<ExecutionState*>(), tmp);
+    }
+  };
+
+  class DFSSearcher : public Searcher {
+    std::vector<ExecutionState*> states;
+
+  public:
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return states.empty(); }
+    void printName(std::ostream &os) {
+      os << "DFSSearcher\n";
+    }
+  };
+
+  class RandomSearcher : public Searcher {
+    std::vector<ExecutionState*> states;
+
+  public:
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return states.empty(); }
+    void printName(std::ostream &os) {
+      os << "RandomSearcher\n";
+    }
+  };
+
+  class WeightedRandomSearcher : public Searcher {
+  public:
+    enum WeightType {
+      Depth,
+      QueryCost,
+      InstCount,
+      CPInstCount,
+      MinDistToUncovered,
+      CoveringNew
+    };
+
+  private:
+    Executor &executor;
+    DiscretePDF<ExecutionState*> *states;
+    WeightType type;
+    bool updateWeights;
+    
+    double getWeight(ExecutionState*);
+
+  public:
+    WeightedRandomSearcher(Executor &executor, WeightType type);
+    ~WeightedRandomSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty();
+    void printName(std::ostream &os) {
+      os << "WeightedRandomSearcher::";
+      switch(type) {
+      case Depth              : os << "Depth\n"; return;
+      case QueryCost          : os << "QueryCost\n"; return;
+      case InstCount          : os << "InstCount\n"; return;
+      case CPInstCount        : os << "CPInstCount\n"; return;
+      case MinDistToUncovered : os << "MinDistToUncovered\n"; return;
+      case CoveringNew        : os << "CoveringNew\n"; return;
+      default                 : os << "<unknown type>\n"; return;
+      }
+    }
+  };
+
+  class RandomPathSearcher : public Searcher {
+    Executor &executor;
+
+  public:
+    RandomPathSearcher(Executor &_executor);
+    ~RandomPathSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty();
+    void printName(std::ostream &os) {
+      os << "RandomPathSearcher\n";
+    }
+  };
+
+  class MergingSearcher : public Searcher {
+    Executor &executor;
+    std::set<ExecutionState*> statesAtMerge;
+    Searcher *baseSearcher;
+    llvm::Function *mergeFunction;
+
+  private:
+    llvm::Instruction *getMergePoint(ExecutionState &es);
+
+  public:
+    MergingSearcher(Executor &executor, Searcher *baseSearcher);
+    ~MergingSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty() && statesAtMerge.empty(); }
+    void printName(std::ostream &os) {
+      os << "MergingSearcher\n";
+    }
+  };
+
+  class BumpMergingSearcher : public Searcher {
+    Executor &executor;
+    std::map<llvm::Instruction*, ExecutionState*> statesAtMerge;
+    Searcher *baseSearcher;
+    llvm::Function *mergeFunction;
+
+  private:
+    llvm::Instruction *getMergePoint(ExecutionState &es);
+
+  public:
+    BumpMergingSearcher(Executor &executor, Searcher *baseSearcher);
+    ~BumpMergingSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty() && statesAtMerge.empty(); }
+    void printName(std::ostream &os) {
+      os << "BumpMergingSearcher\n";
+    }
+  };
+
+  class BatchingSearcher : public Searcher {
+    Searcher *baseSearcher;
+    double timeBudget;
+    unsigned instructionBudget;
+
+    ExecutionState *lastState;
+    double lastStartTime;
+    unsigned lastStartInstructions;
+
+  public:
+    BatchingSearcher(Searcher *baseSearcher, 
+                     double _timeBudget,
+                     unsigned _instructionBudget);
+    ~BatchingSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty(); }
+    void printName(std::ostream &os) {
+      os << "<BatchingSearcher> timeBudget: " << timeBudget
+         << ", instructionBudget: " << instructionBudget
+         << ", baseSearcher:\n";
+      baseSearcher->printName(os);
+      os << "</BatchingSearcher>\n";
+    }
+  };
+
+  class IterativeDeepeningTimeSearcher : public Searcher {
+    Searcher *baseSearcher;
+    double time, startTime;
+    std::set<ExecutionState*> pausedStates;
+
+  public:
+    IterativeDeepeningTimeSearcher(Searcher *baseSearcher);
+    ~IterativeDeepeningTimeSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return baseSearcher->empty() && pausedStates.empty(); }
+    void printName(std::ostream &os) {
+      os << "IterativeDeepeningTimeSearcher\n";
+    }
+  };
+
+  class InterleavedSearcher : public Searcher {
+    typedef std::vector<Searcher*> searchers_ty;
+
+    searchers_ty searchers;
+    unsigned index;
+
+  public:
+    explicit InterleavedSearcher(const searchers_ty &_searchers);
+    ~InterleavedSearcher();
+
+    ExecutionState &selectState();
+    void update(ExecutionState *current,
+                const std::set<ExecutionState*> &addedStates,
+                const std::set<ExecutionState*> &removedStates);
+    bool empty() { return searchers[0]->empty(); }
+    void printName(std::ostream &os) {
+      os << "<InterleavedSearcher> containing "
+         << searchers.size() << " searchers:\n";
+      for (searchers_ty::iterator it = searchers.begin(), ie = searchers.end();
+           it != ie; ++it)
+        (*it)->printName(os);
+      os << "</InterleavedSearcher>\n";
+    }
+  };
+
+}
+
+#endif
diff --git a/lib/Core/SeedInfo.cpp b/lib/Core/SeedInfo.cpp
new file mode 100644
index 00000000..d76d75dc
--- /dev/null
+++ b/lib/Core/SeedInfo.cpp
@@ -0,0 +1,151 @@
+//===-- SeedInfo.cpp ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "Memory.h"
+#include "SeedInfo.h"
+#include "TimingSolver.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Expr.h"
+#include "klee/util/ExprUtil.h"
+#include "klee/Internal/ADT/BOut.h"
+
+using namespace klee;
+
+BOutObject *SeedInfo::getNextInput(const MemoryObject *mo,
+                                   bool byName) {
+  if (byName) {
+    unsigned i;
+    
+    for (i=0; i<input->numObjects; ++i) {
+      BOutObject *obj = &input->objects[i];
+      if (std::string(obj->name) == mo->name)
+        if (used.insert(obj).second)
+          return obj;
+    }
+    
+    // If first unused input matches in size then accept that as
+    // well.
+    for (i=0; i<input->numObjects; ++i)
+      if (!used.count(&input->objects[i]))
+        break;
+    if (i<input->numObjects) {
+      BOutObject *obj = &input->objects[i];
+      if (obj->numBytes == mo->size) {
+        used.insert(obj);
+        klee_warning_once(mo, "using seed input %s[%d] for: %s (no name match)",
+                          obj->name, obj->numBytes, mo->name.c_str());
+        return obj;
+      }
+    }
+    
+    klee_warning_once(mo, "no seed input for: %s", mo->name.c_str());
+    return 0;
+  } else {
+    if (inputPosition >= input->numObjects) {
+      return 0; 
+    } else {
+      return &input->objects[inputPosition++];
+    }
+  }
+}
+
+void SeedInfo::patchSeed(const ExecutionState &state, 
+                         ref<Expr> condition,
+                         TimingSolver *solver) {
+  std::vector< ref<Expr> > required(state.constraints.begin(),
+                                    state.constraints.end());
+  ExecutionState tmp(required);
+  tmp.addConstraint(condition);
+
+  // Try and patch direct reads first, this is likely to resolve the
+  // problem quickly and avoids long traversal of all seed
+  // values. There are other smart ways to do this, the nicest is if
+  // we got a minimal counterexample from STP, in which case we would
+  // just inject those values back into the seed.
+  std::set< std::pair<const Array*, unsigned> > directReads;
+  std::vector< ref<ReadExpr> > reads;
+  findReads(condition, false, reads);
+  for (std::vector< ref<ReadExpr> >::iterator it = reads.begin(), 
+         ie = reads.end(); it != ie; ++it) {
+    ReadExpr *re = it->get();
+    if (re->index.isConstant()) {
+      unsigned index = (unsigned) re->index.getConstantValue();
+      directReads.insert(std::make_pair(re->updates.root, index));
+    }
+  }
+  
+  for (std::set< std::pair<const Array*, unsigned> >::iterator
+         it = directReads.begin(), ie = directReads.end(); it != ie; ++it) {
+    const Array *array = it->first;
+    unsigned i = it->second;
+    ref<Expr> read = ReadExpr::create(UpdateList(array, true, 0),
+                                      ref<Expr>(i, Expr::Int32));
+    
+    // If not in bindings then this can't be a violation?
+    Assignment::bindings_ty::iterator it2 = assignment.bindings.find(array);
+    if (it2 != assignment.bindings.end()) {
+      ref<Expr> isSeed = EqExpr::create(read, ref<Expr>(it2->second[i], Expr::Int8));
+      bool res;
+      bool success = solver->mustBeFalse(tmp, isSeed, res);
+      assert(success && "FIXME: Unhandled solver failure");
+      if (res) {
+        ref<Expr> value;
+        bool success = solver->getValue(tmp, read, value);
+        assert(success && "FIXME: Unhandled solver failure");            
+        it2->second[i] = value.getConstantValue();
+        tmp.addConstraint(EqExpr::create(read, ref<Expr>(it2->second[i], Expr::Int8)));
+      } else {
+        tmp.addConstraint(isSeed);
+      }
+    }
+  }
+
+  bool res;
+  bool success = solver->mayBeTrue(state, assignment.evaluate(condition), res);
+  assert(success && "FIXME: Unhandled solver failure");
+  if (res)
+    return;
+  
+  // We could still do a lot better than this, for example by looking at
+  // independence. But really, this shouldn't be happening often.
+  for (Assignment::bindings_ty::iterator it = assignment.bindings.begin(), 
+         ie = assignment.bindings.end(); it != ie; ++it) {
+    const Array *array = it->first;
+    for (unsigned i=0; i<array->size; ++i) {
+      ref<Expr> read = ReadExpr::create(UpdateList(array, true, 0),
+                                        ref<Expr>(i, Expr::Int32));
+      ref<Expr> isSeed = EqExpr::create(read, ref<Expr>(it->second[i], Expr::Int8));
+      bool res;
+      bool success = solver->mustBeFalse(tmp, isSeed, res);
+      assert(success && "FIXME: Unhandled solver failure");
+      if (res) {
+        ref<Expr> value;
+        bool success = solver->getValue(tmp, read, value);
+        assert(success && "FIXME: Unhandled solver failure");            
+        it->second[i] = value.getConstantValue();
+        tmp.addConstraint(EqExpr::create(read, ref<Expr>(it->second[i], Expr::Int8)));
+      } else {
+        tmp.addConstraint(isSeed);
+      }
+    }
+  }
+
+#ifndef NDEBUG
+  {
+    bool res;
+    bool success = 
+      solver->mayBeTrue(state, assignment.evaluate(condition), res);
+    assert(success && "FIXME: Unhandled solver failure");            
+    assert(res && "seed patching failed");
+  }
+#endif
+}
diff --git a/lib/Core/SeedInfo.h b/lib/Core/SeedInfo.h
new file mode 100644
index 00000000..dd151ed0
--- /dev/null
+++ b/lib/Core/SeedInfo.h
@@ -0,0 +1,48 @@
+//===-- SeedInfo.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_SEEDINFO_H
+#define KLEE_SEEDINFO_H
+
+#include "klee/util/Assignment.h"
+
+extern "C" {
+  struct BOut;
+  struct BOutObject;
+}
+
+namespace klee {
+  class ExecutionState;
+  class TimingSolver;
+
+  class SeedInfo {
+  public:
+    Assignment assignment;
+    BOut *input;
+    unsigned inputPosition;
+    std::set<struct BOutObject*> used;
+    
+  public:
+    explicit
+    SeedInfo(BOut *_input) : assignment(true),
+                             input(_input),
+                             inputPosition(0) {}
+    
+    BOutObject *getNextInput(const MemoryObject *mo,
+                             bool byName);
+    
+    /// Patch the seed so that condition is satisfied while retaining as
+    /// many of the seed values as possible.
+    void patchSeed(const ExecutionState &state, 
+                   ref<Expr> condition,
+                   TimingSolver *solver);
+  };
+}
+
+#endif
diff --git a/lib/Core/SpecialFunctionHandler.cpp b/lib/Core/SpecialFunctionHandler.cpp
new file mode 100644
index 00000000..da2a4a49
--- /dev/null
+++ b/lib/Core/SpecialFunctionHandler.cpp
@@ -0,0 +1,727 @@
+//===-- SpecialFunctionHandler.cpp ----------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "Memory.h"
+#include "SpecialFunctionHandler.h"
+#include "TimingSolver.h"
+
+#include "klee/ExecutionState.h"
+
+#include "klee/Internal/Module/KInstruction.h"
+#include "klee/Internal/Module/KModule.h"
+
+#include "Executor.h"
+#include "MemoryManager.h"
+
+#include "llvm/Module.h"
+
+#include <errno.h>
+
+using namespace llvm;
+using namespace klee;
+
+/// \todo Almost all of the demands in this file should be replaced
+/// with terminateState calls.
+
+///
+
+struct HandlerInfo {
+  const char *name;
+  SpecialFunctionHandler::Handler handler;
+  bool doesNotReturn; /// Intrinsic terminates the process
+  bool hasReturnValue; /// Intrinsic has a return value
+  bool doNotOverride; /// Intrinsic should not be used if already defined
+};
+
+// FIXME: We are more or less committed to requiring an intrinsic
+// library these days. We can move some of this stuff there,
+// especially things like realloc which have complicated semantics
+// w.r.t. forking. Among other things this makes delayed query
+// dispatch easier to implement.
+HandlerInfo handlerInfo[] = {
+#define add(name, handler, ret) { name, \
+                                  &SpecialFunctionHandler::handler, \
+                                  false, ret, false }
+#define addDNR(name, handler) { name, \
+                                &SpecialFunctionHandler::handler, \
+                                true, false, false }
+  addDNR("__assert_rtn", handleAssertFail),
+  addDNR("__assert_fail", handleAssertFail),
+  addDNR("_assert", handleAssert),
+  addDNR("abort", handleAbort),
+  addDNR("_exit", handleExit),
+  { "exit", &SpecialFunctionHandler::handleExit, true, false, true },
+  addDNR("klee_abort", handleAbort),
+  addDNR("klee_silent_exit", handleSilentExit),  
+  addDNR("klee_report_error", handleReportError),
+
+  add("calloc", handleCalloc, true),
+  add("free", handleFree, false),
+  add("klee_assume", handleAssume, false),
+  add("klee_check_memory_access", handleCheckMemoryAccess, false),
+  add("klee_get_value", handleGetValue, true),
+  add("klee_define_fixed_object", handleDefineFixedObject, false),
+  add("klee_get_obj_size", handleGetObjSize, true),
+  add("klee_get_errno", handleGetErrno, true),
+  add("klee_is_symbolic", handleIsSymbolic, true),
+  add("klee_make_symbolic_name", handleMakeSymbolic, false),
+  add("klee_mark_global", handleMarkGlobal, false),
+  add("klee_malloc_n", handleMallocN, true),
+  add("klee_merge", handleMerge, false),
+  add("klee_prefer_cex", handlePreferCex, false),
+  add("klee_print_expr", handlePrintExpr, false),
+  add("klee_print_range", handlePrintRange, false),
+  add("klee_set_forking", handleSetForking, false),
+  add("klee_warning", handleWarning, false),
+  add("klee_warning_once", handleWarningOnce, false),
+  add("klee_under_constrained", handleUnderConstrained, false),
+  add("klee_alias_function", handleAliasFunction, false),
+  add("malloc", handleMalloc, true),
+  add("realloc", handleRealloc, true),
+
+  // operator delete[](void*)
+  add("_ZdaPv", handleDeleteArray, false),
+  // operator delete(void*)
+  add("_ZdlPv", handleDelete, false),
+
+  // operator new[](unsigned int)
+  add("_Znaj", handleNewArray, true),
+  // operator new(unsigned int)
+  add("_Znwj", handleNew, true),
+
+  // FIXME-64: This is wrong for 64-bit long...
+
+  // operator new[](unsigned long)
+  add("_Znam", handleNewArray, true),
+  // operator new(unsigned long)
+  add("_Znwm", handleNew, true),
+
+#undef addDNR
+#undef add  
+};
+
+SpecialFunctionHandler::SpecialFunctionHandler(Executor &_executor) 
+  : executor(_executor) {}
+
+
+void SpecialFunctionHandler::prepare() {
+  unsigned N = sizeof(handlerInfo)/sizeof(handlerInfo[0]);
+
+  for (unsigned i=0; i<N; ++i) {
+    HandlerInfo &hi = handlerInfo[i];
+    Function *f = executor.kmodule->module->getFunction(hi.name);
+    
+    // No need to create if the function doesn't exist, since it cannot
+    // be called in that case.
+  
+    if (f && (!hi.doNotOverride || f->isDeclaration())) {
+      // Make sure NoReturn attribute is set, for optimization and
+      // coverage counting.
+      if (hi.doesNotReturn)
+        f->addFnAttr(Attribute::NoReturn);
+
+      // Change to a declaration since we handle internally (simplifies
+      // module and allows deleting dead code).
+      if (!f->isDeclaration())
+        f->deleteBody();
+    }
+  }
+}
+
+void SpecialFunctionHandler::bind() {
+  unsigned N = sizeof(handlerInfo)/sizeof(handlerInfo[0]);
+
+  for (unsigned i=0; i<N; ++i) {
+    HandlerInfo &hi = handlerInfo[i];
+    Function *f = executor.kmodule->module->getFunction(hi.name);
+    
+    if (f && (!hi.doNotOverride || f->isDeclaration()))
+      handlers[f] = std::make_pair(hi.handler, hi.hasReturnValue);
+  }
+}
+
+
+bool SpecialFunctionHandler::handle(ExecutionState &state, 
+                                    Function *f,
+                                    KInstruction *target,
+                                    std::vector< ref<Expr> > &arguments) {
+  handlers_ty::iterator it = handlers.find(f);
+  if (it != handlers.end()) {    
+    Handler h = it->second.first;
+    bool hasReturnValue = it->second.second;
+     // FIXME: Check this... add test?
+    if (!hasReturnValue && !target->inst->use_empty()) {
+      executor.terminateStateOnExecError(state, 
+                                         "expected return value from void special function");
+    } else {
+      (this->*h)(state, target, arguments);
+    }
+    return true;
+  } else {
+    return false;
+  }
+}
+
+/****/
+
+// reads a concrete string from memory
+std::string SpecialFunctionHandler::readStringAtAddress(ExecutionState &state, 
+                                                        ref<Expr> address) {
+  ObjectPair op;
+  address = executor.toUnique(state, address);
+  assert(address.isConstant() && "symbolic string arg to intrinsic");  
+  if (!state.addressSpace.resolveOne(address.getConstantValue(), op))
+    assert(0 && "XXX out of bounds / multiple resolution unhandled");
+  bool res;
+  assert(executor.solver->mustBeTrue(state, 
+                                     EqExpr::create(address, 
+                                                    op.first->getBaseExpr()),
+                                     res) &&
+         res &&
+         "XXX interior pointer unhandled");
+  const MemoryObject *mo = op.first;
+  const ObjectState *os = op.second;
+
+  char *buf = new char[mo->size];
+
+  unsigned i;
+  for (i = 0; i < mo->size - 1; i++) {
+    ref<Expr> cur = os->read8(i);
+    cur = executor.toUnique(state, cur);
+    assert(cur.isConstant() && 
+           "hit symbolic char while reading concrete string");
+    buf[i] = cur.getConstantValue();
+  }
+  buf[i] = 0;
+  
+  std::string result(buf);
+  delete[] buf;
+  return result;
+}
+
+/****/
+
+void SpecialFunctionHandler::handleAbort(ExecutionState &state,
+                           KInstruction *target,
+                           std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==0 && "invalid number of arguments to abort");
+
+  //XXX:DRE:TAINT
+  if(state.underConstrained) {
+    llvm::cerr << "TAINT: skipping abort fail\n";
+    executor.terminateState(state);
+  } else {
+    executor.terminateStateOnError(state, "abort failure", "abort.err");
+  }
+}
+
+void SpecialFunctionHandler::handleExit(ExecutionState &state,
+                           KInstruction *target,
+                           std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 && "invalid number of arguments to exit");
+  executor.terminateStateOnExit(state);
+}
+
+void SpecialFunctionHandler::handleSilentExit(ExecutionState &state,
+                                              KInstruction *target,
+                                              std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 && "invalid number of arguments to exit");
+  executor.terminateState(state);
+}
+
+void SpecialFunctionHandler::handleAliasFunction(ExecutionState &state,
+						 KInstruction *target,
+						 std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==2 && 
+         "invalid number of arguments to klee_alias_function");
+  std::string old_fn = readStringAtAddress(state, arguments[0]);
+  std::string new_fn = readStringAtAddress(state, arguments[1]);
+  //llvm::cerr << "Replacing " << old_fn << "() with " << new_fn << "()\n";
+  if (old_fn == new_fn)
+    state.removeFnAlias(old_fn);
+  else state.addFnAlias(old_fn, new_fn);
+}
+
+void SpecialFunctionHandler::handleAssert(ExecutionState &state,
+                                          KInstruction *target,
+                                          std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==3 && "invalid number of arguments to _assert");  
+  
+  //XXX:DRE:TAINT
+  if(state.underConstrained) {
+    llvm::cerr << "TAINT: skipping assertion:" 
+               << readStringAtAddress(state, arguments[0]) << "\n";
+    executor.terminateState(state);
+  } else
+    executor.terminateStateOnError(state, 
+                                   "ASSERTION FAIL: " + readStringAtAddress(state, arguments[0]),
+                                   "assert.err");
+}
+
+void SpecialFunctionHandler::handleAssertFail(ExecutionState &state,
+                                              KInstruction *target,
+                                              std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==4 && "invalid number of arguments to __assert_fail");
+  
+  //XXX:DRE:TAINT
+  if(state.underConstrained) {
+    llvm::cerr << "TAINT: skipping assertion:" 
+               << readStringAtAddress(state, arguments[0]) << "\n";
+    executor.terminateState(state);
+  } else
+    executor.terminateStateOnError(state, 
+                                   "ASSERTION FAIL: " + readStringAtAddress(state, arguments[0]),
+                                   "assert.err");
+}
+
+void SpecialFunctionHandler::handleReportError(ExecutionState &state,
+                                               KInstruction *target,
+                                               std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==4 && "invalid number of arguments to klee_report_error");
+  
+  // arguments[0], arguments[1] are file, line
+  
+  //XXX:DRE:TAINT
+  if(state.underConstrained) {
+    llvm::cerr << "TAINT: skipping klee_report_error:"
+               << readStringAtAddress(state, arguments[2]) << ":"
+               << readStringAtAddress(state, arguments[3]) << "\n";
+    executor.terminateState(state);
+  } else
+    executor.terminateStateOnError(state, 
+                                   readStringAtAddress(state, arguments[2]),
+                                   readStringAtAddress(state, arguments[3]));
+}
+
+void SpecialFunctionHandler::handleMerge(ExecutionState &state,
+                           KInstruction *target,
+                           std::vector<ref<Expr> > &arguments) {
+  // nop
+}
+
+void SpecialFunctionHandler::handleNew(ExecutionState &state,
+                         KInstruction *target,
+                         std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 && "invalid number of arguments to new");
+
+  executor.executeAlloc(state, arguments[0], false, target);
+}
+
+void SpecialFunctionHandler::handleDelete(ExecutionState &state,
+                            KInstruction *target,
+                            std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 && "invalid number of arguments to delete");
+  executor.executeFree(state, arguments[0]);
+}
+
+void SpecialFunctionHandler::handleNewArray(ExecutionState &state,
+                              KInstruction *target,
+                              std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 && "invalid number of arguments to new[]");
+  executor.executeAlloc(state, arguments[0], false, target);
+}
+
+void SpecialFunctionHandler::handleDeleteArray(ExecutionState &state,
+                                 KInstruction *target,
+                                 std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 && "invalid number of arguments to delete[]");
+  executor.executeFree(state, arguments[0]);
+}
+
+void SpecialFunctionHandler::handleMalloc(ExecutionState &state,
+                                  KInstruction *target,
+                                  std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 && "invalid number of arguments to malloc");
+  executor.executeAlloc(state, arguments[0], false, target);
+}
+
+void SpecialFunctionHandler::handleMallocN(ExecutionState &state,
+                             KInstruction *target,
+                             std::vector<ref<Expr> > &arguments) {
+
+  // XXX should type check args
+  assert(arguments.size() == 3 && "invalid number of arguments to malloc");
+
+  // mallocn(number, size, alignment)
+  ref<Expr> numElems = executor.toUnique(state, arguments[0]);
+  ref<Expr> elemSize = executor.toUnique(state, arguments[1]);
+  ref<Expr> elemAlignment = executor.toUnique(state, arguments[2]);
+
+  assert(numElems.isConstant() &&
+         elemSize.isConstant() &&
+         elemAlignment.isConstant() &&
+         "symbolic arguments passed to klee_mallocn");
+  
+  executor.executeAllocN(state,
+                         numElems.getConstantValue(),
+                         elemSize.getConstantValue(),
+                         elemAlignment.getConstantValue(),
+                         false,
+                         target);
+}
+
+void SpecialFunctionHandler::handleAssume(ExecutionState &state,
+                            KInstruction *target,
+                            std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 && "invalid number of arguments to klee_assume");
+  
+  ref<Expr> e = arguments[0];
+  
+  if(e.getWidth() != Expr::Bool)
+    e = NeExpr::create(e, ConstantExpr::create(0, e.getWidth()));
+  
+  bool res;
+  bool success = executor.solver->mustBeFalse(state, e, res);
+  assert(success && "FIXME: Unhandled solver failure");
+  if (res) {
+    executor.terminateStateOnError(state, 
+                                   "invalid klee_assume call (provably false)",
+                                   "user.err");
+  } else {
+    executor.addConstraint(state, e);
+  }
+}
+
+void SpecialFunctionHandler::handleIsSymbolic(ExecutionState &state,
+                                KInstruction *target,
+                                std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 && "invalid number of arguments to klee_is_symbolic");
+
+  executor.bindLocal(target, state, 
+                     ConstantExpr::create(!arguments[0].isConstant(), Expr::Int32));
+}
+
+void SpecialFunctionHandler::handlePreferCex(ExecutionState &state,
+                                             KInstruction *target,
+                                             std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==2 &&
+         "invalid number of arguments to klee_prefex_cex");
+
+  ref<Expr> cond = arguments[1];
+  if (cond.getWidth() != Expr::Bool)
+    cond = NeExpr::create(cond, ref<Expr>(0, cond.getWidth()));
+
+  Executor::ExactResolutionList rl;
+  executor.resolveExact(state, arguments[0], rl, "prefex_cex");
+  
+  assert(rl.size() == 1 &&
+         "prefer_cex target must resolve to precisely one object");
+
+  rl[0].first.first->cexPreferences.push_back(cond);
+}
+
+void SpecialFunctionHandler::handlePrintExpr(ExecutionState &state,
+                                  KInstruction *target,
+                                  std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==2 &&
+         "invalid number of arguments to klee_print_expr");
+
+  std::string msg_str = readStringAtAddress(state, arguments[0]);
+  llvm::cerr << msg_str << ":" << arguments[1] << "\n";
+}
+
+
+void SpecialFunctionHandler::handleUnderConstrained(ExecutionState &state,
+                                  KInstruction *target,
+                                  std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 &&
+         "invalid number of arguments to klee_under_constrained().");
+  assert(arguments[0].isConstant() &&
+   	 "symbolic argument given to klee_under_constrained!");
+
+  unsigned v = arguments[0].getConstantValue();
+  llvm::cerr << "argument = " << v << " under=" << state.underConstrained << "\n";
+  if(v) {
+    assert(state.underConstrained == false &&
+         "Bogus call to klee_under_constrained().");
+    state.underConstrained = v;
+    llvm::cerr << "turning on under!\n";
+  } else {
+    assert(state.underConstrained != 0 && "Bogus call to klee_taint_end()");
+    state.underConstrained = 0;
+    llvm::cerr << "turning off under!\n";
+  }
+}
+
+void SpecialFunctionHandler::handleSetForking(ExecutionState &state,
+                                              KInstruction *target,
+                                              std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 &&
+         "invalid number of arguments to klee_set_forking");
+  ref<Expr> value = executor.toUnique(state, arguments[0]);
+  
+  if (!value.isConstant()) {
+    executor.terminateStateOnError(state, 
+                                   "klee_set_forking requires a constant arg",
+                                   "user.err");
+  } else {
+    state.forkDisabled = !value.getConstantValue();
+  }
+}
+
+void SpecialFunctionHandler::handleWarning(ExecutionState &state,
+                                           KInstruction *target,
+                                           std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 && "invalid number of arguments to klee_warning");
+
+  std::string msg_str = readStringAtAddress(state, arguments[0]);
+  klee_warning("%s: %s", state.stack.back().kf->function->getName().c_str(), 
+               msg_str.c_str());
+}
+
+void SpecialFunctionHandler::handleWarningOnce(ExecutionState &state,
+                                               KInstruction *target,
+                                               std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 &&
+         "invalid number of arguments to klee_warning_once");
+
+  std::string msg_str = readStringAtAddress(state, arguments[0]);
+  klee_warning_once(0, "%s: %s", state.stack.back().kf->function->getName().c_str(), 
+                    msg_str.c_str());
+}
+
+void SpecialFunctionHandler::handlePrintRange(ExecutionState &state,
+                                  KInstruction *target,
+                                  std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==2 &&
+         "invalid number of arguments to klee_print_range");
+
+  std::string msg_str = readStringAtAddress(state, arguments[0]);
+  llvm::cerr << msg_str << ":" << arguments[1];
+  if (!arguments[1].isConstant()) {
+    // FIXME: Pull into a unique value method?
+    ref<Expr> value;
+    bool success = executor.solver->getValue(state, arguments[1], value);
+    assert(success && "FIXME: Unhandled solver failure");
+    bool res;
+    success = executor.solver->mustBeTrue(state, 
+                                          EqExpr::create(arguments[1], value), 
+                                          res);
+    assert(success && "FIXME: Unhandled solver failure");
+    if (res) {
+      llvm::cerr << " == " << value;
+    } else { 
+      llvm::cerr << " ~= " << value;
+      std::pair< ref<Expr>, ref<Expr> > res =
+        executor.solver->getRange(state, arguments[1]);
+      llvm::cerr << " (in [" << res.first << ", " << res.second <<"])";
+    }
+  }
+  llvm::cerr << "\n";
+}
+
+void SpecialFunctionHandler::handleGetObjSize(ExecutionState &state,
+                                  KInstruction *target,
+                                  std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 &&
+         "invalid number of arguments to klee_get_obj_size");
+  Executor::ExactResolutionList rl;
+  executor.resolveExact(state, arguments[0], rl, "klee_get_obj_size");
+  for (Executor::ExactResolutionList::iterator it = rl.begin(), 
+         ie = rl.end(); it != ie; ++it) {
+    executor.bindLocal(target, *it->second, 
+                       ConstantExpr::create(it->first.first->size, Expr::Int32));
+  }
+}
+
+void SpecialFunctionHandler::handleGetErrno(ExecutionState &state,
+                                            KInstruction *target,
+                                            std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==0 &&
+         "invalid number of arguments to klee_get_obj_size");
+  executor.bindLocal(target, state,
+                     ConstantExpr::create(errno, Expr::Int32));
+}
+
+void SpecialFunctionHandler::handleCalloc(ExecutionState &state,
+                            KInstruction *target,
+                            std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==2 &&
+         "invalid number of arguments to calloc");
+
+  ref<Expr> size = MulExpr::create(arguments[0],
+                                   arguments[1]);
+  executor.executeAlloc(state, size, false, target, true);
+}
+
+void SpecialFunctionHandler::handleRealloc(ExecutionState &state,
+                            KInstruction *target,
+                            std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==2 &&
+         "invalid number of arguments to realloc");
+  ref<Expr> address = arguments[0];
+  ref<Expr> size = arguments[1];
+
+  Executor::StatePair zeroSize = executor.fork(state, 
+                                               Expr::createIsZero(size), 
+                                               true);
+  
+  if (zeroSize.first) { // size == 0
+    executor.executeFree(*zeroSize.first, address, target);   
+  }
+  if (zeroSize.second) { // size != 0
+    Executor::StatePair zeroPointer = executor.fork(*zeroSize.second, 
+                                                    Expr::createIsZero(address), 
+                                                    true);
+    
+    if (zeroPointer.first) { // address == 0
+      executor.executeAlloc(*zeroPointer.first, size, false, target);
+    } 
+    if (zeroPointer.second) { // address != 0
+      Executor::ExactResolutionList rl;
+      executor.resolveExact(*zeroPointer.second, address, rl, "realloc");
+      
+      for (Executor::ExactResolutionList::iterator it = rl.begin(), 
+             ie = rl.end(); it != ie; ++it) {
+        executor.executeAlloc(*it->second, size, false, target, false, 
+                              it->first.second);
+      }
+    }
+  }
+}
+
+void SpecialFunctionHandler::handleFree(ExecutionState &state,
+                          KInstruction *target,
+                          std::vector<ref<Expr> > &arguments) {
+  // XXX should type check args
+  assert(arguments.size()==1 &&
+         "invalid number of arguments to free");
+  executor.executeFree(state, arguments[0]);
+}
+
+void SpecialFunctionHandler::handleCheckMemoryAccess(ExecutionState &state,
+                                            KInstruction *target,
+                                            std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==2 &&
+         "invalid number of arguments to klee_check_memory_access");
+
+  ref<Expr> address = executor.toUnique(state, arguments[0]);
+  ref<Expr> size = executor.toUnique(state, arguments[1]);
+  if (!address.isConstant() || !size.isConstant()) {
+    executor.terminateStateOnError(state, 
+                                   "check_memory_access requires constant args",
+                                   "user.err");
+  } else {
+    ObjectPair op;
+
+    if (!state.addressSpace.resolveOne(address.getConstantValue(), op)) {
+      executor.terminateStateOnError(state,
+                                     "check_memory_access: memory error",
+                                     "ptr.err",
+                                     executor.getAddressInfo(state, address));
+    } else {
+      ref<Expr> chk = op.first->getBoundsCheckPointer(address, 
+                                                      size.getConstantValue());
+      assert(chk.isConstant());
+      if (!chk.getConstantValue()) {
+        executor.terminateStateOnError(state,
+                                       "check_memory_access: memory error",
+                                       "ptr.err",
+                                       executor.getAddressInfo(state, address));
+      }
+    }
+  }
+}
+
+void SpecialFunctionHandler::handleGetValue(ExecutionState &state,
+                                            KInstruction *target,
+                                            std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 &&
+         "invalid number of arguments to klee_get_value");
+
+  executor.executeGetValue(state, arguments[0], target);
+}
+
+void SpecialFunctionHandler::handleDefineFixedObject(ExecutionState &state,
+                                                     KInstruction *target,
+                                                     std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==2 &&
+         "invalid number of arguments to klee_define_fixed_object");
+  assert(arguments[0].isConstant() &&
+         "expect constant address argument to klee_define_fixed_object");
+  assert(arguments[1].isConstant() &&
+         "expect constant size argument to klee_define_fixed_object");
+  
+  uint64_t address = arguments[0].getConstantValue();
+  uint64_t size = arguments[1].getConstantValue();
+  MemoryObject *mo = executor.memory->allocateFixed(address, size, state.prevPC->inst);
+  executor.bindObjectInState(state, mo, false);
+  mo->isUserSpecified = true; // XXX hack;
+}
+
+void SpecialFunctionHandler::handleMakeSymbolic(ExecutionState &state,
+                                                KInstruction *target,
+                                                std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==3 &&
+         "invalid number of arguments to klee_make_symbolic[_name]");  
+
+  Executor::ExactResolutionList rl;
+  executor.resolveExact(state, arguments[0], rl, "make_symbolic");
+  
+  for (Executor::ExactResolutionList::iterator it = rl.begin(), 
+         ie = rl.end(); it != ie; ++it) {
+    MemoryObject *mo = (MemoryObject*) it->first.first;
+    std::string name = readStringAtAddress(state, arguments[2]);
+    mo->setName(name);
+    
+    const ObjectState *old = it->first.second;
+    ExecutionState *s = it->second;
+    
+    if (old->readOnly) {
+      executor.terminateStateOnError(*s, 
+                                     "cannot make readonly object symbolic", 
+                                     "user.err");
+      return;
+    } 
+
+    bool res;
+    bool success =
+      executor.solver->mustBeTrue(*s, EqExpr::create(arguments[1],
+                                                     mo->getSizeExpr()),
+                                  res);
+    assert(success && "FIXME: Unhandled solver failure");
+    
+    if (res) {
+      executor.executeMakeSymbolic(*s, mo);
+    } else {      
+      executor.terminateStateOnError(*s, 
+                                     "wrong size given to klee_make_symbolic[_name]", 
+                                     "user.err");
+    }
+  }
+}
+
+void SpecialFunctionHandler::handleMarkGlobal(ExecutionState &state,
+                                              KInstruction *target,
+                                              std::vector<ref<Expr> > &arguments) {
+  assert(arguments.size()==1 &&
+         "invalid number of arguments to klee_mark_global");  
+
+  Executor::ExactResolutionList rl;
+  executor.resolveExact(state, arguments[0], rl, "mark_global");
+  
+  for (Executor::ExactResolutionList::iterator it = rl.begin(), 
+         ie = rl.end(); it != ie; ++it) {
+    MemoryObject *mo = (MemoryObject*) it->first.first;
+    assert(!mo->isLocal);
+    mo->isGlobal = true;
+  }
+}
diff --git a/lib/Core/SpecialFunctionHandler.h b/lib/Core/SpecialFunctionHandler.h
new file mode 100644
index 00000000..d5d1af93
--- /dev/null
+++ b/lib/Core/SpecialFunctionHandler.h
@@ -0,0 +1,106 @@
+//===-- SpecialFunctionHandler.h --------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_SPECIALFUNCTIONHANDLER_H
+#define KLEE_SPECIALFUNCTIONHANDLER_H
+
+#include <map>
+#include <vector>
+#include <string>
+
+namespace llvm {
+  class Function;
+}
+
+namespace klee {
+  class Executor;
+  class Expr;
+  class ExecutionState;
+  class KInstruction;
+  template<typename T> class ref;
+  
+  class SpecialFunctionHandler {
+  public:
+    typedef void (SpecialFunctionHandler::*Handler)(ExecutionState &state,
+                                                    KInstruction *target, 
+                                                    std::vector<ref<Expr> > 
+                                                      &arguments);
+    typedef std::map<const llvm::Function*, 
+                     std::pair<Handler,bool> > handlers_ty;
+
+    handlers_ty handlers;
+    class Executor &executor;
+
+  public:
+    SpecialFunctionHandler(Executor &_executor);
+
+    /// Perform any modifications on the LLVM module before it is
+    /// prepared for execution. At the moment this involves deleting
+    /// unused function bodies and marking intrinsics with appropriate
+    /// flags for use in optimizations.
+    void prepare();
+
+    /// Initialize the internal handler map after the module has been
+    /// prepared for execution.
+    void bind();
+
+    bool handle(ExecutionState &state, 
+                llvm::Function *f,
+                KInstruction *target,
+                std::vector< ref<Expr> > &arguments);
+
+    /* Convenience routines */
+
+    std::string readStringAtAddress(ExecutionState &state, ref<Expr> address);
+    
+    /* Handlers */
+
+#define HANDLER(name) void name(ExecutionState &state, \
+                                KInstruction *target, \
+                                std::vector< ref<Expr> > &arguments)
+    HANDLER(handleAbort);
+    HANDLER(handleAssert);
+    HANDLER(handleAssertFail);
+    HANDLER(handleAssume);
+    HANDLER(handleCalloc);
+    HANDLER(handleCheckMemoryAccess);
+    HANDLER(handleDefineFixedObject);
+    HANDLER(handleDelete);    
+    HANDLER(handleDeleteArray);
+    HANDLER(handleExit);
+    HANDLER(handleAliasFunction);
+    HANDLER(handleFree);
+    HANDLER(handleGetErrno);
+    HANDLER(handleGetObjSize);
+    HANDLER(handleGetValue);
+    HANDLER(handleIsSymbolic);
+    HANDLER(handleMakeSymbolic);
+    HANDLER(handleMalloc);
+    HANDLER(handleMallocN);
+    HANDLER(handleMarkGlobal);
+    HANDLER(handleMerge);
+    HANDLER(handleNew);
+    HANDLER(handleNewArray);
+    HANDLER(handlePreferCex);
+    HANDLER(handlePrintExpr);
+    HANDLER(handlePrintRange);
+    HANDLER(handleRange);
+    HANDLER(handleRealloc);
+    HANDLER(handleReportError);
+    HANDLER(handleRevirtObjects);
+    HANDLER(handleSetForking);
+    HANDLER(handleSilentExit);
+    HANDLER(handleUnderConstrained);
+    HANDLER(handleWarning);
+    HANDLER(handleWarningOnce);
+#undef HANDLER
+  };
+} // End klee namespace
+
+#endif
diff --git a/lib/Core/StatsTracker.cpp b/lib/Core/StatsTracker.cpp
new file mode 100644
index 00000000..35c073a3
--- /dev/null
+++ b/lib/Core/StatsTracker.cpp
@@ -0,0 +1,814 @@
+//===-- StatsTracker.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "StatsTracker.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Statistics.h"
+#include "klee/Internal/Module/InstructionInfoTable.h"
+#include "klee/Internal/Module/KModule.h"
+#include "klee/Internal/Module/KInstruction.h"
+#include "klee/Internal/Support/ModuleUtil.h"
+#include "klee/Internal/System/Time.h"
+
+#include "CallPathManager.h"
+#include "CoreStats.h"
+#include "Executor.h"
+#include "MemoryManager.h"
+#include "UserSearcher.h"
+#include "../Solver/SolverStats.h"
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Module.h"
+#include "llvm/Type.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/System/Process.h"
+#include "llvm/System/Path.h"
+
+#include <iostream>
+#include <fstream>
+
+using namespace klee;
+using namespace llvm;
+
+///
+
+namespace {  
+  cl::opt<bool>
+  TrackInstructionTime("track-instruction-time",
+                       cl::desc("Enable tracking of time for individual instructions"),
+                       cl::init(false));
+
+  cl::opt<bool>
+  OutputStats("output-stats",
+              cl::desc("Write running stats trace file"),
+              cl::init(true));
+
+  cl::opt<bool>
+  OutputIStats("output-istats",
+               cl::desc("Write instruction level statistics (in callgrind format)"),
+               cl::init(true));
+
+  cl::opt<double>
+  StatsWriteInterval("stats-write-interval",
+                     cl::desc("Approximate number of seconds between stats writes (default: 1.0)"),
+                     cl::init(1.));
+
+  cl::opt<double>
+  IStatsWriteInterval("istats-write-interval",
+                      cl::desc("Approximate number of seconds between istats writes (default: 10.0)"),
+                      cl::init(10.));
+
+  /*
+  cl::opt<double>
+  BranchCovCountsWriteInterval("branch-cov-counts-write-interval",
+                     cl::desc("Approximate number of seconds between run.branches writes (default: 5.0)"),
+                     cl::init(5.));
+  */
+
+  // XXX I really would like to have dynamic rate control for something like this.
+  cl::opt<double>
+  UncoveredUpdateInterval("uncovered-update-interval",
+                          cl::init(30.));
+  
+  cl::opt<bool>
+  UseCallPaths("use-call-paths",
+               cl::desc("Enable calltree tracking for instruction level statistics"),
+               cl::init(true));
+  
+}
+
+///
+
+bool StatsTracker::useStatistics() {
+  return OutputStats || OutputIStats;
+}
+
+namespace klee {
+  class WriteIStatsTimer : public Executor::Timer {
+    StatsTracker *statsTracker;
+    
+  public:
+    WriteIStatsTimer(StatsTracker *_statsTracker) : statsTracker(_statsTracker) {}
+    ~WriteIStatsTimer() {}
+    
+    void run() { statsTracker->writeIStats(); }
+  };
+  
+  class WriteStatsTimer : public Executor::Timer {
+    StatsTracker *statsTracker;
+    
+  public:
+    WriteStatsTimer(StatsTracker *_statsTracker) : statsTracker(_statsTracker) {}
+    ~WriteStatsTimer() {}
+    
+    void run() { statsTracker->writeStatsLine(); }
+  };
+
+  class UpdateReachableTimer : public Executor::Timer {
+    StatsTracker *statsTracker;
+    
+  public:
+    UpdateReachableTimer(StatsTracker *_statsTracker) : statsTracker(_statsTracker) {}
+    
+    void run() { statsTracker->computeReachableUncovered(); }
+  };
+ 
+}
+
+//
+
+/// Check for special cases where we statically know an instruction is
+/// uncoverable. Currently the case is an unreachable instruction
+/// following a noreturn call; the instruction is really only there to
+/// satisfy LLVM's termination requirement.
+static bool instructionIsCoverable(Instruction *i) {
+  if (i->getOpcode() == Instruction::Unreachable) {
+    BasicBlock *bb = i->getParent();
+    BasicBlock::iterator it(i);
+    if (it==bb->begin()) {
+      return true;
+    } else {
+      Instruction *prev = --it;
+      if (isa<CallInst>(prev) || isa<InvokeInst>(prev)) {
+        Function *target = getDirectCallTarget(prev);
+        if (target && target->doesNotReturn())
+          return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+StatsTracker::StatsTracker(Executor &_executor, std::string _objectFilename,
+                           bool _updateMinDistToUncovered)
+  : executor(_executor),
+    objectFilename(_objectFilename),
+    statsFile(0),
+    istatsFile(0),
+    startWallTime(util::getWallTime()),
+    numBranches(0),
+    fullBranches(0),
+    partialBranches(0),
+    updateMinDistToUncovered(_updateMinDistToUncovered) {
+  KModule *km = executor.kmodule;
+
+  sys::Path module(objectFilename);
+  if (!sys::Path(objectFilename).isAbsolute()) {
+    sys::Path current = sys::Path::GetCurrentDirectory();
+    current.appendComponent(objectFilename);
+    if (current.exists())
+      objectFilename = current.c_str();
+  }
+
+  if (OutputIStats)
+    theStatisticManager->useIndexedStats(km->infos->getMaxID());
+
+  for (std::vector<KFunction*>::iterator it = km->functions.begin(), 
+         ie = km->functions.end(); it != ie; ++it) {
+    KFunction *kf = *it;
+    kf->trackCoverage = 1;
+
+    for (unsigned i=0; i<kf->numInstructions; ++i) {
+      KInstruction *ki = kf->instructions[i];
+
+      if (OutputIStats) {
+        unsigned id = ki->info->id;
+        theStatisticManager->setIndex(id);
+        if (kf->trackCoverage && instructionIsCoverable(ki->inst))
+          ++stats::uncoveredInstructions;
+      }
+      
+      if (kf->trackCoverage) {
+        if (BranchInst *bi = dyn_cast<BranchInst>(ki->inst))
+          if (!bi->isUnconditional())
+            numBranches++;
+      }
+    }
+  }
+
+  if (OutputStats) {
+    statsFile = executor.interpreterHandler->openOutputFile("run.stats");
+    assert(statsFile && "unable to open statistics trace file");
+    writeStatsHeader();
+    writeStatsLine();
+
+    executor.addTimer(new WriteStatsTimer(this), StatsWriteInterval);
+
+    if (updateMinDistToUncovered)
+      executor.addTimer(new UpdateReachableTimer(this), UncoveredUpdateInterval);
+  }
+
+  if (OutputIStats) {
+    istatsFile = executor.interpreterHandler->openOutputFile("run.istats");
+    assert(istatsFile && "unable to open istats file");
+
+    executor.addTimer(new WriteIStatsTimer(this), IStatsWriteInterval);
+  }
+}
+
+StatsTracker::~StatsTracker() {  
+  if (statsFile)
+    delete statsFile;
+  if (istatsFile)
+    delete istatsFile;
+}
+
+void StatsTracker::done() {
+  if (statsFile)
+    writeStatsLine();
+  if (OutputIStats)
+    writeIStats();
+}
+
+void StatsTracker::stepInstruction(ExecutionState &es) {
+  if (OutputIStats) {
+    if (TrackInstructionTime) {
+      static sys::TimeValue lastNowTime(0,0),lastUserTime(0,0);
+    
+      if (lastUserTime.seconds()==0 && lastUserTime.nanoseconds()==0) {
+        sys::TimeValue sys(0,0);
+        sys::Process::GetTimeUsage(lastNowTime,lastUserTime,sys);
+      } else {
+        sys::TimeValue now(0,0),user(0,0),sys(0,0);
+        sys::Process::GetTimeUsage(now,user,sys);
+        sys::TimeValue delta = user - lastUserTime;
+        sys::TimeValue deltaNow = now - lastNowTime;
+        stats::instructionTime += delta.usec();
+        stats::instructionRealTime += deltaNow.usec();
+        lastUserTime = user;
+        lastNowTime = now;
+      }
+    }
+
+    Instruction *inst = es.pc->inst;
+    const InstructionInfo &ii = *es.pc->info;
+    StackFrame &sf = es.stack.back();
+    theStatisticManager->setIndex(ii.id);
+    if (UseCallPaths)
+      theStatisticManager->setContext(&sf.callPathNode->statistics);
+
+    if (es.instsSinceCovNew)
+      ++es.instsSinceCovNew;
+
+    if (sf.kf->trackCoverage && instructionIsCoverable(inst)) {
+      if (!theStatisticManager->getIndexedValue(stats::coveredInstructions, ii.id)) {
+        // Checking for actual stoppoints avoids inconsistencies due
+        // to line number propogation.
+        if (isa<DbgStopPointInst>(inst))
+          es.coveredLines[&ii.file].insert(ii.line);
+	es.coveredNew = true;
+        es.instsSinceCovNew = 1;
+	++stats::coveredInstructions;
+	stats::uncoveredInstructions += (uint64_t)-1;
+      }
+    }
+  }
+}
+
+///
+
+/* Should be called _after_ the es->pushFrame() */
+void StatsTracker::framePushed(ExecutionState &es, StackFrame *parentFrame) {
+  if (OutputIStats) {
+    StackFrame &sf = es.stack.back();
+
+    if (UseCallPaths) {
+      CallPathNode *parent = parentFrame ? parentFrame->callPathNode : 0;
+      CallPathNode *cp = callPathManager.getCallPath(parent, 
+                                                     sf.caller ? sf.caller->inst : 0, 
+                                                     sf.kf->function);
+      sf.callPathNode = cp;
+      cp->count++;
+    }
+
+    if (updateMinDistToUncovered) {
+      uint64_t minDistAtRA = 0;
+      if (parentFrame)
+        minDistAtRA = parentFrame->minDistToUncoveredOnReturn;
+      
+      sf.minDistToUncoveredOnReturn = sf.caller ?
+        computeMinDistToUncovered(sf.caller, minDistAtRA) : 0;
+    }
+  }
+}
+
+/* Should be called _after_ the es->popFrame() */
+void StatsTracker::framePopped(ExecutionState &es) {
+  // XXX remove me?
+}
+
+
+void StatsTracker::markBranchVisited(ExecutionState *visitedTrue, 
+                                     ExecutionState *visitedFalse) {
+  if (OutputIStats) {
+    unsigned id = theStatisticManager->getIndex();
+    uint64_t hasTrue = theStatisticManager->getIndexedValue(stats::trueBranches, id);
+    uint64_t hasFalse = theStatisticManager->getIndexedValue(stats::falseBranches, id);
+    if (visitedTrue && !hasTrue) {
+      visitedTrue->coveredNew = true;
+      visitedTrue->instsSinceCovNew = 1;
+      ++stats::trueBranches;
+      if (hasFalse) { ++fullBranches; --partialBranches; }
+      else ++partialBranches;
+      hasTrue = 1;
+    }
+    if (visitedFalse && !hasFalse) {
+      visitedFalse->coveredNew = true;
+      visitedFalse->instsSinceCovNew = 1;
+      ++stats::falseBranches;
+      if (hasTrue) { ++fullBranches; --partialBranches; }
+      else ++partialBranches;
+    }
+  }
+}
+
+void StatsTracker::writeStatsHeader() {
+  *statsFile << "('Instructions',"
+             << "'FullBranches',"
+             << "'PartialBranches',"
+             << "'NumBranches',"
+             << "'UserTime',"
+             << "'NumStates',"
+             << "'MallocUsage',"
+             << "'NumQueries',"
+             << "'NumQueryConstructs',"
+             << "'NumObjects',"
+             << "'WallTime',"
+             << "'CoveredInstructions',"
+             << "'UncoveredInstructions',"
+             << "'QueryTime',"
+             << "'SolverTime',"
+             << "'CexCacheTime',"
+             << "'ForkTime',"
+             << "'ResolveTime',"
+             << ")\n";
+  statsFile->flush();
+}
+
+double StatsTracker::elapsed() {
+  return util::getWallTime() - startWallTime;
+}
+
+void StatsTracker::writeStatsLine() {
+  *statsFile << "(" << stats::instructions
+             << "," << fullBranches
+             << "," << partialBranches
+             << "," << numBranches
+             << "," << util::getUserTime()
+             << "," << executor.states.size()
+             << "," << sys::Process::GetTotalMemoryUsage()
+             << "," << stats::queries
+             << "," << stats::queryConstructs
+             << "," << 0 // was numObjects
+             << "," << elapsed()
+             << "," << stats::coveredInstructions
+             << "," << stats::uncoveredInstructions
+             << "," << stats::queryTime / 1000000.
+             << "," << stats::solverTime / 1000000.
+             << "," << stats::cexCacheTime / 1000000.
+             << "," << stats::forkTime / 1000000.
+             << "," << stats::resolveTime / 1000000.
+             << ")\n";
+  statsFile->flush();
+}
+
+void StatsTracker::updateStateStatistics(uint64_t addend) {
+  for (std::set<ExecutionState*>::iterator it = executor.states.begin(),
+         ie = executor.states.end(); it != ie; ++it) {
+    ExecutionState &state = **it;
+    const InstructionInfo &ii = *state.pc->info;
+    theStatisticManager->incrementIndexedValue(stats::states, ii.id, addend);
+    if (UseCallPaths)
+      state.stack.back().callPathNode->statistics.incrementValue(stats::states, addend);
+  }
+}
+
+void StatsTracker::writeIStats() {
+  Module *m = executor.kmodule->module;
+  uint64_t istatsMask = 0;
+  std::ostream &of = *istatsFile;
+  
+  of.seekp(0, std::ios::end);
+  unsigned istatsSize = of.tellp();
+  of.seekp(0);
+
+  of << "version: 1\n";
+  of << "creator: klee\n";
+  of << "pid: " << sys::Process::GetCurrentUserId() << "\n";
+  of << "cmd: " << m->getModuleIdentifier() << "\n\n";
+  of << "\n";
+  
+  StatisticManager &sm = *theStatisticManager;
+  unsigned nStats = sm.getNumStatistics();
+
+  // Max is 13, sadly
+  istatsMask |= 1<<sm.getStatisticID("Queries");
+  istatsMask |= 1<<sm.getStatisticID("QueriesValid");
+  istatsMask |= 1<<sm.getStatisticID("QueriesInvalid");
+  istatsMask |= 1<<sm.getStatisticID("QueryTime");
+  istatsMask |= 1<<sm.getStatisticID("ResolveTime");
+  istatsMask |= 1<<sm.getStatisticID("Instructions");
+  istatsMask |= 1<<sm.getStatisticID("InstructionTimes");
+  istatsMask |= 1<<sm.getStatisticID("InstructionRealTimes");
+  istatsMask |= 1<<sm.getStatisticID("Forks");
+  istatsMask |= 1<<sm.getStatisticID("CoveredInstructions");
+  istatsMask |= 1<<sm.getStatisticID("UncoveredInstructions");
+  istatsMask |= 1<<sm.getStatisticID("States");
+  istatsMask |= 1<<sm.getStatisticID("MinDistToUncovered");
+
+  of << "positions: instr line\n";
+
+  for (unsigned i=0; i<nStats; i++) {
+    if (istatsMask & (1<<i)) {
+      Statistic &s = sm.getStatistic(i);
+      of << "event: " << s.getShortName() << " : " 
+         << s.getName() << "\n";
+    }
+  }
+
+  of << "events: ";
+  for (unsigned i=0; i<nStats; i++) {
+    if (istatsMask & (1<<i))
+      of << sm.getStatistic(i).getShortName() << " ";
+  }
+  of << "\n";
+  
+  // set state counts, decremented after we process so that we don't
+  // have to zero all records each time.
+  if (istatsMask & (1<<stats::states.getID()))
+    updateStateStatistics(1);
+
+  std::string sourceFile = "";
+
+  CallSiteSummaryTable callSiteStats;
+  if (UseCallPaths)
+    callPathManager.getSummaryStatistics(callSiteStats);
+
+  of << "ob=" << objectFilename << "\n";
+
+  for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
+       fnIt != fn_ie; ++fnIt) {
+    if (!fnIt->isDeclaration()) {
+      of << "fn=" << fnIt->getName() << "\n";
+      for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
+           bbIt != bb_ie; ++bbIt) {
+        for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
+             it != it; ++it) {
+          Instruction *instr = &*it;
+          const InstructionInfo &ii = executor.kmodule->infos->getInfo(instr);
+          unsigned index = ii.id;
+          if (ii.file!=sourceFile) {
+            of << "fl=" << ii.file << "\n";
+            sourceFile = ii.file;
+          }
+          of << ii.assemblyLine << " ";
+          of << ii.line << " ";
+          for (unsigned i=0; i<nStats; i++)
+            if (istatsMask&(1<<i))
+              of << sm.getIndexedValue(sm.getStatistic(i), index) << " ";
+          of << "\n";
+
+          if (UseCallPaths && 
+              (isa<CallInst>(instr) || isa<InvokeInst>(instr))) {
+            CallSiteSummaryTable::iterator it = callSiteStats.find(instr);
+            if (it!=callSiteStats.end()) {
+              for (std::map<llvm::Function*, CallSiteInfo>::iterator
+                     fit = it->second.begin(), fie = it->second.end(); 
+                   fit != fie; ++fit) {
+                Function *f = fit->first;
+                CallSiteInfo &csi = fit->second;
+                const InstructionInfo &fii = 
+                  executor.kmodule->infos->getFunctionInfo(f);
+  
+                if (fii.file!="" && fii.file!=sourceFile)
+                  of << "cfl=" << fii.file << "\n";
+                of << "cfn=" << f->getName() << "\n";
+                of << "calls=" << csi.count << " ";
+                of << fii.assemblyLine << " ";
+                of << fii.line << "\n";
+
+                of << ii.assemblyLine << " ";
+                of << ii.line << " ";
+                for (unsigned i=0; i<nStats; i++) {
+                  if (istatsMask&(1<<i)) {
+                    Statistic &s = sm.getStatistic(i);
+                    uint64_t value;
+
+                    // Hack, ignore things that don't make sense on
+                    // call paths.
+                    if (&s == &stats::uncoveredInstructions) {
+                      value = 0;
+                    } else {
+                      value = csi.statistics.getValue(s);
+                    }
+
+                    of << value << " ";
+                  }
+                }
+                of << "\n";
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (istatsMask & (1<<stats::states.getID()))
+    updateStateStatistics((uint64_t)-1);
+  
+  // Clear then end of the file if necessary (no truncate op?).
+  unsigned pos = of.tellp();
+  for (unsigned i=pos; i<istatsSize; ++i)
+    of << '\n';
+  
+  of.flush();
+}
+
+///
+
+typedef std::map<Instruction*, std::vector<Function*> > calltargets_ty;
+
+static calltargets_ty callTargets;
+static std::map<Function*, std::vector<Instruction*> > functionCallers;
+static std::map<Function*, unsigned> functionShortestPath;
+
+static std::vector<Instruction*> getSuccs(Instruction *i) {
+  BasicBlock *bb = i->getParent();
+  std::vector<Instruction*> res;
+
+  if (i==bb->getTerminator()) {
+    for (succ_iterator it = succ_begin(bb), ie = succ_end(bb); it != ie; ++it)
+      res.push_back(it->begin());
+  } else {
+    res.push_back(++BasicBlock::iterator(i));
+  }
+
+  return res;
+}
+
+uint64_t klee::computeMinDistToUncovered(const KInstruction *ki,
+                                         uint64_t minDistAtRA) {
+  StatisticManager &sm = *theStatisticManager;
+  if (minDistAtRA==0) { // unreachable on return, best is local
+    return sm.getIndexedValue(stats::minDistToUncovered,
+                              ki->info->id);
+  } else {
+    uint64_t minDistLocal = sm.getIndexedValue(stats::minDistToUncovered,
+                                               ki->info->id);
+    uint64_t distToReturn = sm.getIndexedValue(stats::minDistToReturn,
+                                               ki->info->id);
+
+    if (distToReturn==0) { // return unreachable, best is local
+      return minDistLocal;
+    } else if (!minDistLocal) { // no local reachable
+      return distToReturn + minDistAtRA;
+    } else {
+      return std::min(minDistLocal, distToReturn + minDistAtRA);
+    }
+  }
+}
+
+void StatsTracker::computeReachableUncovered() {
+  KModule *km = executor.kmodule;
+  Module *m = km->module;
+  static bool init = true;
+  const InstructionInfoTable &infos = *km->infos;
+  StatisticManager &sm = *theStatisticManager;
+  
+  if (init) {
+    init = false;
+
+    // Compute call targets. It would be nice to use alias information
+    // instead of assuming all indirect calls hit all escaping
+    // functions, eh?
+    for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
+         fnIt != fn_ie; ++fnIt) {
+      for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
+           bbIt != bb_ie; ++bbIt) {
+        for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
+             it != it; ++it) {
+          if (isa<CallInst>(it) || isa<InvokeInst>(it)) {
+            if (isa<InlineAsm>(it->getOperand(0))) {
+              // We can never call through here so assume no targets
+              // (which should be correct anyhow).
+              callTargets.insert(std::make_pair(it,
+                                                std::vector<Function*>()));
+            } else if (Function *target = getDirectCallTarget(it)) {
+              callTargets[it].push_back(target);
+            } else {
+              callTargets[it] = 
+                std::vector<Function*>(km->escapingFunctions.begin(),
+                                       km->escapingFunctions.end());
+            }
+          }
+        }
+      }
+    }
+
+    // Compute function callers as reflexion of callTargets.
+    for (calltargets_ty::iterator it = callTargets.begin(), 
+           ie = callTargets.end(); it != ie; ++it)
+      for (std::vector<Function*>::iterator fit = it->second.begin(), 
+             fie = it->second.end(); fit != fie; ++fit) 
+        functionCallers[*fit].push_back(it->first);
+
+    // Initialize minDistToReturn to shortest paths through
+    // functions. 0 is unreachable.
+    std::vector<Instruction *> instructions;
+    for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
+         fnIt != fn_ie; ++fnIt) {
+      if (fnIt->isDeclaration()) {
+        if (fnIt->doesNotReturn()) {
+          functionShortestPath[fnIt] = 0;
+        } else {
+          functionShortestPath[fnIt] = 1; // whatever
+        }
+      } else {
+        functionShortestPath[fnIt] = 0;
+      }
+
+      // Not sure if I should bother to preorder here. XXX I should.
+      for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
+           bbIt != bb_ie; ++bbIt) {
+        for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
+             it != it; ++it) {
+          instructions.push_back(it);
+          unsigned id = infos.getInfo(it).id;
+          sm.setIndexedValue(stats::minDistToReturn, 
+                             id, 
+                             isa<ReturnInst>(it) || isa<UnwindInst>(it));
+        }
+      }
+    }
+  
+    std::reverse(instructions.begin(), instructions.end());
+    
+    // I'm so lazy it's not even worklisted.
+    bool changed;
+    do {
+      changed = false;
+      for (std::vector<Instruction*>::iterator it = instructions.begin(),
+             ie = instructions.end(); it != ie; ++it) {
+        Instruction *inst = *it;
+        unsigned bestThrough = 0;
+
+        if (isa<CallInst>(inst) || isa<InvokeInst>(inst)) {
+          std::vector<Function*> &targets = callTargets[inst];
+          for (std::vector<Function*>::iterator fnIt = targets.begin(),
+                 ie = targets.end(); fnIt != ie; ++fnIt) {
+            uint64_t dist = functionShortestPath[*fnIt];
+            if (dist) {
+              dist = 1+dist; // count instruction itself
+              if (bestThrough==0 || dist<bestThrough)
+                bestThrough = dist;
+            }
+          }
+        } else {
+          bestThrough = 1;
+        }
+       
+        if (bestThrough) {
+          unsigned id = infos.getInfo(*it).id;
+          uint64_t best, cur = best = sm.getIndexedValue(stats::minDistToReturn, id);
+          std::vector<Instruction*> succs = getSuccs(*it);
+          for (std::vector<Instruction*>::iterator it2 = succs.begin(),
+                 ie = succs.end(); it2 != ie; ++it2) {
+            uint64_t dist = sm.getIndexedValue(stats::minDistToReturn,
+                                               infos.getInfo(*it2).id);
+            if (dist) {
+              uint64_t val = bestThrough + dist;
+              if (best==0 || val<best)
+                best = val;
+            }
+          }
+          if (best != cur) {
+            sm.setIndexedValue(stats::minDistToReturn, id, best);
+            changed = true;
+
+            // Update shortest path if this is the entry point.
+            Function *f = inst->getParent()->getParent();
+            if (inst==f->begin()->begin())
+              functionShortestPath[f] = best;
+          }
+        }
+      }
+    } while (changed);
+  }
+
+  // compute minDistToUncovered, 0 is unreachable
+  std::vector<Instruction *> instructions;
+  for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
+       fnIt != fn_ie; ++fnIt) {
+    // Not sure if I should bother to preorder here.
+    for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
+         bbIt != bb_ie; ++bbIt) {
+      for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
+           it != it; ++it) {
+        unsigned id = infos.getInfo(it).id;
+        instructions.push_back(&*it);
+        sm.setIndexedValue(stats::minDistToUncovered, 
+                           id, 
+                           sm.getIndexedValue(stats::uncoveredInstructions, id));
+      }
+    }
+  }
+  
+  std::reverse(instructions.begin(), instructions.end());
+  
+  // I'm so lazy it's not even worklisted.
+  bool changed;
+  do {
+    changed = false;
+    for (std::vector<Instruction*>::iterator it = instructions.begin(),
+           ie = instructions.end(); it != ie; ++it) {
+      Instruction *inst = *it;
+      uint64_t best, cur = best = sm.getIndexedValue(stats::minDistToUncovered, 
+                                                     infos.getInfo(inst).id);
+      unsigned bestThrough = 0;
+      
+      if (isa<CallInst>(inst) || isa<InvokeInst>(inst)) {
+        std::vector<Function*> &targets = callTargets[inst];
+        for (std::vector<Function*>::iterator fnIt = targets.begin(),
+               ie = targets.end(); fnIt != ie; ++fnIt) {
+          uint64_t dist = functionShortestPath[*fnIt];
+          if (dist) {
+            dist = 1+dist; // count instruction itself
+            if (bestThrough==0 || dist<bestThrough)
+              bestThrough = dist;
+          }
+
+          if (!(*fnIt)->isDeclaration()) {
+            uint64_t calleeDist = sm.getIndexedValue(stats::minDistToUncovered,
+                                                     infos.getFunctionInfo(*fnIt).id);
+            if (calleeDist) {
+              calleeDist = 1+calleeDist; // count instruction itself
+              if (best==0 || calleeDist<best)
+                best = calleeDist;
+            }
+          }
+        }
+      } else {
+        bestThrough = 1;
+      }
+      
+      if (bestThrough) {
+        std::vector<Instruction*> succs = getSuccs(inst);
+        for (std::vector<Instruction*>::iterator it2 = succs.begin(),
+               ie = succs.end(); it2 != ie; ++it2) {
+          uint64_t dist = sm.getIndexedValue(stats::minDistToUncovered,
+                                             infos.getInfo(*it2).id);
+          if (dist) {
+            uint64_t val = bestThrough + dist;
+            if (best==0 || val<best)
+              best = val;
+          }
+        }
+      }
+
+      if (best != cur) {
+        sm.setIndexedValue(stats::minDistToUncovered, 
+                           infos.getInfo(inst).id, 
+                           best);
+        changed = true;
+      }
+    }
+  } while (changed);
+
+  for (std::set<ExecutionState*>::iterator it = executor.states.begin(),
+         ie = executor.states.end(); it != ie; ++it) {
+    ExecutionState *es = *it;
+    uint64_t currentFrameMinDist = 0;
+    for (ExecutionState::stack_ty::iterator sfIt = es->stack.begin(),
+           sf_ie = es->stack.end(); sfIt != sf_ie; ++sfIt) {
+      ExecutionState::stack_ty::iterator next = sfIt + 1;
+      KInstIterator kii;
+
+      if (next==es->stack.end()) {
+        kii = es->pc;
+      } else {
+        kii = next->caller;
+        ++kii;
+      }
+      
+      sfIt->minDistToUncoveredOnReturn = currentFrameMinDist;
+      
+      currentFrameMinDist = computeMinDistToUncovered(kii, currentFrameMinDist);
+    }
+  }
+}
diff --git a/lib/Core/StatsTracker.h b/lib/Core/StatsTracker.h
new file mode 100644
index 00000000..9d22b389
--- /dev/null
+++ b/lib/Core/StatsTracker.h
@@ -0,0 +1,93 @@
+//===-- StatsTracker.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_STATSTRACKER_H
+#define KLEE_STATSTRACKER_H
+
+#include "CallPathManager.h"
+
+#include <iostream>
+#include <set>
+
+namespace llvm {
+  class BranchInst;
+  class Function;
+  class Instruction;
+}
+
+namespace klee {
+  class ExecutionState;
+  class Executor;  
+  class InstructionInfoTable;
+  class InterpreterHandler;
+  class KInstruction;
+  class StackFrame;
+
+  class StatsTracker {
+    friend class WriteStatsTimer;
+    friend class WriteIStatsTimer;
+
+    Executor &executor;
+    std::string objectFilename;
+
+    std::ostream *statsFile, *istatsFile;
+    double startWallTime;
+    
+    unsigned numBranches;
+    unsigned fullBranches, partialBranches;
+
+    CallPathManager callPathManager;    
+
+    bool updateMinDistToUncovered;
+
+  public:
+    static bool useStatistics();
+
+  private:
+    void updateStateStatistics(uint64_t addend);
+    void writeStatsHeader();
+    void writeStatsLine();
+    void writeIStats();
+
+  public:
+    StatsTracker(Executor &_executor, std::string _objectFilename,
+                 bool _updateMinDistToUncovered);
+    ~StatsTracker();
+
+    // called after a new StackFrame has been pushed (for callpath tracing)
+    void framePushed(ExecutionState &es, StackFrame *parentFrame);
+
+    // called after a StackFrame has been popped 
+    void framePopped(ExecutionState &es);
+
+    // called when some side of a branch has been visited. it is
+    // imperative that this be called when the statistics index is at
+    // the index for the branch itself.
+    void markBranchVisited(ExecutionState *visitedTrue, 
+                           ExecutionState *visitedFalse);
+    
+    // called when execution is done and stats files should be flushed
+    void done();
+
+    // process stats for a single instruction step, es is the state
+    // about to be stepped
+    void stepInstruction(ExecutionState &es);
+
+    /// Return time in seconds since execution start.
+    double elapsed();
+
+    void computeReachableUncovered();
+  };
+
+  uint64_t computeMinDistToUncovered(const KInstruction *ki,
+                                     uint64_t minDistAtRA);
+
+}
+
+#endif
diff --git a/lib/Core/TimingSolver.cpp b/lib/Core/TimingSolver.cpp
new file mode 100644
index 00000000..70e42836
--- /dev/null
+++ b/lib/Core/TimingSolver.cpp
@@ -0,0 +1,147 @@
+//===-- TimingSolver.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TimingSolver.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Solver.h"
+#include "klee/Statistics.h"
+
+#include "CoreStats.h"
+
+#include "llvm/System/Process.h"
+
+using namespace klee;
+using namespace llvm;
+
+/***/
+
+bool TimingSolver::evaluate(const ExecutionState& state, ref<Expr> expr,
+                            Solver::Validity &result) {
+  // Fast path, to avoid timer and OS overhead.
+  if (expr.isConstant()) {
+    result = expr.getConstantValue() ? Solver::True : Solver::False;
+    return true;
+  }
+
+  sys::TimeValue now(0,0),user(0,0),delta(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+
+  if (simplifyExprs)
+    expr = state.constraints.simplifyExpr(expr);
+
+  bool success = solver->evaluate(Query(state.constraints, expr), result);
+
+  sys::Process::GetTimeUsage(delta,user,sys);
+  delta -= now;
+  stats::solverTime += delta.usec();
+  state.queryCost += delta.usec()/1000000.;
+
+  return success;
+}
+
+bool TimingSolver::mustBeTrue(const ExecutionState& state, ref<Expr> expr, 
+                              bool &result) {
+  // Fast path, to avoid timer and OS overhead.
+  if (expr.isConstant()) {
+    result = expr.getConstantValue() ? true : false;
+    return true;
+  }
+
+  sys::TimeValue now(0,0),user(0,0),delta(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+
+  if (simplifyExprs)
+    expr = state.constraints.simplifyExpr(expr);
+
+  bool success = solver->mustBeTrue(Query(state.constraints, expr), result);
+
+  sys::Process::GetTimeUsage(delta,user,sys);
+  delta -= now;
+  stats::solverTime += delta.usec();
+  state.queryCost += delta.usec()/1000000.;
+
+  return success;
+}
+
+bool TimingSolver::mustBeFalse(const ExecutionState& state, ref<Expr> expr,
+                               bool &result) {
+  return mustBeTrue(state, Expr::createNot(expr), result);
+}
+
+bool TimingSolver::mayBeTrue(const ExecutionState& state, ref<Expr> expr, 
+                             bool &result) {
+  bool res;
+  if (!mustBeFalse(state, expr, res))
+    return false;
+  result = !res;
+  return true;
+}
+
+bool TimingSolver::mayBeFalse(const ExecutionState& state, ref<Expr> expr, 
+                              bool &result) {
+  bool res;
+  if (!mustBeTrue(state, expr, res))
+    return false;
+  result = !res;
+  return true;
+}
+
+bool TimingSolver::getValue(const ExecutionState& state, ref<Expr> expr, 
+                            ref<Expr> &result) {
+  // Fast path, to avoid timer and OS overhead.
+  if (expr.isConstant()) {
+    result = expr;
+    return true;
+  }
+  
+  sys::TimeValue now(0,0),user(0,0),delta(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+
+  if (simplifyExprs)
+    expr = state.constraints.simplifyExpr(expr);
+
+  bool success = solver->getValue(Query(state.constraints, expr), result);
+
+  sys::Process::GetTimeUsage(delta,user,sys);
+  delta -= now;
+  stats::solverTime += delta.usec();
+  state.queryCost += delta.usec()/1000000.;
+
+  return success;
+}
+
+bool 
+TimingSolver::getInitialValues(const ExecutionState& state, 
+                               const std::vector<const Array*>
+                                 &objects,
+                               std::vector< std::vector<unsigned char> >
+                                 &result) {
+  if (objects.empty())
+    return true;
+
+  sys::TimeValue now(0,0),user(0,0),delta(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+
+  bool success = solver->getInitialValues(Query(state.constraints,
+                                                ref<Expr>(0, Expr::Bool)), 
+                                          objects, result);
+  
+  sys::Process::GetTimeUsage(delta,user,sys);
+  delta -= now;
+  stats::solverTime += delta.usec();
+  state.queryCost += delta.usec()/1000000.;
+  
+  return success;
+}
+
+std::pair< ref<Expr>, ref<Expr> >
+TimingSolver::getRange(const ExecutionState& state, ref<Expr> expr) {
+  return solver->getRange(Query(state.constraints, expr));
+}
diff --git a/lib/Core/TimingSolver.h b/lib/Core/TimingSolver.h
new file mode 100644
index 00000000..875216d9
--- /dev/null
+++ b/lib/Core/TimingSolver.h
@@ -0,0 +1,70 @@
+//===-- TimingSolver.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_TIMINGSOLVER_H
+#define KLEE_TIMINGSOLVER_H
+
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+
+#include <vector>
+
+namespace klee {
+  class ExecutionState;
+  class Solver;
+  class STPSolver;
+
+  /// TimingSolver - A simple class which wraps a solver and handles
+  /// tracking the statistics that we care about.
+  class TimingSolver {
+  public:
+    Solver *solver;
+    STPSolver *stpSolver;
+    bool simplifyExprs;
+
+  public:
+    /// TimingSolver - Construct a new timing solver.
+    ///
+    /// \param _simplifyExprs - Whether expressions should be
+    /// simplified (via the constraint manager interface) prior to
+    /// querying.
+    TimingSolver(Solver *_solver, STPSolver *_stpSolver, 
+                 bool _simplifyExprs = true) 
+      : solver(_solver), stpSolver(_stpSolver), simplifyExprs(_simplifyExprs) {}
+    ~TimingSolver() {
+      delete solver;
+    }
+
+    void setTimeout(double t) {
+      stpSolver->setTimeout(t);
+    }
+
+    bool evaluate(const ExecutionState&, ref<Expr>, Solver::Validity &result);
+
+    bool mustBeTrue(const ExecutionState&, ref<Expr>, bool &result);
+
+    bool mustBeFalse(const ExecutionState&, ref<Expr>, bool &result);
+
+    bool mayBeTrue(const ExecutionState&, ref<Expr>, bool &result);
+
+    bool mayBeFalse(const ExecutionState&, ref<Expr>, bool &result);
+
+    bool getValue(const ExecutionState &, ref<Expr> expr, ref<Expr> &result);
+
+    bool getInitialValues(const ExecutionState&, 
+                          const std::vector<const Array*> &objects,
+                          std::vector< std::vector<unsigned char> > &result);
+
+    virtual std::pair< ref<Expr>, ref<Expr> >
+    getRange(const ExecutionState&, ref<Expr> query);
+  };
+
+}
+
+#endif
diff --git a/lib/Core/UserSearcher.cpp b/lib/Core/UserSearcher.cpp
new file mode 100644
index 00000000..1aff9e5e
--- /dev/null
+++ b/lib/Core/UserSearcher.cpp
@@ -0,0 +1,175 @@
+//===-- UserSearcher.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Common.h"
+
+#include "UserSearcher.h"
+
+#include "Searcher.h"
+#include "Executor.h"
+
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+using namespace klee;
+
+namespace {
+  cl::opt<bool>
+  UseRandomSearch("use-random-search");
+
+  cl::opt<bool>
+  UseInterleavedRS("use-interleaved-RS");
+
+  cl::opt<bool>
+  UseInterleavedNURS("use-interleaved-NURS");
+
+  cl::opt<bool>
+  UseInterleavedMD2UNURS("use-interleaved-MD2U-NURS");
+
+  cl::opt<bool>
+  UseInterleavedInstCountNURS("use-interleaved-icnt-NURS");
+
+  cl::opt<bool>
+  UseInterleavedCPInstCountNURS("use-interleaved-cpicnt-NURS");
+
+  cl::opt<bool>
+  UseInterleavedQueryCostNURS("use-interleaved-query-cost-NURS");
+
+  cl::opt<bool>
+  UseInterleavedCovNewNURS("use-interleaved-covnew-NURS");
+
+  cl::opt<bool>
+  UseNonUniformRandomSearch("use-non-uniform-random-search");
+
+  cl::opt<bool>
+  UseRandomPathSearch("use-random-path");
+
+  cl::opt<WeightedRandomSearcher::WeightType>
+  WeightType("weight-type", cl::desc("Set the weight type for --use-non-uniform-random-search"),
+             cl::values(clEnumValN(WeightedRandomSearcher::Depth, "none", "use (2^depth)"),
+                        clEnumValN(WeightedRandomSearcher::InstCount, "icnt", "use current pc exec count"),
+                        clEnumValN(WeightedRandomSearcher::CPInstCount, "cpicnt", "use current pc exec count"),
+                        clEnumValN(WeightedRandomSearcher::QueryCost, "query-cost", "use query cost"),
+                        clEnumValN(WeightedRandomSearcher::MinDistToUncovered, "md2u", "use min dist to uncovered"),
+                        clEnumValN(WeightedRandomSearcher::CoveringNew, "covnew", "use min dist to uncovered + coveringNew flag"),
+                        clEnumValEnd));
+  
+  cl::opt<bool>
+  UseMerge("use-merge", 
+           cl::desc("Enable support for klee_merge() (experimental)"));
+ 
+  cl::opt<bool>
+  UseBumpMerge("use-bump-merge", 
+           cl::desc("Enable support for klee_merge() (extra experimental)"));
+ 
+  cl::opt<bool>
+  UseIterativeDeepeningTimeSearch("use-iterative-deepening-time-search", 
+                                    cl::desc("(experimental)"));
+
+  cl::opt<bool>
+  UseBatchingSearch("use-batching-search", 
+           cl::desc("Use batching searcher (keep running selected state for N instructions/time, see --batch-instructions and --batch-time"));
+
+  cl::opt<unsigned>
+  BatchInstructions("batch-instructions",
+                    cl::desc("Number of instructions to batch when using --use-batching-search"),
+                    cl::init(10000));
+  
+  cl::opt<double>
+  BatchTime("batch-time",
+            cl::desc("Amount of time to batch when using --use-batching-search"),
+            cl::init(5.0));
+}
+
+bool klee::userSearcherRequiresMD2U() {
+  return (WeightType==WeightedRandomSearcher::MinDistToUncovered ||
+          WeightType==WeightedRandomSearcher::CoveringNew ||
+          UseInterleavedMD2UNURS ||
+          UseInterleavedCovNewNURS || 
+          UseInterleavedInstCountNURS || 
+          UseInterleavedCPInstCountNURS || 
+          UseInterleavedQueryCostNURS);
+}
+
+// FIXME: Remove.
+bool klee::userSearcherRequiresBranchSequences() {
+  return false;
+}
+
+Searcher *klee::constructUserSearcher(Executor &executor) {
+  Searcher *searcher = 0;
+
+  if (UseRandomPathSearch) {
+    searcher = new RandomPathSearcher(executor);
+  } else if (UseNonUniformRandomSearch) {
+    searcher = new WeightedRandomSearcher(executor, WeightType);
+  } else if (UseRandomSearch) {
+    searcher = new RandomSearcher();
+  } else {
+    searcher = new DFSSearcher();
+  }
+
+  if (UseInterleavedNURS || UseInterleavedMD2UNURS || UseInterleavedRS ||
+      UseInterleavedCovNewNURS || UseInterleavedInstCountNURS ||
+      UseInterleavedCPInstCountNURS || UseInterleavedQueryCostNURS) {
+    std::vector<Searcher *> s;
+    s.push_back(searcher);
+    
+    if (UseInterleavedNURS)
+      s.push_back(new WeightedRandomSearcher(executor, 
+                                             WeightedRandomSearcher::Depth));
+    if (UseInterleavedMD2UNURS)
+      s.push_back(new WeightedRandomSearcher(executor, 
+                                             WeightedRandomSearcher::MinDistToUncovered));
+
+    if (UseInterleavedCovNewNURS)
+      s.push_back(new WeightedRandomSearcher(executor, 
+                                             WeightedRandomSearcher::CoveringNew));
+   
+    if (UseInterleavedInstCountNURS)
+      s.push_back(new WeightedRandomSearcher(executor, 
+                                             WeightedRandomSearcher::InstCount));
+    
+    if (UseInterleavedCPInstCountNURS)
+      s.push_back(new WeightedRandomSearcher(executor, 
+                                             WeightedRandomSearcher::CPInstCount));
+    
+    if (UseInterleavedQueryCostNURS)
+      s.push_back(new WeightedRandomSearcher(executor, 
+                                             WeightedRandomSearcher::QueryCost));
+
+    if (UseInterleavedRS) 
+      s.push_back(new RandomSearcher());
+
+    searcher = new InterleavedSearcher(s);
+  }
+
+  if (UseBatchingSearch) {
+    searcher = new BatchingSearcher(searcher, BatchTime, BatchInstructions);
+  }
+
+  if (UseMerge) {
+    assert(!UseBumpMerge);
+    searcher = new MergingSearcher(executor, searcher);
+  } else if (UseBumpMerge) {    
+    searcher = new BumpMergingSearcher(executor, searcher);
+  }
+  
+  if (UseIterativeDeepeningTimeSearch) {
+    searcher = new IterativeDeepeningTimeSearcher(searcher);
+  }
+
+  std::ostream &os = executor.getHandler().getInfoStream();
+
+  os << "BEGIN searcher description\n";
+  searcher->printName(os);
+  os << "END searcher description\n";
+
+  return searcher;
+}
diff --git a/lib/Core/UserSearcher.h b/lib/Core/UserSearcher.h
new file mode 100644
index 00000000..9571bf5b
--- /dev/null
+++ b/lib/Core/UserSearcher.h
@@ -0,0 +1,25 @@
+//===-- UserSearcher.h ------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_USERSEARCHER_H
+#define KLEE_USERSEARCHER_H
+
+namespace klee {
+  class Executor;
+  class Searcher;
+
+  // XXX gross, should be on demand?
+  bool userSearcherRequiresMD2U();
+
+  bool userSearcherRequiresBranchSequences();
+
+  Searcher *constructUserSearcher(Executor &executor);
+}
+
+#endif
diff --git a/lib/Expr/Constraints.cpp b/lib/Expr/Constraints.cpp
new file mode 100644
index 00000000..e9c376f4
--- /dev/null
+++ b/lib/Expr/Constraints.cpp
@@ -0,0 +1,155 @@
+//===-- Constraints.cpp ---------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Constraints.h"
+
+#include "klee/util/ExprPPrinter.h"
+#include "klee/util/ExprVisitor.h"
+
+#include <iostream>
+#include <map>
+
+using namespace klee;
+
+class ExprReplaceVisitor : public ExprVisitor {
+private:
+  ref<Expr> src, dst;
+
+public:
+  ExprReplaceVisitor(ref<Expr> _src, ref<Expr> _dst) : src(_src), dst(_dst) {}
+
+  Action visitExpr(const Expr &e) {
+    if (e == *src.get()) {
+      return Action::changeTo(dst);
+    } else {
+      return Action::doChildren();
+    }
+  }
+
+  Action visitExprPost(const Expr &e) {
+    if (e == *src.get()) {
+      return Action::changeTo(dst);
+    } else {
+      return Action::doChildren();
+    }
+  }
+};
+
+class ExprReplaceVisitor2 : public ExprVisitor {
+private:
+  const std::map< ref<Expr>, ref<Expr> > &replacements;
+
+public:
+  ExprReplaceVisitor2(const std::map< ref<Expr>, ref<Expr> > &_replacements) 
+    : ExprVisitor(true),
+      replacements(_replacements) {}
+
+  Action visitExprPost(const Expr &e) {
+    std::map< ref<Expr>, ref<Expr> >::const_iterator it =
+      replacements.find(ref<Expr>((Expr*) &e));
+    if (it!=replacements.end()) {
+      return Action::changeTo(it->second);
+    } else {
+      return Action::doChildren();
+    }
+  }
+};
+
+bool ConstraintManager::rewriteConstraints(ExprVisitor &visitor) {
+  ConstraintManager::constraints_ty old;
+  bool changed = false;
+
+  constraints.swap(old);
+  for (ConstraintManager::constraints_ty::iterator 
+         it = old.begin(), ie = old.end(); it != ie; ++it) {
+    ref<Expr> &ce = *it;
+    ref<Expr> e = visitor.visit(ce);
+
+    if (e!=ce) {
+      addConstraintInternal(e); // enable further reductions
+      changed = true;
+    } else {
+      constraints.push_back(ce);
+    }
+  }
+
+  return changed;
+}
+
+void ConstraintManager::simplifyForValidConstraint(ref<Expr> e) {
+  // XXX 
+}
+
+ref<Expr> ConstraintManager::simplifyExpr(ref<Expr> e) const {
+  if (e.isConstant())
+    return e;
+
+  std::map< ref<Expr>, ref<Expr> > equalities;
+  
+  for (ConstraintManager::constraints_ty::const_iterator 
+         it = constraints.begin(), ie = constraints.end(); it != ie; ++it) {
+    if (const EqExpr *ee = dyn_ref_cast<EqExpr>(*it)) {
+      if (ee->left.isConstant()) {
+        equalities.insert(std::make_pair(ee->right,
+                                         ee->left));
+      } else {
+        equalities.insert(std::make_pair(*it,
+                                         ref<Expr>(1,Expr::Bool)));
+      }
+    } else {
+      equalities.insert(std::make_pair(*it,
+                                       ref<Expr>(1,Expr::Bool)));
+    }
+  }
+
+  return ExprReplaceVisitor2(equalities).visit(e);
+}
+
+void ConstraintManager::addConstraintInternal(ref<Expr> e) {
+  // rewrite any known equalities 
+
+  // XXX should profile the effects of this and the overhead.
+  // traversing the constraints looking for equalities is hardly the
+  // slowest thing we do, but it is probably nicer to have a
+  // ConstraintSet ADT which efficiently remembers obvious patterns
+  // (byte-constant comparison).
+
+  switch (e.getKind()) {
+  case Expr::Constant:
+    assert(e.getConstantValue() && "attempt to add invalid (false) constraint");
+    break;
+    
+    // split to enable finer grained independence and other optimizations
+  case Expr::And: {
+    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    addConstraintInternal(be->left);
+    addConstraintInternal(be->right);
+    break;
+  }
+
+  case Expr::Eq: {
+    BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+    if (be->left.isConstant()) {
+      ExprReplaceVisitor visitor(be->right, be->left);
+      rewriteConstraints(visitor);
+    }
+    constraints.push_back(e);
+    break;
+  }
+    
+  default:
+    constraints.push_back(e);
+    break;
+  }
+}
+
+void ConstraintManager::addConstraint(ref<Expr> e) {
+  e = simplifyExpr(e);
+  addConstraintInternal(e);
+}
diff --git a/lib/Expr/Expr.cpp b/lib/Expr/Expr.cpp
new file mode 100644
index 00000000..55b9a0a4
--- /dev/null
+++ b/lib/Expr/Expr.cpp
@@ -0,0 +1,1122 @@
+//===-- Expr.cpp ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Expr.h"
+
+
+#include "klee/Machine.h"
+// FIXME: This shouldn't be here.
+//#include "klee/Memory.h"
+#include "llvm/Type.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Streams.h"
+// FIXME: We shouldn't need this once fast constant support moves into
+// Core. If we need to do arithmetic, we probably want to use APInt.
+#include "klee/Internal/Support/IntEvaluation.h"
+
+#include "klee/util/ExprPPrinter.h"
+
+using namespace klee;
+using namespace llvm;
+
+namespace {
+  cl::opt<bool>
+  ConstArrayOpt("const-array-opt",
+	 cl::init(false),
+	 cl::desc("Enable various optimizations involving all-constant arrays."));
+}
+
+/***/
+
+unsigned Expr::count = 0;
+
+ref<Expr> Expr::createTempRead(const Array *array, Expr::Width w) {
+  UpdateList ul(array, true, 0);
+
+  switch (w) {
+  case Expr::Bool: 
+    return ZExtExpr::create(ReadExpr::create(ul, 
+                                             ref<Expr>(0,kMachinePointerType)),
+                            Expr::Bool);
+  case Expr::Int8: 
+    return ReadExpr::create(ul, 
+                            ref<Expr>(0,kMachinePointerType));
+  case Expr::Int16: 
+    return ConcatExpr::create(ReadExpr::create(ul, 
+                                               ref<Expr>(1,kMachinePointerType)),
+                              ReadExpr::create(ul, 
+                                               ref<Expr>(0,kMachinePointerType)));
+  case Expr::Int32: 
+    return ConcatExpr::create4(ReadExpr::create(ul, 
+                                                ref<Expr>(3,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(2,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(1,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(0,kMachinePointerType)));
+  case Expr::Int64: 
+    return ConcatExpr::create8(ReadExpr::create(ul, 
+                                                ref<Expr>(7,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(6,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(5,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(4,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(3,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(2,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(1,kMachinePointerType)),
+                               ReadExpr::create(ul, 
+                                                ref<Expr>(0,kMachinePointerType)));
+  default: assert(0 && "invalid width");
+  }
+}
+
+// returns 0 if b is structurally equal to *this
+int Expr::compare(const Expr &b) const {
+  if (this == &b) return 0;
+
+  Kind ak = getKind(), bk = b.getKind();
+  if (ak!=bk)
+    return (ak < bk) ? -1 : 1;
+
+  if (hashValue != b.hashValue) 
+    return (hashValue < b.hashValue) ? -1 : 1;
+
+  if (int res = compareContents(b)) 
+    return res;
+
+  unsigned aN = getNumKids();
+  for (unsigned i=0; i<aN; i++)
+    if (int res = getKid(i).compare(b.getKid(i)))
+      return res;
+
+  return 0;
+}
+
+void Expr::printKind(std::ostream &os, Kind k) {
+  switch(k) {
+#define X(C) case C: os << #C; break
+    X(Constant);
+    X(NotOptimized);
+    X(Read);
+    X(Select);
+    X(Concat);
+    X(Extract);
+    X(ZExt);
+    X(SExt);
+    X(Add);
+    X(Sub);
+    X(Mul);
+    X(UDiv);
+    X(SDiv);
+    X(URem);
+    X(SRem);
+    X(And);
+    X(Or);
+    X(Xor);
+    X(Shl);
+    X(LShr);
+    X(AShr);
+    X(Eq);
+    X(Ne);
+    X(Ult);
+    X(Ule);
+    X(Ugt);
+    X(Uge);
+    X(Slt);
+    X(Sle);
+    X(Sgt);
+    X(Sge);
+#undef X
+  default:
+    assert(0 && "invalid kind");
+    }
+}
+
+////////
+//
+// Simple hash functions for various kinds of Exprs
+//
+///////
+
+unsigned Expr::computeHash() {
+  unsigned res = getKind() * Expr::MAGIC_HASH_CONSTANT;
+
+  int n = getNumKids();
+  for (int i = 0; i < n; i++) {
+    res <<= 1;
+    res ^= getKid(i).hash() * Expr::MAGIC_HASH_CONSTANT;
+  }
+  
+  hashValue = res;
+  return hashValue;
+}
+
+unsigned ConstantExpr::computeHash() {
+  hashValue = Expr::hashConstant(asUInt64, width);
+  return hashValue;
+}
+
+unsigned CastExpr::computeHash() {
+  unsigned res = getWidth() * Expr::MAGIC_HASH_CONSTANT;
+  hashValue = res ^ src.hash() * Expr::MAGIC_HASH_CONSTANT;
+  return hashValue;
+}
+
+unsigned ExtractExpr::computeHash() {
+  unsigned res = offset * Expr::MAGIC_HASH_CONSTANT;
+  res ^= getWidth() * Expr::MAGIC_HASH_CONSTANT;
+  hashValue = res ^ expr.hash() * Expr::MAGIC_HASH_CONSTANT;
+  return hashValue;
+}
+
+unsigned ReadExpr::computeHash() {
+  unsigned res = index.hash() * Expr::MAGIC_HASH_CONSTANT;
+  res ^= updates.hash();
+  hashValue = res;
+  return hashValue;
+}
+
+uint64_t Expr::getConstantValue() const {
+  assert(getKind() == Constant);
+  return static_cast<const ConstantExpr*>(this)->asUInt64;
+}
+
+ref<Expr> Expr::createFromKind(Kind k, std::vector<CreateArg> args) {
+  unsigned numArgs = args.size();
+  
+  switch(k) {
+    case NotOptimized:
+      assert(numArgs == 1 && args[0].isExpr() &&
+             "invalid args array for given opcode");
+      return NotOptimizedExpr::create(args[0].expr);
+      
+    case Select:
+      assert(numArgs == 3 && args[0].isExpr() &&
+             args[1].isExpr() && args[2].isExpr() &&
+             "invalid args array for Select opcode");
+      return SelectExpr::create(args[0].expr,
+                                args[1].expr,
+                                args[2].expr);
+
+    case Concat: {
+      assert(numArgs == 2 && args[0].isExpr() && args[1].isExpr() && 
+             "invalid args array for Concat opcode");
+      
+      return ConcatExpr::create(args[0].expr, args[1].expr);
+    }
+      
+#define CAST_EXPR_CASE(T)                                    \
+      case T:                                                \
+        assert(numArgs == 2 &&				     \
+               args[0].isExpr() && args[1].isWidth() &&      \
+               "invalid args array for given opcode");       \
+      return T ## Expr::create(args[0].expr, args[1].width); \
+      
+#define BINARY_EXPR_CASE(T)                                 \
+      case T:                                               \
+        assert(numArgs == 2 &&                              \
+               args[0].isExpr() && args[1].isExpr() &&      \
+               "invalid args array for given opcode");      \
+      return T ## Expr::create(args[0].expr, args[1].expr); \
+
+      CAST_EXPR_CASE(ZExt);
+      CAST_EXPR_CASE(SExt);
+      
+      BINARY_EXPR_CASE(Add);
+      BINARY_EXPR_CASE(Sub);
+      BINARY_EXPR_CASE(Mul);
+      BINARY_EXPR_CASE(UDiv);
+      BINARY_EXPR_CASE(SDiv);
+      BINARY_EXPR_CASE(URem);
+      BINARY_EXPR_CASE(SRem);
+      BINARY_EXPR_CASE(And);
+      BINARY_EXPR_CASE(Or);
+      BINARY_EXPR_CASE(Xor);
+      BINARY_EXPR_CASE(Shl);
+      BINARY_EXPR_CASE(LShr);
+      BINARY_EXPR_CASE(AShr);
+      
+      BINARY_EXPR_CASE(Eq);
+      BINARY_EXPR_CASE(Ne);
+      BINARY_EXPR_CASE(Ult);
+      BINARY_EXPR_CASE(Ule);
+      BINARY_EXPR_CASE(Ugt);
+      BINARY_EXPR_CASE(Uge);
+      BINARY_EXPR_CASE(Slt);
+      BINARY_EXPR_CASE(Sle);
+      BINARY_EXPR_CASE(Sgt);
+      BINARY_EXPR_CASE(Sge);
+
+    case Constant:
+    case Extract:
+    case Read:
+    default:
+      assert(0 && "invalid kind");
+  }
+
+}
+
+
+void Expr::printWidth(std::ostream &os, Width width) {
+  switch(width) {
+  case Expr::Bool: os << "Expr::Bool"; break;
+  case Expr::Int8: os << "Expr::Int8"; break;
+  case Expr::Int16: os << "Expr::Int16"; break;
+  case Expr::Int32: os << "Expr::Int32"; break;
+  case Expr::Int64: os << "Expr::Int64"; break;
+  default: os << "<invalid type: " << (unsigned) width << ">";
+  }
+}
+
+Expr::Width Expr::getWidthForLLVMType(const llvm::Type *t) {
+  switch (t->getTypeID()) {
+  case llvm::Type::IntegerTyID: {
+    Width w = cast<IntegerType>(t)->getBitWidth();
+
+    // should remove this limitation soon
+    if (w == 1 || w == 8 || w == 16 || w == 32 || w == 64)
+      return w;
+    else {
+      assert(0 && "XXX arbitrary bit widths unsupported");
+      abort();
+    }
+  }
+  case llvm::Type::FloatTyID: return Expr::Int32;
+  case llvm::Type::DoubleTyID: return Expr::Int64;
+  case llvm::Type::X86_FP80TyID: return Expr::Int64; // XXX: needs to be fixed
+  case llvm::Type::PointerTyID: return kMachinePointerType;
+  default:
+    cerr << "non-primitive type argument to Expr::getTypeForLLVMType()\n";
+    abort();
+  }
+}
+
+ref<Expr> Expr::createImplies(ref<Expr> hyp, ref<Expr> conc) {
+  return OrExpr::create(Expr::createNot(hyp), conc);
+}
+
+ref<Expr> Expr::createIsZero(ref<Expr> e) {
+  return EqExpr::create(e, ConstantExpr::create(0, e.getWidth()));
+}
+
+ref<Expr> Expr::createCoerceToPointerType(ref<Expr> e) {
+  return ZExtExpr::create(e, kMachinePointerType);
+}
+
+ref<Expr> Expr::createNot(ref<Expr> e) {
+  return createIsZero(e);
+}
+
+ref<Expr> Expr::createPointer(uint64_t v) {
+  return ConstantExpr::create(v, kMachinePointerType);
+}
+
+Expr* Expr::createConstant(uint64_t val, Width w) {
+  Expr *r = new ConstantExpr(val, w);
+  r->computeHash();
+  return r;
+}
+
+void Expr::print(std::ostream &os) const {
+  const ref<Expr> tmp((Expr*)this);
+  ExprPPrinter::printOne(os, "", tmp);
+}
+
+/***/
+
+ref<ConstantExpr> ConstantExpr::fromMemory(void *address, Width width) {
+  switch (width) {
+  case  Expr::Bool: return ConstantExpr::create(*(( uint8_t*) address), width);
+  case  Expr::Int8: return ConstantExpr::create(*(( uint8_t*) address), width);
+  case Expr::Int16: return ConstantExpr::create(*((uint16_t*) address), width);
+  case Expr::Int32: return ConstantExpr::create(*((uint32_t*) address), width);
+  case Expr::Int64: return ConstantExpr::create(*((uint64_t*) address), width);
+  default: assert(0 && "invalid type");
+  }
+}
+
+void ConstantExpr::toMemory(void *address) {
+  switch (width) {
+  case  Expr::Bool: *(( uint8_t*) address) = asUInt64; break;
+  case  Expr::Int8: *(( uint8_t*) address) = asUInt64; break;
+  case Expr::Int16: *((uint16_t*) address) = asUInt64; break;
+  case Expr::Int32: *((uint32_t*) address) = asUInt64; break;
+  case Expr::Int64: *((uint64_t*) address) = asUInt64; break;
+  default: assert(0 && "invalid type");
+  }
+}
+
+/***/
+
+ref<Expr>  NotOptimizedExpr::create(ref<Expr> src) {
+  return NotOptimizedExpr::alloc(src);
+}
+
+ref<Expr> ReadExpr::create(const UpdateList &ul, ref<Expr> index) {
+  // rollback index when possible... 
+
+  // XXX this doesn't really belong here... there are basically two
+  // cases, one is rebuild, where we want to optimistically try various
+  // optimizations when the index has changed, and the other is 
+  // initial creation, where we expect the ObjectState to have constructed
+  // a smart UpdateList so it is not worth rescanning.
+
+  const UpdateNode *un = ul.head;
+  for (; un; un=un->next) {
+    ref<Expr> cond = EqExpr::create(index, un->index);
+    
+    if (cond.isConstant()) {
+      if (cond.getConstantValue())
+        return un->value;
+    } else {
+      break;
+    }
+  }
+
+  return ReadExpr::alloc(ul, index);
+}
+
+int ReadExpr::compareContents(const Expr &b) const { 
+  return updates.compare(static_cast<const ReadExpr&>(b).updates);
+}
+
+ref<Expr> SelectExpr::create(ref<Expr> c, ref<Expr> t, ref<Expr> f) {
+  Expr::Width kt = t.getWidth();
+
+  assert(c.getWidth()==Bool && "type mismatch");
+  assert(kt==f.getWidth() && "type mismatch");
+
+  if (c.isConstant()) {
+    return c.getConstantValue() ? t : f;
+  } else if (t==f) {
+    return t;
+  } else if (kt==Expr::Bool) { // c ? t : f  <=> (c and t) or (not c and f)
+    if (t.isConstant()) {      
+      if (t.getConstantValue()) {
+        return OrExpr::create(c, f);
+      } else {
+        return AndExpr::create(Expr::createNot(c), f);
+      }
+    } else if (f.isConstant()) {
+      if (f.getConstantValue()) {
+        return OrExpr::create(Expr::createNot(c), t);
+      } else {
+        return AndExpr::create(c, t);
+      }
+    }
+  }
+  
+  return SelectExpr::alloc(c, t, f);
+}
+
+/***/
+
+
+ref<Expr> ConcatExpr::create(const ref<Expr> &l, const ref<Expr> &r) {
+  Expr::Width w = l.getWidth() + r.getWidth();
+  
+  /* Constant folding */
+  if (l.getKind() == Expr::Constant && r.getKind() == Expr::Constant) {
+    // XXX: should fix this constant limitation soon
+    assert(w <= 64 && "ConcatExpr::create(): don't support concats describing constants greater than 64 bits yet");
+    
+    uint64_t res = (l.getConstantValue() << r.getWidth()) + r.getConstantValue();
+    return ConstantExpr::create(res, w);
+  }
+
+  // Merge contiguous Extracts
+  if (l.getKind() == Expr::Extract && r.getKind() == Expr::Extract) {
+    const ExtractExpr* ee_left = static_ref_cast<ExtractExpr>(l);
+    const ExtractExpr* ee_right = static_ref_cast<ExtractExpr>(r);
+    if (ee_left->expr == ee_right->expr &&
+	ee_right->offset + ee_right->width == ee_left->offset) {
+      return ExtractExpr::create(ee_left->expr, ee_right->offset, w);
+    }
+  }
+
+  return ConcatExpr::alloc(l, r);
+}
+
+/// Shortcut to concat N kids.  The chain returned is unbalanced to the right
+ref<Expr> ConcatExpr::createN(unsigned n_kids, const ref<Expr> kids[]) {
+  assert(n_kids > 0);
+  if (n_kids == 1)
+    return kids[0];
+  
+  ref<Expr> r = ConcatExpr::create(kids[n_kids-2], kids[n_kids-1]);
+  for (int i=n_kids-3; i>=0; i--)
+    r = ConcatExpr::create(kids[i], r);
+  return r;
+}
+
+/// Shortcut to concat 4 kids.  The chain returned is unbalanced to the right
+ref<Expr> ConcatExpr::create4(const ref<Expr> &kid1, const ref<Expr> &kid2,
+				     const ref<Expr> &kid3, const ref<Expr> &kid4) {
+  return ConcatExpr::create(kid1, ConcatExpr::create(kid2, ConcatExpr::create(kid3, kid4)));
+}
+
+/// Shortcut to concat 8 kids.  The chain returned is unbalanced to the right
+ref<Expr> ConcatExpr::create8(const ref<Expr> &kid1, const ref<Expr> &kid2,
+			      const ref<Expr> &kid3, const ref<Expr> &kid4,
+			      const ref<Expr> &kid5, const ref<Expr> &kid6,
+			      const ref<Expr> &kid7, const ref<Expr> &kid8) {
+  return ConcatExpr::create(kid1, ConcatExpr::create(kid2, ConcatExpr::create(kid3, 
+			      ConcatExpr::create(kid4, ConcatExpr::create4(kid5, kid6, kid7, kid8)))));
+}
+
+/***/
+
+ref<Expr> ExtractExpr::create(ref<Expr> expr, unsigned off, Width w) {
+  unsigned kw = expr.getWidth();
+  assert(w > 0 && off + w <= kw && "invalid extract");
+  
+  if (w == kw)
+    return expr;
+  else if (expr.isConstant()) {
+    return ConstantExpr::create(ints::trunc(expr.getConstantValue() >> off, w, kw), w);
+  } 
+  else 
+    // Extract(Concat)
+    if (ConcatExpr *ce = dyn_ref_cast<ConcatExpr>(expr)) {
+      // if the extract skips the right side of the concat
+      if (off >= ce->getRight().getWidth())
+	return ExtractExpr::create(ce->getLeft(), off - ce->getRight().getWidth(), w);
+      
+      // if the extract skips the left side of the concat
+      if (off + w <= ce->getRight().getWidth())
+	return ExtractExpr::create(ce->getRight(), off, w);
+
+      // E(C(x,y)) = C(E(x), E(y))
+      return ConcatExpr::create(ExtractExpr::create(ce->getKid(0), 0, w - ce->getKid(1).getWidth() + off),
+				ExtractExpr::create(ce->getKid(1), off, ce->getKid(1).getWidth() - off));
+    }
+  
+  return ExtractExpr::alloc(expr, off, w);
+}
+
+
+ref<Expr> ExtractExpr::createByteOff(ref<Expr> expr, unsigned offset, Width bits) {
+  return ExtractExpr::create(expr, 8*offset, bits);
+}
+
+/***/
+
+ref<Expr> ZExtExpr::create(const ref<Expr> &e, Width w) {
+  unsigned kBits = e.getWidth();
+  if (w == kBits) {
+    return e;
+  } else if (w < kBits) { // trunc
+    return ExtractExpr::createByteOff(e, 0, w);
+  } else {
+    if (e.isConstant()) {
+      return ConstantExpr::create(ints::zext(e.getConstantValue(), w, kBits),
+                                  w);
+    }
+    
+    return ZExtExpr::alloc(e, w);
+  }
+}
+
+ref<Expr> SExtExpr::create(const ref<Expr> &e, Width w) {
+  unsigned kBits = e.getWidth();
+  if (w == kBits) {
+    return e;
+  } else if (w < kBits) { // trunc
+    return ExtractExpr::createByteOff(e, 0, w);
+  } else {
+    if (e.isConstant()) {
+      return ConstantExpr::create(ints::sext(e.getConstantValue(), w, kBits),
+                                  w);
+    }
+    
+    return SExtExpr::alloc(e, w);
+  }
+}
+
+/***/
+
+static ref<Expr> AndExpr_create(Expr *l, Expr *r);
+static ref<Expr> XorExpr_create(Expr *l, Expr *r);
+
+static ref<Expr> EqExpr_createPartial(Expr *l, const ref<Expr> &cr);
+static ref<Expr> AndExpr_createPartialR(const ref<Expr> &cl, Expr *r);
+static ref<Expr> SubExpr_createPartialR(const ref<Expr> &cl, Expr *r);
+static ref<Expr> XorExpr_createPartialR(const ref<Expr> &cl, Expr *r);
+
+static ref<Expr> AddExpr_createPartialR(const ref<Expr> &cl, Expr *r) {
+  assert(cl.isConstant() && "non-constant passed in place of constant");
+  uint64_t value = cl.getConstantValue();
+  Expr::Width type = cl.getWidth();
+
+  if (type==Expr::Bool) {
+    return XorExpr_createPartialR(cl, r);
+  } else if (!value) {
+    return r;
+  } else {
+    Expr::Kind rk = r->getKind();
+    if (rk==Expr::Add && r->getKid(0).isConstant()) { // A + (B+c) == (A+B) + c
+      return AddExpr::create(AddExpr::create(cl, r->getKid(0)),
+                             r->getKid(1));
+    } else if (rk==Expr::Sub && r->getKid(0).isConstant()) { // A + (B-c) == (A+B) - c
+      return SubExpr::create(AddExpr::create(cl, r->getKid(0)),
+                             r->getKid(1));
+    } else {
+      return AddExpr::alloc(cl, r);
+    }
+  }
+}
+static ref<Expr> AddExpr_createPartial(Expr *l, const ref<Expr> &cr) {
+  return AddExpr_createPartialR(cr, l);
+}
+static ref<Expr> AddExpr_create(Expr *l, Expr *r) {
+  Expr::Width type = l->getWidth();
+
+  if (type == Expr::Bool) {
+    return XorExpr_create(l, r);
+  } else {
+    Expr::Kind lk = l->getKind(), rk = r->getKind();
+    if (lk==Expr::Add && l->getKid(0).isConstant()) { // (k+a)+b = k+(a+b)
+      return AddExpr::create(l->getKid(0),
+                             AddExpr::create(l->getKid(1), r));
+    } else if (lk==Expr::Sub && l->getKid(0).isConstant()) { // (k-a)+b = k+(b-a)
+      return AddExpr::create(l->getKid(0),
+                             SubExpr::create(r, l->getKid(1)));
+    } else if (rk==Expr::Add && r->getKid(0).isConstant()) { // a + (k+b) = k+(a+b)
+      return AddExpr::create(r->getKid(0),
+                             AddExpr::create(l, r->getKid(1)));
+    } else if (rk==Expr::Sub && r->getKid(0).isConstant()) { // a + (k-b) = k+(a-b)
+      return AddExpr::create(r->getKid(0),
+                             SubExpr::create(l, r->getKid(1)));
+    } else {
+      return AddExpr::alloc(l, r);
+    }
+  }  
+}
+
+static ref<Expr> SubExpr_createPartialR(const ref<Expr> &cl, Expr *r) {
+  assert(cl.isConstant() && "non-constant passed in place of constant");
+  Expr::Width type = cl.getWidth();
+
+  if (type==Expr::Bool) {
+    return XorExpr_createPartialR(cl, r);
+  } else {
+    Expr::Kind rk = r->getKind();
+    if (rk==Expr::Add && r->getKid(0).isConstant()) { // A - (B+c) == (A-B) - c
+      return SubExpr::create(SubExpr::create(cl, r->getKid(0)),
+                             r->getKid(1));
+    } else if (rk==Expr::Sub && r->getKid(0).isConstant()) { // A - (B-c) == (A-B) + c
+      return AddExpr::create(SubExpr::create(cl, r->getKid(0)),
+                             r->getKid(1));
+    } else {
+      return SubExpr::alloc(cl, r);
+    }
+  }
+}
+static ref<Expr> SubExpr_createPartial(Expr *l, const ref<Expr> &cr) {
+  assert(cr.isConstant() && "non-constant passed in place of constant");
+  uint64_t value = cr.getConstantValue();
+  Expr::Width width = cr.getWidth();
+  uint64_t nvalue = ints::sub(0, value, width);
+
+  return AddExpr_createPartial(l, ConstantExpr::create(nvalue, width));
+}
+static ref<Expr> SubExpr_create(Expr *l, Expr *r) {
+  Expr::Width type = l->getWidth();
+
+  if (type == Expr::Bool) {
+    return XorExpr_create(l, r);
+  } else if (*l==*r) {
+    return ref<Expr>(0, type);
+  } else {
+    Expr::Kind lk = l->getKind(), rk = r->getKind();
+    if (lk==Expr::Add && l->getKid(0).isConstant()) { // (k+a)-b = k+(a-b)
+      return AddExpr::create(l->getKid(0),
+                             SubExpr::create(l->getKid(1), r));
+    } else if (lk==Expr::Sub && l->getKid(0).isConstant()) { // (k-a)-b = k-(a+b)
+      return SubExpr::create(l->getKid(0),
+                             AddExpr::create(l->getKid(1), r));
+    } else if (rk==Expr::Add && r->getKid(0).isConstant()) { // a - (k+b) = (a-c) - k
+      return SubExpr::create(SubExpr::create(l, r->getKid(1)),
+                             r->getKid(0));
+    } else if (rk==Expr::Sub && r->getKid(0).isConstant()) { // a - (k-b) = (a+b) - k
+      return SubExpr::create(AddExpr::create(l, r->getKid(1)),
+                             r->getKid(0));
+    } else {
+      return SubExpr::alloc(l, r);
+    }
+  }  
+}
+
+static ref<Expr> MulExpr_createPartialR(const ref<Expr> &cl, Expr *r) {
+  assert(cl.isConstant() && "non-constant passed in place of constant");
+  uint64_t value = cl.getConstantValue();
+  Expr::Width type = cl.getWidth();
+
+  if (type == Expr::Bool) {
+    return AndExpr_createPartialR(cl, r);
+  } else if (value == 1) {
+    return r;
+  } else if (!value) {
+    return cl;
+  } else {
+    return MulExpr::alloc(cl, r);
+  }
+}
+static ref<Expr> MulExpr_createPartial(Expr *l, const ref<Expr> &cr) {
+  return MulExpr_createPartialR(cr, l);
+}
+static ref<Expr> MulExpr_create(Expr *l, Expr *r) {
+  Expr::Width type = l->getWidth();
+  
+  if (type == Expr::Bool) {
+    return AndExpr::alloc(l, r);
+  } else {
+    return MulExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> AndExpr_createPartial(Expr *l, const ref<Expr> &cr) {
+  assert(cr.isConstant() && "non-constant passed in place of constant");
+  uint64_t value = cr.getConstantValue();
+  Expr::Width width = cr.getWidth();;
+
+  if (value==ints::sext(1, width, 1)) {
+    return l;
+  } else if (!value) {
+    return cr;
+  } else {
+    return AndExpr::alloc(l, cr);
+  }
+}
+static ref<Expr> AndExpr_createPartialR(const ref<Expr> &cl, Expr *r) {
+  return AndExpr_createPartial(r, cl);
+}
+static ref<Expr> AndExpr_create(Expr *l, Expr *r) {
+  return AndExpr::alloc(l, r);
+}
+
+static ref<Expr> OrExpr_createPartial(Expr *l, const ref<Expr> &cr) {
+  assert(cr.isConstant() && "non-constant passed in place of constant");
+  uint64_t value = cr.getConstantValue();
+  Expr::Width width = cr.getWidth();
+
+  if (value == ints::sext(1, width, 1)) {
+    return cr;
+  } else if (!value) {
+    return l;
+  } else {
+    return OrExpr::alloc(l, cr);
+  }
+}
+static ref<Expr> OrExpr_createPartialR(const ref<Expr> &cl, Expr *r) {
+  return OrExpr_createPartial(r, cl);
+}
+static ref<Expr> OrExpr_create(Expr *l, Expr *r) {
+  return OrExpr::alloc(l, r);
+}
+
+static ref<Expr> XorExpr_createPartialR(const ref<Expr> &cl, Expr *r) {
+  assert(cl.isConstant() && "non-constant passed in place of constant");
+  uint64_t value = cl.getConstantValue();
+  Expr::Width type = cl.getWidth();
+
+  if (type==Expr::Bool) {
+    if (value) {
+      return EqExpr_createPartial(r, ConstantExpr::create(0, Expr::Bool));
+    } else {
+      return r;
+    }
+  } else if (!value) {
+    return r;
+  } else {
+    return XorExpr::alloc(cl, r);
+  }
+}
+
+static ref<Expr> XorExpr_createPartial(Expr *l, const ref<Expr> &cr) {
+  return XorExpr_createPartialR(cr, l);
+}
+static ref<Expr> XorExpr_create(Expr *l, Expr *r) {
+  return XorExpr::alloc(l, r);
+}
+
+static ref<Expr> UDivExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // r must be 1
+    return l;
+  } else{
+    return UDivExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> SDivExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // r must be 1
+    return l;
+  } else{
+    return SDivExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> URemExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // r must be 1
+    return ConstantExpr::create(0, Expr::Bool);
+  } else{
+    return URemExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> SRemExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // r must be 1
+    return ConstantExpr::create(0, Expr::Bool);
+  } else{
+    return SRemExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> ShlExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // l & !r
+    return AndExpr::create(l, Expr::createNot(r));
+  } else{
+    return ShlExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> LShrExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // l & !r
+    return AndExpr::create(l, Expr::createNot(r));
+  } else{
+    return LShrExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> AShrExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // l
+    return l;
+  } else{
+    return AShrExpr::alloc(l, r);
+  }
+}
+
+#define BCREATE_R(_e_op, _op, partialL, partialR) \
+ref<Expr>  _e_op ::create(const ref<Expr> &l, const ref<Expr> &r) { \
+  assert(l.getWidth()==r.getWidth() && "type mismatch"); \
+  if (l.isConstant()) {                                \
+    if (r.isConstant()) {                              \
+      Expr::Width width = l.getWidth(); \
+      uint64_t val = ints::_op(l.getConstantValue(),  \
+                               r.getConstantValue(), width);  \
+      return ConstantExpr::create(val, width); \
+    } else { \
+      return _e_op ## _createPartialR(l, r.get()); \
+    } \
+  } else if (r.isConstant()) {             \
+    return _e_op ## _createPartial(l.get(), r); \
+  } \
+  return _e_op ## _create(l.get(), r.get()); \
+}
+
+#define BCREATE(_e_op, _op) \
+ref<Expr>  _e_op ::create(const ref<Expr> &l, const ref<Expr> &r) { \
+  assert(l.getWidth()==r.getWidth() && "type mismatch"); \
+  if (l.isConstant()) {                                \
+    if (r.isConstant()) {                              \
+      Expr::Width width = l.getWidth(); \
+      uint64_t val = ints::_op(l.getConstantValue(), \
+                               r.getConstantValue(), width);  \
+      return ConstantExpr::create(val, width); \
+    } \
+  } \
+  return _e_op ## _create(l, r);                    \
+}
+
+BCREATE_R(AddExpr, add, AddExpr_createPartial, AddExpr_createPartialR)
+BCREATE_R(SubExpr, sub, SubExpr_createPartial, SubExpr_createPartialR)
+BCREATE_R(MulExpr, mul, MulExpr_createPartial, MulExpr_createPartialR)
+BCREATE_R(AndExpr, land, AndExpr_createPartial, AndExpr_createPartialR)
+BCREATE_R(OrExpr, lor, OrExpr_createPartial, OrExpr_createPartialR)
+BCREATE_R(XorExpr, lxor, XorExpr_createPartial, XorExpr_createPartialR)
+BCREATE(UDivExpr, udiv)
+BCREATE(SDivExpr, sdiv)
+BCREATE(URemExpr, urem)
+BCREATE(SRemExpr, srem)
+BCREATE(ShlExpr, shl)
+BCREATE(LShrExpr, lshr)
+BCREATE(AShrExpr, ashr)
+
+#define CMPCREATE(_e_op, _op) \
+ref<Expr>  _e_op ::create(const ref<Expr> &l, const ref<Expr> &r) { \
+  assert(l.getWidth()==r.getWidth() && "type mismatch"); \
+  if (l.isConstant()) {                                \
+    if (r.isConstant()) {                              \
+      Expr::Width width = l.getWidth(); \
+      uint64_t val = ints::_op(l.getConstantValue(), \
+                               r.getConstantValue(), width);  \
+      return ConstantExpr::create(val, Expr::Bool); \
+    } \
+  } \
+  return _e_op ## _create(l, r);                    \
+}
+
+#define CMPCREATE_T(_e_op, _op, _reflexive_e_op, partialL, partialR) \
+ref<Expr>  _e_op ::create(const ref<Expr> &l, const ref<Expr> &r) { \
+  assert(l.getWidth()==r.getWidth() && "type mismatch"); \
+  if (l.isConstant()) {                                \
+    if (r.isConstant()) {                              \
+      Expr::Width width = l.getWidth(); \
+      uint64_t val = ints::_op(l.getConstantValue(), \
+                               r.getConstantValue(), width);  \
+      return ConstantExpr::create(val, Expr::Bool); \
+    } else { \
+      return partialR(l, r.get()); \
+    } \
+  } else if (r.isConstant()) {                  \
+    return partialL(l.get(), r); \
+  } else { \
+    return _e_op ## _create(l.get(), r.get()); \
+  } \
+}
+  
+
+static ref<Expr> EqExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l == r) {
+    return ref<Expr>(1, Expr::Bool);
+  } else {
+    return EqExpr::alloc(l, r);
+  }
+}
+
+
+/// Tries to optimize EqExpr cl == rd, where cl is a ConstantExpr and
+/// rd a ReadExpr.  If rd is a read into an all-constant array,
+/// returns a disjunction of equalities on the index.  Otherwise,
+/// returns the initial equality expression. 
+static ref<Expr> TryConstArrayOpt(const ref<Expr> &cl, 
+				  ReadExpr *rd) {
+  assert(cl.isConstant() && "constant expression required");
+  assert(rd->getKind() == Expr::Read && "read expression required");
+  
+  uint64_t ct = cl.getConstantValue();
+  ref<Expr> first_idx_match;
+
+  // number of positions in the array that contain value ct
+  unsigned matches = 0;
+
+  //llvm::cerr << "Size updates/root: " << rd->updates.getSize() << " / " << (rd->updates.root)->size << "\n";
+
+  // for now, just assume standard "flushing" of a concrete array,
+  // where the concrete array has one update for each index, in order
+  bool all_const = true;
+  if (rd->updates.getSize() == rd->updates.root->size) {
+    unsigned k = rd->updates.getSize();
+    for (const UpdateNode *un = rd->updates.head; un; un = un->next) {
+      assert(k > 0);
+      k--;
+
+      ref<Expr> idx = un->index;
+      ref<Expr> val = un->value;
+      if (!idx.isConstant() || !val.isConstant()) {
+	all_const = false;
+	//llvm::cerr << "Idx or val not constant\n";
+	break;
+      }
+      else {
+	if (idx.getConstantValue() != k) {
+	  all_const = false;
+	  //llvm::cerr << "Wrong constant\n";
+	  break;
+	}
+	if (val.getConstantValue() == ct) {
+	  matches++;
+	  if (matches == 1)
+	    first_idx_match = un->index;
+	}
+      }
+    }
+  }
+  else all_const = false;
+  
+  if (all_const && matches <= 100) {
+    // apply optimization
+    //llvm::cerr << "\n\n=== Applying const array optimization ===\n\n";
+
+    if (matches == 0)
+      return ref<Expr>(0, Expr::Bool);
+
+    ref<Expr> res = EqExpr::create(first_idx_match, rd->index);
+    if (matches == 1)
+      return res;
+    
+    for (const UpdateNode *un = rd->updates.head; un; un = un->next) {
+      if (un->index != first_idx_match && un->value.getConstantValue() == ct) {
+	ref<Expr> curr_eq = EqExpr::create(un->index, rd->index);
+	res = OrExpr::create(curr_eq, res);
+      }
+    }
+    
+    return res;
+  }
+
+  return EqExpr_create(cl, ref<Expr>(rd));
+}
+
+
+static ref<Expr> EqExpr_createPartialR(const ref<Expr> &cl, Expr *r) {  
+  assert(cl.isConstant() && "non-constant passed in place of constant");
+  uint64_t value = cl.getConstantValue();
+  Expr::Width width = cl.getWidth();
+
+  Expr::Kind rk = r->getKind();
+  if (width == Expr::Bool) {
+    if (value) {
+      return r;
+    } else {
+      // 0 != ...
+      
+      if (rk == Expr::Eq) {
+        const EqExpr *ree = static_ref_cast<EqExpr>(r);
+
+        // eliminate double negation
+        if (ree->left.isConstant() &&
+            ree->left.getWidth()==Expr::Bool) {
+          assert(!ree->left.getConstantValue());
+          return ree->right;
+        }
+      } else if (rk == Expr::Or) {
+        const OrExpr *roe = static_ref_cast<OrExpr>(r);
+
+        // transform not(or(a,b)) to and(not a, not b)
+        return AndExpr::create(Expr::createNot(roe->left),
+                               Expr::createNot(roe->right));
+      }
+    }
+  } else if (rk == Expr::SExt) {
+    // (sext(a,T)==c) == (a==c)
+    const SExtExpr *see = static_ref_cast<SExtExpr>(r);
+    Expr::Width fromBits = see->src.getWidth();
+    uint64_t trunc = bits64::truncateToNBits(value, fromBits);
+
+    // pathological check, make sure it is possible to
+    // sext to this value *from any value*
+    if (value == ints::sext(trunc, width, fromBits)) {
+      return EqExpr::create(see->src, ConstantExpr::create(trunc, fromBits));
+    } else {
+      return ConstantExpr::create(0, Expr::Bool);
+    }
+  } else if (rk == Expr::ZExt) {
+    // (zext(a,T)==c) == (a==c)
+    const ZExtExpr *zee = static_ref_cast<ZExtExpr>(r);
+    Expr::Width fromBits = zee->src.getWidth();
+    uint64_t trunc = bits64::truncateToNBits(value, fromBits);
+    
+    // pathological check, make sure it is possible to
+    // zext to this value *from any value*
+    if (value == ints::zext(trunc, width, fromBits)) {
+      return EqExpr::create(zee->src, ConstantExpr::create(trunc, fromBits));
+    } else {
+      return ConstantExpr::create(0, Expr::Bool);
+    }
+  } else if (rk==Expr::Add) {
+    const AddExpr *ae = static_ref_cast<AddExpr>(r);
+    if (ae->left.isConstant()) {
+      // c0 = c1 + b => c0 - c1 = b
+      return EqExpr_createPartialR(SubExpr::create(cl, ae->left),
+                                   ae->right.get());
+    }
+  } else if (rk==Expr::Sub) {
+    const SubExpr *se = static_ref_cast<SubExpr>(r);
+    if (se->left.isConstant()) {
+      // c0 = c1 - b => c1 - c0 = b
+      return EqExpr_createPartialR(SubExpr::create(se->left, cl),
+                                   se->right.get());
+    }
+  } else if (rk == Expr::Read && ConstArrayOpt) {
+    return TryConstArrayOpt(cl, static_cast<ReadExpr*>(r));
+  }
+    
+  return EqExpr_create(cl, r);
+}
+
+static ref<Expr> EqExpr_createPartial(Expr *l, const ref<Expr> &cr) {  
+  return EqExpr_createPartialR(cr, l);
+}
+  
+ref<Expr> NeExpr::create(const ref<Expr> &l, const ref<Expr> &r) {
+  return EqExpr::create(ConstantExpr::create(0, Expr::Bool),
+                        EqExpr::create(l, r));
+}
+
+ref<Expr> UgtExpr::create(const ref<Expr> &l, const ref<Expr> &r) {
+  return UltExpr::create(r, l);
+}
+ref<Expr> UgeExpr::create(const ref<Expr> &l, const ref<Expr> &r) {
+  return UleExpr::create(r, l);
+}
+
+ref<Expr> SgtExpr::create(const ref<Expr> &l, const ref<Expr> &r) {
+  return SltExpr::create(r, l);
+}
+ref<Expr> SgeExpr::create(const ref<Expr> &l, const ref<Expr> &r) {
+  return SleExpr::create(r, l);
+}
+
+static ref<Expr> UltExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  Expr::Width t = l.getWidth();
+  if (t == Expr::Bool) { // !l && r
+    return AndExpr::create(Expr::createNot(l), r);
+  } else {
+    if (r.isConstant()) {      
+      uint64_t value = r.getConstantValue();
+      if (value <= 8) {
+        ref<Expr> res(0,Expr::Bool);
+        for (unsigned i=0; i<value; i++) {
+          res = OrExpr::create(EqExpr::create(l, ref<Expr>(i,t)), res);
+        }
+        //        llvm::cerr << l << "<" << r << "  <=>  " << res << "\n";
+        return res;
+      }
+    }
+    return UltExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> UleExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // !(l && !r)
+    return OrExpr::create(Expr::createNot(l), r);
+  } else {
+    return UleExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> SltExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // l && !r
+    return AndExpr::create(l, Expr::createNot(r));
+  } else {
+    return SltExpr::alloc(l, r);
+  }
+}
+
+static ref<Expr> SleExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
+  if (l.getWidth() == Expr::Bool) { // !(!l && r)
+    return OrExpr::create(l, Expr::createNot(r));
+  } else {
+    return SleExpr::alloc(l, r);
+  }
+}
+
+CMPCREATE_T(EqExpr, eq, EqExpr, EqExpr_createPartial, EqExpr_createPartialR)
+CMPCREATE(UltExpr, ult)
+CMPCREATE(UleExpr, ule)
+CMPCREATE(SltExpr, slt)
+CMPCREATE(SleExpr, sle)
diff --git a/lib/Expr/ExprEvaluator.cpp b/lib/Expr/ExprEvaluator.cpp
new file mode 100644
index 00000000..102387e1
--- /dev/null
+++ b/lib/Expr/ExprEvaluator.cpp
@@ -0,0 +1,74 @@
+//===-- ExprEvaluator.cpp -------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/util/ExprEvaluator.h"
+
+using namespace klee;
+
+ExprVisitor::Action ExprEvaluator::evalRead(const UpdateList &ul,
+                                            unsigned index) {
+  for (const UpdateNode *un=ul.head; un; un=un->next) {
+    ref<Expr> ui = visit(un->index);
+    
+    if (ui.isConstant()) {
+      if (ui.getConstantValue() == index)
+        return Action::changeTo(visit(un->value));
+    } else {
+      // update index is unknown, so may or may not be index, we
+      // cannot guarantee value. we can rewrite to read at this
+      // version though (mostly for debugging).
+      
+      UpdateList fwd(ul.root, un, 0);
+      return Action::changeTo(ReadExpr::create(fwd, 
+                                               ref<Expr>(index,Expr::Int32)));
+    }
+  }
+  
+  return Action::changeTo(getInitialValue(*ul.root, index));
+}
+
+ExprVisitor::Action ExprEvaluator::visitRead(const ReadExpr &re) {
+  ref<Expr> v = visit(re.index);
+  
+  if (v.isConstant()) {
+    return evalRead(re.updates, v.getConstantValue());
+  } else {
+    return Action::doChildren();
+  }
+}
+
+// we need to check for div by zero during partial evaluation,
+// if this occurs then simply ignore the 0 divisor and use the
+// original expression.
+ExprVisitor::Action ExprEvaluator::protectedDivOperation(const BinaryExpr &e) {
+  ref<Expr> kids[2] = { visit(e.left),
+                        visit(e.right) };
+
+  if (kids[1].isConstant() && !kids[1].getConstantValue())
+    kids[1] = e.right;
+
+  if (kids[0]!=e.left || kids[1]!=e.right) {
+    return Action::changeTo(e.rebuild(kids));
+  } else {
+    return Action::skipChildren();
+  }
+}
+
+ExprVisitor::Action ExprEvaluator::visitUDiv(const UDivExpr &e) { 
+  return protectedDivOperation(e); 
+}
+ExprVisitor::Action ExprEvaluator::visitSDiv(const SDivExpr &e) { 
+  return protectedDivOperation(e); 
+}
+ExprVisitor::Action ExprEvaluator::visitURem(const URemExpr &e) { 
+  return protectedDivOperation(e); 
+}
+ExprVisitor::Action ExprEvaluator::visitSRem(const SRemExpr &e) { 
+  return protectedDivOperation(e); 
+}
diff --git a/lib/Expr/ExprPPrinter.cpp b/lib/Expr/ExprPPrinter.cpp
new file mode 100644
index 00000000..dc7f4f64
--- /dev/null
+++ b/lib/Expr/ExprPPrinter.cpp
@@ -0,0 +1,478 @@
+//===-- ExprPPrinter.cpp -   ----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/util/ExprPPrinter.h"
+
+#include "klee/Constraints.h"
+
+#include "llvm/Support/CommandLine.h"
+
+#include <map>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+using namespace klee;
+
+namespace {
+  llvm::cl::opt<bool>
+  PCWidthAsArg("pc-width-as-arg", llvm::cl::init(true));
+
+  llvm::cl::opt<bool>
+  PCAllWidths("pc-all-widths", llvm::cl::init(false));
+
+  llvm::cl::opt<bool>
+  PCPrefixWidth("pc-prefix-width", llvm::cl::init(true));
+
+  llvm::cl::opt<bool>
+  PCMultibyteReads("pc-multibyte-reads", llvm::cl::init(true));
+
+  llvm::cl::opt<bool>
+  PCAllConstWidths("pc-all-const-widths",  llvm::cl::init(false));
+}
+
+/// PrintContext - Helper class for storing extra information for
+/// the pretty printer.
+class PrintContext {
+private:
+  std::ostream &os;
+  std::stringstream ss;
+  std::string newline;
+
+public:
+  /// Number of characters on the current line.
+  unsigned pos;
+
+public:
+  PrintContext(std::ostream &_os) : os(_os), newline("\n"), pos(0) {}
+
+  void setNewline(const std::string &_newline) {
+    newline = _newline;
+  }
+
+  void breakLine(unsigned indent=0) {
+    os << newline;
+    if (indent)
+      os << std::setw(indent) << ' ';
+    pos = indent;
+  }
+
+  /// write - Output a string to the stream and update the
+  /// position. The stream should not have any newlines.
+  void write(const std::string &s) {
+    os << s;
+    pos += s.length();
+  }
+
+  template <typename T>
+  PrintContext &operator<<(T elt) {
+    ss.str("");
+    ss << elt;
+    write(ss.str());
+    return *this;
+  }
+};
+
+class PPrinter : public ExprPPrinter {
+  std::map<ref<Expr>, unsigned> bindings;
+  std::map<const UpdateNode*, unsigned> updateBindings;
+  std::set< ref<Expr> > couldPrint, shouldPrint;
+  std::set<const UpdateNode*> couldPrintUpdates, shouldPrintUpdates;
+  std::ostream &os;
+  unsigned counter;
+  unsigned updateCounter;
+  bool hasScan;
+  std::string newline;
+
+  /// shouldPrintWidth - Predicate for whether this expression should
+  /// be printed with its width.
+  bool shouldPrintWidth(ref<Expr> e) {
+    if (PCAllWidths)
+      return true;
+    return e.getWidth() != Expr::Bool;
+  }
+
+  bool isVerySimple(const ref<Expr> &e) { 
+    return e.isConstant() || bindings.find(e)!=bindings.end();
+  }
+
+  bool isVerySimpleUpdate(const UpdateNode *un) {
+    return !un || updateBindings.find(un)!=updateBindings.end();
+  }
+
+
+  // document me!
+  bool isSimple(const ref<Expr> &e) { 
+    if (isVerySimple(e)) {
+      return true;
+    } else if (const ReadExpr *re = dyn_ref_cast<ReadExpr>(e)) {
+      return isVerySimple(re->index) && isVerySimpleUpdate(re->updates.head);
+    } else {
+      Expr *ep = e.get();
+      for (unsigned i=0; i<ep->getNumKids(); i++)
+        if (!isVerySimple(ep->getKid(i)))
+          return false;
+      return true;
+    }
+  }
+
+  bool hasSimpleKids(const Expr *ep) {
+      for (unsigned i=0; i<ep->getNumKids(); i++)
+        if (!isSimple(ep->getKid(i)))
+          return false;
+      return true;
+  }
+  
+  void scanUpdate(const UpdateNode *un) {
+    if (un) {
+      if (couldPrintUpdates.insert(un).second) {
+        scanUpdate(un->next);
+        scan1(un->index);
+        scan1(un->value);
+      } else {
+        shouldPrintUpdates.insert(un);
+      }
+    }
+  }
+
+  void scan1(const ref<Expr> &e) {
+    if (!e.isConstant()) {
+      if (couldPrint.insert(e).second) {
+        Expr *ep = e.get();
+        for (unsigned i=0; i<ep->getNumKids(); i++)
+          scan1(ep->getKid(i));
+        if (const ReadExpr *re = dyn_ref_cast<ReadExpr>(e)) 
+          scanUpdate(re->updates.head);
+      } else {
+        shouldPrint.insert(e);
+      }
+    }
+  }
+
+  void printUpdateList(const UpdateList &updates, PrintContext &PC) {
+    const UpdateNode *head = updates.head;
+
+    // Special case empty list.
+    if (!head) {
+      if (updates.isRooted) {
+        PC << "arr" << updates.root->id;
+      } else {
+        PC << "[]";
+      }
+      return;
+    }
+
+    // FIXME: Explain this breaking policy.
+    bool openedList = false, nextShouldBreak = false;
+    unsigned outerIndent = PC.pos;
+    unsigned middleIndent = 0;
+    for (const UpdateNode *un = head; un; un = un->next) {      
+      // We are done if we hit the cache.
+      std::map<const UpdateNode*, unsigned>::iterator it = 
+        updateBindings.find(un);
+      if (it!=updateBindings.end()) {
+        if (openedList)
+          PC << "] @ ";
+        PC << "U" << it->second;
+        return;
+      } else if (!hasScan || shouldPrintUpdates.count(un)) {
+        if (openedList)
+          PC << "] @";
+        if (un != head)
+          PC.breakLine(outerIndent);
+        PC << "U" << updateCounter << ":"; 
+        updateBindings.insert(std::make_pair(un, updateCounter++));
+        openedList = nextShouldBreak = false;
+     }
+    
+      if (!openedList) {
+        openedList = 1;
+        PC << '[';
+        middleIndent = PC.pos;
+      } else {
+        PC << ',';
+        printSeparator(PC, !nextShouldBreak, middleIndent);
+      }
+      //PC << "(=";
+      //unsigned innerIndent = PC.pos;
+      print(un->index, PC);
+      //printSeparator(PC, isSimple(un->index), innerIndent);
+      PC << "=";
+      print(un->value, PC);
+      //PC << ')';
+      
+      nextShouldBreak = !(un->index.isConstant() && un->value.isConstant());
+    }
+
+    if (openedList)
+      PC << ']';
+
+    if (updates.isRooted)
+      PC << " @ arr" << updates.root->id;
+  }
+
+  void printWidth(PrintContext &PC, ref<Expr> e) {
+    if (!shouldPrintWidth(e))
+      return;
+
+    if (PCWidthAsArg) {
+      PC << ' ';
+      if (PCPrefixWidth)
+        PC << 'w';
+    }
+
+    PC << e.getWidth();
+  }
+
+  /// hasOrderedReads - True iff all children are reads with
+  /// consecutive offsets according to the given \arg stride.
+  bool hasOrderedReads(const Expr *ep, int stride) {
+    const ReadExpr *base = dyn_ref_cast<ReadExpr>(ep->getKid(0));
+    if (!base)
+      return false;
+
+    // Get stride expr in proper index width.
+    Expr::Width idxWidth = base->index.getWidth();
+    ref<Expr> strideExpr(stride, idxWidth), offset(0, idxWidth);
+    for (unsigned i=1; i<ep->getNumKids(); ++i) {
+      const ReadExpr *re = dyn_ref_cast<ReadExpr>(ep->getKid(i));
+      if (!re) 
+        return false;
+
+      // Check if the index follows the stride. 
+      // FIXME: How aggressive should this be simplified. The
+      // canonicalizing builder is probably the right choice, but this
+      // is yet another area where we would really prefer it to be
+      // global or else use static methods.
+      offset = AddExpr::create(offset, strideExpr);
+      if (SubExpr::create(re->index, base->index) != offset)
+        return false;
+    }
+
+    return true;
+  }
+
+  /// hasAllByteReads - True iff all children are byte level reads.
+  bool hasAllByteReads(const Expr *ep) {
+    for (unsigned i=0; i<ep->getNumKids(); ++i) {
+      const ReadExpr *re = dyn_ref_cast<ReadExpr>(ep->getKid(i));
+      if (!re || re->getWidth() != Expr::Int8)
+        return false;
+    }
+    return true;
+  }
+
+  void printRead(const ReadExpr *re, PrintContext &PC, unsigned indent) {
+    print(re->index, PC);
+    printSeparator(PC, isVerySimple(re->index), indent);
+    printUpdateList(re->updates, PC);
+  }
+
+  void printExtract(const ExtractExpr *ee, PrintContext &PC, unsigned indent) {
+    PC << ee->offset << ' ';
+    print(ee->expr, PC);
+  }
+
+  void printExpr(const Expr *ep, PrintContext &PC, unsigned indent, bool printConstWidth=false) {
+    bool simple = hasSimpleKids(ep);
+    
+    print(ep->getKid(0), PC);
+    for (unsigned i=1; i<ep->getNumKids(); i++) {
+      printSeparator(PC, simple, indent);
+      print(ep->getKid(i), PC, printConstWidth);
+    }
+  }
+
+public:
+  PPrinter(std::ostream &_os) : os(_os), newline("\n") {
+    reset();
+  }
+
+  void setNewline(const std::string &_newline) {
+    newline = _newline;
+  }
+
+  void reset() {
+    counter = 0;
+    updateCounter = 0;
+    hasScan = false;
+    bindings.clear();
+    updateBindings.clear();
+    couldPrint.clear();
+    shouldPrint.clear();
+    couldPrintUpdates.clear();
+    shouldPrintUpdates.clear();
+  }
+
+  void scan(const ref<Expr> &e) {
+    hasScan = true;
+    scan1(e);
+  }
+
+  void print(const ref<Expr> &e, unsigned level=0) {
+    PrintContext PC(os);
+    PC.pos = level;
+    print(e, PC);
+  }
+
+  void printConst(const ref<Expr> &e, PrintContext &PC, bool printWidth) {
+    assert(e.isConstant());
+
+    if (e.getWidth() == Expr::Bool)
+      PC << (e.getConstantValue() ? "true" : "false");
+    else {
+      if (PCAllConstWidths)
+	printWidth = true;
+    
+      if (printWidth)
+	PC << "(w" << e.getWidth() << " ";
+
+      PC << e.getConstantValue();
+
+      if (printWidth)
+	PC << ")";
+    }    
+  }
+
+  void print(const ref<Expr> &e, PrintContext &PC, bool printConstWidth=false) {
+    if (e.isConstant()) 
+      printConst(e, PC, printConstWidth);
+    else {
+      std::map<ref<Expr>, unsigned>::iterator it = bindings.find(e);
+      if (it!=bindings.end()) {
+        PC << 'N' << it->second;
+      } else {
+        if (!hasScan || shouldPrint.count(e)) {
+          PC << 'N' << counter << ':';
+          bindings.insert(std::make_pair(e, counter++));
+        }
+
+        // Detect Not.
+        // FIXME: This should be in common code.
+        if (const EqExpr *ee = dyn_ref_cast<EqExpr>(e)) {
+          if (ee->left == ref<Expr>(false, Expr::Bool)) {
+            PC << "(Not";
+            printWidth(PC, e);
+            PC << ' ';
+            // FIXME: This is a boom if right is a constant.
+            print(ee->right, PC);
+            PC << ')';
+            return;
+          }
+        }
+
+        // Detect multibyte reads.
+        // FIXME: Hrm. One problem with doing this is that we are
+        // masking the sharing of the indices which aren't
+        // visible. Need to think if this matters... probably not
+        // because if they are offset reads then its either constant,
+        // or they are (base + offset) and base will get printed with
+        // a declaration.
+        if (PCMultibyteReads && e.getKind() == Expr::Concat) {
+          const Expr *ep = e.get();
+          if (hasAllByteReads(ep)) {
+            bool isMSB = hasOrderedReads(ep, 1);
+            if (isMSB || hasOrderedReads(ep, -1)) {
+              PC << "(Read" << (isMSB ? "MSB" : "LSB");
+              printWidth(PC, e);
+              PC << ' ';
+              unsigned firstIdx = isMSB ? 0 : ep->getNumKids()-1;
+              printRead(static_ref_cast<ReadExpr>(ep->getKid(firstIdx)), 
+                        PC, PC.pos);
+              PC << ')';
+              return;
+            }
+          }
+        }
+
+	PC << '(' << e.getKind();
+        printWidth(PC, e);
+        PC << ' ';
+
+        // Indent at first argument and dispatch to appropriate print
+        // routine for exprs which require special handling.
+        unsigned indent = PC.pos;
+        if (const ReadExpr *re = dyn_ref_cast<ReadExpr>(e)) {
+          printRead(re, PC, indent);
+        } else if (const ExtractExpr *ee = dyn_ref_cast<ExtractExpr>(e)) {
+          printExtract(ee, PC, indent);
+        } else if (e.getKind() == Expr::Concat || e.getKind() == Expr::SExt)
+	  printExpr(e.get(), PC, indent, true);
+	else
+          printExpr(e.get(), PC, indent);	
+        PC << ")";
+      }
+    }
+  }
+
+  /* Public utility functions */
+
+  void printSeparator(PrintContext &PC, bool simple, unsigned indent) {
+    if (simple) {
+      PC << ' ';
+    } else {
+      PC.breakLine(indent);
+    }
+  }
+};
+
+ExprPPrinter *klee::ExprPPrinter::create(std::ostream &os) {
+  return new PPrinter(os);
+}
+
+void ExprPPrinter::printOne(std::ostream &os,
+                            const char *message, 
+                            const ref<Expr> &e) {
+  PPrinter p(os);
+  p.scan(e);
+
+  // FIXME: Need to figure out what to do here. Probably print as a
+  // "forward declaration" with whatever syntax we pick for that.
+  PrintContext PC(os);
+  PC << message << ": ";
+  p.print(e, PC);
+  PC.breakLine();
+}
+
+void ExprPPrinter::printConstraints(std::ostream &os,
+                                    const ConstraintManager &constraints) {
+  printQuery(os, constraints, ref<Expr>(false, Expr::Bool));
+}
+
+void ExprPPrinter::printQuery(std::ostream &os,
+                              const ConstraintManager &constraints,
+                              const ref<Expr> &q) {
+  PPrinter p(os);
+  
+  for (ConstraintManager::const_iterator it = constraints.begin(),
+         ie = constraints.end(); it != ie; ++it)
+    p.scan(*it);
+  p.scan(q);
+
+  PrintContext PC(os);
+  PC << "(query [";
+  
+  // Ident at constraint list;
+  unsigned indent = PC.pos;
+  for (ConstraintManager::const_iterator it = constraints.begin(),
+         ie = constraints.end(); it != ie;) {
+    p.print(*it, PC);
+    ++it;
+    if (it != ie)
+      PC.breakLine(indent);
+  }
+  PC << ']';
+
+  p.printSeparator(PC, constraints.empty(), indent-1);
+  p.print(q, PC);
+
+  PC << ')';
+  PC.breakLine();
+}
diff --git a/lib/Expr/ExprUtil.cpp b/lib/Expr/ExprUtil.cpp
new file mode 100644
index 00000000..f74b519f
--- /dev/null
+++ b/lib/Expr/ExprUtil.cpp
@@ -0,0 +1,127 @@
+//===-- ExprUtil.cpp ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/util/ExprUtil.h"
+#include "klee/util/ExprHashMap.h"
+
+#include "klee/Expr.h"
+
+#include "klee/util/ExprVisitor.h"
+
+#include <set>
+
+using namespace klee;
+
+void klee::findReads(ref<Expr> e, 
+                     bool visitUpdates,
+                     std::vector< ref<ReadExpr> > &results) {
+  // Invariant: \forall_{i \in stack} !i.isConstant() && i \in visited 
+  std::vector< ref<Expr> > stack;
+  ExprHashSet visited;
+  std::set<const UpdateNode *> updates;
+  
+  if (!e.isConstant()) {
+    visited.insert(e);
+    stack.push_back(e);
+  }
+
+  while (!stack.empty()) {
+    ref<Expr> top = stack.back();
+    stack.pop_back();
+
+    if (ReadExpr *re = dyn_ref_cast<ReadExpr>(top)) {
+      // We memoized so can just add to list without worrying about
+      // repeats.
+      results.push_back(re);
+
+      if (!re->index.isConstant() &&
+          visited.insert(re->index).second)
+        stack.push_back(re->index);
+      
+      if (visitUpdates) {
+        // XXX this is probably suboptimal. We want to avoid a potential
+        // explosion traversing update lists which can be quite
+        // long. However, it seems silly to hash all of the update nodes
+        // especially since we memoize all the expr results anyway. So
+        // we take a simple approach of memoizing the results for the
+        // head, which often will be shared among multiple nodes.
+        if (updates.insert(re->updates.head).second) {
+          for (const UpdateNode *un=re->updates.head; un; un=un->next) {
+            if (!un->index.isConstant() &&
+                visited.insert(un->index).second)
+              stack.push_back(un->index);
+            if (!un->value.isConstant() &&
+                visited.insert(un->value).second)
+              stack.push_back(un->value);
+          }
+        }
+      }
+    } else if (!top.isConstant()) {
+      Expr *e = top.get();
+      for (unsigned i=0; i<e->getNumKids(); i++) {
+        ref<Expr> k = e->getKid(i);
+        if (!k.isConstant() &&
+            visited.insert(k).second)
+          stack.push_back(k);
+      }
+    }
+  }
+}
+
+///
+
+namespace klee {
+
+class SymbolicObjectFinder : public ExprVisitor {
+protected:
+  Action visitRead(const ReadExpr &re) {
+    const UpdateList &ul = re.updates;
+
+    // XXX should we memo better than what ExprVisitor is doing for us?
+    for (const UpdateNode *un=ul.head; un; un=un->next) {
+      visit(un->index);
+      visit(un->value);
+    }
+
+    if (ul.isRooted)
+      if (results.insert(ul.root).second)
+        objects.push_back(ul.root);
+
+    return Action::doChildren();
+  }
+
+public:
+  std::set<const Array*> results;
+  std::vector<const Array*> &objects;
+  
+  SymbolicObjectFinder(std::vector<const Array*> &_objects)
+    : objects(_objects) {}
+};
+
+}
+
+template<typename InputIterator>
+void klee::findSymbolicObjects(InputIterator begin, 
+                               InputIterator end,
+                               std::vector<const Array*> &results) {
+  SymbolicObjectFinder of(results);
+  for (; begin!=end; ++begin)
+    of.visit(*begin);
+}
+
+void klee::findSymbolicObjects(ref<Expr> e,
+                               std::vector<const Array*> &results) {
+  findSymbolicObjects(&e, &e+1, results);
+}
+
+typedef std::vector< ref<Expr> >::iterator A;
+template void klee::findSymbolicObjects<A>(A, A, std::vector<const Array*> &);
+
+typedef std::set< ref<Expr> >::iterator B;
+template void klee::findSymbolicObjects<B>(B, B, std::vector<const Array*> &);
diff --git a/lib/Expr/ExprVisitor.cpp b/lib/Expr/ExprVisitor.cpp
new file mode 100644
index 00000000..b15cdffa
--- /dev/null
+++ b/lib/Expr/ExprVisitor.cpp
@@ -0,0 +1,253 @@
+//===-- ExprVisitor.cpp ---------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Expr.h"
+#include "klee/util/ExprVisitor.h"
+
+#include "llvm/Support/CommandLine.h"
+
+namespace {
+  llvm::cl::opt<bool>
+  UseVisitorHash("use-visitor-hash", 
+                 llvm::cl::desc("Use hash-consing during expr visitation."),
+                 llvm::cl::init(true));
+}
+
+using namespace klee;
+
+ref<Expr> ExprVisitor::visit(const ref<Expr> &e) {
+  if (!UseVisitorHash || e.isConstant()) {
+    return visitActual(e);
+  } else {
+    visited_ty::iterator it = visited.find(e);
+
+    if (it!=visited.end()) {
+      return it->second;
+    } else {
+      ref<Expr> res = visitActual(e);
+      visited.insert(std::make_pair(e, res));
+      return res;
+    }
+  }
+}
+
+ref<Expr> ExprVisitor::visitActual(const ref<Expr> &e) {
+  if (e.isConstant()) {    
+    return e;
+  } else {
+    Expr &ep = *e.get();
+
+    Action res = visitExpr(ep);
+    switch(res.kind) {
+    case Action::DoChildren:
+      // continue with normal action
+      break;
+    case Action::SkipChildren:
+      return e;
+    case Action::ChangeTo:
+      return res.argument;
+    }
+
+    switch(ep.getKind()) {
+    case Expr::NotOptimized: res = visitNotOptimized(static_cast<NotOptimizedExpr&>(ep)); break;
+    case Expr::Read: res = visitRead(static_cast<ReadExpr&>(ep)); break;
+    case Expr::Select: res = visitSelect(static_cast<SelectExpr&>(ep)); break;
+    case Expr::Concat: res = visitConcat(static_cast<ConcatExpr&>(ep)); break;
+    case Expr::Extract: res = visitExtract(static_cast<ExtractExpr&>(ep)); break;
+    case Expr::ZExt: res = visitZExt(static_cast<ZExtExpr&>(ep)); break;
+    case Expr::SExt: res = visitSExt(static_cast<SExtExpr&>(ep)); break;
+    case Expr::Add: res = visitAdd(static_cast<AddExpr&>(ep)); break;
+    case Expr::Sub: res = visitSub(static_cast<SubExpr&>(ep)); break;
+    case Expr::Mul: res = visitMul(static_cast<MulExpr&>(ep)); break;
+    case Expr::UDiv: res = visitUDiv(static_cast<UDivExpr&>(ep)); break;
+    case Expr::SDiv: res = visitSDiv(static_cast<SDivExpr&>(ep)); break;
+    case Expr::URem: res = visitURem(static_cast<URemExpr&>(ep)); break;
+    case Expr::SRem: res = visitSRem(static_cast<SRemExpr&>(ep)); break;
+    case Expr::And: res = visitAnd(static_cast<AndExpr&>(ep)); break;
+    case Expr::Or: res = visitOr(static_cast<OrExpr&>(ep)); break;
+    case Expr::Xor: res = visitXor(static_cast<XorExpr&>(ep)); break;
+    case Expr::Shl: res = visitShl(static_cast<ShlExpr&>(ep)); break;
+    case Expr::LShr: res = visitLShr(static_cast<LShrExpr&>(ep)); break;
+    case Expr::AShr: res = visitAShr(static_cast<AShrExpr&>(ep)); break;
+    case Expr::Eq: res = visitEq(static_cast<EqExpr&>(ep)); break;
+    case Expr::Ne: res = visitNe(static_cast<NeExpr&>(ep)); break;
+    case Expr::Ult: res = visitUlt(static_cast<UltExpr&>(ep)); break;
+    case Expr::Ule: res = visitUle(static_cast<UleExpr&>(ep)); break;
+    case Expr::Ugt: res = visitUgt(static_cast<UgtExpr&>(ep)); break;
+    case Expr::Uge: res = visitUge(static_cast<UgeExpr&>(ep)); break;
+    case Expr::Slt: res = visitSlt(static_cast<SltExpr&>(ep)); break;
+    case Expr::Sle: res = visitSle(static_cast<SleExpr&>(ep)); break;
+    case Expr::Sgt: res = visitSgt(static_cast<SgtExpr&>(ep)); break;
+    case Expr::Sge: res = visitSge(static_cast<SgeExpr&>(ep)); break;
+    case Expr::Constant:
+    default:
+      assert(0 && "invalid expression kind");
+    }
+
+    switch(res.kind) {
+    case Action::DoChildren: {  
+      bool rebuild = false;
+      ref<Expr> e(&ep), kids[8];
+      unsigned count = ep.getNumKids();
+      for (unsigned i=0; i<count; i++) {
+        ref<Expr> kid = ep.getKid(i);
+        kids[i] = visit(kid);
+        if (kids[i] != kid)
+          rebuild = true;
+      }
+      if (rebuild) {
+        e = ep.rebuild(kids);
+        if (recursive)
+          e = visit(e);
+      }
+      if (!e.isConstant()) {
+        res = visitExprPost(*e.get());
+        if (res.kind==Action::ChangeTo)
+          e = res.argument;
+      }
+      return e;
+    }
+    case Action::SkipChildren:
+      return e;
+    case Action::ChangeTo:
+      return res.argument;
+    default:
+      assert(0 && "invalid kind");
+    }
+  }
+}
+
+ExprVisitor::Action ExprVisitor::visitExpr(const Expr&) {
+  return Action::doChildren();
+}
+
+ExprVisitor::Action ExprVisitor::visitExprPost(const Expr&) {
+  return Action::skipChildren();
+}
+
+ExprVisitor::Action ExprVisitor::visitNotOptimized(const NotOptimizedExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitRead(const ReadExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSelect(const SelectExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitConcat(const ConcatExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitExtract(const ExtractExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitZExt(const ZExtExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSExt(const SExtExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitAdd(const AddExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSub(const SubExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitMul(const MulExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitUDiv(const UDivExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSDiv(const SDivExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitURem(const URemExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSRem(const SRemExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitAnd(const AndExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitOr(const OrExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitXor(const XorExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitShl(const ShlExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitLShr(const LShrExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitAShr(const AShrExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitEq(const EqExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitNe(const NeExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitUlt(const UltExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitUle(const UleExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitUgt(const UgtExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitUge(const UgeExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSlt(const SltExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSle(const SleExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSgt(const SgtExpr&) {
+  return Action::doChildren(); 
+}
+
+ExprVisitor::Action ExprVisitor::visitSge(const SgeExpr&) {
+  return Action::doChildren(); 
+}
+
diff --git a/lib/Expr/Lexer.cpp b/lib/Expr/Lexer.cpp
new file mode 100644
index 00000000..77e25f62
--- /dev/null
+++ b/lib/Expr/Lexer.cpp
@@ -0,0 +1,261 @@
+//===-- Lexer.cpp ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "expr/Lexer.h"
+
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Streams.h"
+
+#include <iomanip>
+#include <iostream>
+#include <string.h>
+
+using namespace llvm;
+using namespace klee;
+using namespace klee::expr;
+
+///
+
+const char *Token::getKindName() const {
+  switch (kind) {
+  default:
+  case Unknown:    return "Unknown";
+  case Arrow:      return "Arrow";
+  case At:         return "At";
+  case Colon:      return "Colon";
+  case Comma:      return "Comma";
+  case Comment:    return "Comment";
+  case EndOfFile:  return "EndOfFile";
+  case Equals:     return "Equals";
+  case Identifier: return "Identifier";
+  case KWFalse:    return "KWFalse";
+  case KWQuery:    return "KWQuery";
+  case KWReserved: return "KWReserved";
+  case KWTrue:     return "KWTrue";
+  case KWWidth:    return "KWWidth";
+  case LBrace:     return "LBrace";
+  case LParen:     return "LParen";
+  case LSquare:    return "LSquare";
+  case Number:     return "Number";
+  case RBrace:     return "RBrace";
+  case RParen:     return "RParen";
+  case RSquare:    return "RSquare";
+  case Semicolon:  return "Semicolon";
+  }
+}
+
+void Token::dump() {
+  llvm::cerr << "(Token \"" << getKindName() << "\" "
+             << (void*) start << " " << length << " "
+             << line << " " << column << ")";
+}
+
+///
+
+static inline bool isInternalIdentifierChar(int Char) {
+  return isalnum(Char) || Char == '_' || Char == '.';
+}
+
+Lexer::Lexer(const llvm::MemoryBuffer *MB) 
+  : BufferPos(MB->getBufferStart()), BufferEnd(MB->getBufferEnd()), 
+    LineNumber(1), ColumnNumber(0) {
+}
+
+Lexer::~Lexer() {
+}
+
+int Lexer::PeekNextChar() {
+  if (BufferPos == BufferEnd)
+    return -1;
+  return *BufferPos;
+}
+
+int Lexer::GetNextChar() {
+  if (BufferPos == BufferEnd)
+    return -1;
+
+  // Handle DOS/Mac newlines here, by stripping duplicates and by
+  // returning '\n' for both.
+  char Result = *BufferPos++;
+  if (Result == '\n' || Result == '\r') {
+    if (BufferPos != BufferEnd && *BufferPos == ('\n' + '\r' - Result))
+      ++BufferPos;
+    Result = '\n';
+  }
+
+  if (Result == '\n') {
+    ++LineNumber;
+    ColumnNumber = 0;
+  } else {
+    ++ColumnNumber;
+  }
+
+  return Result;
+}
+
+Token &Lexer::SetTokenKind(Token &Result, Token::Kind k) {
+  Result.kind = k;
+  Result.length = BufferPos - Result.start;
+  return Result;
+}
+
+static bool isReservedKW(const char *Str, unsigned N) {
+    unsigned i;
+
+  // Check for i[0-9]+
+  if (N>1 && Str[0] == 'i') {
+    for (i=1; i<N; ++i)
+      if (!isdigit(Str[i]))
+        break;
+    if (i==N)
+      return true;
+  }
+
+  // Check for fp[0-9]+([.].*)?$
+  if (N>3 && Str[0]=='f' && Str[1]=='p' && isdigit(Str[2])) {
+    for (i=3; i<N; ++i)
+      if (!isdigit(Str[i]))
+        break;
+    if (i==N || Str[i]=='.')
+      return true;
+  }
+  
+  return false;
+}
+static bool isWidthKW(const char *Str, unsigned N) {
+  if (N<2 || Str[0] != 'w')
+    return false;
+  for (unsigned i=1; i<N; ++i)
+    if (!isdigit(Str[i]))
+      return false;
+  return true;
+}
+Token &Lexer::SetIdentifierTokenKind(Token &Result) {
+  unsigned Length = BufferPos - Result.start;
+  switch (Length) {
+  case 3:
+    if (memcmp("def", Result.start, 3) == 0)
+      return SetTokenKind(Result, Token::KWReserved);
+    if (memcmp("var", Result.start, 3) == 0)
+      return SetTokenKind(Result, Token::KWReserved);
+    break;
+
+  case 4:
+    if (memcmp("true", Result.start, 4) == 0)
+      return SetTokenKind(Result, Token::KWTrue);
+    break;
+
+  case 5:
+    if (memcmp("array", Result.start, 5) == 0)
+      return SetTokenKind(Result, Token::KWReserved);
+    if (memcmp("false", Result.start, 5) == 0)
+      return SetTokenKind(Result, Token::KWFalse);
+    if (memcmp("query", Result.start, 5) == 0)
+      return SetTokenKind(Result, Token::KWQuery);
+    break;      
+    
+  case 6:
+    if (memcmp("define", Result.start, 6) == 0)
+      return SetTokenKind(Result, Token::KWReserved);
+    break;
+
+  case 7:
+    if (memcmp("declare", Result.start, 7) == 0)
+      return SetTokenKind(Result, Token::KWReserved);
+    break;
+  }
+
+  if (isReservedKW(Result.start, Length))
+    return SetTokenKind(Result, Token::KWReserved);
+  if (isWidthKW(Result.start, Length))
+    return SetTokenKind(Result, Token::KWWidth);
+
+  return SetTokenKind(Result, Token::Identifier);
+}
+
+void Lexer::SkipToEndOfLine() {
+  for (;;) {
+    int Char = GetNextChar();
+    if (Char == -1 || Char =='\n')
+      break;
+  }
+}
+
+Token &Lexer::LexNumber(Token &Result) {
+  while (isalnum(PeekNextChar()) || PeekNextChar()=='_')
+    GetNextChar();
+  return SetTokenKind(Result, Token::Number);
+}
+
+Token &Lexer::LexIdentifier(Token &Result) {
+  while (isInternalIdentifierChar(PeekNextChar()))
+    GetNextChar();
+
+  // Recognize keywords specially.
+  return SetIdentifierTokenKind(Result);
+}
+
+Token &Lexer::Lex(Token &Result) {
+  Result.kind = Token::Unknown;
+  Result.length = 0;
+  Result.start = BufferPos;
+  
+  // Skip whitespace.
+  while (isspace(PeekNextChar()))
+    GetNextChar();
+
+  Result.start = BufferPos;
+  Result.line = LineNumber;
+  Result.column = ColumnNumber;
+  int Char = GetNextChar();
+  switch (Char) {
+  case -1:  return SetTokenKind(Result, Token::EndOfFile);
+    
+  case '(': return SetTokenKind(Result, Token::LParen);
+  case ')': return SetTokenKind(Result, Token::RParen);
+  case ',': return SetTokenKind(Result, Token::Comma);
+  case ':': return SetTokenKind(Result, Token::Colon);
+  case ';': return SetTokenKind(Result, Token::Semicolon);
+  case '=': return SetTokenKind(Result, Token::Equals);
+  case '@': return SetTokenKind(Result, Token::At);
+  case '[': return SetTokenKind(Result, Token::LSquare);
+  case ']': return SetTokenKind(Result, Token::RSquare);
+  case '{': return SetTokenKind(Result, Token::LBrace);
+  case '}': return SetTokenKind(Result, Token::RBrace);
+
+  case '#':
+    SkipToEndOfLine();
+    return SetTokenKind(Result, Token::Comment);
+
+  case '+': {
+    if (isdigit(PeekNextChar()))
+      return LexNumber(Result);
+    else
+      return SetTokenKind(Result, Token::Unknown);
+  }
+
+  case '-': {
+    int Next = PeekNextChar();
+    if (Next == '>')
+      return GetNextChar(), SetTokenKind(Result, Token::Arrow);
+    else if (isdigit(Next))
+      return LexNumber(Result);
+    else
+      return SetTokenKind(Result, Token::Unknown);
+    break;
+  }
+
+  default:
+    if (isdigit(Char))
+      return LexNumber(Result);
+    else if (isalpha(Char) || Char == '_')
+      return LexIdentifier(Result);
+    return SetTokenKind(Result, Token::Unknown);
+  }
+}
diff --git a/lib/Expr/Makefile b/lib/Expr/Makefile
new file mode 100644
index 00000000..b80569b3
--- /dev/null
+++ b/lib/Expr/Makefile
@@ -0,0 +1,16 @@
+#===-- lib/Expr/Makefile -----------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleaverExpr
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Expr/Parser.cpp b/lib/Expr/Parser.cpp
new file mode 100644
index 00000000..f5708384
--- /dev/null
+++ b/lib/Expr/Parser.cpp
@@ -0,0 +1,1310 @@
+//===-- Parser.cpp --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "expr/Parser.h"
+
+#include "expr/Lexer.h"
+
+#include "klee/Constraints.h"
+#include "klee/Solver.h"
+#include "klee/util/ExprPPrinter.h"
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Streams.h"
+
+#include <cassert>
+#include <iostream>
+#include <map>
+
+using namespace llvm;
+using namespace klee;
+using namespace klee::expr;
+
+namespace {
+  /// ParseResult - Represent a possibly invalid parse result.
+  template<typename T>
+  struct ParseResult {
+    bool IsValid;
+    T Value;
+
+  public:
+    ParseResult() : IsValid(false) {}
+    ParseResult(T _Value) : IsValid(true), Value(_Value) {}
+    ParseResult(bool _IsValid, T _Value) : IsValid(_IsValid), Value(_Value) {}
+
+    bool isValid() { 
+      return IsValid; 
+    }
+    T get() { 
+      assert(IsValid && "get() on invalid ParseResult!");
+      return Value; 
+    }
+  };
+  
+  typedef ParseResult<Decl*> DeclResult;
+  typedef ParseResult<ExprHandle> ExprResult;
+  typedef ParseResult<Expr::Width> TypeResult;
+  typedef ParseResult<VersionHandle> VersionResult;
+
+  /// NumberOrExprResult - Represent a number or expression. This is used to
+  /// wrap an expression production which may be a number, but for
+  /// which the type width is unknown.
+  class NumberOrExprResult {
+    Token AsNumber;
+    ExprResult AsExpr;
+    bool IsNumber;
+
+  public:
+    NumberOrExprResult() : IsNumber(false) {}
+    explicit NumberOrExprResult(Token _AsNumber) : AsNumber(_AsNumber),
+                                                   IsNumber(true) {}
+    explicit NumberOrExprResult(ExprResult _AsExpr) : AsExpr(_AsExpr),
+                                                      IsNumber(false) {}
+    
+    bool isNumber() const { return IsNumber; }
+    const Token &getNumber() const { 
+      assert(IsNumber && "Invalid accessor call.");
+      return AsNumber; 
+    }
+    const ExprResult &getExpr() const {
+      assert(!IsNumber && "Invalid accessor call.");
+      return AsExpr;
+    }
+  };
+
+  /// ParserImpl - Parser implementation.
+  class ParserImpl : public Parser {
+    typedef std::map<const std::string, const Identifier*> IdentifierTabTy;
+    typedef std::map<const Identifier*, ExprHandle> ExprSymTabTy;
+    typedef std::map<const Identifier*, VersionHandle> VersionSymTabTy;
+
+    const std::string Filename;
+    const MemoryBuffer *TheMemoryBuffer;
+    Lexer TheLexer;
+    unsigned MaxErrors;
+    unsigned NumErrors;
+
+    // FIXME: Use LLVM symbol tables?
+    IdentifierTabTy IdentifierTab;
+
+    std::map<const Identifier*, const ArrayDecl*> ArraySymTab;
+    ExprSymTabTy ExprSymTab;
+    VersionSymTabTy VersionSymTab;
+
+    /// Tok - The currently lexed token.
+    Token Tok;
+
+    /// ParenLevel - The current depth of matched '(' tokens. 
+    unsigned ParenLevel;
+    /// SquareLevel - The current depth of matched '[' tokens.
+    unsigned SquareLevel;
+
+    /* Core parsing functionality */
+    
+    const Identifier *GetOrCreateIdentifier(const Token &Tok);
+
+    void GetNextNonCommentToken() {
+      do {
+        TheLexer.Lex(Tok);
+      } while (Tok.kind == Token::Comment);
+    }
+
+    /// ConsumeToken - Consume the current 'peek token' and lex the next one.
+    void ConsumeToken() {
+      assert(Tok.kind != Token::LParen && Tok.kind != Token::RParen);
+      GetNextNonCommentToken();
+    }
+
+    /// ConsumeExpectedToken - Check that the current token is of the
+    /// expected kind and consume it.
+    void ConsumeExpectedToken(Token::Kind k) {
+      assert(Tok.kind == k && "Unexpected token!");
+      GetNextNonCommentToken();
+    }
+
+    void ConsumeLParen() {
+      ++ParenLevel;
+      ConsumeExpectedToken(Token::LParen);
+    }
+
+    void ConsumeRParen() {
+      if (ParenLevel) // Cannot go below zero.
+        --ParenLevel;
+      ConsumeExpectedToken(Token::RParen);
+    }
+
+    void ConsumeLSquare() {
+      ++SquareLevel;
+      ConsumeExpectedToken(Token::LSquare);
+    }
+
+    void ConsumeRSquare() {
+      if (SquareLevel) // Cannot go below zero.
+        --SquareLevel;
+      ConsumeExpectedToken(Token::RSquare);
+    }
+
+    void ConsumeAnyToken() {
+      switch (Tok.kind) {
+      case Token::LParen: return ConsumeLParen();
+      case Token::RParen: return ConsumeRParen();
+      case Token::LSquare: return ConsumeLSquare();
+      case Token::RSquare: return ConsumeRSquare();
+      default: 
+        return ConsumeToken();
+      }
+    }
+
+    /* Utility functions */
+
+    /// SkipUntilRParen - Scan forward to the next token following an
+    /// rparen at the given level, or EOF, whichever is first.
+    void SkipUntilRParen(unsigned Level) {
+      // FIXME: I keep wavering on whether it is an error to call this
+      // with the current token an rparen. In most cases this should
+      // have been handled differently (error reported,
+      // whatever). Audit & resolve.
+      assert(Level <= ParenLevel && 
+             "Refusing to skip until rparen at higher level.");
+      while (Tok.kind != Token::EndOfFile) {
+        if (Tok.kind == Token::RParen && ParenLevel == Level) {
+          ConsumeRParen();
+          break;
+        }
+        ConsumeAnyToken();
+      }
+    }
+
+    /// SkipUntilRParen - Scan forward until reaching an rparen token
+    /// at the current level (or EOF).
+    void SkipUntilRParen() {
+      SkipUntilRParen(ParenLevel);
+    }
+    
+    /// ExpectRParen - Utility method to close an sexp. This expects to
+    /// eat an rparen, and emits a diagnostic and skips to the next one
+    /// (or EOF) if it cannot.
+    void ExpectRParen(const char *Msg) {
+      if (Tok.kind == Token::EndOfFile) {
+        // FIXME: Combine with Msg
+        Error("expected ')' but found end-of-file.", Tok);
+      } else if (Tok.kind != Token::RParen) {
+        Error(Msg, Tok);
+        SkipUntilRParen();
+      } else {
+        ConsumeRParen();
+      }
+    }
+
+    /// SkipUntilRSquare - Scan forward to the next token following an
+    /// rsquare at the given level, or EOF, whichever is first.
+    void SkipUntilRSquare(unsigned Level) {
+      // FIXME: I keep wavering on whether it is an error to call this
+      // with the current token an rparen. In most cases this should
+      // have been handled differently (error reported,
+      // whatever). Audit & resolve.
+      assert(Level <= ParenLevel && 
+             "Refusing to skip until rparen at higher level.");
+      while (Tok.kind != Token::EndOfFile) {
+        if (Tok.kind == Token::RSquare && ParenLevel == Level) {
+          ConsumeRSquare();
+          break;
+        }
+        ConsumeAnyToken();
+      }
+    }
+
+    /// SkipUntilRSquare - Scan forward until reaching an rsquare token
+    /// at the current level (or EOF).
+    void SkipUntilRSquare() {
+      SkipUntilRSquare(ParenLevel);
+    }
+    
+    /// ExpectRSquare - Utility method to close an array. This expects
+    /// to eat an rparen, and emits a diagnostic and skips to the next
+    /// one (or EOF) if it cannot.
+    void ExpectRSquare(const char *Msg) {
+      if (Tok.kind == Token::EndOfFile) {
+        // FIXME: Combine with Msg
+        Error("expected ']' but found end-of-file.", Tok);
+      } else if (Tok.kind != Token::RSquare) {
+        Error(Msg, Tok);
+        SkipUntilRSquare();
+      } else {
+        ConsumeRSquare();
+      }
+    }
+
+    /*** Grammar productions ****/
+
+    /* Top level decls */
+
+    DeclResult ParseArrayDecl();
+    DeclResult ParseExprVarDecl();
+    DeclResult ParseVersionVarDecl();
+    DeclResult ParseCommandDecl();
+
+    /* Commands */
+
+    DeclResult ParseQueryCommand();
+
+    /* Etc. */
+
+    NumberOrExprResult ParseNumberOrExpr();
+
+    ExprResult ParseExpr(TypeResult ExpectedType);
+    ExprResult ParseParenExpr(TypeResult ExpectedType);
+    ExprResult ParseUnaryParenExpr(const Token &Name,
+                                   unsigned Kind, bool IsFixed,
+                                   Expr::Width ResTy);
+    ExprResult ParseBinaryParenExpr(const Token &Name,
+                                    unsigned Kind, bool IsFixed,
+                                    Expr::Width ResTy);
+    ExprResult ParseSelectParenExpr(const Token &Name, Expr::Width ResTy);
+    ExprResult ParseConcatParenExpr(const Token &Name, Expr::Width ResTy);
+    ExprResult ParseExtractParenExpr(const Token &Name, Expr::Width ResTy);
+    ExprResult ParseAnyReadParenExpr(const Token &Name,
+                                     unsigned Kind,
+                                     Expr::Width ResTy);
+    void ParseMatchedBinaryArgs(const Token &Name, 
+                                TypeResult ExpectType,
+                                ExprResult &LHS, ExprResult &RHS);
+    ExprResult ParseNumber(Expr::Width Width);
+    ExprResult ParseNumberToken(Expr::Width Width, const Token &Tok);
+
+    VersionResult ParseVersionSpecifier();
+    VersionResult ParseVersion();
+
+    TypeResult ParseTypeSpecifier();
+
+    /*** Diagnostics ***/
+    
+    void Error(const char *Message, const Token &At);
+    void Error(const char *Message) { Error(Message, Tok); }
+
+  public:
+    ParserImpl(const std::string _Filename,
+               const MemoryBuffer *MB) : Filename(_Filename),
+                                         TheMemoryBuffer(MB),
+                                         TheLexer(MB),
+                                         MaxErrors(~0u),
+                                         NumErrors(0) {}
+
+    /// Initialize - Initialize the parsing state. This must be called
+    /// prior to the start of parsing.
+    void Initialize() {
+      ParenLevel = SquareLevel = 0;
+
+      ConsumeAnyToken();
+    }
+
+    /* Parser interface implementation */
+
+    virtual Decl *ParseTopLevelDecl();
+
+    virtual void SetMaxErrors(unsigned N) {
+      MaxErrors = N;
+    }
+
+    virtual unsigned GetNumErrors() const {
+      return NumErrors; 
+    }
+  };
+}
+
+const Identifier *ParserImpl::GetOrCreateIdentifier(const Token &Tok) {
+  // FIXME: Make not horribly inefficient please.
+  assert(Tok.kind == Token::Identifier && "Expected only identifier tokens.");
+  std::string Name(Tok.start, Tok.length);
+  IdentifierTabTy::iterator it = IdentifierTab.find(Name);
+  if (it != IdentifierTab.end())
+    return it->second;
+
+  Identifier *I = new Identifier(Name);
+  IdentifierTab.insert(std::make_pair(Name, I));
+
+  return I;
+}
+
+Decl *ParserImpl::ParseTopLevelDecl() {
+  // Repeat until success or EOF.
+  while (Tok.kind != Token::EndOfFile) {
+    // Only handle commands for now.
+    if (Tok.kind == Token::LParen) {
+      DeclResult Res = ParseCommandDecl();
+      if (Res.isValid())
+        return Res.get();
+    } else {
+      Error("expected '(' token.");
+      ConsumeAnyToken();
+    }
+  }
+
+  return 0;
+}
+
+/// ParseCommandDecl - Parse a command declaration. The lexer should
+/// be positioned at the opening '('.
+///
+/// command = '(' name ... ')'
+DeclResult ParserImpl::ParseCommandDecl() {
+  ConsumeLParen();
+
+  if (!Tok.isKeyword()) {
+    Error("malformed command.");
+    SkipUntilRParen();
+    return DeclResult();
+  }
+
+  switch (Tok.kind) {
+  case Token::KWQuery:
+    return ParseQueryCommand();
+
+  default:
+    Error("malformed command (unexpected keyword).");
+    SkipUntilRParen();
+    return DeclResult();
+  }
+}
+
+/// ParseQueryCommand - Parse query command. The lexer should be
+/// positioned at the 'query' keyword.
+/// 
+/// 'query' expressions-list expression [expression-list [array-list]]
+DeclResult ParserImpl::ParseQueryCommand() {
+  // FIXME: We need a command for this. Or something.
+  ExprSymTab.clear();
+  VersionSymTab.clear();
+
+  std::vector<ExprHandle> Constraints;
+  ConsumeExpectedToken(Token::KWQuery);
+  if (Tok.kind != Token::LSquare) {
+    Error("malformed query, expected constraint list.");
+    SkipUntilRParen();
+    return DeclResult();
+  }
+
+  ConsumeExpectedToken(Token::LSquare);
+  // FIXME: Should avoid reading past unbalanced parens here.
+  while (Tok.kind != Token::RSquare) {
+    if (Tok.kind == Token::EndOfFile) {
+      Error("unexpected end of file.");
+      return new QueryCommand(Constraints.begin(), Constraints.end(),
+                              ref<Expr>(false, Expr::Bool));
+    }
+
+    ExprResult Res = ParseExpr(TypeResult(Expr::Bool));
+    if (Res.isValid())
+      Constraints.push_back(Res.get());
+  }
+
+  ConsumeRSquare();
+
+  ExprResult Res = ParseExpr(TypeResult());
+  if (!Res.isValid()) // Error emitted by ParseExpr.
+    Res = ExprResult(ref<Expr>(0, Expr::Bool));
+
+  ExpectRParen("unexpected argument to 'query'.");  
+  return new QueryCommand(Constraints.begin(), Constraints.end(),
+                          Res.get());
+}
+
+/// ParseNumberOrExpr - Parse an expression whose type cannot be
+/// predicted.
+NumberOrExprResult ParserImpl::ParseNumberOrExpr() {
+  if (Tok.kind == Token::Number){ 
+    Token Num = Tok;
+    ConsumeToken();
+    return NumberOrExprResult(Num);
+  } else {
+    return NumberOrExprResult(ParseExpr(TypeResult()));
+  }
+}
+
+/// ParseExpr - Parse an expression with the given \arg
+/// ExpectedType. \arg ExpectedType can be invalid if the type cannot
+/// be inferred from the context.
+///
+/// expr = false | true
+/// expr = <constant>
+/// expr = <identifier>
+/// expr = [<identifier>:] paren-expr
+ExprResult ParserImpl::ParseExpr(TypeResult ExpectedType) {
+  // FIXME: Is it right to need to do this here?
+  if (Tok.kind == Token::EndOfFile) {
+    Error("unexpected end of file.");
+    return ExprResult();
+  }
+
+  if (Tok.kind == Token::KWFalse || Tok.kind == Token::KWTrue) {
+    bool Value = Tok.kind == Token::KWTrue;
+    ConsumeToken();
+    return ExprResult(ref<Expr>(Value, Expr::Bool));
+  }
+  
+  if (Tok.kind == Token::Number) {
+    if (!ExpectedType.isValid()) {
+      Error("cannot infer type of number.");
+      ConsumeToken();
+      return ExprResult();
+    }
+    
+    return ParseNumber(ExpectedType.get());
+  }
+
+  const Identifier *Label = 0;
+  if (Tok.kind == Token::Identifier) {
+    Token LTok = Tok;
+    Label = GetOrCreateIdentifier(Tok);
+    ConsumeToken();
+
+    if (Tok.kind != Token::Colon) {
+      ExprSymTabTy::iterator it = ExprSymTab.find(Label);
+
+      if (it == ExprSymTab.end()) {
+        Error("invalid expression label reference.", LTok);
+        return ExprResult();
+      }
+
+      return it->second;
+    }
+
+    ConsumeToken();
+    if (ExprSymTab.count(Label)) {
+      Error("duplicate expression label definition.", LTok);
+      Label = 0;
+    }
+  }
+
+  Token Start = Tok;
+  ExprResult Res = ParseParenExpr(ExpectedType);
+  if (!Res.isValid()) {
+    // If we know the type, define the identifier just so we don't get
+    // use-of-undef errors. 
+    // FIXME: Maybe we should let the symbol table map to invalid
+    // entries?
+    if (Label && ExpectedType.isValid())
+      ExprSymTab.insert(std::make_pair(Label, 
+                                       ref<Expr>(0, ExpectedType.get())));
+    return Res;
+  } else if (ExpectedType.isValid()) {
+    // Type check result.    
+    if (Res.get().getWidth() != ExpectedType.get()) {
+      // FIXME: Need more info, and range
+      Error("expression has incorrect type.", Start);
+      return ExprResult();
+    }
+  }
+
+  if (Label)
+    ExprSymTab.insert(std::make_pair(Label, Res.get()));
+  return Res;
+}
+
+// Additional kinds for macro forms.
+enum MacroKind {
+  eMacroKind_Not = Expr::LastKind + 1,     // false == x
+  eMacroKind_Neg,                          // 0 - x
+  eMacroKind_ReadLSB,                      // Multibyte read
+  eMacroKind_ReadMSB,                      // Multibyte write
+  eMacroKind_Concat,                       // Magic concatenation syntax
+  eMacroKind_LastMacroKind = eMacroKind_ReadMSB
+};
+
+/// LookupExprInfo - Return information on the named token, if it is
+/// recognized.
+///
+/// \param Kind [out] - The Expr::Kind or MacroKind of the identifier.
+/// \param IsFixed [out] - True if the given kinds result and
+/// (expression) arguments are all of the same width.
+/// \param NumArgs [out] - The number of expression arguments for this
+/// kind. -1 indicates the kind is variadic or has non-expression
+/// arguments.
+/// \return True if the token is a valid kind or macro name.
+static bool LookupExprInfo(const Token &Tok, unsigned &Kind, 
+                           bool &IsFixed, int &NumArgs) {
+#define SetOK(kind, isfixed, numargs) (Kind=kind, IsFixed=isfixed,\
+                                       NumArgs=numargs, true)
+  assert(Tok.kind == Token::Identifier && "Unexpected token.");
+  
+  switch (Tok.length) {
+  case 2:
+    if (memcmp(Tok.start, "Eq", 2) == 0)
+      return SetOK(Expr::Eq, false, 2);
+    if (memcmp(Tok.start, "Ne", 2) == 0)
+      return SetOK(Expr::Ne, false, 2);
+
+    if (memcmp(Tok.start, "Or", 2) == 0)
+      return SetOK(Expr::Or, true, 2);
+    break;
+
+  case 3:
+    if (memcmp(Tok.start, "Add", 3) == 0)
+      return SetOK(Expr::Add, true, 2);
+    if (memcmp(Tok.start, "Sub", 3) == 0)
+      return SetOK(Expr::Sub, true, 2);
+    if (memcmp(Tok.start, "Mul", 3) == 0)
+      return SetOK(Expr::Mul, true, 2);
+
+    if (memcmp(Tok.start, "And", 3) == 0)
+      return SetOK(Expr::And, true, 2);
+    if (memcmp(Tok.start, "Shl", 3) == 0)
+      return SetOK(Expr::Shl, true, 2);
+    if (memcmp(Tok.start, "Xor", 3) == 0)
+      return SetOK(Expr::Xor, true, 2);
+
+    if (memcmp(Tok.start, "Not", 3) == 0)
+      return SetOK(eMacroKind_Not, true, 1);
+    if (memcmp(Tok.start, "Neg", 3) == 0)
+      return SetOK(eMacroKind_Neg, true, 1);
+    if (memcmp(Tok.start, "Ult", 3) == 0)
+      return SetOK(Expr::Ult, false, 2);
+    if (memcmp(Tok.start, "Ule", 3) == 0)
+      return SetOK(Expr::Ule, false, 2);
+    if (memcmp(Tok.start, "Ugt", 3) == 0)
+      return SetOK(Expr::Ugt, false, 2);
+    if (memcmp(Tok.start, "Uge", 3) == 0)
+      return SetOK(Expr::Uge, false, 2);
+    if (memcmp(Tok.start, "Slt", 3) == 0)
+      return SetOK(Expr::Slt, false, 2);
+    if (memcmp(Tok.start, "Sle", 3) == 0)
+      return SetOK(Expr::Sle, false, 2);
+    if (memcmp(Tok.start, "Sgt", 3) == 0)
+      return SetOK(Expr::Sgt, false, 2);
+    if (memcmp(Tok.start, "Sge", 3) == 0)
+      return SetOK(Expr::Sge, false, 2);
+    break;
+
+  case 4:
+    if (memcmp(Tok.start, "Read", 4) == 0)
+      return SetOK(Expr::Read, true, -1);
+    if (memcmp(Tok.start, "AShr", 4) == 0)
+      return SetOK(Expr::AShr, true, 2);
+    if (memcmp(Tok.start, "LShr", 4) == 0)
+      return SetOK(Expr::LShr, true, 2);
+
+    if (memcmp(Tok.start, "UDiv", 4) == 0)
+      return SetOK(Expr::UDiv, true, 2);
+    if (memcmp(Tok.start, "SDiv", 4) == 0)
+      return SetOK(Expr::SDiv, true, 2);
+    if (memcmp(Tok.start, "URem", 4) == 0)
+      return SetOK(Expr::URem, true, 2);
+    if (memcmp(Tok.start, "SRem", 4) == 0)
+      return SetOK(Expr::SRem, true, 2);
+    
+    if (memcmp(Tok.start, "SExt", 4) == 0)
+      return SetOK(Expr::SExt, false, 1);
+    if (memcmp(Tok.start, "ZExt", 4) == 0)
+      return SetOK(Expr::ZExt, false, 1);
+    break;
+    
+  case 6:
+    if (memcmp(Tok.start, "Concat", 6) == 0)
+      return SetOK(eMacroKind_Concat, false, -1); 
+    if (memcmp(Tok.start, "Select", 6) == 0)
+      return SetOK(Expr::Select, false, 3);
+    break;
+    
+  case 7:
+    if (memcmp(Tok.start, "Extract", 7) == 0)
+      return SetOK(Expr::Extract, false, -1);
+    if (memcmp(Tok.start, "ReadLSB", 7) == 0)
+      return SetOK(eMacroKind_ReadLSB, true, -1);
+    if (memcmp(Tok.start, "ReadMSB", 7) == 0)
+      return SetOK(eMacroKind_ReadMSB, true, -1);
+    break;
+  }
+
+  return false;
+#undef SetOK
+}
+
+/// ParseParenExpr - Parse a parenthesized expression with the given
+/// \arg ExpectedType. \arg ExpectedType can be invalid if the type
+/// cannot be inferred from the context.
+///
+/// paren-expr = '(' type number ')'
+/// paren-expr = '(' identifier [type] expr+ ')
+/// paren-expr = '(' ('Read' | 'ReadMSB' | 'ReadLSB') type expr update-list ')'
+ExprResult ParserImpl::ParseParenExpr(TypeResult FIXME_UNUSED) {
+  if (Tok.kind != Token::LParen) {
+    Error("unexpected token.");
+    ConsumeAnyToken();
+    return ExprResult();
+  }
+
+  ConsumeLParen();
+  
+  // Check for coercion case (w32 11).
+  if (Tok.kind == Token::KWWidth) {
+    TypeResult ExpectedType = ParseTypeSpecifier();
+
+    if (Tok.kind != Token::Number) {
+      Error("coercion can only apply to a number.");
+      SkipUntilRParen();
+      return ExprResult();
+    }
+    
+    // Make sure this was a type specifier we support.
+    ExprResult Res;
+    if (ExpectedType.isValid()) 
+      Res = ParseNumber(ExpectedType.get());
+    else
+      ConsumeToken();
+
+    ExpectRParen("unexpected argument in coercion.");  
+    return Res;
+  }
+  
+  if (Tok.kind != Token::Identifier) {
+    Error("unexpected token, expected expression.");
+    SkipUntilRParen();
+    return ExprResult();
+  }
+
+  Token Name = Tok;
+  ConsumeToken();
+
+  // FIXME: Use invalid type (i.e. width==0)?
+  Token TypeTok = Tok;
+  bool HasType = TypeTok.kind == Token::KWWidth;
+  TypeResult Type = HasType ? ParseTypeSpecifier() : Expr::Bool;
+
+  // FIXME: For now just skip to rparen on error. It might be nice
+  // to try and actually parse the child nodes though for error
+  // messages & better recovery?
+  if (!Type.isValid()) {
+    SkipUntilRParen();
+    return ExprResult();
+  }
+  Expr::Width ResTy = Type.get();
+
+  unsigned ExprKind;
+  bool IsFixed;
+  int NumArgs;
+  if (!LookupExprInfo(Name, ExprKind, IsFixed, NumArgs)) {
+    // FIXME: For now just skip to rparen on error. It might be nice
+    // to try and actually parse the child nodes though for error
+    // messages & better recovery?
+    Error("unknown expression kind.", Name);
+    SkipUntilRParen();
+    return ExprResult();
+  }
+
+  // See if we have to parse this form specially.
+  if (NumArgs == -1) {
+    switch (ExprKind) {
+    case eMacroKind_Concat:
+      return ParseConcatParenExpr(Name, ResTy);
+
+    case Expr::Extract:
+      return ParseExtractParenExpr(Name, ResTy);
+
+    case eMacroKind_ReadLSB:
+    case eMacroKind_ReadMSB:
+    case Expr::Read:
+      return ParseAnyReadParenExpr(Name, ExprKind, ResTy);
+
+    default:
+      Error("internal error, unimplemented special form.", Name);
+      SkipUntilRParen();
+      return ExprResult(ref<Expr>(0, ResTy));
+    }
+  }
+
+  switch (NumArgs) {
+  case 1:
+    return ParseUnaryParenExpr(Name, ExprKind, IsFixed, ResTy);
+  case 2:
+    return ParseBinaryParenExpr(Name, ExprKind, IsFixed, ResTy);
+  case 3:
+    if (ExprKind == Expr::Select)
+      return ParseSelectParenExpr(Name, ResTy);
+  default:
+    assert(0 && "Invalid argument kind (number of args).");
+    return ExprResult();
+  }
+}
+
+ExprResult ParserImpl::ParseUnaryParenExpr(const Token &Name,
+                                           unsigned Kind, bool IsFixed,
+                                           Expr::Width ResTy) {
+  if (Tok.kind == Token::RParen) {
+    Error("unexpected end of arguments.", Name);
+    ConsumeRParen();
+    return ref<Expr>(0, ResTy);
+  }
+
+  ExprResult Arg = ParseExpr(IsFixed ? ResTy : TypeResult());
+  if (!Arg.isValid())
+    Arg = ref<Expr>(0, ResTy);
+
+  ExpectRParen("unexpected argument in unary expression.");  
+  ExprHandle E = Arg.get();
+  switch (Kind) {
+  case eMacroKind_Not:
+    return EqExpr::alloc(ref<Expr>(0, E.getWidth()), E);
+  case eMacroKind_Neg:
+    return SubExpr::alloc(ref<Expr>(0, E.getWidth()), E);
+  case Expr::SExt:
+    // FIXME: Type check arguments.
+    return SExtExpr::alloc(E, ResTy);
+  case Expr::ZExt:
+    // FIXME: Type check arguments.
+    return ZExtExpr::alloc(E, ResTy);
+  default:
+    Error("internal error, unhandled kind.", Name);
+    return ref<Expr>(0, ResTy);
+  }
+}
+
+/// ParseMatchedBinaryArgs - Parse a pair of arguments who are
+/// expected to be of the same type. Upon return, if both LHS and RHS
+/// are valid then they are guaranteed to have the same type.
+///
+/// Name - The name token of the expression, for diagnostics.
+/// ExpectType - The expected type of the arguments, if known.
+void ParserImpl::ParseMatchedBinaryArgs(const Token &Name, 
+                                        TypeResult ExpectType,
+                                        ExprResult &LHS, ExprResult &RHS) {
+  if (Tok.kind == Token::RParen) {
+    Error("unexpected end of arguments.", Name);
+    ConsumeRParen();
+    return;
+  }
+
+  // Avoid NumberOrExprResult overhead and give more precise
+  // diagnostics when we know the type.
+  if (ExpectType.isValid()) {
+    LHS = ParseExpr(ExpectType);
+    if (Tok.kind == Token::RParen) {
+      Error("unexpected end of arguments.", Name);
+      ConsumeRParen();
+      return;
+    }
+    RHS = ParseExpr(ExpectType);
+  } else {
+    NumberOrExprResult LHS_NOE = ParseNumberOrExpr();
+
+    if (Tok.kind == Token::RParen) {
+      Error("unexpected end of arguments.", Name);
+      ConsumeRParen();
+      return;
+    }
+
+    if (LHS_NOE.isNumber()) {
+      NumberOrExprResult RHS_NOE = ParseNumberOrExpr();
+      
+      if (RHS_NOE.isNumber()) {
+        Error("ambiguous arguments to expression.", Name);
+      } else {
+        RHS = RHS_NOE.getExpr();
+        if (RHS.isValid())
+          LHS = ParseNumberToken(RHS.get().getWidth(), LHS_NOE.getNumber());
+      }
+    } else {
+      LHS = LHS_NOE.getExpr();
+      if (!LHS.isValid()) {
+        // FIXME: Should suppress ambiguity warnings here.
+        RHS = ParseExpr(TypeResult());
+      } else {
+        RHS = ParseExpr(LHS.get().getWidth());
+      }
+    }
+  }
+
+  ExpectRParen("unexpected argument to expression.");
+}
+
+ExprResult ParserImpl::ParseBinaryParenExpr(const Token &Name,
+                                           unsigned Kind, bool IsFixed,
+                                           Expr::Width ResTy) {
+  ExprResult LHS, RHS;
+  ParseMatchedBinaryArgs(Name, IsFixed ? TypeResult(ResTy) : TypeResult(), 
+                         LHS, RHS);
+  if (!LHS.isValid() || !RHS.isValid())
+    return ref<Expr>(0, ResTy);
+
+  ref<Expr> LHS_E = LHS.get(), RHS_E = RHS.get();
+  assert(LHS_E.getWidth() == RHS_E.getWidth() && "Mismatched types!");
+
+  switch (Kind) {    
+  case Expr::Add: return AddExpr::alloc(LHS_E, RHS_E);
+  case Expr::Sub: return SubExpr::alloc(LHS_E, RHS_E);
+  case Expr::Mul: return MulExpr::alloc(LHS_E, RHS_E);
+  case Expr::UDiv: return UDivExpr::alloc(LHS_E, RHS_E);
+  case Expr::SDiv: return SDivExpr::alloc(LHS_E, RHS_E);
+  case Expr::URem: return URemExpr::alloc(LHS_E, RHS_E);
+  case Expr::SRem: return SRemExpr::alloc(LHS_E, RHS_E);
+
+  case Expr::AShr: return AShrExpr::alloc(LHS_E, RHS_E);
+  case Expr::LShr: return LShrExpr::alloc(LHS_E, RHS_E);
+  case Expr::Shl: return AndExpr::alloc(LHS_E, RHS_E);
+
+  case Expr::And: return AndExpr::alloc(LHS_E, RHS_E);
+  case Expr::Or:  return OrExpr::alloc(LHS_E, RHS_E);
+  case Expr::Xor: return XorExpr::alloc(LHS_E, RHS_E);
+
+  case Expr::Eq:  return EqExpr::alloc(LHS_E, RHS_E);
+  case Expr::Ne:  return NeExpr::alloc(LHS_E, RHS_E);
+  case Expr::Ult: return UltExpr::alloc(LHS_E, RHS_E);
+  case Expr::Ule: return UleExpr::alloc(LHS_E, RHS_E);
+  case Expr::Ugt: return UgtExpr::alloc(LHS_E, RHS_E);
+  case Expr::Uge: return UgeExpr::alloc(LHS_E, RHS_E);
+  case Expr::Slt: return SltExpr::alloc(LHS_E, RHS_E);
+  case Expr::Sle: return SleExpr::alloc(LHS_E, RHS_E);
+  case Expr::Sgt: return SgtExpr::alloc(LHS_E, RHS_E);
+  case Expr::Sge: return SgeExpr::alloc(LHS_E, RHS_E);
+  default:
+    Error("FIXME: unhandled kind.", Name);
+    return ref<Expr>(0, ResTy);
+  }  
+}
+
+ExprResult ParserImpl::ParseSelectParenExpr(const Token &Name, 
+                                            Expr::Width ResTy) {
+  // FIXME: Why does this need to be here?
+  if (Tok.kind == Token::RParen) {
+    Error("unexpected end of arguments.", Name);
+    ConsumeRParen();
+    return ref<Expr>(0, ResTy);
+  }
+
+  ExprResult Cond = ParseExpr(Expr::Bool);
+  ExprResult LHS, RHS;
+  ParseMatchedBinaryArgs(Name, ResTy, LHS, RHS);
+  if (!Cond.isValid() || !LHS.isValid() || !RHS.isValid())
+    return ref<Expr>(0, ResTy);
+  return SelectExpr::alloc(Cond.get(), LHS.get(), RHS.get());
+}
+
+
+// need to decide if we want to allow n-ary Concat expressions in the
+// language
+ExprResult ParserImpl::ParseConcatParenExpr(const Token &Name,
+                                            Expr::Width ResTy) {
+  std::vector<ExprHandle> Kids;
+  
+  unsigned Width = 0;
+  while (Tok.kind != Token::RParen) {
+    ExprResult E = ParseExpr(TypeResult());
+
+    // Skip to end of expr on error.
+    if (!E.isValid()) {
+      SkipUntilRParen();
+      return ref<Expr>(0, ResTy);
+    }
+    
+    Kids.push_back(E.get());
+    Width += E.get().getWidth();
+  }
+  
+  ConsumeRParen();
+
+  if (Width != ResTy) {
+    Error("concat does not match expected result size.");
+    return ref<Expr>(0, ResTy);
+  }
+
+  return ConcatExpr::createN(Kids.size(), &Kids[0]);
+}
+
+ExprResult ParserImpl::ParseExtractParenExpr(const Token &Name,
+                                             Expr::Width ResTy) {
+  // FIXME: Pull out parse constant integer expression.
+  ExprResult OffsetExpr = ParseNumber(Expr::Int32);
+  ExprResult Child = ParseExpr(TypeResult());
+
+  ExpectRParen("unexpected argument to expression.");
+
+  if (!OffsetExpr.isValid() || !Child.isValid())
+    return ref<Expr>(0, ResTy);
+
+  assert(OffsetExpr.get().isConstant() && "ParseNumber returned non-constant.");
+  unsigned Offset = (unsigned) OffsetExpr.get().getConstantValue();
+
+  if (Offset + ResTy > Child.get().getWidth()) {
+    Error("extract out-of-range of child expression.", Name);
+    return ref<Expr>(0, ResTy);
+  }
+
+  return ExtractExpr::alloc(Child.get(), Offset, ResTy);
+}
+
+ExprResult ParserImpl::ParseAnyReadParenExpr(const Token &Name,
+                                             unsigned Kind,
+                                             Expr::Width ResTy) {
+  NumberOrExprResult Index = ParseNumberOrExpr();
+  VersionResult Array = ParseVersionSpecifier();
+  ExpectRParen("unexpected argument in read expression.");
+  
+  if (!Array.isValid())
+    return ref<Expr>(0, ResTy);
+
+  // FIXME: Need generic way to get array width. Needs to work with
+  // anonymous arrays.
+  Expr::Width ArrayDomainType = Expr::Int32;
+  Expr::Width ArrayRangeType = Expr::Int8;
+
+  // Coerce number to correct type.
+  ExprResult IndexExpr;
+  if (Index.isNumber())
+    IndexExpr = ParseNumberToken(ArrayDomainType, Index.getNumber());
+  else
+    IndexExpr = Index.getExpr();
+  
+  if (!IndexExpr.isValid())
+    return ref<Expr>(0, ResTy);
+  else if (IndexExpr.get().getWidth() != ArrayDomainType) {
+    Error("index width does not match array domain.");
+    return ref<Expr>(0, ResTy);
+  }
+
+  // FIXME: Check range width.
+
+  switch (Kind) {
+  default:
+    assert(0 && "Invalid kind.");
+    return ref<Expr>(0, ResTy);
+  case eMacroKind_ReadLSB:
+  case eMacroKind_ReadMSB: {
+    unsigned NumReads = ResTy / ArrayRangeType;
+    if (ResTy != NumReads*ArrayRangeType) {
+      Error("invalid ordered read (not multiple of range type).", Name);
+      return ref<Expr>(0, ResTy);
+    }
+    std::vector<ExprHandle> Kids;
+    Kids.reserve(NumReads);
+    ExprHandle Index = IndexExpr.get();
+    for (unsigned i=0; i<NumReads; ++i) {
+      // FIXME: using folding here
+      ExprHandle OffsetIndex = AddExpr::create(IndexExpr.get(),
+                                               ref<Expr>(i, ArrayDomainType));
+      Kids.push_back(ReadExpr::alloc(Array.get(), OffsetIndex));
+    }
+    if (Kind == eMacroKind_ReadLSB)
+      std::reverse(Kids.begin(), Kids.end());
+    return ConcatExpr::createN(NumReads, &Kids[0]);
+  }
+  case Expr::Read:
+    return ReadExpr::alloc(Array.get(), IndexExpr.get());
+  }
+}
+
+/// version-specifier = <identifier>
+/// version-specifier = [<identifier>:] [ version ]
+VersionResult ParserImpl::ParseVersionSpecifier() {
+  const Identifier *Label = 0;
+  if (Tok.kind == Token::Identifier) {
+    Token LTok = Tok;
+    Label = GetOrCreateIdentifier(Tok);
+    ConsumeToken();
+
+    // FIXME: hack: add array declarations and ditch this.
+    if (memcmp(Label->Name.c_str(), "arr", 3) == 0) {
+      // Declare or create array.
+      const ArrayDecl *&A = ArraySymTab[Label];
+      if (!A) {
+        //        Array = new ArrayDecl(Label, 0, 32, 8);
+        unsigned id = atoi(&Label->Name.c_str()[3]);
+        Array *root = new Array(0, id, 0);
+        // Create update list mapping of name -> array.
+        VersionSymTab.insert(std::make_pair(Label,
+                                            UpdateList(root, true, NULL)));
+      }
+    }
+
+    if (Tok.kind != Token::Colon) {
+      VersionSymTabTy::iterator it = VersionSymTab.find(Label);
+      
+      if (it == VersionSymTab.end()) {
+        Error("invalid update list label reference.", LTok);
+        return VersionResult(false,
+                             UpdateList(0, true, NULL));
+      }
+
+      return it->second;
+    }
+
+    ConsumeToken();
+    if (VersionSymTab.count(Label)) {
+      Error("duplicate update list label definition.", LTok);
+      Label = 0;
+    }
+  }
+
+  Token Start = Tok;
+  VersionResult Res = ParseVersion();
+  // Define update list to avoid use-of-undef errors.
+  if (!Res.isValid())
+    Res = VersionResult(false,
+                        UpdateList(0, true, NULL));
+  
+  if (Label)
+    VersionSymTab.insert(std::make_pair(Label, Res.get()));
+  return Res;
+}
+
+/// version - '[' update-list? ']' ['@' version-specifier]
+/// update-list - empty
+/// update-list - lhs '=' rhs [',' update-list]
+VersionResult ParserImpl::ParseVersion() {
+  if (Tok.kind != Token::LSquare)
+    return VersionResult(false, UpdateList(0, false, NULL));
+  
+  std::vector< std::pair<NumberOrExprResult, NumberOrExprResult> > Writes;
+  ConsumeLSquare();
+  for (;;) {
+    // FIXME: Type check exprs.
+
+    // FIXME: We need to do this (the above) anyway just to handle
+    // implicit constants correctly.
+    NumberOrExprResult LHS = ParseNumberOrExpr();
+    
+    if (Tok.kind != Token::Equals) {
+      Error("expected '='.", Tok);
+      break;
+    }
+    
+    ConsumeToken();
+    NumberOrExprResult RHS = ParseNumberOrExpr();
+
+    Writes.push_back(std::make_pair(LHS, RHS));
+    
+    if (Tok.kind == Token::Comma)
+      ConsumeToken();
+    else
+      break;
+  }
+  ExpectRSquare("expected close of update list");
+
+  VersionHandle Base(0, false, NULL);
+
+  // Anonymous array case.
+  if (Tok.kind != Token::At) { 
+    Array *root = new Array(0, 0, 0);
+    Base = UpdateList(root, false, NULL);
+  } else {
+    ConsumeToken();
+
+    VersionResult BaseRes = ParseVersionSpecifier();
+    if (!BaseRes.isValid())
+      return BaseRes;
+
+    Base = BaseRes.get();
+  }
+
+  Expr::Width ArrayDomainType = Expr::Int32;
+  Expr::Width ArrayRangeType = Expr::Int8;
+
+  for (std::vector< std::pair<NumberOrExprResult, NumberOrExprResult> >::reverse_iterator
+         it = Writes.rbegin(), ie = Writes.rend(); it != ie; ++it) {
+    ExprResult LHS, RHS;
+    // FIXME: This can be factored into common helper for coercing a
+    // NumberOrExpr into an Expr.
+    if (it->first.isNumber()) {
+      LHS = ParseNumberToken(ArrayDomainType, it->first.getNumber());
+    } else {
+      LHS = it->first.getExpr(); 
+      if (LHS.isValid() && LHS.get().getWidth() != ArrayDomainType) {
+        // FIXME: bad token location. We should maybe try and know the
+        // array up-front?
+        Error("invalid value in write index (doesn't match domain).", Tok);
+        LHS = ExprResult();
+      }
+    }
+
+    if (it->second.isNumber()) {
+      RHS = ParseNumberToken(ArrayRangeType, it->second.getNumber());
+    } else {
+      RHS = it->second.getExpr();
+      if (RHS.isValid() && RHS.get().getWidth() != ArrayRangeType) {
+        // FIXME: bad token location. We should maybe try and know the
+        // array up-front?
+        Error("invalid value in write assignment (doesn't match range).", Tok);
+        RHS = ExprResult();
+      }
+    }
+    
+    if (LHS.isValid() && RHS.isValid())
+      Base.extend(LHS.get(), RHS.get());
+  }
+
+  return Base;
+}
+
+/// ParseNumber - Parse a number of the given type.
+ExprResult ParserImpl::ParseNumber(Expr::Width Type) {
+  ExprResult Res = ParseNumberToken(Type, Tok);
+  ConsumeExpectedToken(Token::Number);
+  return Res;
+}
+
+/// ParseNumberToken - Parse a number of the given type from the given
+/// token.
+ExprResult ParserImpl::ParseNumberToken(Expr::Width Type, const Token &Tok) {
+  const char *S = Tok.start;
+  unsigned N = Tok.length;
+  unsigned Radix = 10, RadixBits = 4;
+  bool HasMinus = false;
+
+  // Detect +/- (a number token cannot have both).
+  if (S[0] == '+') {
+    ++S;
+    --N;
+  } else if (S[0] == '-') {
+    HasMinus = true;
+    ++S;
+    --N;
+  }
+
+  // Detect 0[box].
+  if ((Tok.length >= 2 && S[0] == '0') &&
+      (S[1] == 'b' || S[1] == 'o' || S[1] == 'x')) {
+    if (S[1] == 'b') {
+      Radix = 2; 
+      RadixBits = 1;
+    } else if (S[1] == 'o') {
+      Radix = 8;
+      RadixBits = 3;
+    } else {
+      Radix = 16;
+      RadixBits = 4;
+    }
+    S += 2;
+    N -= 2;
+
+    // Diagnose 0[box] with no trailing digits.
+    if (!N) {
+      Error("invalid numeric token (no digits).", Tok);
+      return ref<Expr>(0, Type);
+    }
+  }
+
+  // This is a simple but slow way to handle overflow.
+  APInt Val(std::max(64U, RadixBits * N), 0);
+  APInt RadixVal(Val.getBitWidth(), Radix);
+  APInt DigitVal(Val.getBitWidth(), 0);
+  for (unsigned i=0; i<N; ++i) {
+    unsigned Digit, Char = S[i];
+    
+    if (Char == '_')
+      continue;
+    
+    if ('0' <= Char && Char <= '9')
+      Digit = Char - '0';
+    else if ('a' <= Char && Char <= 'z')
+      Digit = Char - 'a' + 10;
+    else if ('A' <= Char && Char <= 'Z')
+      Digit = Char - 'A' + 10;
+    else {
+      Error("invalid character in numeric token.", Tok);
+      return ref<Expr>(0, Type);
+    }
+
+    if (Digit >= Radix) {
+      Error("invalid character in numeric token (out of range).", Tok);
+      return ref<Expr>(0, Type);
+    }
+
+    DigitVal = Digit;
+    Val = Val * RadixVal + DigitVal;
+  }
+
+  // FIXME: Actually do the check for overflow.
+  if (HasMinus)
+    Val = -Val;
+
+  return ExprResult(ref<Expr>(Val.trunc(Type).getZExtValue(), Type));
+}
+
+/// ParseTypeSpecifier - Parse a type specifier.
+///
+/// type = w[0-9]+
+TypeResult ParserImpl::ParseTypeSpecifier() {
+  assert(Tok.kind == Token::KWWidth && "Unexpected token.");
+
+  // FIXME: Need APInt technically.
+  Token TypeTok = Tok;
+  int width = atoi(std::string(Tok.start+1,Tok.length-1).c_str());
+  ConsumeToken();
+
+  // FIXME: We should impose some sort of maximum just for sanity?
+  return TypeResult(width);
+}
+
+void ParserImpl::Error(const char *Message, const Token &At) {
+  ++NumErrors;
+  if (MaxErrors && NumErrors >= MaxErrors)
+    return;
+
+  llvm::cerr << Filename 
+             << ":" << At.line << ":" << At.column 
+             << ": error: " << Message << "\n";
+
+  // Skip carat diagnostics on EOF token.
+  if (At.kind == Token::EndOfFile)
+    return;
+  
+  // Simple caret style diagnostics.
+  const char *LineBegin = At.start, *LineEnd = At.start,
+    *BufferBegin = TheMemoryBuffer->getBufferStart(),
+    *BufferEnd = TheMemoryBuffer->getBufferEnd();
+
+  // Run line pointers forward and back.
+  while (LineBegin > BufferBegin && 
+         LineBegin[-1] != '\r' && LineBegin[-1] != '\n')
+    --LineBegin;
+  while (LineEnd < BufferEnd && 
+         LineEnd[0] != '\r' && LineEnd[0] != '\n')
+    ++LineEnd;
+
+  // Show the line.
+  llvm::cerr << std::string(LineBegin, LineEnd) << "\n";
+
+  // Show the caret or squiggly, making sure to print back spaces the
+  // same.
+  for (const char *S=LineBegin; S != At.start; ++S)
+    llvm::cerr << (isspace(*S) ? *S : ' ');
+  if (At.length > 1) {
+    for (unsigned i=0; i<At.length; ++i)
+      llvm::cerr << '~';
+  } else
+    llvm::cerr << '^';
+  llvm::cerr << '\n';
+}
+
+// AST API
+// FIXME: Move out of parser.
+
+Decl::Decl() {}
+
+void QueryCommand::dump() {
+  // FIXME: This is masking the difference between an actual query and
+  // a query decl.
+  ExprPPrinter::printQuery(std::cerr, 
+                           ConstraintManager(Constraints), 
+                           Query);
+}
+
+// Public parser API
+
+Parser::Parser() {
+}
+
+Parser::~Parser() {
+}
+
+Parser *Parser::Create(const std::string Filename,
+                       const MemoryBuffer *MB) {
+  ParserImpl *P = new ParserImpl(Filename, MB);
+  P->Initialize();
+  return P;
+}
diff --git a/lib/Expr/Updates.cpp b/lib/Expr/Updates.cpp
new file mode 100644
index 00000000..b2ceeaf1
--- /dev/null
+++ b/lib/Expr/Updates.cpp
@@ -0,0 +1,126 @@
+//===-- Updates.cpp -------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Expr.h"
+
+#include <cassert>
+
+using namespace klee;
+
+///
+
+UpdateNode::UpdateNode(const UpdateNode *_next, 
+                       const ref<Expr> &_index, 
+                       const ref<Expr> &_value) 
+  : refCount(0),
+    stpArray(0),
+    next(_next),
+    index(_index),
+    value(_value) {
+  assert(_value.getWidth() == Expr::Int8 && "Update value should be 8-bit wide.");
+  computeHash();
+  if (next) {
+    ++next->refCount;
+    size = 1 + next->size;
+  }
+  else size = 1;
+}
+
+extern "C" void vc_DeleteExpr(void*);
+
+UpdateNode::~UpdateNode() {
+  // XXX gross
+  if (stpArray)
+    ::vc_DeleteExpr(stpArray);
+}
+
+int UpdateNode::compare(const UpdateNode &b) const {
+  if (int i = index.compare(b.index)) 
+    return i;
+  return value.compare(b.value);
+}
+
+unsigned UpdateNode::computeHash() {
+  hashValue = index.hash() ^ value.hash();
+  if (next)
+    hashValue ^= next->hash();
+  return hashValue;
+}
+
+///
+
+UpdateList::UpdateList(const Array *_root, bool _isRooted,
+                       const UpdateNode *_head)
+  : root(_root),
+    head(_head),
+    isRooted(_isRooted) {
+  if (head) ++head->refCount;
+}
+
+UpdateList::UpdateList(const UpdateList &b)
+  : root(b.root),
+    head(b.head),
+    isRooted(b.isRooted) {
+  if (head) ++head->refCount;
+}
+
+UpdateList::~UpdateList() {
+  // We need to be careful and avoid recursion here. We do this in
+  // cooperation with the private dtor of UpdateNode which does not
+  // recursively free its tail.
+  while (head && --head->refCount==0) {
+    const UpdateNode *n = head->next;
+    delete head;
+    head = n;
+  }
+}
+
+UpdateList &UpdateList::operator=(const UpdateList &b) {
+  if (b.head) ++b.head->refCount;
+  if (head && --head->refCount==0) delete head;
+  root = b.root;
+  head = b.head;
+  isRooted = b.isRooted;
+  return *this;
+}
+
+void UpdateList::extend(const ref<Expr> &index, const ref<Expr> &value) {
+  if (head) --head->refCount;
+  head = new UpdateNode(head, index, value);
+  ++head->refCount;
+}
+
+int UpdateList::compare(const UpdateList &b) const {
+  // use object id to increase determinism
+  if (root->id != b.root->id) 
+    return root->id < b.root->id ? -1 : 1;
+  
+  if (getSize() < b.getSize()) return -1;
+  else if (getSize() > b.getSize()) return 1;    
+
+  // XXX build comparison into update, make fast
+  const UpdateNode *an=head, *bn=b.head;
+  for (; an && bn; an=an->next,bn=bn->next) {
+    if (an==bn) { // exploit shared list structure
+      return 0;
+    } else {
+      if (int res = an->compare(*bn))
+        return res;
+    }
+  }
+  assert(!an && !bn);
+  return 0;
+}
+
+unsigned UpdateList::hash() const {
+  unsigned res = root->id * Expr::MAGIC_HASH_CONSTANT;
+  if (head)
+    res ^= head->hash();
+  return res;
+}
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 00000000..e12fef50
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,15 @@
+#===-- lib/Makefile ----------------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=..
+
+PARALLEL_DIRS=Basic Support Expr Solver Module Core
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Module/Checks.cpp b/lib/Module/Checks.cpp
new file mode 100644
index 00000000..ca4eeb44
--- /dev/null
+++ b/lib/Module/Checks.cpp
@@ -0,0 +1,68 @@
+//===-- Checks.cpp --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Passes.h"
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Type.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Target/TargetData.h"
+
+using namespace llvm;
+using namespace klee;
+
+char DivCheckPass::ID;
+
+bool DivCheckPass::runOnModule(Module &M) { 
+  Function *divZeroCheckFunction = 0;
+
+  bool moduleChanged = false;
+  
+  for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) {
+    for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) {
+      for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) {     
+          if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) {
+          // find all [s|u][div|mod] instructions
+          Instruction::BinaryOps opcode = binOp->getOpcode();
+          if (opcode == Instruction::SDiv || opcode == Instruction::UDiv ||
+              opcode == Instruction::SRem || opcode == Instruction::URem) {
+            
+            CastInst *denominator =
+              CastInst::CreateIntegerCast(i->getOperand(1),
+                                          (Type*)Type::Int64Ty,
+                                          false,  /* sign doesn't matter */
+                                          "int_cast_to_i64",
+                                          i);
+            
+            // Lazily bind the function to avoid always importing it.
+            if (!divZeroCheckFunction) {
+              Constant *fc = M.getOrInsertFunction("klee_div_zero_check", 
+                                                   Type::VoidTy, 
+                                                   Type::Int64Ty, NULL);
+              divZeroCheckFunction = cast<Function>(fc);
+            }
+
+	    CallInst::Create(divZeroCheckFunction, denominator, "", &*i);
+            moduleChanged = true;
+          }
+        }
+      }
+    }
+  }
+  return moduleChanged;
+}
diff --git a/lib/Module/InstructionInfoTable.cpp b/lib/Module/InstructionInfoTable.cpp
new file mode 100644
index 00000000..82874406
--- /dev/null
+++ b/lib/Module/InstructionInfoTable.cpp
@@ -0,0 +1,196 @@
+//===-- InstructionInfoTable.cpp ------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Internal/Module/InstructionInfoTable.h"
+
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Linker.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/AsmAnnotationWriter.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Analysis/ValueTracking.h"
+
+#include <map>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+
+using namespace llvm;
+using namespace klee;
+
+class InstructionToLineAnnotator : public llvm::AssemblyAnnotationWriter {
+public:
+  void emitInstructionAnnot(const Instruction *i, llvm::raw_ostream &os) {
+    os << "%%%" << (uintptr_t) i;
+  }
+};
+        
+static void buildInstructionToLineMap(Module *m,
+                                      std::map<const Instruction*, unsigned> &out) {  
+  InstructionToLineAnnotator a;
+  std::ostringstream buffer;
+  m->print(buffer, &a);
+  std::string str = buffer.str();
+  const char *s;
+
+  unsigned line = 1;
+  for (s=str.c_str(); *s; s++) {
+    if (*s=='\n') {
+      line++;
+      if (s[1]=='%' && s[2]=='%' && s[3]=='%') {
+        s += 4;
+        char *end;
+        unsigned long long value = strtoull(s, &end, 10);
+        if (end!=s) {
+          out.insert(std::make_pair((const Instruction*) value, line));
+        }
+        s = end;
+      }
+    }
+  }
+}
+
+static std::string getDSPIPath(DbgStopPointInst *dspi) {
+  std::string dir, file;
+  bool res = GetConstantStringInfo(dspi->getDirectory(), dir);
+  assert(res && "GetConstantStringInfo failed");
+  res = GetConstantStringInfo(dspi->getFileName(), file);
+  assert(res && "GetConstantStringInfo failed");
+  if (dir.empty()) {
+    return file;
+  } else if (*dir.rbegin() == '/') {
+    return dir + file;
+  } else {
+    return dir + "/" + file;
+  }
+}
+
+InstructionInfoTable::InstructionInfoTable(Module *m) 
+  : dummyString(""), dummyInfo(0, dummyString, 0, 0) {
+  unsigned id = 0;
+  std::map<const Instruction*, unsigned> lineTable;
+  buildInstructionToLineMap(m, lineTable);
+
+  for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
+       fnIt != fn_ie; ++fnIt) {
+    const std::string *initialFile = &dummyString;
+    unsigned initialLine = 0;
+
+    // It may be better to look for the closest stoppoint to the entry
+    // following the CFG, but it is not clear that it ever matters in
+    // practice.
+    for (inst_iterator it = inst_begin(fnIt), ie = inst_end(fnIt);
+         it != ie; ++it) {
+      if (DbgStopPointInst *dspi = dyn_cast<DbgStopPointInst>(&*it)) {
+        initialFile = internString(getDSPIPath(dspi));
+        initialLine = dspi->getLine();
+        break;
+      }
+    }
+    
+    typedef std::map<BasicBlock*, std::pair<const std::string*,unsigned> > 
+      sourceinfo_ty;
+    sourceinfo_ty sourceInfo;
+    for (llvm::Function::iterator bbIt = fnIt->begin(), bbie = fnIt->end(); 
+         bbIt != bbie; ++bbIt) {
+      std::pair<sourceinfo_ty::iterator, bool>
+        res = sourceInfo.insert(std::make_pair(bbIt,
+                                               std::make_pair(initialFile,
+                                                              initialLine)));
+      if (!res.second)
+        continue;
+
+      std::vector<BasicBlock*> worklist;
+      worklist.push_back(bbIt);
+
+      do {
+        BasicBlock *bb = worklist.back();
+        worklist.pop_back();
+
+        sourceinfo_ty::iterator si = sourceInfo.find(bb);
+        assert(si != sourceInfo.end());
+        const std::string *file = si->second.first;
+        unsigned line = si->second.second;
+        
+        for (BasicBlock::iterator it = bb->begin(), ie = bb->end();
+             it != ie; ++it) {
+          Instruction *instr = it;
+          unsigned assemblyLine = 0;
+          std::map<const Instruction*, unsigned>::const_iterator ltit = 
+            lineTable.find(instr);
+          if (ltit!=lineTable.end())
+            assemblyLine = ltit->second;
+          if (DbgStopPointInst *dspi = dyn_cast<DbgStopPointInst>(instr)) {
+            file = internString(getDSPIPath(dspi));
+            line = dspi->getLine();
+          }
+          infos.insert(std::make_pair(instr,
+                                      InstructionInfo(id++,
+                                                      *file,
+                                                      line,
+                                                      assemblyLine)));        
+        }
+        
+        for (succ_iterator it = succ_begin(bb), ie = succ_end(bb); 
+             it != ie; ++it) {
+          if (sourceInfo.insert(std::make_pair(*it,
+                                               std::make_pair(file, line))).second)
+            worklist.push_back(*it);
+        }
+      } while (!worklist.empty());
+    }
+  }
+}
+
+InstructionInfoTable::~InstructionInfoTable() {
+  for (std::set<const std::string *, ltstr>::iterator
+         it = internedStrings.begin(), ie = internedStrings.end();
+       it != ie; ++it)
+    delete *it;
+}
+
+const std::string *InstructionInfoTable::internString(std::string s) {
+  std::set<const std::string *, ltstr>::iterator it = internedStrings.find(&s);
+  if (it==internedStrings.end()) {
+    std::string *interned = new std::string(s);
+    internedStrings.insert(interned);
+    return interned;
+  } else {
+    return *it;
+  }
+}
+
+unsigned InstructionInfoTable::getMaxID() const {
+  return infos.size();
+}
+
+const InstructionInfo &
+InstructionInfoTable::getInfo(const Instruction *inst) const {
+  std::map<const llvm::Instruction*, InstructionInfo>::const_iterator it = 
+    infos.find(inst);
+  if (it==infos.end()) {
+    return dummyInfo;
+  } else {
+    return it->second;
+  }
+}
+
+const InstructionInfo &
+InstructionInfoTable::getFunctionInfo(const Function *f) const {
+  if (f->isDeclaration()) {
+    return dummyInfo;
+  } else {
+    return getInfo(f->begin()->begin());
+  }
+}
diff --git a/lib/Module/IntrinsicCleaner.cpp b/lib/Module/IntrinsicCleaner.cpp
new file mode 100644
index 00000000..e59b7ff6
--- /dev/null
+++ b/lib/Module/IntrinsicCleaner.cpp
@@ -0,0 +1,119 @@
+//===-- IntrinsicCleaner.cpp ----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Passes.h"
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Type.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Target/TargetData.h"
+
+using namespace llvm;
+
+namespace klee {
+
+char IntrinsicCleanerPass::ID;
+
+bool IntrinsicCleanerPass::runOnModule(Module &M) {
+  bool dirty = false;
+  for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f)
+    for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b)
+        dirty |= runOnBasicBlock(*b);
+  return dirty;
+}
+
+bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b) { 
+  bool dirty = false;
+
+  for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie;) {     
+    IntrinsicInst *ii = dyn_cast<IntrinsicInst>(&*i);
+    // increment now since LowerIntrinsic deletion makes iterator invalid.
+    ++i;  
+    if(ii) {
+      switch (ii->getIntrinsicID()) {
+      case Intrinsic::vastart:
+      case Intrinsic::vaend:
+        break;
+        
+        // Lower vacopy so that object resolution etc is handled by
+        // normal instructions.  FIXME: This is broken for non-x86_32.
+      case Intrinsic::vacopy: { // (dst, src) -> *((i8**) dst) = *((i8**) src)
+        Value *dst = ii->getOperand(1);
+        Value *src = ii->getOperand(2);
+        Type *i8pp = PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty));
+        Value *castedDst = CastInst::CreatePointerCast(dst, i8pp, "vacopy.cast.dst", ii);
+        Value *castedSrc = CastInst::CreatePointerCast(src, i8pp, "vacopy.cast.src", ii);
+        Value *load = new LoadInst(castedSrc, "vacopy.read", ii);
+        new StoreInst(load, castedDst, false, ii);
+        ii->removeFromParent();
+        delete ii;
+        break;
+      }
+
+      case Intrinsic::dbg_stoppoint: {
+        // We can remove this stoppoint if the next instruction is
+        // sure to be another stoppoint. This is nice for cleanliness
+        // but also important for switch statements where it can allow
+        // the targets to be joined.
+        bool erase = false;
+        if (isa<DbgStopPointInst>(i) ||
+            isa<UnreachableInst>(i)) {
+          erase = true;
+        } else if (isa<BranchInst>(i) ||
+                   isa<SwitchInst>(i)) {
+          BasicBlock *bb = i->getParent();
+          erase = true;
+          for (succ_iterator it=succ_begin(bb), ie=succ_end(bb);
+               it!=ie; ++it) {
+            if (!isa<DbgStopPointInst>(it->getFirstNonPHI())) {
+              erase = false;
+              break;
+            }
+          }
+        }
+
+        if (erase) {
+          ii->eraseFromParent();
+          dirty = true;
+        }
+        break;
+      }
+
+      case Intrinsic::dbg_region_start:
+      case Intrinsic::dbg_region_end:
+      case Intrinsic::dbg_func_start:
+      case Intrinsic::dbg_declare:
+        // Remove these regardless of lower intrinsics flag. This can
+        // be removed once IntrinsicLowering is fixed to not have bad
+        // caches.
+        ii->eraseFromParent();
+        dirty = true;
+        break;
+                    
+      default:
+        if (LowerIntrinsics)
+          IL->LowerIntrinsicCall(ii);
+        dirty = true;
+        break;
+      }
+    }
+  }
+
+  return dirty;
+}
+}
diff --git a/lib/Module/KInstruction.cpp b/lib/Module/KInstruction.cpp
new file mode 100644
index 00000000..799620c6
--- /dev/null
+++ b/lib/Module/KInstruction.cpp
@@ -0,0 +1,19 @@
+//===-- KInstruction.cpp --------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Internal/Module/KInstruction.h"
+
+using namespace llvm;
+using namespace klee;
+
+/***/
+
+KInstruction::~KInstruction() {
+  delete[] operands;
+}
diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp
new file mode 100644
index 00000000..5d88fbda
--- /dev/null
+++ b/lib/Module/KModule.cpp
@@ -0,0 +1,506 @@
+//===-- KModule.cpp -------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: This does not belong here.
+#include "../Core/Common.h"
+
+#include "klee/Internal/Module/KModule.h"
+
+#include "Passes.h"
+
+#include "klee/Interpreter.h"
+#include "klee/Internal/Module/Cell.h"
+#include "klee/Internal/Module/KInstruction.h"
+#include "klee/Internal/Module/InstructionInfoTable.h"
+#include "klee/Internal/Support/ModuleUtil.h"
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/System/Path.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/Scalar.h"
+
+#include <sstream>
+
+using namespace llvm;
+using namespace klee;
+
+namespace {
+  enum SwitchImplType {
+    eSwitchTypeSimple,
+    eSwitchTypeLLVM,
+    eSwitchTypeInternal
+  };
+
+  cl::list<std::string>
+  MergeAtExit("merge-at-exit");
+    
+  cl::opt<bool>
+  NoTruncateSourceLines("no-truncate-source-lines",
+                        cl::desc("Don't truncate long lines in the output source"));
+
+  cl::opt<bool>
+  OutputSource("output-source",
+               cl::desc("Write the assembly for the final transformed source"),
+               cl::init(true));
+
+  cl::opt<bool>
+  OutputModule("output-module",
+               cl::desc("Write the bitcode for the final transformed module"),
+               cl::init(false));
+
+  cl::opt<SwitchImplType>
+  SwitchType("switch-type", cl::desc("Select the implementation of switch"),
+             cl::values(clEnumValN(eSwitchTypeSimple, "simple", 
+                                   "lower to ordered branches"),
+                        clEnumValN(eSwitchTypeLLVM, "llvm", 
+                                   "lower using LLVM"),
+                        clEnumValN(eSwitchTypeInternal, "internal", 
+                                   "execute switch internally"),
+                        clEnumValEnd),
+             cl::init(eSwitchTypeInternal));
+  
+  cl::opt<bool>
+  DebugPrintEscapingFunctions("debug-print-escaping-functions", 
+                              cl::desc("Print functions whose address is taken."));
+}
+
+KModule::KModule(Module *_module) 
+  : module(_module),
+    targetData(new TargetData(module)),
+    dbgStopPointFn(0),
+    kleeMergeFn(0),
+    infos(0),
+    constantTable(0) {
+}
+
+KModule::~KModule() {
+  delete[] constantTable;
+  delete infos;
+
+  for (std::vector<KFunction*>::iterator it = functions.begin(), 
+         ie = functions.end(); it != ie; ++it)
+    delete *it;
+
+  delete targetData;
+  delete module;
+}
+
+/***/
+
+namespace llvm {
+extern void Optimize(Module*);
+}
+
+// what a hack
+static Function *getStubFunctionForCtorList(Module *m,
+                                            GlobalVariable *gv, 
+                                            std::string name) {
+  assert(!gv->isDeclaration() && !gv->hasInternalLinkage() &&
+         "do not support old LLVM style constructor/destructor lists");
+  
+  std::vector<const Type*> nullary;
+
+  Function *fn = Function::Create(FunctionType::get(Type::VoidTy, 
+						    nullary, false),
+				  GlobalVariable::InternalLinkage, 
+				  name,
+                              m);
+  BasicBlock *bb = BasicBlock::Create("entry", fn);
+  
+  // From lli:
+  // Should be an array of '{ int, void ()* }' structs.  The first value is
+  // the init priority, which we ignore.
+  ConstantArray *arr = dyn_cast<ConstantArray>(gv->getInitializer());
+  if (arr) {
+    for (unsigned i=0; i<arr->getNumOperands(); i++) {
+      ConstantStruct *cs = cast<ConstantStruct>(arr->getOperand(i));
+      assert(cs->getNumOperands()==2 && "unexpected element in ctor initializer list");
+      
+      Constant *fp = cs->getOperand(1);      
+      if (!fp->isNullValue()) {
+        if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(fp))
+          fp = ce->getOperand(0);
+
+        if (Function *f = dyn_cast<Function>(fp)) {
+	  CallInst::Create(f, "", bb);
+        } else {
+          assert(0 && "unable to get function pointer from ctor initializer list");
+        }
+      }
+    }
+  }
+  
+  ReturnInst::Create(bb);
+
+  return fn;
+}
+
+static void injectStaticConstructorsAndDestructors(Module *m) {
+  GlobalVariable *ctors = m->getNamedGlobal("llvm.global_ctors");
+  GlobalVariable *dtors = m->getNamedGlobal("llvm.global_dtors");
+  
+  if (ctors || dtors) {
+    Function *mainFn = m->getFunction("main");
+    assert(mainFn && "unable to find main function");
+
+    if (ctors)
+    CallInst::Create(getStubFunctionForCtorList(m, ctors, "klee.ctor_stub"),
+		     "", mainFn->begin()->begin());
+    if (dtors) {
+      Function *dtorStub = getStubFunctionForCtorList(m, dtors, "klee.dtor_stub");
+      for (Function::iterator it = mainFn->begin(), ie = mainFn->end();
+           it != ie; ++it) {
+        if (isa<ReturnInst>(it->getTerminator()))
+	  CallInst::Create(dtorStub, "", it->getTerminator());
+      }
+    }
+  }
+}
+
+static void forceImport(Module *m, const char *name, const Type *retType, ...) {
+  // If module lacks an externally visible symbol for the name then we
+  // need to create one. We have to look in the symbol table because
+  // we want to check everything (global variables, functions, and
+  // aliases).
+
+  Value *v = m->getValueSymbolTable().lookup(name);
+  GlobalValue *gv = dyn_cast_or_null<GlobalValue>(v);
+
+  if (!gv || gv->hasInternalLinkage()) {
+    va_list ap;
+
+    va_start(ap, retType);
+    std::vector<const Type *> argTypes;
+    while (const Type *t = va_arg(ap, const Type*))
+      argTypes.push_back(t);
+    va_end(ap);
+
+    m->getOrInsertFunction(name, FunctionType::get(retType, argTypes, false));
+  }
+}
+
+void KModule::prepare(const Interpreter::ModuleOptions &opts,
+                      InterpreterHandler *ih) {
+  if (!MergeAtExit.empty()) {
+    Function *mergeFn = module->getFunction("klee_merge");
+    if (!mergeFn) {
+      const llvm::FunctionType *Ty = 
+        FunctionType::get(Type::VoidTy, std::vector<const Type*>(), false);
+      mergeFn = Function::Create(Ty, GlobalVariable::ExternalLinkage,
+				 "klee_merge",
+				 module);
+    }
+
+    for (cl::list<std::string>::iterator it = MergeAtExit.begin(), 
+           ie = MergeAtExit.end(); it != ie; ++it) {
+      std::string &name = *it;
+      Function *f = module->getFunction(name);
+      if (!f) {
+        klee_error("cannot insert merge-at-exit for: %s (cannot find)",
+                   name.c_str());
+      } else if (f->isDeclaration()) {
+        klee_error("cannot insert merge-at-exit for: %s (external)",
+                   name.c_str());
+      }
+
+      BasicBlock *exit = BasicBlock::Create("exit", f);
+      PHINode *result = 0;
+      if (f->getReturnType() != Type::VoidTy)
+        result = PHINode::Create(f->getReturnType(), "retval", exit);
+      CallInst::Create(mergeFn, "", exit);
+      ReturnInst::Create(result, exit);
+
+      llvm::cerr << "KLEE: adding klee_merge at exit of: " << name << "\n";
+      for (llvm::Function::iterator bbit = f->begin(), bbie = f->end(); 
+           bbit != bbie; ++bbit) {
+        if (&*bbit != exit) {
+          Instruction *i = bbit->getTerminator();
+          if (i->getOpcode()==Instruction::Ret) {
+            if (result) {
+              result->addIncoming(i->getOperand(0), bbit);
+            }
+            i->eraseFromParent();
+	    BranchInst::Create(exit, bbit);
+          }
+        }
+      }
+    }
+  }
+
+  // Inject checks prior to optimization... we also perform the
+  // invariant transformations that we will end up doing later so that
+  // optimize is seeing what is as close as possible to the final
+  // module.
+  PassManager pm;
+  pm.add(new RaiseAsmPass());
+  if (opts.CheckDivZero) pm.add(new DivCheckPass());
+  // FIXME: This false here is to work around a bug in
+  // IntrinsicLowering which caches values which may eventually be
+  // deleted (via RAUW). This can be removed once LLVM fixes this
+  // issue.
+  pm.add(new IntrinsicCleanerPass(*targetData, false));
+  pm.run(*module);
+
+  if (opts.Optimize)
+    Optimize(module);
+
+  // Force importing functions required by intrinsic lowering. Kind of
+  // unfortunate clutter when we don't need them but we won't know
+  // that until after all linking and intrinsic lowering is
+  // done. After linking and passes we just try to manually trim these
+  // by name. We only add them if such a function doesn't exist to
+  // avoid creating stale uses.
+
+  forceImport(module, "memcpy", PointerType::getUnqual(Type::Int8Ty),
+              PointerType::getUnqual(Type::Int8Ty),
+              PointerType::getUnqual(Type::Int8Ty),
+              targetData->getIntPtrType(), (Type*) 0);
+  forceImport(module, "memmove", PointerType::getUnqual(Type::Int8Ty),
+              PointerType::getUnqual(Type::Int8Ty),
+              PointerType::getUnqual(Type::Int8Ty),
+              targetData->getIntPtrType(), (Type*) 0);
+  forceImport(module, "memset", PointerType::getUnqual(Type::Int8Ty),
+              PointerType::getUnqual(Type::Int8Ty),
+              Type::Int32Ty,
+              targetData->getIntPtrType(), (Type*) 0);
+
+  // FIXME: Missing force import for various math functions.
+
+  // FIXME: Find a way that we can test programs without requiring
+  // this to be linked in, it makes low level debugging much more
+  // annoying.
+  llvm::sys::Path path(opts.LibraryDir);
+  path.appendComponent("libintrinsic.bca");
+  module = linkWithLibrary(module, path.c_str());
+
+  // Needs to happen after linking (since ctors/dtors can be modified)
+  // and optimization (since global optimization can rewrite lists).
+  injectStaticConstructorsAndDestructors(module);
+
+  // Finally, run the passes that maintain invariants we expect during
+  // interpretation. We run the intrinsic cleaner just in case we
+  // linked in something with intrinsics but any external calls are
+  // going to be unresolved. We really need to handle the intrinsics
+  // directly I think?
+  PassManager pm3;
+  pm3.add(createCFGSimplificationPass());
+  switch(SwitchType) {
+  case eSwitchTypeInternal: break;
+  case eSwitchTypeSimple: pm3.add(new LowerSwitchPass()); break;
+  case eSwitchTypeLLVM:  pm3.add(createLowerSwitchPass()); break;
+  default: klee_error("invalid --switch-type");
+  }
+  pm3.add(new IntrinsicCleanerPass(*targetData));
+  pm3.add(new PhiCleanerPass());
+  pm3.run(*module);
+
+  // For cleanliness see if we can discard any of the functions we
+  // forced to import.
+  Function *f;
+  f = module->getFunction("memcpy");
+  if (f && f->use_empty()) f->eraseFromParent();
+  f = module->getFunction("memmove");
+  if (f && f->use_empty()) f->eraseFromParent();
+  f = module->getFunction("memset");
+  if (f && f->use_empty()) f->eraseFromParent();
+
+
+  // Write out the .ll assembly file. We truncate long lines to work
+  // around a kcachegrind parsing bug (it puts them on new lines), so
+  // that source browsing works.
+  if (OutputSource) {
+    std::ostream *os = ih->openOutputFile("assembly.ll");
+    assert(os && os->good() && "unable to open source output");
+
+    // We have an option for this in case the user wants a .ll they
+    // can compile.
+    if (NoTruncateSourceLines) {
+      *os << *module;
+    } else {
+      bool truncated = false;
+      std::stringstream buffer;
+      buffer << *module;
+      std::string string = buffer.str();
+      const char *position = string.c_str();
+
+      for (;;) {
+        const char *end = index(position, '\n');
+        if (!end) {
+          *os << position;
+          break;
+        } else {
+          unsigned count = (end - position) + 1;
+          if (count<255) {
+            os->write(position, count);
+          } else {
+            os->write(position, 254);
+            *os << "\n";
+            truncated = true;
+          }
+          position = end+1;
+        }
+      }
+    }
+
+    delete os;
+  }
+
+  if (OutputModule) {
+    std::ostream *f = ih->openOutputFile("final.bc");
+    WriteBitcodeToFile(module, *f);
+    delete f;
+  }
+
+  dbgStopPointFn = module->getFunction("llvm.dbg.stoppoint");
+  kleeMergeFn = module->getFunction("klee_merge");
+
+  /* Build shadow structures */
+
+  infos = new InstructionInfoTable(module);  
+  
+  for (Module::iterator it = module->begin(), ie = module->end();
+       it != ie; ++it) {
+    if (it->isDeclaration())
+      continue;
+
+    KFunction *kf = new KFunction(it, this);
+    
+    for (unsigned i=0; i<kf->numInstructions; ++i) {
+      KInstruction *ki = kf->instructions[i];
+      ki->info = &infos->getInfo(ki->inst);
+    }
+
+    functions.push_back(kf);
+    functionMap.insert(std::make_pair(it, kf));
+  }
+
+  /* Compute various interesting properties */
+
+  for (std::vector<KFunction*>::iterator it = functions.begin(), 
+         ie = functions.end(); it != ie; ++it) {
+    KFunction *kf = *it;
+    if (functionEscapes(kf->function))
+      escapingFunctions.insert(kf->function);
+  }
+
+  if (DebugPrintEscapingFunctions && !escapingFunctions.empty()) {
+    llvm::cerr << "KLEE: escaping functions: [";
+    for (std::set<Function*>::iterator it = escapingFunctions.begin(), 
+         ie = escapingFunctions.end(); it != ie; ++it) {
+      llvm::cerr << (*it)->getName() << ", ";
+    }
+    llvm::cerr << "]\n";
+  }
+}
+
+KConstant* KModule::getKConstant(Constant *c) {
+  std::map<llvm::Constant*, KConstant*>::iterator it = constantMap.find(c);
+  if (it != constantMap.end())
+    return it->second;
+  return NULL;
+}
+
+unsigned KModule::getConstantID(Constant *c, KInstruction* ki) {
+  KConstant *kc = getKConstant(c);
+  if (kc)
+    return kc->id;  
+
+  unsigned id = constants.size();
+  kc = new KConstant(c, id, ki);
+  constantMap.insert(std::make_pair(c, kc));
+  constants.push_back(c);
+  return id;
+}
+
+/***/
+
+KConstant::KConstant(llvm::Constant* _ct, unsigned _id, KInstruction* _ki) {
+  ct = _ct;
+  id = _id;
+  ki = _ki;
+}
+
+/***/
+
+KFunction::KFunction(llvm::Function *_function,
+                     KModule *km) 
+  : function(_function),
+    numArgs(function->arg_size()),
+    numInstructions(0),
+    trackCoverage(true) {
+  for (llvm::Function::iterator bbit = function->begin(), 
+         bbie = function->end(); bbit != bbie; ++bbit) {
+    BasicBlock *bb = bbit;
+    basicBlockEntry[bb] = numInstructions;
+    numInstructions += bb->size();
+  }
+
+  instructions = new KInstruction*[numInstructions];
+
+  std::map<Instruction*, unsigned> registerMap;
+
+  // The first arg_size() registers are reserved for formals.
+  unsigned rnum = numArgs;
+  for (llvm::Function::iterator bbit = function->begin(), 
+         bbie = function->end(); bbit != bbie; ++bbit) {
+    for (llvm::BasicBlock::iterator it = bbit->begin(), ie = bbit->end();
+         it != ie; ++it)
+      registerMap[it] = rnum++;
+  }
+  numRegisters = rnum;
+  
+  unsigned i = 0;
+  for (llvm::Function::iterator bbit = function->begin(), 
+         bbie = function->end(); bbit != bbie; ++bbit) {
+    for (llvm::BasicBlock::iterator it = bbit->begin(), ie = bbit->end();
+         it != ie; ++it) {
+      KInstruction *ki;
+
+      switch(it->getOpcode()) {
+      case Instruction::GetElementPtr:
+        ki = new KGEPInstruction(); break;
+      default:
+        ki = new KInstruction(); break;
+      }
+
+      unsigned numOperands = it->getNumOperands();
+      ki->inst = it;      
+      ki->operands = new int[numOperands];
+      ki->dest = registerMap[it];
+      for (unsigned j=0; j<numOperands; j++) {
+        Value *v = it->getOperand(j);
+        
+        if (Instruction *inst = dyn_cast<Instruction>(v)) {
+          ki->operands[j] = registerMap[inst];
+        } else if (Argument *a = dyn_cast<Argument>(v)) {
+          ki->operands[j] = a->getArgNo();
+        } else if (isa<BasicBlock>(v) || isa<InlineAsm>(v)) {
+          ki->operands[j] = -1;
+        } else {
+          assert(isa<Constant>(v));
+          Constant *c = cast<Constant>(v);
+          ki->operands[j] = -(km->getConstantID(c, ki) + 2);
+        }
+      }
+
+      instructions[i++] = ki;
+    }
+  }
+}
+
+KFunction::~KFunction() {
+  for (unsigned i=0; i<numInstructions; ++i)
+    delete instructions[i];
+  delete[] instructions;
+}
diff --git a/lib/Module/LowerSwitch.cpp b/lib/Module/LowerSwitch.cpp
new file mode 100644
index 00000000..a1b887f3
--- /dev/null
+++ b/lib/Module/LowerSwitch.cpp
@@ -0,0 +1,134 @@
+//===-- LowerSwitch.cpp - Eliminate Switch instructions -------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Derived from LowerSwitch.cpp in LLVM, heavily modified by piotrek
+// to get rid of the binary search transform, as it was creating
+// multiple paths through the program (i.e., extra paths that didn't
+// exist in the original program).
+//
+//===----------------------------------------------------------------------===//
+
+#include "Passes.h"
+#include <algorithm>
+
+using namespace llvm;
+
+namespace klee {
+
+char LowerSwitchPass::ID = 0;
+
+// The comparison function for sorting the switch case values in the vector.
+struct SwitchCaseCmp {
+  bool operator () (const LowerSwitchPass::SwitchCase& C1,
+                    const LowerSwitchPass::SwitchCase& C2) {
+    
+    const ConstantInt* CI1 = cast<const ConstantInt>(C1.value);
+    const ConstantInt* CI2 = cast<const ConstantInt>(C2.value);
+    return CI1->getValue().slt(CI2->getValue());
+  }
+};
+
+bool LowerSwitchPass::runOnFunction(Function &F) {
+  bool changed = false;
+
+  for (Function::iterator I = F.begin(), E = F.end(); I != E; ) {
+    BasicBlock *cur = I++; // Advance over block so we don't traverse new blocks
+
+    if (SwitchInst *SI = dyn_cast<SwitchInst>(cur->getTerminator())) {
+      changed = true;
+      processSwitchInst(SI);
+    }
+  }
+
+  return changed;
+}
+
+// switchConvert - Convert the switch statement into a linear scan
+// through all the case values
+void LowerSwitchPass::switchConvert(CaseItr begin, CaseItr end,
+                                    Value* value, BasicBlock* origBlock,
+                                    BasicBlock* defaultBlock)
+{
+  BasicBlock *curHead = defaultBlock;
+  Function *F = origBlock->getParent();
+  
+  // iterate through all the cases, creating a new BasicBlock for each
+  for (CaseItr it = begin; it < end; ++it) {
+    BasicBlock *newBlock = BasicBlock::Create("NodeBlock");
+    Function::iterator FI = origBlock;
+    F->getBasicBlockList().insert(++FI, newBlock);
+    
+    ICmpInst *cmpInst = new ICmpInst(ICmpInst::ICMP_EQ,
+                                     value,
+                                     it->value,
+                                     "Case Comparison");
+    
+    newBlock->getInstList().push_back(cmpInst);
+    BranchInst::Create(it->block, curHead, cmpInst, newBlock);
+
+    // If there were any PHI nodes in this successor, rewrite one entry
+    // from origBlock to come from newBlock.
+    for (BasicBlock::iterator bi = it->block->begin(); isa<PHINode>(bi); ++bi) {
+      PHINode* PN = cast<PHINode>(bi);
+
+      int blockIndex = PN->getBasicBlockIndex(origBlock);
+      assert(blockIndex != -1 && "Switch didn't go to this successor??");
+      PN->setIncomingBlock((unsigned)blockIndex, newBlock);
+    }
+    
+    curHead = newBlock;
+  }
+
+  // Branch to our shiny new if-then stuff...
+  BranchInst::Create(curHead, origBlock);
+}
+
+// processSwitchInst - Replace the specified switch instruction with a sequence
+// of chained if-then instructions.
+//
+void LowerSwitchPass::processSwitchInst(SwitchInst *SI) {
+  BasicBlock *origBlock = SI->getParent();
+  BasicBlock *defaultBlock = SI->getDefaultDest();
+  Function *F = origBlock->getParent();
+  Value *switchValue = SI->getOperand(0);
+
+  // Create a new, empty default block so that the new hierarchy of
+  // if-then statements go to this and the PHI nodes are happy.
+  BasicBlock* newDefault = BasicBlock::Create("newDefault");
+
+  F->getBasicBlockList().insert(defaultBlock, newDefault);
+  BranchInst::Create(defaultBlock, newDefault);
+
+  // If there is an entry in any PHI nodes for the default edge, make sure
+  // to update them as well.
+  for (BasicBlock::iterator I = defaultBlock->begin(); isa<PHINode>(I); ++I) {
+    PHINode *PN = cast<PHINode>(I);
+    int BlockIdx = PN->getBasicBlockIndex(origBlock);
+    assert(BlockIdx != -1 && "Switch didn't go to this successor??");
+    PN->setIncomingBlock((unsigned)BlockIdx, newDefault);
+  }
+  
+  CaseVector cases;
+  for (unsigned i = 1; i < SI->getNumSuccessors(); ++i)
+    cases.push_back(SwitchCase(SI->getSuccessorValue(i),
+                               SI->getSuccessor(i)));
+  
+  // reverse cases, as switchConvert constructs a chain of
+  //   basic blocks by appending to the front. if we reverse,
+  //   the if comparisons will happen in the same order
+  //   as the cases appear in the switch
+  std::reverse(cases.begin(), cases.end());
+  
+  switchConvert(cases.begin(), cases.end(), switchValue, origBlock, newDefault);
+
+  // We are now done with the switch instruction, so delete it
+  origBlock->getInstList().erase(SI);
+}
+
+}
diff --git a/lib/Module/Makefile b/lib/Module/Makefile
new file mode 100755
index 00000000..bfd7c469
--- /dev/null
+++ b/lib/Module/Makefile
@@ -0,0 +1,16 @@
+#===-- lib/Module/Makefile ---------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleeModule
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp
new file mode 100644
index 00000000..d86b9d48
--- /dev/null
+++ b/lib/Module/ModuleUtil.cpp
@@ -0,0 +1,101 @@
+//===-- ModuleUtil.cpp ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Internal/Support/ModuleUtil.h"
+
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Linker.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/AsmAnnotationWriter.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Analysis/ValueTracking.h"
+
+#include <map>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+
+using namespace llvm;
+using namespace klee;
+
+Module *klee::linkWithLibrary(Module *module, 
+                              const std::string &libraryName) {
+  try {
+    Linker linker("klee", module, false);
+
+    llvm::sys::Path libraryPath(libraryName);
+    bool native = false;
+    
+    if (linker.LinkInFile(libraryPath, native)) {
+      assert(0 && "linking in library failed!");
+    }
+    
+    return linker.releaseModule();
+  } catch (...) {
+    assert(0 && "error during linking");
+  }
+}
+
+Function *klee::getDirectCallTarget(const Instruction *i) {
+  assert(isa<CallInst>(i) || isa<InvokeInst>(i));
+
+  Value *v = i->getOperand(0);
+  if (Function *f = dyn_cast<Function>(v)) {
+    return f;
+  } else if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(v)) {
+    if (ce->getOpcode()==Instruction::BitCast)
+      if (Function *f = dyn_cast<Function>(ce->getOperand(0)))
+        return f;
+
+    // NOTE: This assert may fire, it isn't necessarily a problem and
+    // can be disabled, I just wanted to know when and if it happened.
+    assert(0 && "FIXME: Unresolved direct target for a constant expression.");
+  }
+  
+  return 0;
+}
+
+static bool valueIsOnlyCalled(const Value *v) {
+  for (Value::use_const_iterator it = v->use_begin(), ie = v->use_end();
+       it != ie; ++it) {
+    if (const Instruction *instr = dyn_cast<Instruction>(*it)) {
+      if (instr->getOpcode()==0) continue; // XXX function numbering inst
+      if (!isa<CallInst>(instr) && !isa<InvokeInst>(instr)) return false;
+      
+      // Make sure that the value is only the target of this call and
+      // not an argument.
+      for (unsigned i=1,e=instr->getNumOperands(); i!=e; ++i)
+        if (instr->getOperand(i)==v)
+          return false;
+    } else if (const llvm::ConstantExpr *ce = 
+               dyn_cast<llvm::ConstantExpr>(*it)) {
+      if (ce->getOpcode()==Instruction::BitCast)
+        if (valueIsOnlyCalled(ce))
+          continue;
+      return false;
+    } else if (const GlobalAlias *ga = dyn_cast<GlobalAlias>(*it)) {
+      // XXX what about v is bitcast of aliasee?
+      if (v==ga->getAliasee() && !valueIsOnlyCalled(ga))
+        return false;
+    } else {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool klee::functionEscapes(const Function *f) {
+  return !valueIsOnlyCalled(f);
+}
diff --git a/lib/Module/Optimize.cpp b/lib/Module/Optimize.cpp
new file mode 100644
index 00000000..83e67292
--- /dev/null
+++ b/lib/Module/Optimize.cpp
@@ -0,0 +1,272 @@
+// FIXME: This file is a bastard child of opt.cpp and llvm-ld's
+// Optimize.cpp. This stuff should live in common code.
+
+
+//===- Optimize.cpp - Optimize a complete program -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements all optimization of the linked module for llvm-ld.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Support/PassNameParser.h"
+#include "llvm/Support/PluginLoader.h"
+#include <iostream>
+using namespace llvm;
+
+#if 0
+// Pass Name Options as generated by the PassNameParser
+static cl::list<const PassInfo*, bool, PassNameParser>
+  OptimizationList(cl::desc("Optimizations available:"));
+#endif
+
+// Don't verify at the end
+static cl::opt<bool> DontVerify("disable-verify", cl::ReallyHidden);
+
+static cl::opt<bool> DisableInline("disable-inlining",
+  cl::desc("Do not run the inliner pass"));
+
+static cl::opt<bool>
+DisableOptimizations("disable-opt",
+  cl::desc("Do not run any optimization passes"));
+
+static cl::opt<bool> DisableInternalize("disable-internalize",
+  cl::desc("Do not mark all symbols as internal"));
+
+static cl::opt<bool> VerifyEach("verify-each",
+ cl::desc("Verify intermediate results of all passes"));
+
+static cl::alias ExportDynamic("export-dynamic",
+  cl::aliasopt(DisableInternalize),
+  cl::desc("Alias for -disable-internalize"));
+
+static cl::opt<bool> Strip("strip-all", 
+  cl::desc("Strip all symbol info from executable"));
+
+static cl::alias A0("s", cl::desc("Alias for --strip-all"), 
+  cl::aliasopt(Strip));
+
+static cl::opt<bool> StripDebug("strip-debug",
+  cl::desc("Strip debugger symbol info from executable"));
+
+static cl::alias A1("S", cl::desc("Alias for --strip-debug"),
+  cl::aliasopt(StripDebug));
+
+// A utility function that adds a pass to the pass manager but will also add
+// a verifier pass after if we're supposed to verify.
+static inline void addPass(PassManager &PM, Pass *P) {
+  // Add the pass to the pass manager...
+  PM.add(P);
+
+  // If we are verifying all of the intermediate steps, add the verifier...
+  if (VerifyEach)
+    PM.add(createVerifierPass());
+}
+
+namespace llvm {
+
+
+static void AddStandardCompilePasses(PassManager &PM) {
+  PM.add(createVerifierPass());                  // Verify that input is correct
+
+  addPass(PM, createLowerSetJmpPass());          // Lower llvm.setjmp/.longjmp
+
+  // If the -strip-debug command line option was specified, do it.
+  if (StripDebug)
+    addPass(PM, createStripSymbolsPass(true));
+
+  if (DisableOptimizations) return;
+
+  addPass(PM, createRaiseAllocationsPass());     // call %malloc -> malloc inst
+  addPass(PM, createCFGSimplificationPass());    // Clean up disgusting code
+  addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas
+  addPass(PM, createGlobalOptimizerPass());      // Optimize out global vars
+  addPass(PM, createGlobalDCEPass());            // Remove unused fns and globs
+  addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation
+  addPass(PM, createDeadArgEliminationPass());   // Dead argument elimination
+  addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE
+  addPass(PM, createCFGSimplificationPass());    // Clean up after IPCP & DAE
+
+  addPass(PM, createPruneEHPass());              // Remove dead EH info
+  addPass(PM, createFunctionAttrsPass());        // Deduce function attrs
+
+  if (!DisableInline)
+    addPass(PM, createFunctionInliningPass());   // Inline small functions
+  addPass(PM, createArgumentPromotionPass());    // Scalarize uninlined fn args
+
+  addPass(PM, createSimplifyLibCallsPass());     // Library Call Optimizations
+  addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl.
+  addPass(PM, createJumpThreadingPass());        // Thread jumps.
+  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
+  addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
+  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
+  addPass(PM, createCondPropagationPass());      // Propagate conditionals
+
+  addPass(PM, createTailCallEliminationPass());  // Eliminate tail calls
+  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
+  addPass(PM, createReassociatePass());          // Reassociate expressions
+  addPass(PM, createLoopRotatePass());
+  addPass(PM, createLICMPass());                 // Hoist loop invariants
+  addPass(PM, createLoopUnswitchPass());         // Unswitch loops.
+  addPass(PM, createLoopIndexSplitPass());       // Index split loops.
+  // FIXME : Removing instcombine causes nestedloop regression.
+  addPass(PM, createInstructionCombiningPass());
+  addPass(PM, createIndVarSimplifyPass());       // Canonicalize indvars
+  addPass(PM, createLoopDeletionPass());         // Delete dead loops
+  addPass(PM, createLoopUnrollPass());           // Unroll small loops
+  addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller
+  addPass(PM, createGVNPass());                  // Remove redundancies
+  addPass(PM, createMemCpyOptPass());            // Remove memcpy / form memset
+  addPass(PM, createSCCPPass());                 // Constant prop with SCCP
+
+  // Run instcombine after redundancy elimination to exploit opportunities
+  // opened up by them.
+  addPass(PM, createInstructionCombiningPass());
+  addPass(PM, createCondPropagationPass());      // Propagate conditionals
+
+  addPass(PM, createDeadStoreEliminationPass()); // Delete dead stores
+  addPass(PM, createAggressiveDCEPass());        // Delete dead instructions
+  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
+  addPass(PM, createStripDeadPrototypesPass());  // Get rid of dead prototypes
+  addPass(PM, createDeadTypeEliminationPass());  // Eliminate dead types
+  addPass(PM, createConstantMergePass());        // Merge dup global constants
+}
+
+/// Optimize - Perform link time optimizations. This will run the scalar
+/// optimizations, any loaded plugin-optimization modules, and then the
+/// inter-procedural optimizations if applicable.
+void Optimize(Module* M) {
+
+  // Instantiate the pass manager to organize the passes.
+  PassManager Passes;
+
+  // If we're verifying, start off with a verification pass.
+  if (VerifyEach)
+    Passes.add(createVerifierPass());
+
+  // Add an appropriate TargetData instance for this module...
+  addPass(Passes, new TargetData(M));
+
+  // DWD - Run the opt standard pass list as well.
+  AddStandardCompilePasses(Passes);
+
+  if (!DisableOptimizations) {
+    // Now that composite has been compiled, scan through the module, looking
+    // for a main function.  If main is defined, mark all other functions
+    // internal.
+    if (!DisableInternalize)
+      addPass(Passes, createInternalizePass(true));
+
+    // Propagate constants at call sites into the functions they call.  This
+    // opens opportunities for globalopt (and inlining) by substituting function
+    // pointers passed as arguments to direct uses of functions.  
+    addPass(Passes, createIPSCCPPass());
+
+    // Now that we internalized some globals, see if we can hack on them!
+    addPass(Passes, createGlobalOptimizerPass());
+
+    // Linking modules together can lead to duplicated global constants, only
+    // keep one copy of each constant...
+    addPass(Passes, createConstantMergePass());
+
+    // Remove unused arguments from functions...
+    addPass(Passes, createDeadArgEliminationPass());
+
+    // Reduce the code after globalopt and ipsccp.  Both can open up significant
+    // simplification opportunities, and both can propagate functions through
+    // function pointers.  When this happens, we often have to resolve varargs
+    // calls, etc, so let instcombine do this.
+    addPass(Passes, createInstructionCombiningPass());
+
+    if (!DisableInline)
+      addPass(Passes, createFunctionInliningPass()); // Inline small functions
+
+    addPass(Passes, createPruneEHPass());            // Remove dead EH info
+    addPass(Passes, createGlobalOptimizerPass());    // Optimize globals again.
+    addPass(Passes, createGlobalDCEPass());          // Remove dead functions
+
+    // If we didn't decide to inline a function, check to see if we can
+    // transform it to pass arguments by value instead of by reference.
+    addPass(Passes, createArgumentPromotionPass());
+
+    // The IPO passes may leave cruft around.  Clean up after them.
+    addPass(Passes, createInstructionCombiningPass());
+    addPass(Passes, createJumpThreadingPass());        // Thread jumps.
+    addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas
+
+    // Run a few AA driven optimizations here and now, to cleanup the code.
+    addPass(Passes, createFunctionAttrsPass());      // Add nocapture
+    addPass(Passes, createGlobalsModRefPass());      // IP alias analysis
+
+    addPass(Passes, createLICMPass());               // Hoist loop invariants
+    addPass(Passes, createGVNPass());                // Remove redundancies
+    addPass(Passes, createMemCpyOptPass());          // Remove dead memcpy's
+    addPass(Passes, createDeadStoreEliminationPass()); // Nuke dead stores
+
+    // Cleanup and simplify the code after the scalar optimizations.
+    addPass(Passes, createInstructionCombiningPass());
+
+    addPass(Passes, createJumpThreadingPass());        // Thread jumps.
+    addPass(Passes, createPromoteMemoryToRegisterPass()); // Cleanup jumpthread.
+    
+    // Delete basic blocks, which optimization passes may have killed...
+    addPass(Passes, createCFGSimplificationPass());
+
+    // Now that we have optimized the program, discard unreachable functions...
+    addPass(Passes, createGlobalDCEPass());
+  }
+
+  // If the -s or -S command line options were specified, strip the symbols out
+  // of the resulting program to make it smaller.  -s and -S are GNU ld options
+  // that we are supporting; they alias -strip-all and -strip-debug.
+  if (Strip || StripDebug)
+    addPass(Passes, createStripSymbolsPass(StripDebug && !Strip));
+
+#if 0
+  // Create a new optimization pass for each one specified on the command line
+  std::auto_ptr<TargetMachine> target;
+  for (unsigned i = 0; i < OptimizationList.size(); ++i) {
+    const PassInfo *Opt = OptimizationList[i];
+    if (Opt->getNormalCtor())
+      addPass(Passes, Opt->getNormalCtor()());
+    else
+      std::cerr << "llvm-ld: cannot create pass: " << Opt->getPassName() 
+                << "\n";
+  }
+#endif
+
+  // The user's passes may leave cruft around. Clean up after them them but
+  // only if we haven't got DisableOptimizations set
+  if (!DisableOptimizations) {
+    addPass(Passes, createInstructionCombiningPass());
+    addPass(Passes, createCFGSimplificationPass());
+    addPass(Passes, createAggressiveDCEPass());
+    addPass(Passes, createGlobalDCEPass());
+  }
+
+  // Make sure everything is still good.
+  if (!DontVerify)
+    Passes.add(createVerifierPass());
+
+  // Run our queue of passes all at once now, efficiently.
+  Passes.run(*M);
+}
+
+}
diff --git a/lib/Module/Passes.h b/lib/Module/Passes.h
new file mode 100644
index 00000000..23205f75
--- /dev/null
+++ b/lib/Module/Passes.h
@@ -0,0 +1,132 @@
+//===-- Passes.h ------------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_PASSES_H
+#define KLEE_PASSES_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+
+namespace llvm {
+  class Function;
+  class Instruction;
+  class Module;
+  class TargetData;
+  class Type;
+}
+
+namespace klee {
+
+  /// RaiseAsmPass - This pass raises some common occurences of inline
+  /// asm which are used by glibc into normal LLVM IR.
+class RaiseAsmPass : public llvm::ModulePass {
+  static char ID;
+
+  llvm::Function *getIntrinsic(llvm::Module &M,
+                               unsigned IID,
+                               const llvm::Type **Tys,
+                               unsigned NumTys);
+  llvm::Function *getIntrinsic(llvm::Module &M,
+                               unsigned IID, 
+                               const llvm::Type *Ty0) {
+    return getIntrinsic(M, IID, &Ty0, 1);
+  }
+
+  bool runOnInstruction(llvm::Module &M, llvm::Instruction *I);
+
+public:
+  RaiseAsmPass() : llvm::ModulePass((intptr_t) &ID) {}
+  
+  virtual bool runOnModule(llvm::Module &M);
+};
+
+  // This is a module pass because it can add and delete module
+  // variables (via intrinsic lowering).
+class IntrinsicCleanerPass : public llvm::ModulePass {
+  static char ID;
+  llvm::IntrinsicLowering *IL;
+  bool LowerIntrinsics;
+
+  bool runOnBasicBlock(llvm::BasicBlock &b);
+public:
+  IntrinsicCleanerPass(const llvm::TargetData &TD,
+                       bool LI=true)
+    : llvm::ModulePass((intptr_t) &ID),
+      IL(new llvm::IntrinsicLowering(TD)),
+      LowerIntrinsics(LI) {}
+  ~IntrinsicCleanerPass() { delete IL; } 
+  
+  virtual bool runOnModule(llvm::Module &M);
+};
+  
+  // performs two transformations which make interpretation
+  // easier and faster.
+  //
+  // 1) Ensure that all the PHI nodes in a basic block have
+  //    the incoming block list in the same order. Thus the
+  //    incoming block index only needs to be computed once
+  //    for each transfer.
+  // 
+  // 2) Ensure that no PHI node result is used as an argument to
+  //    a subsequent PHI node in the same basic block. This allows
+  //    the transfer to execute the instructions in order instead
+  //    of in two passes.
+class PhiCleanerPass : public llvm::FunctionPass {
+  static char ID;
+
+public:
+  PhiCleanerPass() : llvm::FunctionPass((intptr_t) &ID) {}
+  
+  virtual bool runOnFunction(llvm::Function &f);
+};
+  
+class DivCheckPass : public llvm::ModulePass {
+  static char ID;
+public:
+  DivCheckPass(): ModulePass((intptr_t) &ID) {}
+  virtual bool runOnModule(llvm::Module &M);
+};
+
+/// LowerSwitchPass - Replace all SwitchInst instructions with chained branch
+/// instructions.  Note that this cannot be a BasicBlock pass because it
+/// modifies the CFG!
+class LowerSwitchPass : public llvm::FunctionPass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+  LowerSwitchPass() : FunctionPass((intptr_t) &ID) {} 
+  
+  virtual bool runOnFunction(llvm::Function &F);
+  
+  struct SwitchCase {
+    llvm ::Constant *value;
+    llvm::BasicBlock *block;
+    
+    SwitchCase() : value(0), block(0) { }
+    SwitchCase(llvm::Constant *v, llvm::BasicBlock *b) :
+      value(v), block(b) { }
+  };
+  
+  typedef std::vector<SwitchCase>           CaseVector;
+  typedef std::vector<SwitchCase>::iterator CaseItr;
+  
+private:
+  void processSwitchInst(llvm::SwitchInst *SI);
+  void switchConvert(CaseItr begin,
+                     CaseItr end,
+                     llvm::Value *value,
+                     llvm::BasicBlock *origBlock,
+                     llvm::BasicBlock *defaultBlock);
+};
+
+}
+
+#endif
diff --git a/lib/Module/PhiCleaner.cpp b/lib/Module/PhiCleaner.cpp
new file mode 100644
index 00000000..3d8d7867
--- /dev/null
+++ b/lib/Module/PhiCleaner.cpp
@@ -0,0 +1,83 @@
+//===-- PhiCleaner.cpp ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Passes.h"
+
+#include <set>
+
+using namespace llvm;
+
+char klee::PhiCleanerPass::ID = 0;
+
+bool klee::PhiCleanerPass::runOnFunction(Function &f) {
+  bool changed = false;
+  
+  for (Function::iterator b = f.begin(), be = f.end(); b != be; ++b) {
+    BasicBlock::iterator it = b->begin();
+
+    if (it->getOpcode() == Instruction::PHI) {
+      PHINode *reference = cast<PHINode>(it);
+      
+      std::set<Value*> phis;
+      phis.insert(reference);
+
+      unsigned numBlocks = reference->getNumIncomingValues();
+      for (++it; isa<PHINode>(*it); ++it) {
+        PHINode *pi = cast<PHINode>(it);
+
+        assert(numBlocks == pi->getNumIncomingValues());
+
+        // see if it is out of order
+        unsigned i;
+        for (i=0; i<numBlocks; i++)
+          if (pi->getIncomingBlock(i) != reference->getIncomingBlock(i))
+            break;
+
+        if (i!=numBlocks) {
+          std::vector<Value*> values;
+          values.reserve(numBlocks);
+          for (unsigned i=0; i<numBlocks; i++)
+            values[i] = pi->getIncomingValueForBlock(reference->getIncomingBlock(i));
+          for (unsigned i=0; i<numBlocks; i++) {
+            pi->setIncomingBlock(i, reference->getIncomingBlock(i));
+            pi->setIncomingValue(i, values[i]);
+          }
+          changed = true;
+        }
+
+        // see if it uses any previously defined phi nodes
+        for (i=0; i<numBlocks; i++) {
+          Value *value = pi->getIncomingValue(i);
+
+          if (phis.find(value) != phis.end()) {
+            // fix by making a "move" at the end of the incoming block
+            // to a new temporary, which is thus known not to be a phi
+            // result. we could be somewhat more efficient about this
+            // by sharing temps and by reordering phi instructions so
+            // this isn't completely necessary, but in the end this is
+            // just a pathological case which does not occur very
+            // often.
+            Instruction *tmp = 
+              new BitCastInst(value, 
+                              value->getType(),
+                              value->getName() + ".phiclean",
+                              pi->getIncomingBlock(i)->getTerminator());
+            pi->setIncomingValue(i, tmp);
+          }
+
+          changed = true;
+        }
+        
+        phis.insert(pi);
+      }
+    }
+  }
+
+  return changed;
+}
diff --git a/lib/Module/RaiseAsm.cpp b/lib/Module/RaiseAsm.cpp
new file mode 100644
index 00000000..67fbf8ae
--- /dev/null
+++ b/lib/Module/RaiseAsm.cpp
@@ -0,0 +1,69 @@
+//===-- RaiseAsm.cpp ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Passes.h"
+
+#include "llvm/InlineAsm.h"
+
+using namespace llvm;
+using namespace klee;
+
+char RaiseAsmPass::ID = 0;
+
+Function *RaiseAsmPass::getIntrinsic(llvm::Module &M,
+                                     unsigned IID,
+                                     const Type **Tys,
+                                     unsigned NumTys) {  
+  return Intrinsic::getDeclaration(&M, (llvm::Intrinsic::ID) IID, Tys, NumTys);
+}
+
+// FIXME: This should just be implemented as a patch to
+// X86TargetAsmInfo.cpp, then everyone will benefit.
+bool RaiseAsmPass::runOnInstruction(Module &M, Instruction *I) {
+  if (CallInst *ci = dyn_cast<CallInst>(I)) {
+    if (InlineAsm *ia = dyn_cast<InlineAsm>(ci->getCalledValue())) {
+      const std::string &as = ia->getAsmString();
+      const std::string &cs = ia->getConstraintString();
+      const llvm::Type *T = ci->getType();
+
+      // bswaps
+      if (ci->getNumOperands() == 2 && 
+          T == ci->getOperand(1)->getType() &&
+          ((T == llvm::Type::Int16Ty && 
+            as == "rorw $$8, ${0:w}" &&
+            cs == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") ||
+           (T == llvm::Type::Int32Ty &&
+            as == "rorw $$8, ${0:w};rorl $$16, $0;rorw $$8, ${0:w}" &&
+            cs == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}"))) {
+        llvm::Value *Arg0 = ci->getOperand(1);
+        Function *F = getIntrinsic(M, Intrinsic::bswap, Arg0->getType());
+        ci->setOperand(0, F);
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+bool RaiseAsmPass::runOnModule(Module &M) {
+  bool changed = false;
+  
+  for (Module::iterator fi = M.begin(), fe = M.end(); fi != fe; ++fi) {
+    for (Function::iterator bi = fi->begin(), be = fi->end(); bi != be; ++bi) {
+      for (BasicBlock::iterator ii = bi->begin(), ie = bi->end(); ii != ie;) {
+        Instruction *i = ii;
+        ++ii;  
+        changed |= runOnInstruction(M, i);
+      }
+    }
+  }
+
+  return changed;
+}
diff --git a/lib/README.txt b/lib/README.txt
new file mode 100644
index 00000000..1750d900
--- /dev/null
+++ b/lib/README.txt
@@ -0,0 +1,18 @@
+The klee and kleaver code is organized as follows:
+
+lib/Basic   - Low level support for both klee and kleaver which should
+              be independent of LLVM.
+
+lib/Support - Higher level support, but only used by klee. This can
+              use LLVM facilities.
+
+lib/Expr    - The core kleaver expression library.
+
+lib/Solver  - The kleaver solver library.
+
+lib/Module  - klee facilities for working with LLVM modules, including
+              the shadow module/instruction structures we use during
+              execution.
+
+lib/Core    - The core symbolic virtual machine.
+
diff --git a/lib/Solver/CachingSolver.cpp b/lib/Solver/CachingSolver.cpp
new file mode 100644
index 00000000..517e133b
--- /dev/null
+++ b/lib/Solver/CachingSolver.cpp
@@ -0,0 +1,241 @@
+//===-- CachingSolver.cpp - Caching expression solver ---------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "klee/Solver.h"
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/IncompleteSolver.h"
+#include "klee/SolverImpl.h"
+
+#include "SolverStats.h"
+
+#include <tr1/unordered_map>
+
+using namespace klee;
+
+class CachingSolver : public SolverImpl {
+private:
+  ref<Expr> canonicalizeQuery(ref<Expr> originalQuery,
+                              bool &negationUsed);
+
+  void cacheInsert(const Query& query,
+                   IncompleteSolver::PartialValidity result);
+
+  bool cacheLookup(const Query& query,
+                   IncompleteSolver::PartialValidity &result);
+  
+  struct CacheEntry {
+    CacheEntry(const ConstraintManager &c, ref<Expr> q)
+      : constraints(c), query(q) {}
+
+    CacheEntry(const CacheEntry &ce)
+      : constraints(ce.constraints), query(ce.query) {}
+    
+    ConstraintManager constraints;
+    ref<Expr> query;
+
+    bool operator==(const CacheEntry &b) const {
+      return constraints==b.constraints && *query.get()==*b.query.get();
+    }
+  };
+  
+  struct CacheEntryHash {
+    unsigned operator()(const CacheEntry &ce) const {
+      unsigned result = ce.query.hash();
+      
+      for (ConstraintManager::constraint_iterator it = ce.constraints.begin();
+           it != ce.constraints.end(); ++it)
+        result ^= it->hash();
+      
+      return result;
+    }
+  };
+
+  typedef std::tr1::unordered_map<CacheEntry, 
+                                  IncompleteSolver::PartialValidity, 
+                                  CacheEntryHash> cache_map;
+  
+  Solver *solver;
+  cache_map cache;
+
+public:
+  CachingSolver(Solver *s) : solver(s) {}
+  ~CachingSolver() { cache.clear(); delete solver; }
+
+  bool computeValidity(const Query&, Solver::Validity &result);
+  bool computeTruth(const Query&, bool &isValid);
+  bool computeValue(const Query& query, ref<Expr> &result) {
+    return solver->impl->computeValue(query, result);
+  }
+  bool computeInitialValues(const Query& query,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution) {
+    return solver->impl->computeInitialValues(query, objects, values, 
+                                              hasSolution);
+  }
+};
+
+/** @returns the canonical version of the given query.  The reference
+    negationUsed is set to true if the original query was negated in
+    the canonicalization process. */
+ref<Expr> CachingSolver::canonicalizeQuery(ref<Expr> originalQuery,
+                                           bool &negationUsed) {
+  ref<Expr> negatedQuery = Expr::createNot(originalQuery);
+
+  // select the "smaller" query to the be canonical representation
+  if (originalQuery.compare(negatedQuery) < 0) {
+    negationUsed = false;
+    return originalQuery;
+  } else {
+    negationUsed = true;
+    return negatedQuery;
+  }
+}
+
+/** @returns true on a cache hit, false of a cache miss.  Reference
+    value result only valid on a cache hit. */
+bool CachingSolver::cacheLookup(const Query& query,
+                                IncompleteSolver::PartialValidity &result) {
+  bool negationUsed;
+  ref<Expr> canonicalQuery = canonicalizeQuery(query.expr, negationUsed);
+
+  CacheEntry ce(query.constraints, canonicalQuery);
+  cache_map::iterator it = cache.find(ce);
+  
+  if (it != cache.end()) {
+    result = (negationUsed ?
+              IncompleteSolver::negatePartialValidity(it->second) :
+              it->second);
+    return true;
+  }
+  
+  return false;
+}
+
+/// Inserts the given query, result pair into the cache.
+void CachingSolver::cacheInsert(const Query& query,
+                                IncompleteSolver::PartialValidity result) {
+  bool negationUsed;
+  ref<Expr> canonicalQuery = canonicalizeQuery(query.expr, negationUsed);
+
+  CacheEntry ce(query.constraints, canonicalQuery);
+  IncompleteSolver::PartialValidity cachedResult = 
+    (negationUsed ? IncompleteSolver::negatePartialValidity(result) : result);
+  
+  cache.insert(std::make_pair(ce, cachedResult));
+}
+
+bool CachingSolver::computeValidity(const Query& query,
+                                    Solver::Validity &result) {
+  IncompleteSolver::PartialValidity cachedResult;
+  bool tmp, cacheHit = cacheLookup(query, cachedResult);
+  
+  if (cacheHit) {
+    ++stats::queryCacheHits;
+
+    switch(cachedResult) {
+    case IncompleteSolver::MustBeTrue:   
+      result = Solver::True;
+      return true;
+    case IncompleteSolver::MustBeFalse:  
+      result = Solver::False;
+      return true;
+    case IncompleteSolver::TrueOrFalse:  
+      result = Solver::Unknown;
+      return true;
+    case IncompleteSolver::MayBeTrue: {
+      if (!solver->impl->computeTruth(query, tmp))
+        return false;
+      if (tmp) {
+        cacheInsert(query, IncompleteSolver::MustBeTrue);
+        result = Solver::True;
+        return true;
+      } else {
+        cacheInsert(query, IncompleteSolver::TrueOrFalse);
+        result = Solver::Unknown;
+        return true;
+      }
+    }
+    case IncompleteSolver::MayBeFalse: {
+      if (!solver->impl->computeTruth(query.negateExpr(), tmp))
+        return false;
+      if (tmp) {
+        cacheInsert(query, IncompleteSolver::MustBeFalse);
+        result = Solver::False;
+        return true;
+      } else {
+        cacheInsert(query, IncompleteSolver::TrueOrFalse);
+        result = Solver::Unknown;
+        return true;
+      }
+    }
+    default: assert(0 && "unreachable");
+    }
+  }
+
+  ++stats::queryCacheMisses;
+  
+  if (!solver->impl->computeValidity(query, result))
+    return false;
+
+  switch (result) {
+  case Solver::True: 
+    cachedResult = IncompleteSolver::MustBeTrue; break;
+  case Solver::False: 
+    cachedResult = IncompleteSolver::MustBeFalse; break;
+  default: 
+    cachedResult = IncompleteSolver::TrueOrFalse; break;
+  }
+  
+  cacheInsert(query, cachedResult);
+  return true;
+}
+
+bool CachingSolver::computeTruth(const Query& query,
+                                 bool &isValid) {
+  IncompleteSolver::PartialValidity cachedResult;
+  bool cacheHit = cacheLookup(query, cachedResult);
+
+  // a cached result of MayBeTrue forces us to check whether
+  // a False assignment exists.
+  if (cacheHit && cachedResult != IncompleteSolver::MayBeTrue) {
+    ++stats::queryCacheHits;
+    isValid = (cachedResult == IncompleteSolver::MustBeTrue);
+    return true;
+  }
+
+  ++stats::queryCacheMisses;
+  
+  // cache miss: query solver
+  if (!solver->impl->computeTruth(query, isValid))
+    return false;
+
+  if (isValid) {
+    cachedResult = IncompleteSolver::MustBeTrue;
+  } else if (cacheHit) {
+    // We know a true assignment exists, and query isn't valid, so
+    // must be TrueOrFalse.
+    assert(cachedResult == IncompleteSolver::MayBeTrue);
+    cachedResult = IncompleteSolver::TrueOrFalse;
+  } else {
+    cachedResult = IncompleteSolver::MayBeFalse;
+  }
+  
+  cacheInsert(query, cachedResult);
+  return true;
+}
+
+///
+
+Solver *klee::createCachingSolver(Solver *_solver) {
+  return new Solver(new CachingSolver(_solver));
+}
diff --git a/lib/Solver/CexCachingSolver.cpp b/lib/Solver/CexCachingSolver.cpp
new file mode 100644
index 00000000..79bc985d
--- /dev/null
+++ b/lib/Solver/CexCachingSolver.cpp
@@ -0,0 +1,313 @@
+//===-- CexCachingSolver.cpp ----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Solver.h"
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/SolverImpl.h"
+#include "klee/TimerStatIncrementer.h"
+#include "klee/util/Assignment.h"
+#include "klee/util/ExprUtil.h"
+#include "klee/util/ExprVisitor.h"
+#include "klee/Internal/ADT/MapOfSets.h"
+
+#include "SolverStats.h"
+
+#include "llvm/Support/CommandLine.h"
+
+using namespace klee;
+using namespace llvm;
+
+namespace {
+  cl::opt<bool>
+  DebugCexCacheCheckBinding("debug-cex-cache-check-binding");
+
+  cl::opt<bool>
+  CexCacheTryAll("cex-cache-try-all",
+                 cl::desc("try substituting all counterexamples before asking STP"),
+                 cl::init(false));
+
+  cl::opt<bool>
+  CexCacheExperimental("cex-cache-exp", cl::init(false));
+
+}
+
+///
+
+typedef std::set< ref<Expr> > KeyType;
+
+struct AssignmentLessThan {
+  bool operator()(const Assignment *a, const Assignment *b) {
+    return a->bindings < b->bindings;
+  }
+};
+
+
+class CexCachingSolver : public SolverImpl {
+  typedef std::set<Assignment*, AssignmentLessThan> assignmentsTable_ty;
+
+  Solver *solver;
+  
+  MapOfSets<ref<Expr>, Assignment*> cache;
+  // memo table
+  assignmentsTable_ty assignmentsTable;
+
+  bool searchForAssignment(KeyType &key, 
+                           Assignment *&result);
+  
+  bool lookupAssignment(const Query& query, Assignment *&result);
+
+  bool getAssignment(const Query& query, Assignment *&result);
+  
+public:
+  CexCachingSolver(Solver *_solver) : solver(_solver) {}
+  ~CexCachingSolver();
+  
+  bool computeTruth(const Query&, bool &isValid);
+  bool computeValidity(const Query&, Solver::Validity &result);
+  bool computeValue(const Query&, ref<Expr> &result);
+  bool computeInitialValues(const Query&,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution);
+};
+
+///
+
+struct NullAssignment {
+  bool operator()(Assignment *a) const { return !a; }
+};
+
+struct NonNullAssignment {
+  bool operator()(Assignment *a) const { return a!=0; }
+};
+
+struct NullOrSatisfyingAssignment {
+  KeyType &key;
+  
+  NullOrSatisfyingAssignment(KeyType &_key) : key(_key) {}
+
+  bool operator()(Assignment *a) const { 
+    return !a || a->satisfies(key.begin(), key.end()); 
+  }
+};
+
+bool CexCachingSolver::searchForAssignment(KeyType &key, Assignment *&result) {
+  Assignment * const *lookup = cache.lookup(key);
+  if (lookup) {
+    result = *lookup;
+    return true;
+  }
+
+  if (CexCacheTryAll) {
+    Assignment **lookup = cache.findSuperset(key, NonNullAssignment());
+    if (!lookup) lookup = cache.findSubset(key, NullAssignment());
+    if (lookup) {
+      result = *lookup;
+      return true;
+    }
+    for (assignmentsTable_ty::iterator it = assignmentsTable.begin(), 
+           ie = assignmentsTable.end(); it != ie; ++it) {
+      Assignment *a = *it;
+      if (a->satisfies(key.begin(), key.end())) {
+        result = a;
+        return true;
+      }
+    }
+  } else {
+    // XXX which order? one is sure to be better
+    Assignment **lookup = cache.findSuperset(key, NonNullAssignment());
+    if (!lookup) lookup = cache.findSubset(key, NullOrSatisfyingAssignment(key));
+    if (lookup) {
+      result = *lookup;
+      return true;
+    }
+  }
+  
+  return false;
+}
+
+bool CexCachingSolver::lookupAssignment(const Query &query, 
+                                        Assignment *&result) {
+  KeyType key(query.constraints.begin(), query.constraints.end());
+  ref<Expr> neg = Expr::createNot(query.expr);
+  if (neg.isConstant()) {
+    if (!neg.getConstantValue()) {
+      result = (Assignment*) 0;
+      return true;
+    }
+  } else {
+    key.insert(neg);
+  }
+
+  return searchForAssignment(key, result);
+}
+
+bool CexCachingSolver::getAssignment(const Query& query, Assignment *&result) {
+  KeyType key(query.constraints.begin(), query.constraints.end());
+  ref<Expr> neg = Expr::createNot(query.expr);
+  if (neg.isConstant()) {
+    if (!neg.getConstantValue()) {
+      result = (Assignment*) 0;
+      return true;
+    }
+  } else {
+    key.insert(neg);
+  }
+
+  if (!searchForAssignment(key, result)) {
+    // need to solve
+    
+    std::vector<const Array*> objects;
+    findSymbolicObjects(key.begin(), key.end(), objects);
+
+    std::vector< std::vector<unsigned char> > values;
+    bool hasSolution;
+    if (!solver->impl->computeInitialValues(query, objects, values, 
+                                            hasSolution))
+      return false;
+    
+    Assignment *binding;
+    if (hasSolution) {
+      binding = new Assignment(objects, values);
+
+      // memoization
+      std::pair<assignmentsTable_ty::iterator, bool>
+        res = assignmentsTable.insert(binding);
+      if (!res.second) {
+        delete binding;
+        binding = *res.first;
+      }
+
+      if (DebugCexCacheCheckBinding)
+        assert(binding->satisfies(key.begin(), key.end()));
+    } else {
+      binding = (Assignment*) 0;
+    }
+
+    result = binding;
+    cache.insert(key, binding);
+  }
+
+  return true;
+}
+
+///
+
+CexCachingSolver::~CexCachingSolver() {
+  cache.clear();
+  delete solver;
+  for (assignmentsTable_ty::iterator it = assignmentsTable.begin(), 
+         ie = assignmentsTable.end(); it != ie; ++it)
+    delete *it;
+}
+
+bool CexCachingSolver::computeValidity(const Query& query,
+                                       Solver::Validity &result) {
+  TimerStatIncrementer t(stats::cexCacheTime);
+  Assignment *a;
+  if (!getAssignment(query.withFalse(), a))
+    return false;
+  assert(a && "computeValidity() must have assignment");
+  ref<Expr> q = a->evaluate(query.expr);
+  assert(q.isConstant() && "assignment evaluation did not result in constant");
+
+  if (q.getConstantValue()) {
+    if (!getAssignment(query, a))
+      return false;
+    result = !a ? Solver::True : Solver::Unknown;
+  } else {
+    if (!getAssignment(query.negateExpr(), a))
+      return false;
+    result = !a ? Solver::False : Solver::Unknown;
+  }
+  
+  return true;
+}
+
+bool CexCachingSolver::computeTruth(const Query& query,
+                                    bool &isValid) {
+  TimerStatIncrementer t(stats::cexCacheTime);
+
+  // There is a small amount of redundancy here. We only need to know
+  // truth and do not really need to compute an assignment. This means
+  // that we could check the cache to see if we already know that
+  // state ^ query has no assignment. In that case, by the validity of
+  // state, we know that state ^ !query must have an assignment, and
+  // so query cannot be true (valid). This does get hits, but doesn't
+  // really seem to be worth the overhead.
+
+  if (CexCacheExperimental) {
+    Assignment *a;
+    if (lookupAssignment(query.negateExpr(), a) && !a)
+      return false;
+  }
+
+  Assignment *a;
+  if (!getAssignment(query, a))
+    return false;
+
+  isValid = !a;
+
+  return true;
+}
+
+bool CexCachingSolver::computeValue(const Query& query,
+                                    ref<Expr> &result) {
+  TimerStatIncrementer t(stats::cexCacheTime);
+
+  Assignment *a;
+  if (!getAssignment(query.withFalse(), a))
+    return false;
+  assert(a && "computeValue() must have assignment");
+  result = a->evaluate(query.expr);  
+  assert(result.isConstant() && 
+         "assignment evaluation did not result in constant");
+  return true;
+}
+
+bool 
+CexCachingSolver::computeInitialValues(const Query& query,
+                                       const std::vector<const Array*> 
+                                         &objects,
+                                       std::vector< std::vector<unsigned char> >
+                                         &values,
+                                       bool &hasSolution) {
+  TimerStatIncrementer t(stats::cexCacheTime);
+  Assignment *a;
+  if (!getAssignment(query, a))
+    return false;
+  hasSolution = !!a;
+  
+  if (!a)
+    return true;
+
+  // FIXME: We should use smarter assignment for result so we don't
+  // need redundant copy.
+  values = std::vector< std::vector<unsigned char> >(objects.size());
+  for (unsigned i=0; i < objects.size(); ++i) {
+    const Array *os = objects[i];
+    Assignment::bindings_ty::iterator it = a->bindings.find(os);
+    
+    if (it == a->bindings.end()) {
+      values[i] = std::vector<unsigned char>(os->size, 0);
+    } else {
+      values[i] = it->second;
+    }
+  }
+  
+  return true;
+}
+
+///
+
+Solver *klee::createCexCachingSolver(Solver *_solver) {
+  return new Solver(new CexCachingSolver(_solver));
+}
diff --git a/lib/Solver/ConstantDivision.cpp b/lib/Solver/ConstantDivision.cpp
new file mode 100644
index 00000000..c8f8f3d5
--- /dev/null
+++ b/lib/Solver/ConstantDivision.cpp
@@ -0,0 +1,146 @@
+//===-- ConstantDivision.cpp ----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ConstantDivision.h"
+
+#include "klee/util/Bits.h"
+
+#include <algorithm>
+#include <cassert>
+
+namespace klee {
+
+/* Macros and functions which define the basic bit-level operations 
+ * needed to implement quick division operations.
+ *
+ * Based on Hacker's Delight (2003) by Henry S. Warren, Jr.
+ */
+
+/* 32 -- number of bits in the integer type on this architecture */
+
+/* 2^32 -- NUM_BITS=32 requires 64 bits to represent this unsigned value */
+#define TWO_TO_THE_32_U64 (1ULL << 32)
+
+/* 2e31 -- NUM_BITS=32 requires 64 bits to represent this signed value */
+#define TWO_TO_THE_31_S64 (1LL << 31)
+
+/* ABS(x) -- positive x */
+#define ABS(x) ( ((x)>0)?x:-(x) ) /* fails if x is the min value of its type */
+
+/* XSIGN(x) -- -1 if x<0 and 0 otherwise */
+#define XSIGN(x) ( (x) >> 31 )
+
+/* LOG2_CEIL(x) -- logarithm base 2 of x, rounded up */
+#define LOG2_CEIL(x) ( 32 - ldz(x - 1) )
+
+/* ones(x) -- counts the number of bits in x with the value 1 */
+static uint32_t ones( register uint32_t x ) {
+  x -= ((x >> 1) & 0x55555555);
+  x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+  x = (((x >> 4) + x) & 0x0f0f0f0f);
+  x += (x >> 8);
+  x += (x >> 16);
+
+  return( x & 0x0000003f );
+}
+
+/* ldz(x) -- counts the number of leading zeroes in a 32-bit word */
+static uint32_t ldz( register uint32_t x ) {
+  x |= (x >> 1);
+  x |= (x >> 2);
+  x |= (x >> 4);
+  x |= (x >> 8);
+  x |= (x >> 16);
+
+  return 32 - ones(x);
+}
+
+/* exp_base_2(n) -- 2^n computed as an integer */
+static uint32_t exp_base_2( register int32_t n ) {
+  register uint32_t x = ~n & (n - 32);
+  x = x >> 31;
+  return( x << n );
+}
+
+// A simple algorithm: Iterate over all contiguous regions of 1 bits
+// in x starting with the lowest bits.
+//
+// For a particular range where x is 1 for bits [low,high) then:
+//   1) if the range is just one bit, simple add it
+//   2) if the range is more than one bit, replace with an add
+//      of the high bit and a subtract of the low bit. we apply
+//      one useful optimization: if we were going to add the bit
+//      below the one we wish to subtract, we simply change that
+//      add to a subtract instead of subtracting the low bit itself.
+// Obviously we must take care when high==64.
+void ComputeMultConstants64(uint64_t multiplicand, 
+                            uint64_t &add, uint64_t &sub) {
+  uint64_t x = multiplicand;
+  add = sub = 0;
+
+  while (x) {
+    // Determine rightmost contiguous region of 1s.
+    unsigned low = bits64::indexOfRightmostBit(x);
+    uint64_t lowbit = 1LL << low;
+    uint64_t p = x + lowbit;
+    uint64_t q = bits64::isolateRightmostBit(p);
+    unsigned high = q ? bits64::indexOfSingleBit(q) : 64;
+
+    if (high==low+1) { // Just one bit...
+      add |= lowbit;
+    } else {
+      // Rewrite as +(1<<high) - (1<<low).
+
+      // Optimize +(1<<x) - (1<<(x+1)) to -(1<<x).
+      if (low && (add & (lowbit>>1))) {
+        add ^= lowbit>>1;
+        sub ^= lowbit>>1;
+      } else {
+        sub |= lowbit;
+      }
+
+      if (high!=64)
+        add |= 1LL << high;
+    }
+
+    x = p ^ q;
+  }
+
+  assert(multiplicand == add - sub);
+}
+
+void ComputeUDivConstants32(uint32_t d, uint32_t &mprime, uint32_t &sh1, 
+                            uint32_t &sh2) {
+  int32_t l = LOG2_CEIL( d ); /* signed so l-1 => -1 when l=0 (see sh2) */
+  uint32_t mid = exp_base_2(l) - d;
+
+  mprime = (TWO_TO_THE_32_U64 * mid / d) + 1;
+  sh1    = std::min( l,   1 );
+  sh2    = std::max( l-1, 0 );
+}
+
+void ComputeSDivConstants32(int32_t d, int32_t &mprime, int32_t &dsign, 
+                            int32_t &shpost ) {
+  uint64_t abs_d = ABS( (int64_t)d ); /* use 64-bits in case d is INT32_MIN */
+
+  /* LOG2_CEIL works on 32-bits, so we cast abs_d.  The only possible value
+   * outside the 32-bit rep. is 2^31.  This is special cased to save computer 
+   * time since 64-bit routines would be overkill. */
+  int32_t l = std::max( 1U, LOG2_CEIL((uint32_t)abs_d) );
+  if( abs_d == TWO_TO_THE_31_S64 ) l = 31;
+
+  uint32_t mid = exp_base_2( l - 1 );
+  uint64_t m = TWO_TO_THE_32_U64 * mid / abs_d + 1ULL;
+
+  mprime = m - TWO_TO_THE_32_U64; /* implicit cast to 32-bits signed */
+  dsign  = XSIGN( d );
+  shpost = l - 1;
+}
+
+}
diff --git a/lib/Solver/ConstantDivision.h b/lib/Solver/ConstantDivision.h
new file mode 100644
index 00000000..9e3e9c95
--- /dev/null
+++ b/lib/Solver/ConstantDivision.h
@@ -0,0 +1,51 @@
+//===-- ConstantDivision.h --------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_CONSTANTDIVISION_H__
+#define __UTIL_CONSTANTDIVISION_H__
+
+#include <stdint.h>
+
+namespace klee {
+
+/// ComputeMultConstants64 - Compute add and sub such that add-sub==x,
+/// while attempting to minimize the number of bits in add and sub
+/// combined.
+void ComputeMultConstants64(uint64_t x, uint64_t &add_out, 
+                            uint64_t &sub_out);
+
+/// Compute the constants to perform a quicker equivalent of a division of some 
+/// 32-bit unsigned integer n by a known constant d (also a 32-bit unsigned 
+/// integer).  The constants to compute n/d without explicit division will be 
+/// stored in mprime, sh1, and sh2 (unsigned 32-bit integers).
+/// 
+/// @param d - denominator (divisor)
+/// 
+/// @param [out] mprime
+/// @param [out] sh1
+/// @param [out] sh2
+void ComputeUDivConstants32(uint32_t d, uint32_t &mprime, uint32_t &sh1, 
+                            uint32_t &sh2);
+
+/// Compute the constants to perform a quicker equivalent of a division of some 
+/// 32-bit signed integer n by a known constant d (also a 32-bit signed 
+/// integer).  The constants to compute n/d without explicit division will be 
+/// stored in mprime, dsign, and shpost (signed 32-bit integers).
+/// 
+/// @param d - denominator (divisor)
+/// 
+/// @param [out] mprime
+/// @param [out] dsign
+/// @param [out] shpost
+void ComputeSDivConstants32(int32_t d, int32_t &mprime, int32_t &dsign, 
+                            int32_t &shpost);
+
+}
+
+#endif
diff --git a/lib/Solver/FastCexSolver.cpp b/lib/Solver/FastCexSolver.cpp
new file mode 100644
index 00000000..d2bc27c6
--- /dev/null
+++ b/lib/Solver/FastCexSolver.cpp
@@ -0,0 +1,959 @@
+//===-- FastCexSolver.cpp -------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Solver.h"
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/IncompleteSolver.h"
+#include "klee/util/ExprEvaluator.h"
+#include "klee/util/ExprRangeEvaluator.h"
+#include "klee/util/ExprVisitor.h"
+// FIXME: Use APInt.
+#include "klee/Internal/Support/IntEvaluation.h"
+
+#include <iostream>
+#include <sstream>
+#include <cassert>
+#include <map>
+#include <vector>
+
+using namespace klee;
+
+/***/
+
+//#define LOG
+#ifdef LOG
+std::ostream *theLog;
+#endif
+
+      // Hacker's Delight, pgs 58-63
+static uint64_t minOR(uint64_t a, uint64_t b,
+                      uint64_t c, uint64_t d) {
+  uint64_t temp, m = ((uint64_t) 1)<<63;
+  while (m) {
+    if (~a & c & m) {
+      temp = (a | m) & -m;
+      if (temp <= b) { a = temp; break; }
+    } else if (a & ~c & m) {
+      temp = (c | m) & -m;
+      if (temp <= d) { c = temp; break; }
+    }
+    m >>= 1;
+  }
+  
+  return a | c;
+}
+static uint64_t maxOR(uint64_t a, uint64_t b,
+                      uint64_t c, uint64_t d) {
+  uint64_t temp, m = ((uint64_t) 1)<<63;
+
+  while (m) {
+    if (b & d & m) {
+      temp = (b - m) | (m - 1);
+      if (temp >= a) { b = temp; break; }
+      temp = (d - m) | (m -1);
+      if (temp >= c) { d = temp; break; }
+    }
+    m >>= 1;
+  }
+
+  return b | d;
+}
+static uint64_t minAND(uint64_t a, uint64_t b,
+                       uint64_t c, uint64_t d) {
+  uint64_t temp, m = ((uint64_t) 1)<<63;
+  while (m) {
+    if (~a & ~c & m) {
+      temp = (a | m) & -m;
+      if (temp <= b) { a = temp; break; }
+      temp = (c | m) & -m;
+      if (temp <= d) { c = temp; break; }
+    }
+    m >>= 1;
+  }
+  
+  return a & c;
+}
+static uint64_t maxAND(uint64_t a, uint64_t b,
+                       uint64_t c, uint64_t d) {
+  uint64_t temp, m = ((uint64_t) 1)<<63;
+  while (m) {
+    if (b & ~d & m) {
+      temp = (b & ~m) | (m - 1);
+      if (temp >= a) { b = temp; break; }
+    } else if (~b & d & m) {
+      temp = (d & ~m) | (m - 1);
+      if (temp >= c) { d = temp; break; }
+    }
+    m >>= 1;
+  }
+  
+  return b & d;
+}
+
+///
+
+class ValueRange {
+private:
+  uint64_t m_min, m_max;
+
+public:
+  ValueRange() : m_min(1),m_max(0) {}
+  ValueRange(uint64_t value) : m_min(value), m_max(value) {}
+  ValueRange(uint64_t _min, uint64_t _max) : m_min(_min), m_max(_max) {}
+  ValueRange(const ValueRange &b) : m_min(b.m_min), m_max(b.m_max) {}
+
+  void print(std::ostream &os) const {
+    if (isFixed()) {
+      os << m_min;
+    } else {
+      os << "[" << m_min << "," << m_max << "]";
+    }
+  }
+
+  bool isEmpty() const { 
+    return m_min>m_max; 
+  }
+  bool contains(uint64_t value) const { 
+    return this->intersects(ValueRange(value)); 
+  }
+  bool intersects(const ValueRange &b) const { 
+    return !this->set_intersection(b).isEmpty(); 
+  }
+
+  bool isFullRange(unsigned bits) {
+    return m_min==0 && m_max==bits64::maxValueOfNBits(bits);
+  }
+
+  ValueRange set_intersection(const ValueRange &b) const {
+    return ValueRange(std::max(m_min,b.m_min), std::min(m_max,b.m_max));
+  }
+  ValueRange set_union(const ValueRange &b) const {
+    return ValueRange(std::min(m_min,b.m_min), std::max(m_max,b.m_max));
+  }
+  ValueRange set_difference(const ValueRange &b) const {
+    if (b.isEmpty() || b.m_min > m_max || b.m_max < m_min) { // no intersection
+      return *this;
+    } else if (b.m_min <= m_min && b.m_max >= m_max) { // empty
+      return ValueRange(1,0); 
+    } else if (b.m_min <= m_min) { // one range out
+      // cannot overflow because b.m_max < m_max
+      return ValueRange(b.m_max+1, m_max);
+    } else if (b.m_max >= m_max) {
+      // cannot overflow because b.min > m_min
+      return ValueRange(m_min, b.m_min-1);
+    } else {
+      // two ranges, take bottom
+      return ValueRange(m_min, b.m_min-1);
+    }
+  }
+  ValueRange binaryAnd(const ValueRange &b) const {
+    // XXX
+    assert(!isEmpty() && !b.isEmpty() && "XXX");
+    if (isFixed() && b.isFixed()) {
+      return ValueRange(m_min & b.m_min);
+    } else {
+      return ValueRange(minAND(m_min, m_max, b.m_min, b.m_max),
+                        maxAND(m_min, m_max, b.m_min, b.m_max));
+    }
+  }
+  ValueRange binaryAnd(uint64_t b) const { return binaryAnd(ValueRange(b)); }
+  ValueRange binaryOr(ValueRange b) const {
+    // XXX
+    assert(!isEmpty() && !b.isEmpty() && "XXX");
+    if (isFixed() && b.isFixed()) {
+      return ValueRange(m_min | b.m_min);
+    } else {
+      return ValueRange(minOR(m_min, m_max, b.m_min, b.m_max),
+                        maxOR(m_min, m_max, b.m_min, b.m_max));
+    }
+  }
+  ValueRange binaryOr(uint64_t b) const { return binaryOr(ValueRange(b)); }
+  ValueRange binaryXor(ValueRange b) const {
+    if (isFixed() && b.isFixed()) {
+      return ValueRange(m_min ^ b.m_min);
+    } else {
+      uint64_t t = m_max | b.m_max;
+      while (!bits64::isPowerOfTwo(t))
+        t = bits64::withoutRightmostBit(t);
+      return ValueRange(0, (t<<1)-1);
+    }
+  }
+
+  ValueRange binaryShiftLeft(unsigned bits) const {
+    return ValueRange(m_min<<bits, m_max<<bits);
+  }
+  ValueRange binaryShiftRight(unsigned bits) const {
+    return ValueRange(m_min>>bits, m_max>>bits);
+  }
+
+  ValueRange concat(const ValueRange &b, unsigned bits) const {
+    return binaryShiftLeft(bits).binaryOr(b);
+  }
+  ValueRange extract(uint64_t lowBit, uint64_t maxBit) const {
+    return binaryShiftRight(lowBit).binaryAnd(bits64::maxValueOfNBits(maxBit-lowBit));
+  }
+
+  ValueRange add(const ValueRange &b, unsigned width) const {
+    return ValueRange(0, bits64::maxValueOfNBits(width));
+  }
+  ValueRange sub(const ValueRange &b, unsigned width) const {
+    return ValueRange(0, bits64::maxValueOfNBits(width));
+  }
+  ValueRange mul(const ValueRange &b, unsigned width) const {
+    return ValueRange(0, bits64::maxValueOfNBits(width));
+  }
+  ValueRange udiv(const ValueRange &b, unsigned width) const {
+    return ValueRange(0, bits64::maxValueOfNBits(width));
+  }
+  ValueRange sdiv(const ValueRange &b, unsigned width) const {
+    return ValueRange(0, bits64::maxValueOfNBits(width));
+  }
+  ValueRange urem(const ValueRange &b, unsigned width) const {
+    return ValueRange(0, bits64::maxValueOfNBits(width));
+  }
+  ValueRange srem(const ValueRange &b, unsigned width) const {
+    return ValueRange(0, bits64::maxValueOfNBits(width));
+  }
+
+  // use min() to get value if true (XXX should we add a method to
+  // make code clearer?)
+  bool isFixed() const { return m_min==m_max; }
+
+  bool operator==(const ValueRange &b) const { return m_min==b.m_min && m_max==b.m_max; }
+  bool operator!=(const ValueRange &b) const { return !(*this==b); }
+
+  bool mustEqual(const uint64_t b) const { return m_min==m_max && m_min==b; }
+  bool mayEqual(const uint64_t b) const { return m_min<=b && m_max>=b; }
+  
+  bool mustEqual(const ValueRange &b) const { return isFixed() && b.isFixed() && m_min==b.m_min; }
+  bool mayEqual(const ValueRange &b) const { return this->intersects(b); }
+
+  uint64_t min() const { 
+    assert(!isEmpty() && "cannot get minimum of empty range");
+    return m_min; 
+  }
+
+  uint64_t max() const { 
+    assert(!isEmpty() && "cannot get maximum of empty range");
+    return m_max; 
+  }
+  
+  int64_t minSigned(unsigned bits) const {
+    assert((m_min>>bits)==0 && (m_max>>bits)==0 &&
+           "range is outside given number of bits");
+
+    // if max allows sign bit to be set then it can be smallest value,
+    // otherwise since the range is not empty, min cannot have a sign
+    // bit
+
+    uint64_t smallest = ((uint64_t) 1 << (bits-1));
+    if (m_max >= smallest) {
+      return ints::sext(smallest, 64, bits);
+    } else {
+      return m_min;
+    }
+  }
+
+  int64_t maxSigned(unsigned bits) const {
+    assert((m_min>>bits)==0 && (m_max>>bits)==0 &&
+           "range is outside given number of bits");
+
+    uint64_t smallest = ((uint64_t) 1 << (bits-1));
+
+    // if max and min have sign bit then max is max, otherwise if only
+    // max has sign bit then max is largest signed integer, otherwise
+    // max is max
+
+    if (m_min < smallest && m_max >= smallest) {
+      return smallest - 1;
+    } else {
+      return ints::sext(m_max, 64, bits);
+    }
+  }
+};
+
+inline std::ostream &operator<<(std::ostream &os, const ValueRange &vr) {
+  vr.print(os);
+  return os;
+}
+
+// used to find all memory object ids and the maximum size of any
+// object state that references them (for symbolic size).
+class ObjectFinder : public ExprVisitor {
+protected:
+  Action visitRead(const ReadExpr &re) {
+    addUpdates(re.updates);
+    return Action::doChildren();
+  }
+
+  // XXX nice if this information was cached somewhere, used by
+  // independence as well right?
+  void addUpdates(const UpdateList &ul) {
+    for (const UpdateNode *un=ul.head; un; un=un->next) {
+      visit(un->index);
+      visit(un->value);
+    }
+
+    addObject(*ul.root);
+  }
+
+public:
+  void addObject(const Array& array) {
+    unsigned id = array.id;
+    std::map<unsigned,unsigned>::iterator it = results.find(id);
+
+    // FIXME: Not 64-bit size clean.
+    if (it == results.end()) {
+      results[id] = (unsigned) array.size;      
+    } else {
+      it->second = std::max(it->second, (unsigned) array.size);
+    }
+  }
+
+public:
+  std::map<unsigned, unsigned> results;
+};
+
+// XXX waste of space, rather have ByteValueRange
+typedef ValueRange CexValueData;
+
+class CexObjectData {
+public:
+  unsigned size;
+  CexValueData *values;
+
+public:
+  CexObjectData(unsigned _size) : size(_size), values(new CexValueData[size]) {
+    for (unsigned i=0; i<size; i++)
+      values[i] = ValueRange(0, 255);
+  }
+};
+
+class CexRangeEvaluator : public ExprRangeEvaluator<ValueRange> {
+public:
+  std::map<unsigned, CexObjectData> &objectValues;
+  CexRangeEvaluator(std::map<unsigned, CexObjectData> &_objectValues) 
+    : objectValues(_objectValues) {}
+
+  ValueRange getInitialReadRange(const Array &os, ValueRange index) {
+    return ValueRange(0, 255);
+  }
+};
+
+class CexConstifier : public ExprEvaluator {
+protected:
+  ref<Expr> getInitialValue(const Array& array, unsigned index) {
+    std::map<unsigned, CexObjectData>::iterator it = 
+      objectValues.find(array.id);
+    assert(it != objectValues.end() && "missing object?");
+    CexObjectData &cod = it->second;
+    
+    if (index >= cod.size) {
+      return ReadExpr::create(UpdateList(&array, true, 0), 
+                              ref<Expr>(index, Expr::Int32));
+    } else {
+      CexValueData &cvd = cod.values[index];
+      assert(cvd.min() == cvd.max() && "value is not fixed");
+      return ref<Expr>(cvd.min(), Expr::Int8);
+    }
+  }
+
+public:
+  std::map<unsigned, CexObjectData> &objectValues;
+  CexConstifier(std::map<unsigned, CexObjectData> &_objectValues) 
+    : objectValues(_objectValues) {}
+};
+
+class CexData {
+public:
+  std::map<unsigned, CexObjectData> objectValues;
+
+public:
+  CexData(ObjectFinder &finder) {
+    for (std::map<unsigned,unsigned>::iterator it = finder.results.begin(),
+           ie = finder.results.end(); it != ie; ++it) {
+      objectValues.insert(std::pair<unsigned, CexObjectData>(it->first, 
+                                                             CexObjectData(it->second)));
+    }
+  }  
+  ~CexData() {
+    for (std::map<unsigned, CexObjectData>::iterator it = objectValues.begin(),
+           ie = objectValues.end(); it != ie; ++it)
+      delete[] it->second.values;
+  }
+
+  void forceExprToValue(ref<Expr> e, uint64_t value) {
+    forceExprToRange(e, CexValueData(value,value));
+  }
+
+  void forceExprToRange(ref<Expr> e, CexValueData range) {
+#ifdef LOG
+    //    *theLog << "force: " << e << " to " << range << "\n";
+#endif
+    switch (e.getKind()) {
+    case Expr::Constant: {
+      // rather a pity if the constant isn't in the range, but how can
+      // we use this?
+      break;
+    }
+
+      // Special
+
+    case Expr::NotOptimized: break;
+
+    case Expr::Read: {
+      ReadExpr *re = static_ref_cast<ReadExpr>(e);
+      const Array *array = re->updates.root;
+      CexObjectData &cod = objectValues.find(array->id)->second;
+
+      // XXX we need to respect the version here and object state chain
+
+      if (re->index.isConstant() && 
+          re->index.getConstantValue() < array->size) {
+        CexValueData &cvd = cod.values[re->index.getConstantValue()];
+        CexValueData tmp = cvd.set_intersection(range);
+        
+        if (tmp.isEmpty()) {
+          if (range.isFixed()) // ranges conflict, if new one is fixed use that
+            cvd = range;
+        } else {
+          cvd = tmp;
+        }
+      } else {
+        // XXX        fatal("XXX not implemented");
+      }
+      
+      break;
+    }
+
+    case Expr::Select: {
+      SelectExpr *se = static_ref_cast<SelectExpr>(e);
+      ValueRange cond = evalRangeForExpr(se->cond);
+      if (cond.isFixed()) {
+        if (cond.min()) {
+          forceExprToRange(se->trueExpr, range);
+        } else {
+          forceExprToRange(se->falseExpr, range);
+        }
+      } else {
+        // XXX imprecise... we have a choice here. One method is to
+        // simply force both sides into the specified range (since the
+        // condition is indetermined). This may lose in two ways, the
+        // first is that the condition chosen may limit further
+        // restrict the range in each of the children, however this is
+        // less of a problem as the range will be a superset of legal
+        // values. The other is if the condition ends up being forced
+        // by some other constraints, then we needlessly forced one
+        // side into the given range.
+        //
+        // The other method would be to force the condition to one
+        // side and force that side into the given range. This loses
+        // when we force the condition to an unsatisfiable value
+        // (either because the condition cannot be that, or the
+        // resulting range given that condition is not in the required
+        // range).
+        // 
+        // Currently we just force both into the range. A hybrid would
+        // be to evaluate the ranges for each of the children... if
+        // one of the ranges happens to already be a subset of the
+        // required range then it may be preferable to force the
+        // condition to that side.
+        forceExprToRange(se->trueExpr, range);
+        forceExprToRange(se->falseExpr, range);
+      }
+      break;
+    }
+
+      // XXX imprecise... the problem here is that extracting bits
+      // loses information about what bits are connected across the
+      // bytes. if a value can be 1 or 256 then either the top or
+      // lower byte is 0, but just extraction loses this information
+      // and will allow neither,one,or both to be 1.
+      //
+      // we can protect against this in a limited fashion by writing
+      // the extraction a byte at a time, then checking the evaluated
+      // value, isolating for that range, and continuing.
+    case Expr::Concat: {
+      ConcatExpr *ce = static_ref_cast<ConcatExpr>(e);
+      if (ce->is2ByteConcat()) {
+	forceExprToRange(ce->getKid(0), range.extract( 8, 16));
+	forceExprToRange(ce->getKid(1), range.extract( 0,  8));
+      }
+      else if (ce->is4ByteConcat()) {
+	forceExprToRange(ce->getKid(0), range.extract(24, 32));
+	forceExprToRange(ce->getKid(1), range.extract(16, 24));
+	forceExprToRange(ce->getKid(2), range.extract( 8, 16));
+	forceExprToRange(ce->getKid(3), range.extract( 0,  8));
+      }
+      else if (ce->is8ByteConcat()) {
+	forceExprToRange(ce->getKid(0), range.extract(56, 64));
+	forceExprToRange(ce->getKid(1), range.extract(48, 56));
+	forceExprToRange(ce->getKid(2), range.extract(40, 48));
+	forceExprToRange(ce->getKid(3), range.extract(32, 40));
+	forceExprToRange(ce->getKid(4), range.extract(24, 32));
+	forceExprToRange(ce->getKid(5), range.extract(16, 24));
+	forceExprToRange(ce->getKid(6), range.extract( 8, 16));
+	forceExprToRange(ce->getKid(7), range.extract( 0,  8));
+      }
+      
+      break;
+    }
+
+    case Expr::Extract: {
+      // XXX
+      break;
+    }
+
+      // Casting
+
+      // Simply intersect the output range with the range of all
+      // possible outputs and then truncate to the desired number of
+      // bits. 
+
+      // For ZExt this simplifies to just intersection with the
+      // possible input range.
+    case Expr::ZExt: {
+      CastExpr *ce = static_ref_cast<CastExpr>(e);
+      unsigned inBits = ce->src.getWidth();
+      ValueRange input = range.set_intersection(ValueRange(0, bits64::maxValueOfNBits(inBits)));
+      forceExprToRange(ce->src, input);
+      break;
+    }
+      // For SExt instead of doing the intersection we just take the output range
+      // minus the impossible values. This is nicer since it is a single interval.
+    case Expr::SExt: {
+      CastExpr *ce = static_ref_cast<CastExpr>(e);
+      unsigned inBits = ce->src.getWidth();
+      unsigned outBits = ce->width;
+      ValueRange output = range.set_difference(ValueRange(1<<(inBits-1),
+                                                          (bits64::maxValueOfNBits(outBits)-
+                                                           bits64::maxValueOfNBits(inBits-1)-1)));
+      ValueRange input = output.binaryAnd(bits64::maxValueOfNBits(inBits));
+      forceExprToRange(ce->src, input);
+      break;
+    }
+
+      // Binary
+
+    case Expr::And: {
+      BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+      if (be->getWidth()==Expr::Bool) {
+        if (range.isFixed()) {
+          ValueRange left = evalRangeForExpr(be->left);
+          ValueRange right = evalRangeForExpr(be->right);
+
+          if (!range.min()) {
+            if (left.mustEqual(0) || right.mustEqual(0)) {
+              // all is well
+            } else {
+              // XXX heuristic, which order
+
+              forceExprToValue(be->left, 0);
+              left = evalRangeForExpr(be->left);
+
+              // see if that worked
+              if (!left.mustEqual(1))
+                forceExprToValue(be->right, 0);
+            }
+          } else {
+            if (!left.mustEqual(1)) forceExprToValue(be->left, 1);
+            if (!right.mustEqual(1)) forceExprToValue(be->right, 1);
+          }
+        }
+      } else {
+        // XXX
+      }
+      break;
+    }
+
+    case Expr::Or: {
+      BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+      if (be->getWidth()==Expr::Bool) {
+        if (range.isFixed()) {
+          ValueRange left = evalRangeForExpr(be->left);
+          ValueRange right = evalRangeForExpr(be->right);
+
+          if (range.min()) {
+            if (left.mustEqual(1) || right.mustEqual(1)) {
+              // all is well
+            } else {
+              // XXX heuristic, which order?
+              
+              // force left to value we need
+              forceExprToValue(be->left, 1);
+              left = evalRangeForExpr(be->left);
+
+              // see if that worked
+              if (!left.mustEqual(1))
+                forceExprToValue(be->right, 1);
+            }
+          } else {
+            if (!left.mustEqual(0)) forceExprToValue(be->left, 0);
+            if (!right.mustEqual(0)) forceExprToValue(be->right, 0);
+          }
+        }
+      } else {
+        // XXX
+      }
+      break;
+    }
+
+    case Expr::Xor: break;
+
+      // Comparison
+
+    case Expr::Eq: {
+      BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+      if (range.isFixed()) {
+        if (be->left.isConstant()) {
+          uint64_t value = be->left.getConstantValue();
+          if (range.min()) {
+            forceExprToValue(be->right, value);
+          } else {
+            if (value==0) {
+              forceExprToRange(be->right, 
+                               CexValueData(1,
+                                            ints::sext(1, 
+                                                       be->right.getWidth(),
+                                                       1)));
+            } else {
+              // XXX heuristic / lossy, could be better to pick larger range?
+              forceExprToRange(be->right, CexValueData(0, value-1));
+            }
+          }
+        } else {
+          // XXX what now
+        }
+      }
+      break;
+    }
+
+    case Expr::Ult: {
+      BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+      
+      // XXX heuristic / lossy, what order if conflict
+
+      if (range.isFixed()) {
+        ValueRange left = evalRangeForExpr(be->left);
+        ValueRange right = evalRangeForExpr(be->right);
+
+        uint64_t maxValue = bits64::maxValueOfNBits(be->right.getWidth());
+
+        // XXX should deal with overflow (can lead to empty range)
+
+        if (left.isFixed()) {
+          if (range.min()) {
+            forceExprToRange(be->right, CexValueData(left.min()+1, maxValue));
+          } else {
+            forceExprToRange(be->right, CexValueData(0, left.min()));
+          }
+        } else if (right.isFixed()) {
+          if (range.min()) {
+            forceExprToRange(be->left, CexValueData(0, right.min()-1));
+          } else {
+            forceExprToRange(be->left, CexValueData(right.min(), maxValue));
+          }
+        } else {
+          // XXX ???
+        }
+      }
+      break;
+    }
+    case Expr::Ule: {
+      BinaryExpr *be = static_ref_cast<BinaryExpr>(e);
+      
+      // XXX heuristic / lossy, what order if conflict
+
+      if (range.isFixed()) {
+        ValueRange left = evalRangeForExpr(be->left);
+        ValueRange right = evalRangeForExpr(be->right);
+
+        // XXX should deal with overflow (can lead to empty range)
+
+        uint64_t maxValue = bits64::maxValueOfNBits(be->right.getWidth());
+        if (left.isFixed()) {
+          if (range.min()) {
+            forceExprToRange(be->right, CexValueData(left.min(), maxValue));
+          } else {
+            forceExprToRange(be->right, CexValueData(0, left.min()-1));
+          }
+        } else if (right.isFixed()) {
+          if (range.min()) {
+            forceExprToRange(be->left, CexValueData(0, right.min()));
+          } else {
+            forceExprToRange(be->left, CexValueData(right.min()+1, maxValue));
+          }
+        } else {
+          // XXX ???
+        }
+      }
+      break;
+    }
+
+    case Expr::Ne:
+    case Expr::Ugt:
+    case Expr::Uge:
+    case Expr::Sgt:
+    case Expr::Sge:
+      assert(0 && "invalid expressions (uncanonicalized");
+
+    default:
+      break;
+    }
+  }
+
+  void fixValues() {
+    for (std::map<unsigned, CexObjectData>::iterator it = objectValues.begin(),
+           ie = objectValues.end(); it != ie; ++it) {
+      CexObjectData &cod = it->second;
+      for (unsigned i=0; i<cod.size; i++) {
+        CexValueData &cvd = cod.values[i];
+        cvd = CexValueData(cvd.min() + (cvd.max()-cvd.min())/2);
+      }
+    }
+  }
+
+  ValueRange evalRangeForExpr(ref<Expr> &e) {
+    CexRangeEvaluator ce(objectValues);
+    return ce.evaluate(e);
+  }
+
+  bool exprMustBeValue(ref<Expr> e, uint64_t value) {
+    CexConstifier cc(objectValues);
+    ref<Expr> v = cc.visit(e);
+    if (!v.isConstant()) return false;
+    // XXX reenable once all reads and vars are fixed
+    //    assert(v.isConstant() && "not all values have been fixed");
+    return v.getConstantValue()==value;
+  }
+};
+
+/* *** */
+
+
+class FastCexSolver : public IncompleteSolver {
+public:
+  FastCexSolver();
+  ~FastCexSolver();
+
+  IncompleteSolver::PartialValidity computeTruth(const Query&);  
+  bool computeValue(const Query&, ref<Expr> &result);
+  bool computeInitialValues(const Query&,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution);
+};
+
+FastCexSolver::FastCexSolver() { }
+
+FastCexSolver::~FastCexSolver() { }
+
+IncompleteSolver::PartialValidity 
+FastCexSolver::computeTruth(const Query& query) {
+#ifdef LOG
+  std::ostringstream log;
+  theLog = &log;
+  //  log << "------ start FastCexSolver::mustBeTrue ------\n";
+  log << "-- QUERY --\n";
+  unsigned i=0;
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    log << "    C" << i++ << ": " << *it << ", \n";
+  log << "    Q : " << query.expr << "\n";
+#endif
+
+  ObjectFinder of;
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    of.visit(*it);
+  of.visit(query.expr);
+  CexData cd(of);
+
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    cd.forceExprToValue(*it, 1);
+  cd.forceExprToValue(query.expr, 0);
+
+#ifdef LOG
+  log << " -- ranges --\n";
+  for (std::map<unsigned, CexObjectData>::iterator it = objectValues.begin(),
+         ie = objectValues.end(); it != ie; ++it) {
+    CexObjectData &cod = it->second;
+    log << "    arr" << it->first << "[" << cod.size << "] = [";
+    unsigned continueFrom=cod.size-1;
+    for (; continueFrom>0; continueFrom--)
+      if (cod.values[continueFrom-1]!=cod.values[continueFrom])
+        break;
+    for (unsigned i=0; i<cod.size; i++) {
+      log << cod.values[i];
+      if (i<cod.size-1) {
+        log << ", ";
+        if (i==continueFrom) {
+          log << "...";
+          break;
+        }
+      }
+    }
+    log << "]\n";
+  }
+#endif
+
+  // this could be done lazily of course
+  cd.fixValues();
+
+#ifdef LOG
+  log << " -- fixed values --\n";
+  for (std::map<unsigned, CexObjectData>::iterator it = objectValues.begin(),
+         ie = objectValues.end(); it != ie; ++it) {
+    CexObjectData &cod = it->second;
+    log << "    arr" << it->first << "[" << cod.size << "] = [";
+    unsigned continueFrom=cod.size-1;
+    for (; continueFrom>0; continueFrom--)
+      if (cod.values[continueFrom-1]!=cod.values[continueFrom])
+        break;
+    for (unsigned i=0; i<cod.size; i++) {
+      log << cod.values[i];
+      if (i<cod.size-1) {
+        log << ", ";
+        if (i==continueFrom) {
+          log << "...";
+          break;
+        }
+      }
+    }
+    log << "]\n";
+  }
+#endif
+
+  // check the result
+
+  bool isGood = true;
+
+  if (!cd.exprMustBeValue(query.expr, 0)) isGood = false;
+
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    if (!cd.exprMustBeValue(*it, 1)) 
+      isGood = false;
+
+#ifdef LOG
+  log << " -- evaluating result --\n";
+  
+  i=0;
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it) {
+    bool res = cd.exprMustBeValue(*it, 1);
+    log << "    C" << i++ << ": " << (res?"true":"false") << "\n";
+  }
+  log << "    Q : " 
+      << (cd.exprMustBeValue(query.expr, 0)?"true":"false") << "\n";
+  
+  log << "\n\n";
+#endif
+
+  return isGood ? IncompleteSolver::MayBeFalse : IncompleteSolver::None;
+}
+
+bool FastCexSolver::computeValue(const Query& query, ref<Expr> &result) {
+  ObjectFinder of;
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    of.visit(*it);
+  of.visit(query.expr);
+  CexData cd(of);
+
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    cd.forceExprToValue(*it, 1);
+
+  // this could be done lazily of course
+  cd.fixValues();
+
+  // check the result
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    if (!cd.exprMustBeValue(*it, 1))
+      return false;
+
+  CexConstifier cc(cd.objectValues);
+  ref<Expr> value = cc.visit(query.expr);
+
+  if (value.isConstant()) {
+    result = value;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool
+FastCexSolver::computeInitialValues(const Query& query,
+                                    const std::vector<const Array*>
+                                      &objects,
+                                    std::vector< std::vector<unsigned char> >
+                                      &values,
+                                    bool &hasSolution) {
+  ObjectFinder of;
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    of.visit(*it);
+  of.visit(query.expr);
+  for (unsigned i = 0; i != objects.size(); ++i)
+    of.addObject(*objects[i]);
+  CexData cd(of);
+
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    cd.forceExprToValue(*it, 1);
+  cd.forceExprToValue(query.expr, 0);
+
+  // this could be done lazily of course
+  cd.fixValues();
+
+  // check the result
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    if (!cd.exprMustBeValue(*it, 1))
+      return false;
+  if (!cd.exprMustBeValue(query.expr, 0))
+    return false;
+
+  hasSolution = true;
+  CexConstifier cc(cd.objectValues);
+  for (unsigned i = 0; i != objects.size(); ++i) {
+    const Array *array = objects[i];
+    std::vector<unsigned char> data;
+    data.reserve(array->size);
+
+    for (unsigned i=0; i < array->size; i++) {
+      ref<Expr> value =
+        cc.visit(ReadExpr::create(UpdateList(array, true, 0),
+                                  ConstantExpr::create(i,
+                                                       kMachinePointerType)));
+      
+      if (value.isConstant()) {
+        data.push_back(value.getConstantValue());
+      } else {
+        // FIXME: When does this happen?
+        return false;
+      }
+    }
+
+    values.push_back(data);
+  }
+
+  return true;
+}
+
+
+Solver *klee::createFastCexSolver(Solver *s) {
+  return new Solver(new StagedSolverImpl(new FastCexSolver(), s));
+}
diff --git a/lib/Solver/IncompleteSolver.cpp b/lib/Solver/IncompleteSolver.cpp
new file mode 100644
index 00000000..f473f70b
--- /dev/null
+++ b/lib/Solver/IncompleteSolver.cpp
@@ -0,0 +1,136 @@
+//===-- IncompleteSolver.cpp ----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/IncompleteSolver.h"
+
+#include "klee/Constraints.h"
+
+using namespace klee;
+using namespace llvm;
+
+/***/
+
+IncompleteSolver::PartialValidity 
+IncompleteSolver::negatePartialValidity(PartialValidity pv) {
+  switch(pv) {
+    case MustBeTrue:  return MustBeFalse;
+    case MustBeFalse: return MustBeTrue;
+    case MayBeTrue:   return MayBeFalse;
+    case MayBeFalse:  return MayBeTrue;
+    case TrueOrFalse: return TrueOrFalse;
+    default: assert(0 && "invalid partial validity");  
+  }
+}
+
+IncompleteSolver::PartialValidity 
+IncompleteSolver::computeValidity(const Query& query) {
+  PartialValidity trueResult = computeTruth(query);
+
+  if (trueResult == MustBeTrue) {
+    return MustBeTrue;
+  } else {
+    PartialValidity falseResult = computeTruth(query.negateExpr());
+
+    if (falseResult == MustBeTrue) {
+      return MustBeFalse;
+    } else {
+      bool trueCorrect = trueResult != None,
+        falseCorrect = falseResult != None;
+      
+      if (trueCorrect && falseCorrect) {
+        return TrueOrFalse;
+      } else if (trueCorrect) { // ==> trueResult == MayBeFalse
+        return MayBeFalse;
+      } else if (falseCorrect) { // ==> falseResult == MayBeFalse
+        return MayBeTrue;
+      } else {
+        return None;
+      }
+    }
+  }
+}
+
+/***/
+
+StagedSolverImpl::StagedSolverImpl(IncompleteSolver *_primary, 
+                                   Solver *_secondary) 
+  : primary(_primary),
+    secondary(_secondary) {
+}
+
+StagedSolverImpl::~StagedSolverImpl() {
+  delete primary;
+  delete secondary;
+}
+
+bool StagedSolverImpl::computeTruth(const Query& query, bool &isValid) {
+  IncompleteSolver::PartialValidity trueResult = primary->computeTruth(query); 
+  
+  if (trueResult != IncompleteSolver::None) {
+    isValid = (trueResult == IncompleteSolver::MustBeTrue);
+    return true;
+  } 
+
+  return secondary->impl->computeTruth(query, isValid);
+}
+
+bool StagedSolverImpl::computeValidity(const Query& query,
+                                       Solver::Validity &result) {
+  bool tmp;
+
+  switch(primary->computeValidity(query)) {
+  case IncompleteSolver::MustBeTrue: 
+    result = Solver::True;
+    break;
+  case IncompleteSolver::MustBeFalse: 
+    result = Solver::False;
+    break;
+  case IncompleteSolver::TrueOrFalse: 
+    result = Solver::Unknown;
+    break;
+  case IncompleteSolver::MayBeTrue:
+    if (!secondary->impl->computeTruth(query, tmp))
+      return false;
+    result = tmp ? Solver::True : Solver::Unknown;
+    break;
+  case IncompleteSolver::MayBeFalse:
+    if (!secondary->impl->computeTruth(query.negateExpr(), tmp))
+      return false;
+    result = tmp ? Solver::False : Solver::Unknown;
+    break;
+  default:
+    if (!secondary->impl->computeValidity(query, result))
+      return false;
+    break;
+  }
+
+  return true;
+}
+
+bool StagedSolverImpl::computeValue(const Query& query,
+                                    ref<Expr> &result) {
+  if (primary->computeValue(query, result))
+    return true;
+
+  return secondary->impl->computeValue(query, result);
+}
+
+bool 
+StagedSolverImpl::computeInitialValues(const Query& query,
+                                       const std::vector<const Array*> 
+                                         &objects,
+                                       std::vector< std::vector<unsigned char> >
+                                         &values,
+                                       bool &hasSolution) {
+  if (primary->computeInitialValues(query, objects, values, hasSolution))
+    return true;
+  
+  return secondary->impl->computeInitialValues(query, objects, values,
+                                               hasSolution);
+}
diff --git a/lib/Solver/IndependentSolver.cpp b/lib/Solver/IndependentSolver.cpp
new file mode 100644
index 00000000..c966aff6
--- /dev/null
+++ b/lib/Solver/IndependentSolver.cpp
@@ -0,0 +1,314 @@
+//===-- IndependentSolver.cpp ---------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Solver.h"
+
+#include "klee/Expr.h"
+#include "klee/Constraints.h"
+#include "klee/SolverImpl.h"
+
+#include "klee/util/ExprUtil.h"
+
+#include "llvm/Support/Streams.h"
+
+#include <map>
+#include <vector>
+
+using namespace klee;
+using namespace llvm;
+
+template<class T>
+class DenseSet {
+  typedef std::set<T> set_ty;
+  set_ty s;
+
+public:
+  DenseSet() {}
+
+  void add(T x) {
+    s.insert(x);
+  }
+  void add(T start, T end) {
+    for (; start<end; start++)
+      s.insert(start);
+  }
+
+  // returns true iff set is changed by addition
+  bool add(const DenseSet &b) {
+    bool modified = false;
+    for (typename set_ty::const_iterator it = b.s.begin(), ie = b.s.end(); 
+         it != ie; ++it) {
+      if (modified || !s.count(*it)) {
+        modified = true;
+        s.insert(*it);
+      }
+    }
+    return modified;
+  }
+
+  bool intersects(const DenseSet &b) {
+    for (typename set_ty::iterator it = s.begin(), ie = s.end(); 
+         it != ie; ++it)
+      if (b.s.count(*it))
+        return true;
+    return false;
+  }
+
+  void print(std::ostream &os) const {
+    bool first = true;
+    os << "{";
+    for (typename set_ty::iterator it = s.begin(), ie = s.end(); 
+         it != ie; ++it) {
+      if (first) {
+        first = false;
+      } else {
+        os << ",";
+      }
+      os << *it;
+    }
+    os << "}";
+  }
+};
+
+template<class T>
+inline std::ostream &operator<<(std::ostream &os, const DenseSet<T> &dis) {
+  dis.print(os);
+  return os;
+}
+
+class IndependentElementSet {
+  typedef std::map<const Array*, DenseSet<unsigned> > elements_ty;
+  elements_ty elements;
+  std::set<const Array*> wholeObjects;
+
+public:
+  IndependentElementSet() {}
+  IndependentElementSet(ref<Expr> e) {
+    std::vector< ref<ReadExpr> > reads;
+    findReads(e, /* visitUpdates= */ true, reads);
+    for (unsigned i = 0; i != reads.size(); ++i) {
+      ReadExpr *re = reads[i].get();
+      if (re->updates.isRooted) {
+        const Array *array = re->updates.root;
+        if (!wholeObjects.count(array)) {
+          if (re->index.isConstant()) {
+            DenseSet<unsigned> &dis = elements[array];
+            dis.add((unsigned) re->index.getConstantValue());
+          } else {
+            elements_ty::iterator it2 = elements.find(array);
+            if (it2!=elements.end())
+              elements.erase(it2);
+            wholeObjects.insert(array);
+          }
+        }
+      }
+    }
+  }
+  IndependentElementSet(const IndependentElementSet &ies) : 
+    elements(ies.elements),
+    wholeObjects(ies.wholeObjects) {}    
+
+  IndependentElementSet &operator=(const IndependentElementSet &ies) {
+    elements = ies.elements;
+    wholeObjects = ies.wholeObjects;
+    return *this;
+  }
+
+  void print(std::ostream &os) const {
+    os << "{";
+    bool first = true;
+    for (std::set<const Array*>::iterator it = wholeObjects.begin(), 
+           ie = wholeObjects.end(); it != ie; ++it) {
+      const Array *array = *it;
+
+      if (first) {
+        first = false;
+      } else {
+        os << ", ";
+      }
+
+      os << "MO" << array->id;
+    }
+    for (elements_ty::const_iterator it = elements.begin(), ie = elements.end();
+         it != ie; ++it) {
+      const Array *array = it->first;
+      const DenseSet<unsigned> &dis = it->second;
+
+      if (first) {
+        first = false;
+      } else {
+        os << ", ";
+      }
+
+      os << "MO" << array->id << " : " << dis;
+    }
+    os << "}";
+  }
+
+  // more efficient when this is the smaller set
+  bool intersects(const IndependentElementSet &b) {
+    for (std::set<const Array*>::iterator it = wholeObjects.begin(), 
+           ie = wholeObjects.end(); it != ie; ++it) {
+      const Array *array = *it;
+      if (b.wholeObjects.count(array) || 
+          b.elements.find(array) != b.elements.end())
+        return true;
+    }
+    for (elements_ty::iterator it = elements.begin(), ie = elements.end();
+         it != ie; ++it) {
+      const Array *array = it->first;
+      if (b.wholeObjects.count(array))
+        return true;
+      elements_ty::const_iterator it2 = b.elements.find(array);
+      if (it2 != b.elements.end()) {
+        if (it->second.intersects(it2->second))
+          return true;
+      }
+    }
+    return false;
+  }
+
+  // returns true iff set is changed by addition
+  bool add(const IndependentElementSet &b) {
+    bool modified = false;
+    for (std::set<const Array*>::const_iterator it = b.wholeObjects.begin(), 
+           ie = b.wholeObjects.end(); it != ie; ++it) {
+      const Array *array = *it;
+      elements_ty::iterator it2 = elements.find(array);
+      if (it2!=elements.end()) {
+        modified = true;
+        elements.erase(it2);
+        wholeObjects.insert(array);
+      } else {
+        if (!wholeObjects.count(array)) {
+          modified = true;
+          wholeObjects.insert(array);
+        }
+      }
+    }
+    for (elements_ty::const_iterator it = b.elements.begin(), 
+           ie = b.elements.end(); it != ie; ++it) {
+      const Array *array = it->first;
+      if (!wholeObjects.count(array)) {
+        elements_ty::iterator it2 = elements.find(array);
+        if (it2==elements.end()) {
+          modified = true;
+          elements.insert(*it);
+        } else {
+          if (it2->second.add(it->second))
+            modified = true;
+        }
+      }
+    }
+    return modified;
+  }
+};
+
+inline std::ostream &operator<<(std::ostream &os, const IndependentElementSet &ies) {
+  ies.print(os);
+  return os;
+}
+
+static 
+IndependentElementSet getIndependentConstraints(const Query& query,
+                                                std::vector< ref<Expr> > &result) {
+  IndependentElementSet eltsClosure(query.expr);
+  std::vector< std::pair<ref<Expr>, IndependentElementSet> > worklist;
+
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    worklist.push_back(std::make_pair(*it, IndependentElementSet(*it)));
+
+  // XXX This should be more efficient (in terms of low level copy stuff).
+  bool done = false;
+  do {
+    done = true;
+    std::vector< std::pair<ref<Expr>, IndependentElementSet> > newWorklist;
+    for (std::vector< std::pair<ref<Expr>, IndependentElementSet> >::iterator
+           it = worklist.begin(), ie = worklist.end(); it != ie; ++it) {
+      if (it->second.intersects(eltsClosure)) {
+        if (eltsClosure.add(it->second))
+          done = false;
+        result.push_back(it->first);
+      } else {
+        newWorklist.push_back(*it);
+      }
+    }
+    worklist.swap(newWorklist);
+  } while (!done);
+
+  if (0) {
+    std::set< ref<Expr> > reqset(result.begin(), result.end());
+    llvm::cerr << "--\n";
+    llvm::cerr << "Q: " << query.expr << "\n";
+    llvm::cerr << "\telts: " << IndependentElementSet(query.expr) << "\n";
+    int i = 0;
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it) {
+      llvm::cerr << "C" << i++ << ": " << *it;
+      llvm::cerr << " " << (reqset.count(*it) ? "(required)" : "(independent)") << "\n";
+      llvm::cerr << "\telts: " << IndependentElementSet(*it) << "\n";
+    }
+    llvm::cerr << "elts closure: " << eltsClosure << "\n";
+  }
+
+  return eltsClosure;
+}
+
+class IndependentSolver : public SolverImpl {
+private:
+  Solver *solver;
+
+public:
+  IndependentSolver(Solver *_solver) 
+    : solver(_solver) {}
+  ~IndependentSolver() { delete solver; }
+
+  bool computeTruth(const Query&, bool &isValid);
+  bool computeValidity(const Query&, Solver::Validity &result);
+  bool computeValue(const Query&, ref<Expr> &result);
+  bool computeInitialValues(const Query& query,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution) {
+    return solver->impl->computeInitialValues(query, objects, values,
+                                              hasSolution);
+  }
+};
+  
+bool IndependentSolver::computeValidity(const Query& query,
+                                        Solver::Validity &result) {
+  std::vector< ref<Expr> > required;
+  IndependentElementSet eltsClosure =
+    getIndependentConstraints(query, required);
+  ConstraintManager tmp(required);
+  return solver->impl->computeValidity(Query(tmp, query.expr), 
+                                       result);
+}
+
+bool IndependentSolver::computeTruth(const Query& query, bool &isValid) {
+  std::vector< ref<Expr> > required;
+  IndependentElementSet eltsClosure = 
+    getIndependentConstraints(query, required);
+  ConstraintManager tmp(required);
+  return solver->impl->computeTruth(Query(tmp, query.expr), 
+                                    isValid);
+}
+
+bool IndependentSolver::computeValue(const Query& query, ref<Expr> &result) {
+  std::vector< ref<Expr> > required;
+  IndependentElementSet eltsClosure = 
+    getIndependentConstraints(query, required);
+  ConstraintManager tmp(required);
+  return solver->impl->computeValue(Query(tmp, query.expr), result);
+}
+
+Solver *klee::createIndependentSolver(Solver *s) {
+  return new Solver(new IndependentSolver(s));
+}
diff --git a/lib/Solver/Makefile b/lib/Solver/Makefile
new file mode 100755
index 00000000..11d3d330
--- /dev/null
+++ b/lib/Solver/Makefile
@@ -0,0 +1,16 @@
+#===-- lib/Solver/Makefile ---------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleaverSolver
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Solver/PCLoggingSolver.cpp b/lib/Solver/PCLoggingSolver.cpp
new file mode 100644
index 00000000..4b787acb
--- /dev/null
+++ b/lib/Solver/PCLoggingSolver.cpp
@@ -0,0 +1,134 @@
+//===-- PCLoggingSolver.cpp -----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Solver.h"
+
+// FIXME: This should not be here.
+#include "klee/ExecutionState.h"
+#include "klee/Expr.h"
+#include "klee/SolverImpl.h"
+#include "klee/Statistics.h"
+#include "klee/util/ExprPPrinter.h"
+#include "klee/Internal/Support/QueryLog.h"
+#include "klee/Internal/System/Time.h"
+
+#include "llvm/Support/CommandLine.h"
+
+#include <fstream>
+
+using namespace klee;
+using namespace llvm;
+using namespace klee::util;
+
+///
+
+class PCLoggingSolver : public SolverImpl {
+  Solver *solver;
+  std::ofstream os;
+  ExprPPrinter *printer;
+  unsigned queryCount;
+  double startTime;
+
+  void startQuery(const Query& query, const char *typeName) {
+    Statistic *S = theStatisticManager->getStatisticByName("Instructions");
+    uint64_t instructions = S ? S->getValue() : 0;
+    os << "# Query " << queryCount++ << " -- "
+       << "Type: " << typeName << ", "
+       << "Instructions: " << instructions << "\n";
+    printer->printQuery(os, query.constraints, query.expr);
+    
+    startTime = getWallTime();
+  }
+
+  void finishQuery(bool success) {
+    double delta = getWallTime() - startTime;
+    os << "#   " << (success ? "OK" : "FAIL") << " -- "
+       << "Elapsed: " << delta << "\n";
+  }
+  
+public:
+  PCLoggingSolver(Solver *_solver, std::string path) 
+  : solver(_solver),
+    os(path.c_str(), std::ios::trunc),
+    printer(ExprPPrinter::create(os)),
+    queryCount(0) {
+  }                                                      
+  ~PCLoggingSolver() {
+    delete printer;
+    delete solver;
+  }
+  
+  bool computeTruth(const Query& query, bool &isValid) {
+    startQuery(query, "Truth");
+    bool success = solver->impl->computeTruth(query, isValid);
+    finishQuery(success);
+    if (success)
+      os << "#   Is Valid: " << (isValid ? "true" : "false") << "\n";
+    os << "\n";
+    return success;
+  }
+
+  bool computeValidity(const Query& query, Solver::Validity &result) {
+    startQuery(query, "Validity");
+    bool success = solver->impl->computeValidity(query, result);
+    finishQuery(success);
+    if (success)
+      os << "#   Validity: " << result << "\n";
+    os << "\n";
+    return success;
+  }
+
+  bool computeValue(const Query& query, ref<Expr> &result) {
+    startQuery(query, "Value");
+    bool success = solver->impl->computeValue(query, result);
+    finishQuery(success);
+    if (success)
+      os << "#   Result: " << result << "\n";
+    os << "\n";
+    return success;
+  }
+
+  bool computeInitialValues(const Query& query,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution) {
+    // FIXME: Add objects to output.
+    startQuery(query, "InitialValues");
+    bool success = solver->impl->computeInitialValues(query, objects, 
+                                                      values, hasSolution);
+    finishQuery(success);
+    if (success) {
+      os << "#   Solvable: " << (hasSolution ? "true" : "false") << "\n";
+      if (hasSolution) {
+        std::vector< std::vector<unsigned char> >::iterator
+          values_it = values.begin();
+        for (std::vector<const Array*>::const_iterator i = objects.begin(),
+               e = objects.end(); i != e; ++i, ++values_it) {
+          const Array *array = *i;
+          std::vector<unsigned char> &data = *values_it;
+          os << "#     arr" << array->id << " = [";
+          for (unsigned j = 0; j < array->size; j++) {
+            os << (int) data[j];
+            if (j+1 < array->size)
+              os << ",";
+          }
+          os << "]\n";
+        }
+      }
+    }
+    os << "\n";
+    return success;
+  }
+};
+
+///
+
+Solver *klee::createPCLoggingSolver(Solver *_solver, std::string path) {
+  return new Solver(new PCLoggingSolver(_solver, path));
+}
diff --git a/lib/Solver/STPBuilder.cpp b/lib/Solver/STPBuilder.cpp
new file mode 100644
index 00000000..33aee035
--- /dev/null
+++ b/lib/Solver/STPBuilder.cpp
@@ -0,0 +1,819 @@
+//===-- STPBuilder.cpp ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "STPBuilder.h"
+
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+#include "klee/util/Bits.h"
+
+#include "ConstantDivision.h"
+#include "SolverStats.h"
+
+#include "llvm/Support/CommandLine.h"
+
+#define vc_bvBoolExtract IAMTHESPAWNOFSATAN
+// unclear return
+#define vc_bvLeftShiftExpr IAMTHESPAWNOFSATAN
+#define vc_bvRightShiftExpr IAMTHESPAWNOFSATAN
+// bad refcnt'ng
+#define vc_bvVar32LeftShiftExpr IAMTHESPAWNOFSATAN
+#define vc_bvVar32RightShiftExpr IAMTHESPAWNOFSATAN
+#define vc_bvVar32DivByPowOfTwoExpr IAMTHESPAWNOFSATAN
+#define vc_bvCreateMemoryArray IAMTHESPAWNOFSATAN
+#define vc_bvReadMemoryArray IAMTHESPAWNOFSATAN
+#define vc_bvWriteToMemoryArray IAMTHESPAWNOFSATAN
+
+#include <algorithm> // max, min
+#include <cassert>
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <vector>
+
+using namespace klee;
+
+namespace {
+  llvm::cl::opt<bool>
+  UseConstructHash("use-construct-hash", 
+                   llvm::cl::desc("Use hash-consing during STP query construction."),
+                   llvm::cl::init(true));
+}
+
+///
+
+/***/
+
+STPBuilder::STPBuilder(::VC _vc, bool _optimizeDivides) 
+  : vc(_vc), optimizeDivides(_optimizeDivides)
+{
+  tempVars[0] = buildVar("__tmpInt8", 8);
+  tempVars[1] = buildVar("__tmpInt16", 16);
+  tempVars[2] = buildVar("__tmpInt32", 32);
+  tempVars[3] = buildVar("__tmpInt64", 64);
+}
+
+STPBuilder::~STPBuilder() {
+}
+
+///
+
+/* Warning: be careful about what c_interface functions you use. Some of
+   them look like they cons memory but in fact don't, which is bad when
+   you call vc_DeleteExpr on them. */
+
+::VCExpr STPBuilder::buildVar(const char *name, unsigned width) {
+  // XXX don't rebuild if this stuff cons's
+  ::Type t = (width==1) ? vc_boolType(vc) : vc_bvType(vc, width);
+  ::VCExpr res = vc_varExpr(vc, (char*) name, t);
+  vc_DeleteExpr(t);
+  return res;
+}
+
+::VCExpr STPBuilder::buildArray(const char *name, unsigned indexWidth, unsigned valueWidth) {
+  // XXX don't rebuild if this stuff cons's
+  ::Type t1 = vc_bvType(vc, indexWidth);
+  ::Type t2 = vc_bvType(vc, valueWidth);
+  ::Type t = vc_arrayType(vc, t1, t2);
+  ::VCExpr res = vc_varExpr(vc, (char*) name, t);
+  vc_DeleteExpr(t);
+  vc_DeleteExpr(t2);
+  vc_DeleteExpr(t1);
+  return res;
+}
+
+ExprHandle STPBuilder::getTempVar(Expr::Width w) {
+  switch (w) {
+  case Expr::Int8: return tempVars[0];
+  case Expr::Int16: return tempVars[1];
+  case Expr::Int32: return tempVars[2];
+  case Expr::Int64: return tempVars[3];
+  default:
+    assert(0 && "invalid type");
+  }
+}
+
+ExprHandle STPBuilder::getTrue() {
+  return vc_trueExpr(vc);
+}
+ExprHandle STPBuilder::getFalse() {
+  return vc_falseExpr(vc);
+}
+ExprHandle STPBuilder::bvOne(unsigned width) {
+  return bvConst32(width, 1);
+}
+ExprHandle STPBuilder::bvZero(unsigned width) {
+  return bvConst32(width, 0);
+}
+ExprHandle STPBuilder::bvMinusOne(unsigned width) {
+  return bvConst64(width, (int64_t) -1);
+}
+ExprHandle STPBuilder::bvConst32(unsigned width, uint32_t value) {
+  return vc_bvConstExprFromInt(vc, width, value);
+}
+ExprHandle STPBuilder::bvConst64(unsigned width, uint64_t value) {
+  return vc_bvConstExprFromLL(vc, width, value);
+}
+
+ExprHandle STPBuilder::bvBoolExtract(ExprHandle expr, int bit) {
+  return vc_eqExpr(vc, bvExtract(expr, bit, bit), bvOne(1));
+}
+ExprHandle STPBuilder::bvExtract(ExprHandle expr, unsigned top, unsigned bottom) {
+  return vc_bvExtract(vc, expr, top, bottom);
+}
+ExprHandle STPBuilder::eqExpr(ExprHandle a, ExprHandle b) {
+  return vc_eqExpr(vc, a, b);
+}
+
+// logical right shift
+ExprHandle STPBuilder::bvRightShift(ExprHandle expr, unsigned amount, unsigned shiftBits) {
+  unsigned width = vc_getBVLength(vc, expr);
+  unsigned shift = amount & ((1<<shiftBits) - 1);
+
+  if (shift==0) {
+    return expr;
+  } else if (shift>=width) {
+    return bvZero(width);
+  } else {
+    return vc_bvConcatExpr(vc,
+                           bvZero(shift),
+                           bvExtract(expr, width - 1, shift));
+  }
+}
+
+// logical left shift
+ExprHandle STPBuilder::bvLeftShift(ExprHandle expr, unsigned amount, unsigned shiftBits) {
+  unsigned width = vc_getBVLength(vc, expr);
+  unsigned shift = amount & ((1<<shiftBits) - 1);
+
+  if (shift==0) {
+    return expr;
+  } else if (shift>=width) {
+    return bvZero(width);
+  } else {
+    // stp shift does "expr @ [0 x s]" which we then have to extract,
+    // rolling our own gives slightly smaller exprs
+    return vc_bvConcatExpr(vc, 
+                           bvExtract(expr, width - shift - 1, 0),
+                           bvZero(shift));
+  }
+}
+
+// left shift by a variable amount on an expression of the specified width
+ExprHandle STPBuilder::bvVarLeftShift(ExprHandle expr, ExprHandle amount, unsigned width) {
+  ExprHandle res = bvZero(width);
+
+  int shiftBits = getShiftBits( width );
+
+  //get the shift amount (looking only at the bits appropriate for the given width)
+  ExprHandle shift = vc_bvExtract( vc, amount, shiftBits - 1, 0 ); 
+
+  //construct a big if-then-elif-elif-... with one case per possible shift amount
+  for( int i=width-1; i>=0; i-- ) {
+    res = vc_iteExpr(vc,
+                     eqExpr(shift, bvConst32(shiftBits, i)),
+                     bvLeftShift(expr, i, shiftBits),
+                     res);
+  }
+  return res;
+}
+
+// logical right shift by a variable amount on an expression of the specified width
+ExprHandle STPBuilder::bvVarRightShift(ExprHandle expr, ExprHandle amount, unsigned width) {
+  ExprHandle res = bvZero(width);
+
+  int shiftBits = getShiftBits( width );
+
+  //get the shift amount (looking only at the bits appropriate for the given width)
+  ExprHandle shift = vc_bvExtract( vc, amount, shiftBits - 1, 0 ); 
+
+  //construct a big if-then-elif-elif-... with one case per possible shift amount
+  for( int i=width-1; i>=0; i-- ) {
+    res = vc_iteExpr(vc,
+                     eqExpr(shift, bvConst32(shiftBits, i)),
+                     bvRightShift(expr, i, shiftBits),
+                     res);
+  }
+
+  return res;
+}
+
+// arithmetic right shift by a variable amount on an expression of the specified width
+ExprHandle STPBuilder::bvVarArithRightShift(ExprHandle expr, ExprHandle amount, unsigned width) {
+  int shiftBits = getShiftBits( width );
+
+  //get the shift amount (looking only at the bits appropriate for the given width)
+  ExprHandle shift = vc_bvExtract( vc, amount, shiftBits - 1, 0 );
+
+  //get the sign bit to fill with
+  ExprHandle signedBool = bvBoolExtract(expr, width-1);
+
+  //start with the result if shifting by width-1
+  ExprHandle res = constructAShrByConstant(expr, width-1, signedBool, shiftBits);
+
+  //construct a big if-then-elif-elif-... with one case per possible shift amount
+  // XXX more efficient to move the ite on the sign outside all exprs?
+  // XXX more efficient to sign extend, right shift, then extract lower bits?
+  for( int i=width-2; i>=0; i-- ) {
+    res = vc_iteExpr(vc,
+                     eqExpr(shift, bvConst32(shiftBits,i)),
+                     constructAShrByConstant(expr, 
+                                             i, 
+                                             signedBool, 
+                                             shiftBits),
+                     res);
+  }
+
+  return res;
+}
+
+ExprHandle STPBuilder::constructAShrByConstant(ExprHandle expr,
+                                               unsigned amount,
+                                               ExprHandle isSigned, 
+                                               unsigned shiftBits) {
+  unsigned width = vc_getBVLength(vc, expr);
+  unsigned shift = amount & ((1<<shiftBits) - 1);
+
+  if (shift==0) {
+    return expr;
+  } else if (shift>=width-1) {
+    return vc_iteExpr(vc, isSigned, bvMinusOne(width), bvZero(width));
+  } else {
+    return vc_iteExpr(vc,
+                      isSigned,
+                      ExprHandle(vc_bvConcatExpr(vc,
+                                                 bvMinusOne(shift),
+                                                 bvExtract(expr, width - 1, shift))),
+                      bvRightShift(expr, shift, shiftBits));
+  }
+}
+
+ExprHandle STPBuilder::constructMulByConstant(ExprHandle expr, unsigned width, uint64_t x) {
+  unsigned shiftBits = getShiftBits(width);
+  uint64_t add, sub;
+  ExprHandle res = 0;
+
+  // expr*x == expr*(add-sub) == expr*add - expr*sub
+  ComputeMultConstants64(x, add, sub);
+
+  // legal, these would overflow completely
+  add = bits64::truncateToNBits(add, width);
+  sub = bits64::truncateToNBits(sub, width);
+
+  for (int j=63; j>=0; j--) {
+    uint64_t bit = 1LL << j;
+
+    if ((add&bit) || (sub&bit)) {
+      assert(!((add&bit) && (sub&bit)) && "invalid mult constants");
+      ExprHandle op = bvLeftShift(expr, j, shiftBits);
+      
+      if (add&bit) {
+        if (res) {
+          res = vc_bvPlusExpr(vc, width, res, op);
+        } else {
+          res = op;
+        }
+      } else {
+        if (res) {
+          res = vc_bvMinusExpr(vc, width, res, op);
+        } else {
+          res = vc_bvUMinusExpr(vc, op);
+        }
+      }
+    }
+  }
+
+  if (!res) 
+    res = bvZero(width);
+
+  return res;
+}
+
+/* 
+ * Compute the 32-bit unsigned integer division of n by a divisor d based on 
+ * the constants derived from the constant divisor d.
+ *
+ * Returns n/d without doing explicit division.  The cost is 2 adds, 3 shifts, 
+ * and a (64-bit) multiply.
+ *
+ * @param n      numerator (dividend) as an expression
+ * @param width  number of bits used to represent the value
+ * @param d      the divisor
+ *
+ * @return n/d without doing explicit division
+ */
+ExprHandle STPBuilder::constructUDivByConstant(ExprHandle expr_n, unsigned width, uint64_t d) {
+  assert(width==32 && "can only compute udiv constants for 32-bit division");
+
+  // Compute the constants needed to compute n/d for constant d w/o
+  // division by d.
+  uint32_t mprime, sh1, sh2;
+  ComputeUDivConstants32(d, mprime, sh1, sh2);
+  ExprHandle expr_sh1    = bvConst32( 32, sh1);
+  ExprHandle expr_sh2    = bvConst32( 32, sh2);
+
+  // t1  = MULUH(mprime, n) = ( (uint64_t)mprime * (uint64_t)n ) >> 32
+  ExprHandle expr_n_64   = vc_bvConcatExpr( vc, bvZero(32), expr_n ); //extend to 64 bits
+  ExprHandle t1_64bits   = constructMulByConstant( expr_n_64, 64, (uint64_t)mprime );
+  ExprHandle t1          = vc_bvExtract( vc, t1_64bits, 63, 32 ); //upper 32 bits
+
+  // n/d = (((n - t1) >> sh1) + t1) >> sh2;
+  ExprHandle n_minus_t1  = vc_bvMinusExpr( vc, width, expr_n, t1 );
+  ExprHandle shift_sh1   = bvVarRightShift( n_minus_t1, expr_sh1, 32 );
+  ExprHandle plus_t1     = vc_bvPlusExpr( vc, width, shift_sh1, t1 );
+  ExprHandle res         = bvVarRightShift( plus_t1, expr_sh2, 32 );
+
+  return res;
+}
+
+/* 
+ * Compute the 32-bitnsigned integer division of n by a divisor d based on 
+ * the constants derived from the constant divisor d.
+ *
+ * Returns n/d without doing explicit division.  The cost is 3 adds, 3 shifts, 
+ * a (64-bit) multiply, and an XOR.
+ *
+ * @param n      numerator (dividend) as an expression
+ * @param width  number of bits used to represent the value
+ * @param d      the divisor
+ *
+ * @return n/d without doing explicit division
+ */
+ExprHandle STPBuilder::constructSDivByConstant(ExprHandle expr_n, unsigned width, uint64_t d) {
+  assert(width==32 && "can only compute udiv constants for 32-bit division");
+
+  // Compute the constants needed to compute n/d for constant d w/o division by d.
+  int32_t mprime, dsign, shpost;
+  ComputeSDivConstants32(d, mprime, dsign, shpost);
+  ExprHandle expr_dsign   = bvConst32( 32, dsign);
+  ExprHandle expr_shpost  = bvConst32( 32, shpost);
+
+  // q0 = n + MULSH( mprime, n ) = n + (( (int64_t)mprime * (int64_t)n ) >> 32)
+  int64_t mprime_64     = (int64_t)mprime;
+
+  ExprHandle expr_n_64    = vc_bvSignExtend( vc, expr_n, 64 );
+  ExprHandle mult_64      = constructMulByConstant( expr_n_64, 64, mprime_64 );
+  ExprHandle mulsh        = vc_bvExtract( vc, mult_64, 63, 32 ); //upper 32-bits
+  ExprHandle n_plus_mulsh = vc_bvPlusExpr( vc, width, expr_n, mulsh );
+
+  // Improved variable arithmetic right shift: sign extend, shift,
+  // extract.
+  ExprHandle extend_npm   = vc_bvSignExtend( vc, n_plus_mulsh, 64 );
+  ExprHandle shift_npm    = bvVarRightShift( extend_npm, expr_shpost, 64 );
+  ExprHandle shift_shpost = vc_bvExtract( vc, shift_npm, 31, 0 ); //lower 32-bits
+
+  // XSIGN(n) is -1 if n is negative, positive one otherwise
+  ExprHandle is_signed    = bvBoolExtract( expr_n, 31 );
+  ExprHandle neg_one      = bvMinusOne(32);
+  ExprHandle xsign_of_n   = vc_iteExpr( vc, is_signed, neg_one, bvZero(32) );
+
+  // q0 = (n_plus_mulsh >> shpost) - XSIGN(n)
+  ExprHandle q0           = vc_bvMinusExpr( vc, width, shift_shpost, xsign_of_n );
+  
+  // n/d = (q0 ^ dsign) - dsign
+  ExprHandle q0_xor_dsign = vc_bvXorExpr( vc, q0, expr_dsign );
+  ExprHandle res          = vc_bvMinusExpr( vc, width, q0_xor_dsign, expr_dsign );
+
+  return res;
+}
+
+::VCExpr STPBuilder::getInitialArray(const Array *root) {
+  if (root->stpInitialArray) {
+    return root->stpInitialArray;
+  } else {
+    char buf[32];
+    sprintf(buf, "arr%d", root->id);
+    root->stpInitialArray = buildArray(buf, 32, 8);
+    return root->stpInitialArray;
+  }
+}
+
+ExprHandle STPBuilder::getInitialRead(const Array *root, unsigned index) {
+  return vc_readExpr(vc, getInitialArray(root), bvConst32(32, index));
+}
+
+::VCExpr STPBuilder::getArrayForUpdate(const Array *root, 
+                                       const UpdateNode *un) {
+  if (!un) {
+    return getInitialArray(root);
+  } else {
+    // FIXME: This really needs to be non-recursive.
+    if (!un->stpArray)
+      un->stpArray = vc_writeExpr(vc,
+                                  getArrayForUpdate(root, un->next),
+                                  construct(un->index, 0),
+                                  construct(un->value, 0));
+
+    return un->stpArray;
+  }
+}
+
+/** if *width_out!=1 then result is a bitvector,
+    otherwise it is a bool */
+ExprHandle STPBuilder::construct(ref<Expr> e, int *width_out) {
+  if (!UseConstructHash || e.isConstant()) {
+    return constructActual(e, width_out);
+  } else {
+    ExprHashMap< std::pair<ExprHandle, unsigned> >::iterator it = 
+      constructed.find(e);
+    if (it!=constructed.end()) {
+      if (width_out)
+        *width_out = it->second.second;
+      return it->second.first;
+    } else {
+      int width;
+      if (!width_out) width_out = &width;
+      ExprHandle res = constructActual(e, width_out);
+      constructed.insert(std::make_pair(e, std::make_pair(res, *width_out)));
+      return res;
+    }
+  }
+}
+
+
+/** if *width_out!=1 then result is a bitvector,
+    otherwise it is a bool */
+ExprHandle STPBuilder::constructActual(ref<Expr> e, int *width_out) {
+  int width;
+  if (!width_out) width_out = &width;
+
+  ++stats::queryConstructs;
+
+  switch(e.getKind()) {
+
+  case Expr::Constant: {
+    uint64_t asUInt64 = e.getConstantValue();
+    *width_out = e.getWidth();
+
+    if (*width_out > 64)
+      assert(0 && "constructActual: width > 64");
+
+    if (*width_out == 1)
+      return asUInt64 ? getTrue() : getFalse();
+    else if (*width_out <= 32) 
+      return bvConst32(*width_out, asUInt64);
+    else return bvConst64(*width_out, asUInt64);
+  }
+    
+  // Special
+  case Expr::NotOptimized: {
+    NotOptimizedExpr *noe = static_ref_cast<NotOptimizedExpr>(e);
+    return construct(noe->src, width_out);
+  }
+
+  case Expr::Read: {
+    ReadExpr *re = static_ref_cast<ReadExpr>(e);
+    *width_out = 8;
+    return vc_readExpr(vc,
+                       getArrayForUpdate(re->updates.root, re->updates.head),
+                       construct(re->index, 0));
+  }
+    
+  case Expr::Select: {
+    SelectExpr *se = static_ref_cast<SelectExpr>(e);
+    ExprHandle cond = construct(se->cond, 0);
+    ExprHandle tExpr = construct(se->trueExpr, width_out);
+    ExprHandle fExpr = construct(se->falseExpr, width_out);
+    return vc_iteExpr(vc, cond, tExpr, fExpr);
+  }
+
+  case Expr::Concat: {
+    ConcatExpr *ce = static_ref_cast<ConcatExpr>(e);
+    unsigned numKids = ce->getNumKids();
+    ExprHandle res = construct(ce->getKid(numKids-1), 0);
+    for (int i=numKids-2; i>=0; i--) {
+      res = vc_bvConcatExpr(vc, construct(ce->getKid(i), 0), res);
+    }
+    *width_out = ce->getWidth();
+    return res;
+  }
+
+  case Expr::Extract: {
+    ExtractExpr *ee = static_ref_cast<ExtractExpr>(e);
+    ExprHandle src = construct(ee->expr, width_out);    
+    *width_out = ee->getWidth();
+    if (*width_out==1) {
+      return bvBoolExtract(src, 0);
+    } else {
+      return vc_bvExtract(vc, src, ee->offset + *width_out - 1, ee->offset);
+    }
+  }
+
+    // Casting
+
+  case Expr::ZExt: {
+    int srcWidth;
+    CastExpr *ce = static_ref_cast<CastExpr>(e);
+    ExprHandle src = construct(ce->src, &srcWidth);
+    *width_out = ce->getWidth();
+    if (srcWidth==1) {
+      return vc_iteExpr(vc, src, bvOne(*width_out), bvZero(*width_out));
+    } else {
+      return vc_bvConcatExpr(vc, bvZero(*width_out-srcWidth), src);
+    }
+  }
+
+  case Expr::SExt: {
+    int srcWidth;
+    CastExpr *ce = static_ref_cast<CastExpr>(e);
+    ExprHandle src = construct(ce->src, &srcWidth);
+    *width_out = ce->getWidth();
+    if (srcWidth==1) {
+      return vc_iteExpr(vc, src, bvMinusOne(*width_out), bvZero(*width_out));
+    } else {
+      return vc_bvSignExtend(vc, src, *width_out);
+    }
+  }
+
+    // Arithmetic
+
+  case Expr::Add: {
+    AddExpr *ae = static_ref_cast<AddExpr>(e);
+    ExprHandle left = construct(ae->left, width_out);
+    ExprHandle right = construct(ae->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized add");
+    return vc_bvPlusExpr(vc, *width_out, left, right);
+  }
+
+  case Expr::Sub: {
+    SubExpr *se = static_ref_cast<SubExpr>(e);
+    ExprHandle left = construct(se->left, width_out);
+    ExprHandle right = construct(se->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized sub");
+    return vc_bvMinusExpr(vc, *width_out, left, right);
+  } 
+
+  case Expr::Mul: {
+    MulExpr *me = static_ref_cast<MulExpr>(e);
+    ExprHandle right = construct(me->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized mul");
+
+    if (me->left.isConstant()) {
+      return constructMulByConstant(right, *width_out, me->left.getConstantValue());
+    } else {
+      ExprHandle left = construct(me->left, width_out);
+      return vc_bvMultExpr(vc, *width_out, left, right);
+    }
+  }
+
+  case Expr::UDiv: {
+    UDivExpr *de = static_ref_cast<UDivExpr>(e);
+    ExprHandle left = construct(de->left, width_out);
+    assert(*width_out!=1 && "uncanonicalized udiv");
+    
+    if (de->right.isConstant()) {
+      uint64_t divisor = de->right.getConstantValue();
+      
+      if (bits64::isPowerOfTwo(divisor)) {
+        return bvRightShift(left,
+                            bits64::indexOfSingleBit(divisor),
+                            getShiftBits(*width_out));
+      } else if (optimizeDivides) {
+        if (*width_out == 32) //only works for 32-bit division
+          return constructUDivByConstant( left, *width_out, (uint32_t)divisor );
+      }
+    } 
+
+    ExprHandle right = construct(de->right, width_out);
+    return vc_bvDivExpr(vc, *width_out, left, right);
+  }
+
+  case Expr::SDiv: {
+    SDivExpr *de = static_ref_cast<SDivExpr>(e);
+    ExprHandle left = construct(de->left, width_out);
+    assert(*width_out!=1 && "uncanonicalized sdiv");
+
+    if (de->right.isConstant()) {
+      uint64_t divisor = de->right.getConstantValue();
+ 
+      if (optimizeDivides) {
+	if (*width_out == 32) //only works for 32-bit division
+	  return constructSDivByConstant( left, *width_out, divisor);
+      }
+    } 
+
+    // XXX need to test for proper handling of sign, not sure I
+    // trust STP
+    ExprHandle right = construct(de->right, width_out);
+    return vc_sbvDivExpr(vc, *width_out, left, right);
+  }
+
+  case Expr::URem: {
+    URemExpr *de = static_ref_cast<URemExpr>(e);
+    ExprHandle left = construct(de->left, width_out);
+    assert(*width_out!=1 && "uncanonicalized urem");
+    
+    if (de->right.isConstant()) {
+      uint64_t divisor = de->right.getConstantValue();
+
+      if (bits64::isPowerOfTwo(divisor)) {
+        unsigned bits = bits64::indexOfSingleBit(divisor);
+
+        // special case for modding by 1 or else we bvExtract -1:0
+        if (bits == 0) {
+          return bvZero(*width_out);
+        } else {
+          return vc_bvConcatExpr(vc,
+                                 bvZero(*width_out - bits),
+                                 bvExtract(left, bits - 1, 0));
+        }
+      }
+
+      //use fast division to compute modulo without explicit division for constant divisor
+      if (optimizeDivides) {
+	if (*width_out == 32) { //only works for 32-bit division
+	  ExprHandle quotient = constructUDivByConstant( left, *width_out, (uint32_t)divisor );
+	  ExprHandle quot_times_divisor = constructMulByConstant( quotient, *width_out, divisor );
+          ExprHandle rem = vc_bvMinusExpr( vc, *width_out, left, quot_times_divisor );
+	  return rem;
+	}
+      }
+    }
+    
+    ExprHandle right = construct(de->right, width_out);
+    return vc_bvModExpr(vc, *width_out, left, right);
+  }
+
+  case Expr::SRem: {
+    SRemExpr *de = static_ref_cast<SRemExpr>(e);
+    ExprHandle left = construct(de->left, width_out);
+    ExprHandle right = construct(de->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized srem");
+
+#if 0 //not faster per first benchmark
+    if (optimizeDivides) {
+      if (ConstantExpr *cre = de->right->asConstant()) {
+	uint64_t divisor = cre->asUInt64;
+
+	//use fast division to compute modulo without explicit division for constant divisor
+      	if( *width_out == 32 ) { //only works for 32-bit division
+	  ExprHandle quotient = constructSDivByConstant( left, *width_out, divisor );
+	  ExprHandle quot_times_divisor = constructMulByConstant( quotient, *width_out, divisor );
+	  ExprHandle rem = vc_bvMinusExpr( vc, *width_out, left, quot_times_divisor );
+	  return rem;
+	}
+      }
+    }
+#endif
+
+    // XXX implement my fast path and test for proper handling of sign
+    return vc_sbvModExpr(vc, *width_out, left, right);
+  }
+
+    // Binary
+
+  case Expr::And: {
+    AndExpr *ae = static_ref_cast<AndExpr>(e);
+    ExprHandle left = construct(ae->left, width_out);
+    ExprHandle right = construct(ae->right, width_out);
+    if (*width_out==1) {
+      return vc_andExpr(vc, left, right);
+    } else {
+      return vc_bvAndExpr(vc, left, right);
+    }
+  }
+  case Expr::Or: {
+    OrExpr *oe = static_ref_cast<OrExpr>(e);
+    ExprHandle left = construct(oe->left, width_out);
+    ExprHandle right = construct(oe->right, width_out);
+    if (*width_out==1) {
+      return vc_orExpr(vc, left, right);
+    } else {
+      return vc_bvOrExpr(vc, left, right);
+    }
+  }
+
+  case Expr::Xor: {
+    XorExpr *xe = static_ref_cast<XorExpr>(e);
+    ExprHandle left = construct(xe->left, width_out);
+    ExprHandle right = construct(xe->right, width_out);
+    
+    if (*width_out==1) {
+      // XXX check for most efficient?
+      return vc_iteExpr(vc, left, 
+                        ExprHandle(vc_notExpr(vc, right)), right);
+    } else {
+      return vc_bvXorExpr(vc, left, right);
+    }
+  }
+
+  case Expr::Shl: {
+    ShlExpr *se = static_ref_cast<ShlExpr>(e);
+    ExprHandle left = construct(se->left, width_out);
+    assert(*width_out!=1 && "uncanonicalized shl");
+
+    if (se->right.isConstant()) {
+      return bvLeftShift(left, se->right.getConstantValue(), getShiftBits(*width_out));
+    } else {
+      int shiftWidth;
+      ExprHandle amount = construct(se->right, &shiftWidth);
+      return bvVarLeftShift( left, amount, *width_out );
+    }
+  }
+
+  case Expr::LShr: {
+    LShrExpr *lse = static_ref_cast<LShrExpr>(e);
+    ExprHandle left = construct(lse->left, width_out);
+    unsigned shiftBits = getShiftBits(*width_out);
+    assert(*width_out!=1 && "uncanonicalized lshr");
+
+    if (lse->right.isConstant()) {
+      return bvRightShift(left, (unsigned) lse->right.getConstantValue(), shiftBits);
+    } else {
+      int shiftWidth;
+      ExprHandle amount = construct(lse->right, &shiftWidth);
+      return bvVarRightShift( left, amount, *width_out );
+    }
+  }
+
+  case Expr::AShr: {
+    AShrExpr *ase = static_ref_cast<AShrExpr>(e);
+    ExprHandle left = construct(ase->left, width_out);
+    assert(*width_out!=1 && "uncanonicalized ashr");
+    
+    if (ase->right.isConstant()) {
+      unsigned shift = (unsigned) ase->right.getConstantValue();
+      ExprHandle signedBool = bvBoolExtract(left, *width_out-1);
+      return constructAShrByConstant(left, shift, signedBool, getShiftBits(*width_out));
+    } else {
+      int shiftWidth;
+      ExprHandle amount = construct(ase->right, &shiftWidth);
+      return bvVarArithRightShift( left, amount, *width_out );
+    }
+  }
+
+    // Comparison
+
+  case Expr::Eq: {
+    EqExpr *ee = static_ref_cast<EqExpr>(e);
+    ExprHandle left = construct(ee->left, width_out);
+    ExprHandle right = construct(ee->right, width_out);
+    if (*width_out==1) {
+      if (ee->left.isConstant()) {
+        assert(!ee->left.getConstantValue() && "uncanonicalized eq");
+        return vc_notExpr(vc, right);
+      } else {
+        return vc_iffExpr(vc, left, right);
+      }
+    } else {
+      *width_out = 1;
+      return vc_eqExpr(vc, left, right);
+    }
+  }
+
+  case Expr::Ult: {
+    UltExpr *ue = static_ref_cast<UltExpr>(e);
+    ExprHandle left = construct(ue->left, width_out);
+    ExprHandle right = construct(ue->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized ult");
+    *width_out = 1;
+    return vc_bvLtExpr(vc, left, right);
+  }
+
+  case Expr::Ule: {
+    UleExpr *ue = static_ref_cast<UleExpr>(e);
+    ExprHandle left = construct(ue->left, width_out);
+    ExprHandle right = construct(ue->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized ule");
+    *width_out = 1;
+    return vc_bvLeExpr(vc, left, right);
+  }
+
+  case Expr::Slt: {
+    SltExpr *se = static_ref_cast<SltExpr>(e);
+    ExprHandle left = construct(se->left, width_out);
+    ExprHandle right = construct(se->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized slt");
+    *width_out = 1;
+    return vc_sbvLtExpr(vc, left, right);
+  }
+
+  case Expr::Sle: {
+    SleExpr *se = static_ref_cast<SleExpr>(e);
+    ExprHandle left = construct(se->left, width_out);
+    ExprHandle right = construct(se->right, width_out);
+    assert(*width_out!=1 && "uncanonicalized sle");
+    *width_out = 1;
+    return vc_sbvLeExpr(vc, left, right);
+  }
+
+    // unused due to canonicalization
+#if 0
+  case Expr::Ne:
+  case Expr::Ugt:
+  case Expr::Uge:
+  case Expr::Sgt:
+  case Expr::Sge:
+#endif
+
+  default: 
+    assert(0 && "unhandled Expr type");
+    return vc_trueExpr(vc);
+  }
+}
diff --git a/lib/Solver/STPBuilder.h b/lib/Solver/STPBuilder.h
new file mode 100644
index 00000000..6382bc1f
--- /dev/null
+++ b/lib/Solver/STPBuilder.h
@@ -0,0 +1,125 @@
+//===-- STPBuilder.h --------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UTIL_STPBUILDER_H__
+#define __UTIL_STPBUILDER_H__
+
+#include "klee/util/ExprHashMap.h"
+#include "klee/Config/config.h"
+
+#include <vector>
+#include <map>
+
+#define Expr VCExpr
+#include "stp/c_interface.h"
+
+#if ENABLE_STPLOG == 1
+#include "stp/stplog.h"
+#endif
+#undef Expr
+
+namespace klee {
+  class ExprHolder {
+    friend class ExprHandle;
+    ::VCExpr expr;
+    unsigned count;
+    
+  public:
+    ExprHolder(const ::VCExpr _expr) : expr(_expr), count(0) {}
+    ~ExprHolder() { 
+      if (expr) vc_DeleteExpr(expr); 
+    }
+  };
+
+  class ExprHandle {
+    ExprHolder *H;
+    
+  public:
+    ExprHandle() : H(new ExprHolder(0)) { H->count++; }
+    ExprHandle(::VCExpr _expr) : H(new ExprHolder(_expr)) { H->count++; }
+    ExprHandle(const ExprHandle &b) : H(b.H) { H->count++; }
+    ~ExprHandle() { if (--H->count == 0) delete H; }
+    
+    ExprHandle &operator=(const ExprHandle &b) {
+      if (--H->count == 0) delete H;
+      H = b.H;
+      H->count++;
+      return *this;
+    }
+
+    operator bool () { return H->expr; }
+    operator ::VCExpr () { return H->expr; }
+  };
+
+class STPBuilder {
+  ::VC vc;
+  ExprHandle tempVars[4];
+  ExprHashMap< std::pair<ExprHandle, unsigned> > constructed;
+
+  /// optimizeDivides - Rewrite division and reminders by constants
+  /// into multiplies and shifts. STP should probably handle this for
+  /// use.
+  bool optimizeDivides;
+
+private:
+  unsigned getShiftBits(unsigned amount) {
+    return (amount == 64) ? 6 : 5;
+  }
+
+  ExprHandle bvOne(unsigned width);
+  ExprHandle bvZero(unsigned width);
+  ExprHandle bvMinusOne(unsigned width);
+  ExprHandle bvConst32(unsigned width, uint32_t value);
+  ExprHandle bvConst64(unsigned width, uint64_t value);
+
+  ExprHandle bvBoolExtract(ExprHandle expr, int bit);
+  ExprHandle bvExtract(ExprHandle expr, unsigned top, unsigned bottom);
+  ExprHandle eqExpr(ExprHandle a, ExprHandle b);
+
+  //logical left and right shift (not arithmetic)
+  ExprHandle bvLeftShift(ExprHandle expr, unsigned shift, unsigned shiftBits);
+  ExprHandle bvRightShift(ExprHandle expr, unsigned amount, unsigned shiftBits);
+  ExprHandle bvVarLeftShift(ExprHandle expr, ExprHandle amount, unsigned width);
+  ExprHandle bvVarRightShift(ExprHandle expr, ExprHandle amount, unsigned width);
+  ExprHandle bvVarArithRightShift(ExprHandle expr, ExprHandle amount, unsigned width);
+
+  ExprHandle constructAShrByConstant(ExprHandle expr, unsigned shift, 
+                                     ExprHandle isSigned, unsigned shiftBits);
+  ExprHandle constructMulByConstant(ExprHandle expr, unsigned width, uint64_t x);
+  ExprHandle constructUDivByConstant(ExprHandle expr_n, unsigned width, uint64_t d);
+  ExprHandle constructSDivByConstant(ExprHandle expr_n, unsigned width, uint64_t d);
+
+  ::VCExpr getInitialArray(const Array *os);
+  ::VCExpr getArrayForUpdate(const Array *root, const UpdateNode *un);
+
+  ExprHandle constructActual(ref<Expr> e, int *width_out);
+  ExprHandle construct(ref<Expr> e, int *width_out);
+  
+  ::VCExpr buildVar(const char *name, unsigned width);
+  ::VCExpr buildArray(const char *name, unsigned indexWidth, unsigned valueWidth);
+
+public:
+  STPBuilder(::VC _vc, bool _optimizeDivides=true);
+  ~STPBuilder();
+
+  ExprHandle getTrue();
+  ExprHandle getFalse();
+  ExprHandle getTempVar(Expr::Width w);
+  ExprHandle getInitialRead(const Array *os, unsigned index);
+
+  ExprHandle construct(ref<Expr> e) { 
+    ExprHandle res = construct(e, 0);
+    constructed.clear();
+    return res;
+  }
+};
+
+}
+
+#endif
diff --git a/lib/Solver/Solver.cpp b/lib/Solver/Solver.cpp
new file mode 100644
index 00000000..24d3ef86
--- /dev/null
+++ b/lib/Solver/Solver.cpp
@@ -0,0 +1,643 @@
+//===-- Solver.cpp --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Solver.h"
+#include "klee/SolverImpl.h"
+
+#include "SolverStats.h"
+#include "STPBuilder.h"
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/TimerStatIncrementer.h"
+#include "klee/util/Assignment.h"
+#include "klee/util/ExprPPrinter.h"
+#include "klee/util/ExprUtil.h"
+#include "klee/Internal/Support/Timer.h"
+
+#define vc_bvBoolExtract IAMTHESPAWNOFSATAN
+
+#include <cassert>
+#include <map>
+#include <vector>
+
+#include <sys/wait.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+using namespace klee;
+
+/***/
+
+const char *Solver::validity_to_str(Validity v) {
+  switch (v) {
+  default:    return "Unknown";
+  case True:  return "True";
+  case False: return "False";
+  }
+}
+
+Solver::~Solver() { 
+  delete impl; 
+}
+
+SolverImpl::~SolverImpl() {
+}
+
+bool Solver::evaluate(const Query& query, Validity &result) {
+  assert(query.expr.getWidth() == Expr::Bool && "Invalid expression type!");
+
+  // Maintain invariants implementation expect.
+  if (query.expr.isConstant()) {
+    result = query.expr.getConstantValue() ? True : False;
+    return true;
+  }
+
+  return impl->computeValidity(query, result);
+}
+
+bool SolverImpl::computeValidity(const Query& query, Solver::Validity &result) {
+  bool isTrue, isFalse;
+  if (!computeTruth(query, isTrue))
+    return false;
+  if (isTrue) {
+    result = Solver::True;
+  } else {
+    if (!computeTruth(query.negateExpr(), isFalse))
+      return false;
+    result = isFalse ? Solver::False : Solver::Unknown;
+  }
+  return true;
+}
+
+bool Solver::mustBeTrue(const Query& query, bool &result) {
+  assert(query.expr.getWidth() == Expr::Bool && "Invalid expression type!");
+
+  // Maintain invariants implementation expect.
+  if (query.expr.isConstant()) {
+    result = query.expr.getConstantValue() ? true : false;
+    return true;
+  }
+
+  return impl->computeTruth(query, result);
+}
+
+bool Solver::mustBeFalse(const Query& query, bool &result) {
+  return mustBeTrue(query.negateExpr(), result);
+}
+
+bool Solver::mayBeTrue(const Query& query, bool &result) {
+  bool res;
+  if (!mustBeFalse(query, res))
+    return false;
+  result = !res;
+  return true;
+}
+
+bool Solver::mayBeFalse(const Query& query, bool &result) {
+  bool res;
+  if (!mustBeTrue(query, res))
+    return false;
+  result = !res;
+  return true;
+}
+
+bool Solver::getValue(const Query& query, ref<Expr> &result) {
+  // Maintain invariants implementation expect.
+  if (query.expr.isConstant()) {
+    result = query.expr;
+    return true;
+  }
+
+  return impl->computeValue(query, result);
+}
+
+bool 
+Solver::getInitialValues(const Query& query,
+                         const std::vector<const Array*> &objects,
+                         std::vector< std::vector<unsigned char> > &values) {
+  bool hasSolution;
+  bool success =
+    impl->computeInitialValues(query, objects, values, hasSolution);
+  // FIXME: Propogate this out.
+  if (!hasSolution)
+    return false;
+    
+  return success;
+}
+
+std::pair< ref<Expr>, ref<Expr> > Solver::getRange(const Query& query) {
+  ref<Expr> e = query.expr;
+  Expr::Width width = e.getWidth();
+  uint64_t min, max;
+
+  if (width==1) {
+    Solver::Validity result;
+    if (!evaluate(query, result))
+      assert(0 && "computeValidity failed");
+    switch (result) {
+    case Solver::True: 
+      min = max = 1; break;
+    case Solver::False: 
+      min = max = 0; break;
+    default:
+      min = 0, max = 1; break;
+    }
+  } else if (e.isConstant()) {
+    min = max = e.getConstantValue();
+  } else {
+    // binary search for # of useful bits
+    uint64_t lo=0, hi=width, mid, bits=0;
+    while (lo<hi) {
+      mid = (lo+hi)/2;
+      bool res;
+      bool success = 
+        mustBeTrue(query.withExpr(
+                     EqExpr::create(LShrExpr::create(e,
+                                                     ConstantExpr::create(mid, 
+                                                                          width)),
+                                    ConstantExpr::create(0, width))),
+                   res);
+      assert(success && "FIXME: Unhandled solver failure");
+      if (res) {
+        hi = mid;
+      } else {
+        lo = mid+1;
+      }
+
+      bits = lo;
+    }
+    
+    // could binary search for training zeros and offset
+    // min max but unlikely to be very useful
+
+    // check common case
+    bool res = false;
+    bool success = 
+      mayBeTrue(query.withExpr(EqExpr::create(e, ConstantExpr::create(0, 
+                                                                      width))), 
+                res);
+    assert(success && "FIXME: Unhandled solver failure");      
+    if (res) {
+      min = 0;
+    } else {
+      // binary search for min
+      lo=0, hi=bits64::maxValueOfNBits(bits);
+      while (lo<hi) {
+        mid = (lo+hi)/2;
+        bool res = false;
+        bool success = 
+          mayBeTrue(query.withExpr(UleExpr::create(e, 
+                                                   ConstantExpr::create(mid, 
+                                                                        width))),
+                    res);
+        assert(success && "FIXME: Unhandled solver failure");      
+        if (res) {
+          hi = mid;
+        } else {
+          lo = mid+1;
+        }
+      }
+
+      min = lo;
+    }
+
+    // binary search for max
+    lo=min, hi=bits64::maxValueOfNBits(bits);
+    while (lo<hi) {
+      mid = (lo+hi)/2;
+      bool res;
+      bool success = 
+        mustBeTrue(query.withExpr(UleExpr::create(e, 
+                                                  ConstantExpr::create(mid, 
+                                                                       width))),
+                   res);
+      assert(success && "FIXME: Unhandled solver failure");      
+      if (res) {
+        hi = mid;
+      } else {
+        lo = mid+1;
+      }
+    }
+
+    max = lo;
+  }
+
+  return std::make_pair(ConstantExpr::create(min, width),
+                        ConstantExpr::create(max, width));
+}
+
+/***/
+
+class ValidatingSolver : public SolverImpl {
+private:
+  Solver *solver, *oracle;
+
+public: 
+  ValidatingSolver(Solver *_solver, Solver *_oracle) 
+    : solver(_solver), oracle(_oracle) {}
+  ~ValidatingSolver() { delete solver; }
+  
+  bool computeValidity(const Query&, Solver::Validity &result);
+  bool computeTruth(const Query&, bool &isValid);
+  bool computeValue(const Query&, ref<Expr> &result);
+  bool computeInitialValues(const Query&,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution);
+};
+
+bool ValidatingSolver::computeTruth(const Query& query,
+                                    bool &isValid) {
+  bool answer;
+  
+  if (!solver->impl->computeTruth(query, isValid))
+    return false;
+  if (!oracle->impl->computeTruth(query, answer))
+    return false;
+  
+  if (isValid != answer)
+    assert(0 && "invalid solver result (computeTruth)");
+  
+  return true;
+}
+
+bool ValidatingSolver::computeValidity(const Query& query,
+                                       Solver::Validity &result) {
+  Solver::Validity answer;
+  
+  if (!solver->impl->computeValidity(query, result))
+    return false;
+  if (!oracle->impl->computeValidity(query, answer))
+    return false;
+  
+  if (result != answer)
+    assert(0 && "invalid solver result (computeValidity)");
+  
+  return true;
+}
+
+bool ValidatingSolver::computeValue(const Query& query,
+                                    ref<Expr> &result) {  
+  bool answer;
+
+  if (!solver->impl->computeValue(query, result))
+    return false;
+  // We don't want to compare, but just make sure this is a legal
+  // solution.
+  if (!oracle->impl->computeTruth(query.withExpr(NeExpr::create(query.expr, 
+                                                                result)),
+                                  answer))
+    return false;
+
+  if (answer)
+    assert(0 && "invalid solver result (computeValue)");
+
+  return true;
+}
+
+bool 
+ValidatingSolver::computeInitialValues(const Query& query,
+                                       const std::vector<const Array*>
+                                         &objects,
+                                       std::vector< std::vector<unsigned char> >
+                                         &values,
+                                       bool &hasSolution) {
+  bool answer;
+
+  if (!solver->impl->computeInitialValues(query, objects, values, 
+                                          hasSolution))
+    return false;
+
+  if (hasSolution) {
+    // Assert the bindings as constraints, and verify that the
+    // conjunction of the actual constraints is satisfiable.
+    std::vector< ref<Expr> > bindings;
+    for (unsigned i = 0; i != values.size(); ++i) {
+      const Array *array = objects[i];
+      for (unsigned j=0; j<array->size; j++) {
+        unsigned char value = values[i][j];
+        bindings.push_back(EqExpr::create(ReadExpr::create(UpdateList(array,
+                                                                      true, 0),
+                                                           ref<Expr>(j, Expr::Int32)),
+                                          ref<Expr>(value, Expr::Int8)));
+      }
+    }
+    ConstraintManager tmp(bindings);
+    ref<Expr> constraints = Expr::createNot(query.expr);
+    for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+           ie = query.constraints.end(); it != ie; ++it)
+      constraints = AndExpr::create(constraints, *it);
+    
+    if (!oracle->impl->computeTruth(Query(tmp, constraints), answer))
+      return false;
+    if (!answer)
+      assert(0 && "invalid solver result (computeInitialValues)");
+  } else {
+    if (!oracle->impl->computeTruth(query, answer))
+      return false;
+    if (!answer)
+      assert(0 && "invalid solver result (computeInitialValues)");    
+  }
+
+  return true;
+}
+
+Solver *klee::createValidatingSolver(Solver *s, Solver *oracle) {
+  return new Solver(new ValidatingSolver(s, oracle));
+}
+
+/***/
+
+class STPSolverImpl : public SolverImpl {
+private:
+  /// The solver we are part of, for access to public information.
+  STPSolver *solver;
+  VC vc;
+  STPBuilder *builder;
+  double timeout;
+  bool useForkedSTP;
+
+public:
+  STPSolverImpl(STPSolver *_solver, bool _useForkedSTP);
+  ~STPSolverImpl();
+
+  char *getConstraintLog(const Query&);
+  void setTimeout(double _timeout) { timeout = _timeout; }
+
+  bool computeTruth(const Query&, bool &isValid);
+  bool computeValue(const Query&, ref<Expr> &result);
+  bool computeInitialValues(const Query&,
+                            const std::vector<const Array*> &objects,
+                            std::vector< std::vector<unsigned char> > &values,
+                            bool &hasSolution);
+};
+
+static unsigned char *shared_memory_ptr;
+static const unsigned shared_memory_size = 1<<20;
+static int shared_memory_id;
+
+static void stp_error_handler(const char* err_msg) {
+  fprintf(stderr, "error: STP Error: %s\n", err_msg);
+  abort();
+}
+
+STPSolverImpl::STPSolverImpl(STPSolver *_solver, bool _useForkedSTP) 
+  : solver(_solver),
+    vc(vc_createValidityChecker()),
+    builder(new STPBuilder(vc)),
+    timeout(0.0),
+    useForkedSTP(_useForkedSTP)
+{
+  assert(vc && "unable to create validity checker");
+  assert(builder && "unable to create STPBuilder");
+
+  vc_registerErrorHandler(::stp_error_handler);
+
+  if (useForkedSTP) {
+    shared_memory_id = shmget(IPC_PRIVATE, shared_memory_size, IPC_CREAT | 0700);
+    assert(shared_memory_id>=0 && "shmget failed");
+    shared_memory_ptr = (unsigned char*) shmat(shared_memory_id, NULL, 0);
+    assert(shared_memory_ptr!=(void*)-1 && "shmat failed");
+    shmctl(shared_memory_id, IPC_RMID, NULL);
+  }
+}
+
+STPSolverImpl::~STPSolverImpl() {
+  delete builder;
+
+  vc_Destroy(vc);
+}
+
+/***/
+
+STPSolver::STPSolver(bool useForkedSTP) 
+  : Solver(new STPSolverImpl(this, useForkedSTP))
+{
+}
+
+char *STPSolver::getConstraintLog(const Query &query) {
+  return static_cast<STPSolverImpl*>(impl)->getConstraintLog(query);  
+}
+
+void STPSolver::setTimeout(double timeout) {
+  static_cast<STPSolverImpl*>(impl)->setTimeout(timeout);
+}
+
+/***/
+
+char *STPSolverImpl::getConstraintLog(const Query &query) {
+  vc_push(vc);
+  for (std::vector< ref<Expr> >::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    vc_assertFormula(vc, builder->construct(*it));
+  assert(query.expr == ref<Expr>(0, Expr::Bool) &&
+         "Unexpected expression in query!");
+
+  char *buffer;
+  unsigned long length;
+  vc_printQueryStateToBuffer(vc, builder->getFalse(), 
+                             &buffer, &length, false);
+  vc_pop(vc);
+
+  return buffer;
+}
+
+bool STPSolverImpl::computeTruth(const Query& query,
+                                 bool &isValid) {
+  std::vector<const Array*> objects;
+  std::vector< std::vector<unsigned char> > values;
+  bool hasSolution;
+
+  if (!computeInitialValues(query, objects, values, hasSolution))
+    return false;
+
+  isValid = !hasSolution;
+  return true;
+}
+
+bool STPSolverImpl::computeValue(const Query& query,
+                                 ref<Expr> &result) {
+  std::vector<const Array*> objects;
+  std::vector< std::vector<unsigned char> > values;
+  bool hasSolution;
+
+  // Find the object used in the expression, and compute an assignment
+  // for them.
+  findSymbolicObjects(query.expr, objects);
+  if (!computeInitialValues(query.withFalse(), objects, values, hasSolution))
+    return false;
+  assert(hasSolution && "state has invalid constraint set");
+  
+  // Evaluate the expression with the computed assignment.
+  Assignment a(objects, values);
+  result = a.evaluate(query.expr);
+
+  return true;
+}
+
+static void runAndGetCex(::VC vc, STPBuilder *builder, ::VCExpr q,
+                   const std::vector<const Array*> &objects,
+                   std::vector< std::vector<unsigned char> > &values,
+                   bool &hasSolution) {
+  // XXX I want to be able to timeout here, safely
+  hasSolution = !vc_query(vc, q);
+
+  if (hasSolution) {
+    values.reserve(objects.size());
+    for (std::vector<const Array*>::const_iterator
+           it = objects.begin(), ie = objects.end(); it != ie; ++it) {
+      const Array *array = *it;
+      std::vector<unsigned char> data;
+      
+      data.reserve(array->size);
+      for (unsigned offset = 0; offset < array->size; offset++) {
+        ExprHandle counter = 
+          vc_getCounterExample(vc, builder->getInitialRead(array, offset));
+        unsigned char val = getBVUnsigned(counter);
+        data.push_back(val);
+      }
+      
+      values.push_back(data);
+    }
+  }
+}
+
+static void stpTimeoutHandler(int x) {
+  _exit(52);
+}
+
+static bool runAndGetCexForked(::VC vc, 
+                               STPBuilder *builder,
+                               ::VCExpr q,
+                               const std::vector<const Array*> &objects,
+                               std::vector< std::vector<unsigned char> >
+                                 &values,
+                               bool &hasSolution,
+                               double timeout) {
+  unsigned char *pos = shared_memory_ptr;
+  unsigned sum = 0;
+  for (std::vector<const Array*>::const_iterator
+         it = objects.begin(), ie = objects.end(); it != ie; ++it)
+    sum += (*it)->size;
+  assert(sum<shared_memory_size && "not enough shared memory for counterexample");
+
+  fflush(stdout);
+  fflush(stderr);
+  int pid = fork();
+  if (pid==-1) {
+    fprintf(stderr, "error: fork failed (for STP)");
+    return false;
+  }
+
+  if (pid == 0) {
+    if (timeout) {
+      ::alarm(0); /* Turn off alarm so we can safely set signal handler */
+      ::signal(SIGALRM, stpTimeoutHandler);
+      ::alarm(std::max(1, (int)timeout));
+    }    
+    unsigned res = vc_query(vc, q);
+    if (!res) {
+      for (std::vector<const Array*>::const_iterator
+             it = objects.begin(), ie = objects.end(); it != ie; ++it) {
+        const Array *array = *it;
+        for (unsigned offset = 0; offset < array->size; offset++) {
+          ExprHandle counter = 
+            vc_getCounterExample(vc, builder->getInitialRead(array, offset));
+          *pos++ = getBVUnsigned(counter);
+        }
+      }
+    }
+    _exit(res);
+  } else {
+    int status;
+    int res = waitpid(pid, &status, 0);
+    
+    if (res<0) {
+      fprintf(stderr, "error: waitpid() for STP failed");
+      return false;
+    }
+    
+    // From timed_run.py: It appears that linux at least will on
+    // "occasion" return a status when the process was terminated by a
+    // signal, so test signal first.
+    if (WIFSIGNALED(status) || !WIFEXITED(status)) {
+      fprintf(stderr, "error: STP did not return successfully");
+      return false;
+    }
+
+    int exitcode = WEXITSTATUS(status);
+    if (exitcode==0) {
+      hasSolution = true;
+    } else if (exitcode==1) {
+      hasSolution = false;
+    } else if (exitcode==52) {
+      fprintf(stderr, "error: STP timed out");
+      return false;
+    } else {
+      fprintf(stderr, "error: STP did not return a recognized code");
+      return false;
+    }
+    
+    if (hasSolution) {
+      values = std::vector< std::vector<unsigned char> >(objects.size());
+      unsigned i=0;
+      for (std::vector<const Array*>::const_iterator
+             it = objects.begin(), ie = objects.end(); it != ie; ++it) {
+        const Array *array = *it;
+        std::vector<unsigned char> &data = values[i++];
+        data.insert(data.begin(), pos, pos + array->size);
+        pos += array->size;
+      }
+    }
+
+    return true;
+  }
+}
+
+bool
+STPSolverImpl::computeInitialValues(const Query &query,
+                                    const std::vector<const Array*> 
+                                      &objects,
+                                    std::vector< std::vector<unsigned char> > 
+                                      &values,
+                                    bool &hasSolution) {
+  TimerStatIncrementer t(stats::queryTime);
+
+  vc_push(vc);
+
+  for (ConstraintManager::const_iterator it = query.constraints.begin(), 
+         ie = query.constraints.end(); it != ie; ++it)
+    vc_assertFormula(vc, builder->construct(*it));
+  
+  ++stats::queries;
+  ++stats::queryCounterexamples;
+
+  ExprHandle stp_e = builder->construct(query.expr);
+     
+  bool success;
+  if (useForkedSTP) {
+    success = runAndGetCexForked(vc, builder, stp_e, objects, values, 
+                                 hasSolution, timeout);
+  } else {
+    runAndGetCex(vc, builder, stp_e, objects, values, hasSolution);
+    success = true;
+  }
+  
+  if (success) {
+    if (hasSolution)
+      ++stats::queriesInvalid;
+    else
+      ++stats::queriesValid;
+  }
+  
+  vc_pop(vc);
+  
+  return success;
+}
diff --git a/lib/Solver/SolverStats.cpp b/lib/Solver/SolverStats.cpp
new file mode 100644
index 00000000..9d48792a
--- /dev/null
+++ b/lib/Solver/SolverStats.cpp
@@ -0,0 +1,23 @@
+//===-- SolverStats.cpp ---------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SolverStats.h"
+
+using namespace klee;
+
+Statistic stats::cexCacheTime("CexCacheTime", "CCtime");
+Statistic stats::queries("Queries", "Q");
+Statistic stats::queriesInvalid("QueriesInvalid", "Qiv");
+Statistic stats::queriesValid("QueriesValid", "Qv");
+Statistic stats::queryCacheHits("QueryCacheHits", "QChits") ;
+Statistic stats::queryCacheMisses("QueryCacheMisses", "QCmisses");
+Statistic stats::queryConstructTime("QueryConstructTime", "QBtime") ;
+Statistic stats::queryConstructs("QueriesConstructs", "QB");
+Statistic stats::queryCounterexamples("QueriesCEX", "Qcex");
+Statistic stats::queryTime("QueryTime", "Qtime");
diff --git a/lib/Solver/SolverStats.h b/lib/Solver/SolverStats.h
new file mode 100644
index 00000000..6fee7699
--- /dev/null
+++ b/lib/Solver/SolverStats.h
@@ -0,0 +1,32 @@
+//===-- SolverStats.h -------------------------------------------*- C++ -*-===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef KLEE_SOLVERSTATS_H
+#define KLEE_SOLVERSTATS_H
+
+#include "klee/Statistic.h"
+
+namespace klee {
+namespace stats {
+
+  extern Statistic cexCacheTime;
+  extern Statistic queries;
+  extern Statistic queriesInvalid;
+  extern Statistic queriesValid;
+  extern Statistic queryCacheHits;
+  extern Statistic queryCacheMisses;
+  extern Statistic queryConstructTime;
+  extern Statistic queryConstructs;
+  extern Statistic queryCounterexamples;
+  extern Statistic queryTime;
+
+}
+}
+
+#endif
diff --git a/lib/Support/Makefile b/lib/Support/Makefile
new file mode 100644
index 00000000..a1b46f3c
--- /dev/null
+++ b/lib/Support/Makefile
@@ -0,0 +1,16 @@
+#===-- lib/Support/Makefile --------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleeSupport
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Support/README.txt b/lib/Support/README.txt
new file mode 100644
index 00000000..1ed6fcb4
--- /dev/null
+++ b/lib/Support/README.txt
@@ -0,0 +1,2 @@
+This directory holds basic support facilities (data structures,
+utilities, etc.) used by klee.
diff --git a/lib/Support/RNG.cpp b/lib/Support/RNG.cpp
new file mode 100644
index 00000000..fef7e489
--- /dev/null
+++ b/lib/Support/RNG.cpp
@@ -0,0 +1,146 @@
+/* 
+   A C-program for MT19937, with initialization improved 2002/1/26.
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+   Modified to be a C++ class by Daniel Dunbar.
+
+   Before using, initialize the state by using init_genrand(seed)  
+   or init_by_array(init_key, key_length).
+
+   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+   All rights reserved.                          
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote 
+        products derived from this software without specific prior written 
+        permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+   Any feedback is very welcome.
+   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+*/
+
+#include "klee/Internal/ADT/RNG.h"
+
+using namespace klee;
+
+/* initializes mt[N] with a seed */
+RNG::RNG(unsigned int s) {
+  seed(s);
+}
+
+void RNG::seed(unsigned int s) {
+  mt[0]= s & 0xffffffffUL;
+  for (mti=1; mti<N; mti++) {
+    mt[mti] = 
+      (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 
+    /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+    /* In the previous versions, MSBs of the seed affect   */
+    /* only MSBs of the array mt[].                        */
+    /* 2002/01/09 modified by Makoto Matsumoto             */
+    mt[mti] &= 0xffffffffUL;
+    /* for >32 bit machines */
+  }
+}
+
+/* generates a random number on [0,0xffffffff]-interval */
+unsigned int RNG::getInt32() {
+  unsigned int y;
+  static unsigned int mag01[2]={0x0UL, MATRIX_A};
+  /* mag01[x] = x * MATRIX_A  for x=0,1 */
+  
+  if (mti >= N) { /* generate N words at one time */
+    int kk;
+    
+    for (kk=0;kk<N-M;kk++) {
+      y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+      mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+    }
+    for (;kk<N-1;kk++) {
+      y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+      mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+    }
+    y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+    mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+    
+    mti = 0;
+  }
+  
+  y = mt[mti++];
+
+  /* Tempering */
+  y ^= (y >> 11);
+  y ^= (y << 7) & 0x9d2c5680UL;
+  y ^= (y << 15) & 0xefc60000UL;
+  y ^= (y >> 18);
+  
+  return y;
+}
+
+/* generates a random number on [0,0x7fffffff]-interval */
+int RNG::getInt31() {
+  return (int)(getInt32()>>1);
+}
+
+/* generates a random number on [0,1]-real-interval */
+double RNG::getDoubleLR() {
+  return getInt32()*(1.0/4294967295.0); 
+  /* divided by 2^32-1 */ 
+}
+
+/* generates a random number on [0,1)-real-interval */
+double RNG::getDoubleL() {
+  return getInt32()*(1.0/4294967296.0); 
+  /* divided by 2^32 */
+}
+
+/* generates a random number on (0,1)-real-interval */
+double RNG::getDouble() {
+  return (((double)getInt32()) + 0.5)*(1.0/4294967296.0); 
+  /* divided by 2^32 */
+}
+
+float RNG::getFloatLR() {
+  return getInt32()*(1.0f/4294967295.0f); 
+  /* divided by 2^32-1 */ 
+}
+float RNG::getFloatL() {
+  return getInt32()*(1.0f/4294967296.0f); 
+  /* divided by 2^32 */
+}
+float RNG::getFloat() {
+  return (getInt32() + 0.5f)*(1.0f/4294967296.0f); 
+  /* divided by 2^32 */
+}
+
+bool RNG::getBool() {
+  unsigned bits = getInt32();
+  bits ^= bits >> 16;
+  bits ^= bits >> 8;
+  bits ^= bits >> 4;
+  bits ^= bits >> 2;
+  bits ^= bits >> 1;
+  return bits&1;
+}
diff --git a/lib/Support/Time.cpp b/lib/Support/Time.cpp
new file mode 100644
index 00000000..0ec8d9d7
--- /dev/null
+++ b/lib/Support/Time.cpp
@@ -0,0 +1,27 @@
+//===-- Time.cpp ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Internal/System/Time.h"
+
+#include "llvm/System/Process.h"
+
+using namespace llvm;
+using namespace klee;
+
+double util::getUserTime() {
+  sys::TimeValue now(0,0),user(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+  return (user.seconds() + (double) user.nanoseconds() * 1e-9);
+}
+
+double util::getWallTime() {
+  sys::TimeValue now(0,0),user(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+  return (now.seconds() + (double) now.nanoseconds() * 1e-9);
+}
diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp
new file mode 100644
index 00000000..cddb0707
--- /dev/null
+++ b/lib/Support/Timer.cpp
@@ -0,0 +1,27 @@
+//===-- Timer.cpp ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Internal/Support/Timer.h"
+
+#include "llvm/System/Process.h"
+
+using namespace klee;
+using namespace llvm;
+
+WallTimer::WallTimer() {
+  sys::TimeValue now(0,0),user(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+  startMicroseconds = now.usec();
+}
+
+uint64_t WallTimer::check() {
+  sys::TimeValue now(0,0),user(0,0),sys(0,0);
+  sys::Process::GetTimeUsage(now,user,sys);
+  return now.usec() - startMicroseconds;
+}
diff --git a/lib/Support/TreeStream.cpp b/lib/Support/TreeStream.cpp
new file mode 100644
index 00000000..0e8b86dd
--- /dev/null
+++ b/lib/Support/TreeStream.cpp
@@ -0,0 +1,201 @@
+//===-- TreeStream.cpp ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/Internal/ADT/TreeStream.h"
+
+#include <cassert>
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <iterator>
+#include <map>
+
+#include <string.h>
+
+using namespace klee;
+
+///
+
+TreeStreamWriter::TreeStreamWriter(const std::string &_path) 
+  : lastID(0),
+    bufferCount(0),
+    path(_path),
+    output(new std::ofstream(path.c_str(), 
+                             std::ios::out | std::ios::binary)),
+    ids(1) {
+  if (!output->good()) {
+    delete output;
+    output = 0;
+  }
+}
+
+TreeStreamWriter::~TreeStreamWriter() {
+  flush();
+  if (output)
+    delete output;
+}
+
+bool TreeStreamWriter::good() {
+  return !!output;
+}
+
+TreeOStream TreeStreamWriter::open() {
+  return open(TreeOStream(*this, 0));
+}
+
+TreeOStream TreeStreamWriter::open(const TreeOStream &os) {
+  assert(output && os.writer==this);
+  flushBuffer();
+  unsigned id = ids++;
+  output->write(reinterpret_cast<const char*>(&os.id), 4);
+  unsigned tag = id | (1<<31);
+  output->write(reinterpret_cast<const char*>(&tag), 4);
+  return TreeOStream(*this, id);
+}
+
+void TreeStreamWriter::write(TreeOStream &os, const char *s, unsigned size) {
+#if 1
+  if (bufferCount && 
+      (os.id!=lastID || size+bufferCount>bufferSize))
+    flushBuffer();
+  if (bufferCount) { // (os.id==lastID && size+bufferCount<=bufferSize)
+    memcpy(&buffer[bufferCount], s, size);
+    bufferCount += size;
+  } else if (size<bufferSize) {
+    lastID = os.id;
+    memcpy(buffer, s, size);
+    bufferCount = size;
+  } else {
+    output->write(reinterpret_cast<const char*>(&os.id), 4);
+    output->write(reinterpret_cast<const char*>(&size), 4);
+    output->write(buffer, size);
+  }
+#else
+  output->write(reinterpret_cast<const char*>(&os.id), 4);
+  output->write(reinterpret_cast<const char*>(&size), 4);
+  output->write(s, size);
+#endif
+}
+
+void TreeStreamWriter::flushBuffer() {
+  if (bufferCount) {    
+    output->write(reinterpret_cast<const char*>(&lastID), 4);
+    output->write(reinterpret_cast<const char*>(&bufferCount), 4);
+    output->write(buffer, bufferCount);
+    bufferCount = 0;
+  }
+}
+
+void TreeStreamWriter::flush() {
+  flushBuffer();
+  output->flush();
+}
+
+void TreeStreamWriter::readStream(TreeStreamID streamID,
+                                  std::vector<unsigned char> &out) {
+  assert(streamID>0 && streamID<ids);
+  flush();
+  
+  std::ifstream is(path.c_str(),
+                   std::ios::in | std::ios::binary);
+  assert(is.good());
+#if 0
+  std::cout << "finding chain for: " << streamID << "\n";
+#endif
+  
+  std::map<unsigned,unsigned> parents;
+  std::vector<unsigned> roots;
+  for (;;) {
+    assert(is.good());
+    unsigned id;
+    unsigned tag;
+    is.read(reinterpret_cast<char*>(&id), 4);
+    is.read(reinterpret_cast<char*>(&tag), 4);
+    if (tag&(1<<31)) { // fork
+      unsigned child = tag ^ (1<<31);
+
+      if (child==streamID) {
+        roots.push_back(child);
+        while (id) {
+          roots.push_back(id);
+          std::map<unsigned, unsigned>::iterator it = parents.find(id);
+          assert(it!=parents.end());
+          id = it->second;
+        } 
+        break;
+      } else {
+        parents.insert(std::make_pair(child,id));
+      }
+    } else {
+      unsigned size = tag;
+      while (size--) is.get();
+    }
+  }
+#if 0
+  std::cout << "roots: ";
+  std::copy(roots.begin(), roots.end(), std::ostream_iterator<unsigned>(std::cout, " "));
+  std::cout << "\n"; 
+#endif
+  is.seekg(0, std::ios::beg);
+  for (;;) {
+    unsigned id;
+    unsigned tag;
+    is.read(reinterpret_cast<char*>(&id), 4);
+    is.read(reinterpret_cast<char*>(&tag), 4);
+    if (!is.good()) break;
+    if (tag&(1<<31)) { // fork
+      unsigned child = tag ^ (1<<31);
+      if (id==roots.back() && roots.size()>1 && child==roots[roots.size()-2])
+        roots.pop_back();
+    } else {
+      unsigned size = tag;
+      if (id==roots.back()) {
+        while (size--) out.push_back(is.get());
+      } else {
+        while (size--) is.get();
+      }
+    }
+  }  
+}
+
+///
+
+TreeOStream::TreeOStream()
+  : writer(0),
+    id(0) {
+}
+
+TreeOStream::TreeOStream(TreeStreamWriter &_writer, unsigned _id)
+  : writer(&_writer),
+    id(_id) {
+}
+
+TreeOStream::~TreeOStream() {
+}
+
+unsigned TreeOStream::getID() const {
+  assert(writer);
+  return id;
+}
+
+void TreeOStream::write(const char *buffer, unsigned size) {
+  assert(writer);
+  writer->write(*this, buffer, size);
+}
+
+TreeOStream &TreeOStream::operator<<(const std::string &s) {
+  assert(writer);
+  write(s.c_str(), s.size());
+  return *this;
+}
+
+void TreeOStream::flush() {
+  assert(writer);
+  writer->flush();
+}
diff --git a/runtime/Intrinsic/Makefile b/runtime/Intrinsic/Makefile
new file mode 100644
index 00000000..ce4a34ba
--- /dev/null
+++ b/runtime/Intrinsic/Makefile
@@ -0,0 +1,20 @@
+#===-- runtime/Intrinsic/Makefile --------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=intrinsic
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+BYTECODE_LIBRARY=1
+# Don't strip debug info from the module.
+DEBUG_RUNTIME=1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/Intrinsic/klee_div_zero_check.c b/runtime/Intrinsic/klee_div_zero_check.c
new file mode 100644
index 00000000..3fde1af5
--- /dev/null
+++ b/runtime/Intrinsic/klee_div_zero_check.c
@@ -0,0 +1,15 @@
+//===-- klee_div_zero_check.c ---------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <klee/klee.h>
+
+void klee_div_zero_check(long long z) {
+  if (z == 0)
+    klee_report_error(__FILE__, __LINE__, "divide by zero", "div.err");
+}
diff --git a/runtime/Intrinsic/klee_int.c b/runtime/Intrinsic/klee_int.c
new file mode 100644
index 00000000..88ec5026
--- /dev/null
+++ b/runtime/Intrinsic/klee_int.c
@@ -0,0 +1,17 @@
+//===-- klee_int.c --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+#include <klee/klee.h>
+
+int klee_int(const char *name) {
+  int x;
+  klee_make_symbolic_name(&x, sizeof x, name);
+  return x;
+}
diff --git a/runtime/Intrinsic/klee_make_symbolic.c b/runtime/Intrinsic/klee_make_symbolic.c
new file mode 100644
index 00000000..b9dec2a7
--- /dev/null
+++ b/runtime/Intrinsic/klee_make_symbolic.c
@@ -0,0 +1,14 @@
+//===-- klee_make_symbolic.c ----------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <klee/klee.h>
+
+void klee_make_symbolic(void *addr, unsigned nbytes) {
+  klee_make_symbolic_name(addr, nbytes, "unnamed");
+}
diff --git a/runtime/Intrinsic/klee_range.c b/runtime/Intrinsic/klee_range.c
new file mode 100644
index 00000000..59d1a05e
--- /dev/null
+++ b/runtime/Intrinsic/klee_range.c
@@ -0,0 +1,33 @@
+//===-- klee_range.c ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+#include <klee/klee.h>
+
+int klee_range(int start, int end, const char* name) {
+  int x;
+
+  assert(start < end);
+
+  if (start+1==end) {
+    return start;
+  } else {
+    klee_make_symbolic_name(&x, sizeof x, name); 
+
+    /* Make nicer constraint when simple... */
+    if (start==0) {
+      klee_assume((unsigned) x < (unsigned) end);
+    } else {
+      klee_assume(start <= x);
+      klee_assume(x < end);
+    }
+
+    return x;
+  }
+}
diff --git a/runtime/Intrinsic/memcpy.c b/runtime/Intrinsic/memcpy.c
new file mode 100644
index 00000000..14b98ce6
--- /dev/null
+++ b/runtime/Intrinsic/memcpy.c
@@ -0,0 +1,19 @@
+//===-- memcpy.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return destaddr;
+}
diff --git a/runtime/Intrinsic/memmove.c b/runtime/Intrinsic/memmove.c
new file mode 100644
index 00000000..c6e1ada9
--- /dev/null
+++ b/runtime/Intrinsic/memmove.c
@@ -0,0 +1,28 @@
+//===-- memmove.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memmove(void *dst, const void *src, size_t count) {
+  char *a = dst;
+  const char *b = src;
+
+  if (src == dst)
+    return dst;
+
+  if (src>dst) {
+    while (count--) *a++ = *b++;
+  } else {
+    a+=count-1;
+    b+=count-1;
+    while (count--) *a-- = *b--;
+  }
+
+  return dst;
+}
diff --git a/runtime/Intrinsic/mempcpy.c b/runtime/Intrinsic/mempcpy.c
new file mode 100644
index 00000000..6327e748
--- /dev/null
+++ b/runtime/Intrinsic/mempcpy.c
@@ -0,0 +1,19 @@
+//===-- mempcpy.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *mempcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return dest;
+}
diff --git a/runtime/Intrinsic/memset.c b/runtime/Intrinsic/memset.c
new file mode 100644
index 00000000..ee9ecb87
--- /dev/null
+++ b/runtime/Intrinsic/memset.c
@@ -0,0 +1,17 @@
+//===-- memset.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memset(void * dst, int s, size_t count) {
+    char * a = dst;
+    while (count-- > 0)
+      *a++ = s;
+    return dst;
+}
diff --git a/runtime/Makefile b/runtime/Makefile
new file mode 100755
index 00000000..24824d08
--- /dev/null
+++ b/runtime/Makefile
@@ -0,0 +1,26 @@
+#===-- runtime/Makefile ------------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+#
+# Relative path to the top of the source tree.
+#
+LEVEL=..
+
+#
+# List all of the subdirectories that we will compile.
+#
+PARALLEL_DIRS=Intrinsic klee-libc Runtest
+
+include $(LEVEL)/Makefile.config
+
+ifeq ($(ENABLE_POSIX_RUNTIME),1)
+PARALLEL_DIRS += POSIX
+endif
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/POSIX/Makefile b/runtime/POSIX/Makefile
new file mode 100644
index 00000000..9a42f5c0
--- /dev/null
+++ b/runtime/POSIX/Makefile
@@ -0,0 +1,20 @@
+#===-- runtime/POSIX/Makefile ------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=kleeRuntimePOSIX
+DONT_BUILD_RELINKED=1
+BUILD_ARCHIVE=1
+BYTECODE_LIBRARY=1
+# Don't strip debug info from the module.
+DEBUG_RUNTIME=1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/POSIX/fd.c b/runtime/POSIX/fd.c
new file mode 100644
index 00000000..367a8c4a
--- /dev/null
+++ b/runtime/POSIX/fd.c
@@ -0,0 +1,1287 @@
+//===-- fd.c --------------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#include "fd.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <termios.h>
+#include <sys/select.h>
+#include <klee/klee.h>
+
+/* #define DEBUG */
+
+void klee_warning(const char*);
+void klee_warning_once(const char*);
+int klee_get_errno(void);
+
+/* Returns pointer to the symbolic file structure is the pathname is symbolic */
+static exe_disk_file_t *__get_sym_file(const char *pathname) {
+  char c = pathname[0];
+  unsigned i;
+
+  if (c == 0 || pathname[1] != 0)
+    return NULL;
+
+  for (i=0; i<__exe_fs.n_sym_files; ++i) {
+    if (c == 'A' + (char) i) {
+      exe_disk_file_t *df = &__exe_fs.sym_files[i];
+      if (df->stat->st_ino == 0)
+        return NULL;
+      return df;
+    }
+  }
+  
+  return NULL;
+}
+
+static void *__concretize_ptr(const void *p);
+static size_t __concretize_size(size_t s);
+static const char *__concretize_string(const char *s);
+
+/* Returns pointer to the file entry for a valid fd */
+static exe_file_t *__get_file(int fd) {
+  if (fd>=0 && fd<MAX_FDS) {
+    exe_file_t *f = &__exe_env.fds[fd];
+    if (f->flags & eOpen)
+      return f;
+  }
+
+  return 0;
+}
+
+int access(const char *pathname, int mode) {
+  exe_disk_file_t *dfile = __get_sym_file(pathname);
+  
+  if (dfile) {
+    /* XXX we should check against stat values but we also need to
+       enforce in open and friends then. */
+    return 0;
+  } else {
+    int r = syscall(__NR_access, __concretize_string(pathname), mode);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  } 
+}
+
+mode_t umask(mode_t mask) {  
+  mode_t r = __exe_env.umask;
+  __exe_env.umask = mask & 0777;
+  return r;
+}
+
+
+/* Returns 1 if the process has the access rights specified by 'flags'
+   to the file with stat 's'.  Returns 0 otherwise*/
+static int has_permission(int flags, struct stat64 *s) {
+  int write_access, read_access;
+  mode_t mode = s->st_mode;
+  
+  if (flags & O_RDONLY || flags & O_RDWR)
+    read_access = 1;
+  else read_access = 0;
+
+  if (flags & O_WRONLY || flags & O_RDWR)
+    write_access = 1;
+  else write_access = 0;
+
+  /* XXX: We don't worry about process uid and gid for now. 
+     We allow access if any user has access to the file. */
+#if 0
+  uid_t uid = s->st_uid;
+  uid_t euid = geteuid();
+  gid_t gid = s->st_gid;
+  gid_t egid = getegid();
+#endif  
+
+  if (read_access && ((mode & S_IRUSR) | (mode & S_IRGRP) | (mode & S_IROTH)))
+    return 0;
+
+  if (write_access && !((mode & S_IWUSR) | (mode & S_IWGRP) | (mode & S_IWOTH)))
+    return 0;
+
+  return 1;
+}
+
+
+int __fd_open(const char *pathname, int flags, mode_t mode) {
+  exe_disk_file_t *df;
+  exe_file_t *f;
+  int fd;
+
+  for (fd = 0; fd < MAX_FDS; ++fd)
+    if (!(__exe_env.fds[fd].flags & eOpen))
+      break;
+  if (fd == MAX_FDS) {
+    errno = EMFILE;
+    return -1;
+  }
+  
+  f = &__exe_env.fds[fd];
+
+  /* Should be the case if file was available, but just in case. */
+  memset(f, 0, sizeof *f);
+
+  df = __get_sym_file(pathname); 
+  if (df) {    
+    /* XXX Should check access against mode / stat / possible
+       deletion. */
+    f->dfile = df;
+    
+    if ((flags & O_CREAT) && (flags & O_EXCL)) {
+      errno = EEXIST;
+      return -1;
+    }
+    
+    if ((flags & O_TRUNC) && (flags & O_RDONLY)) {
+      /* The result of using O_TRUNC with O_RDONLY is undefined, so we
+	 return error */
+      fprintf(stderr, "Undefined call to open(): O_TRUNC | O_RDONLY\n");
+      errno = EACCES;
+      return -1;
+    }
+
+    if ((flags & O_EXCL) && !(flags & O_CREAT)) {
+      /* The result of using O_EXCL without O_CREAT is undefined, so
+	 we return error */
+      fprintf(stderr, "Undefined call to open(): O_EXCL w/o O_RDONLY\n");
+      errno = EACCES;
+      return -1;
+    }
+
+    if (!has_permission(flags, df->stat)) {
+	errno = EACCES;
+	return -1;
+    }
+    else
+      f->dfile->stat->st_mode = ((f->dfile->stat->st_mode & ~0777) |
+				 (mode & ~__exe_env.umask));
+  } else {    
+    int os_fd = syscall(__NR_open, __concretize_string(pathname), flags, mode);
+    if (os_fd == -1) {
+      errno = klee_get_errno();
+      return -1;
+    }
+    f->fd = os_fd;
+  }
+  
+  f->flags = eOpen;
+  if ((flags & O_ACCMODE) == O_RDONLY) {
+    f->flags |= eReadable;
+  } else if ((flags & O_ACCMODE) == O_WRONLY) {
+    f->flags |= eWriteable;
+  } else { /* XXX What actually happens here if != O_RDWR. */
+    f->flags |= eReadable | eWriteable;
+  }
+  
+  return fd;
+}
+
+int close(int fd) {
+  static int n_calls = 0;
+  exe_file_t *f;
+  int r = 0;
+  
+  n_calls++;  
+
+  f = __get_file(fd);
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  } 
+
+  if (__exe_fs.max_failures && *__exe_fs.close_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+#if 0
+  if (!f->dfile) {
+    /* if a concrete fd */
+    r = syscall(__NR_close, f->fd);
+  }
+  else r = 0;
+#endif
+
+  memset(f, 0, sizeof *f);
+  
+  return r;
+}
+
+ssize_t read(int fd, void *buf, size_t count) {
+  static int n_calls = 0;
+  exe_file_t *f;
+
+  n_calls++;
+
+  if (count == 0) 
+    return 0;
+
+  if (buf == NULL) {
+    errno = EFAULT;
+    return -1;
+  }
+  
+  f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }  
+
+  if (__exe_fs.max_failures && *__exe_fs.read_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+  
+  if (!f->dfile) {
+    /* concrete file */
+    int r;
+    buf = __concretize_ptr(buf);
+    count = __concretize_size(count);
+    /* XXX In terms of looking for bugs we really should do this check
+       before concretization, at least once the routine has been fixed
+       to properly work with symbolics. */
+    klee_check_memory_access(buf, count);
+    if (f->fd == 0)
+      r = syscall(__NR_read, f->fd, buf, count);
+    else
+      r = syscall(__NR_pread64, f->fd, buf, count, (off64_t) f->off);
+
+    if (r == -1) {
+      errno = klee_get_errno();
+      return -1;
+    }
+    
+    if (f->fd != 0)
+      f->off += r;
+    return r;
+  }
+  else {
+    assert(f->off >= 0);
+    if (f->dfile->size < f->off)
+      return 0;
+
+    /* symbolic file */
+    if (f->off + count > f->dfile->size) {
+      count = f->dfile->size - f->off;
+    }
+    
+    memcpy(buf, f->dfile->contents + f->off, count);
+    f->off += count;
+    
+    return count;
+  }
+}
+
+
+ssize_t write(int fd, const void *buf, size_t count) {
+  static int n_calls = 0;
+  exe_file_t *f;
+
+  n_calls++;
+
+  f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (__exe_fs.max_failures && *__exe_fs.write_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+  if (!f->dfile) {
+    int r;
+
+    buf = __concretize_ptr(buf);
+    count = __concretize_size(count);
+    /* XXX In terms of looking for bugs we really should do this check
+       before concretization, at least once the routine has been fixed
+       to properly work with symbolics. */
+    klee_check_memory_access(buf, count);
+    if (f->fd == 1 || f->fd == 2)
+      r = syscall(__NR_write, f->fd, buf, count);
+    else r = syscall(__NR_pwrite64, f->fd, buf, count, (off64_t) f->off);
+    
+    if (r == -1) {
+      errno = klee_get_errno();
+      return -1;
+    }
+    
+    assert(r >= 0);
+    if (f->fd != 1 && f->fd != 2)
+      f->off += r;
+
+    return r;
+  }
+  else {
+    /* symbolic file */    
+    size_t actual_count = 0;
+    if (f->off + count <= f->dfile->size)
+      actual_count = count;
+    else {
+      if (__exe_env.save_all_writes)
+	assert(0);
+      else {
+	if (f->off < f->dfile->size)
+	  actual_count = f->dfile->size - f->off;	
+      }
+    }
+    
+    if (actual_count)
+      memcpy(f->dfile->contents + f->off, buf, actual_count);
+    
+    if (count != actual_count)
+      fprintf(stderr, "WARNING: write() ignores bytes.\n");
+
+    if (f->dfile == __exe_fs.sym_stdout)
+      __exe_fs.stdout_writes += actual_count;
+
+    f->off += count;
+    return count;
+  }
+}
+
+
+off64_t __fd_lseek(int fd, off64_t offset, int whence) {
+  off64_t new_off;
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (!f->dfile) {
+    /* We could always do SEEK_SET then whence, but this causes
+       troubles with directories since we play nasty tricks with the
+       offset, and the OS doesn't want us to randomly seek
+       directories. We could detect if it is a directory and correct
+       the offset, but really directories should only be SEEK_SET, so
+       this solves the problem. */
+    if (whence == SEEK_SET) {
+      new_off = syscall(__NR_lseek, f->fd, (int) offset, SEEK_SET);
+    } else {
+      new_off = syscall(__NR_lseek, f->fd, (int) f->off, SEEK_SET);
+
+      /* If we can't seek to start off, just return same error.
+         Probably ESPIPE. */
+      if (new_off != -1) {
+        assert(new_off == f->off);
+        new_off = syscall(__NR_lseek, f->fd, (int) offset, whence);
+      }
+    }
+
+    if (new_off == -1) {
+      errno = klee_get_errno();
+      return -1;
+    }
+
+    f->off = new_off;
+    return new_off;
+  }
+  
+  switch (whence) {
+  case SEEK_SET: new_off = offset; break;
+  case SEEK_CUR: new_off = f->off + offset; break;
+  case SEEK_END: new_off = f->dfile->size + offset; break;
+  default: {
+    errno = EINVAL;
+    return (off64_t) -1;
+  }
+  }
+
+  if (new_off < 0) {
+    errno = EINVAL;
+    return (off64_t) -1;
+  }
+    
+  f->off = new_off;
+  return f->off;
+}
+
+int __fd_stat(const char *path, struct stat64 *buf) {  
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    memcpy(buf, dfile->stat, sizeof(*dfile->stat));
+    return 0;
+  } 
+
+  {
+    int r = syscall(__NR_stat64, __concretize_string(path), buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int __fd_lstat(const char *path, struct stat64 *buf) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    memcpy(buf, dfile->stat, sizeof(*dfile->stat));
+    return 0;
+  } 
+
+  {    
+    int r = syscall(__NR_lstat64, __concretize_string(path), buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int chdir(const char *path) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+
+  if (dfile) {
+    /* XXX incorrect */
+    klee_warning("symbolic file, ignoring (ENOENT)");
+    errno = ENOENT;
+    return -1;
+  }
+
+  {
+    int r = syscall(__NR_chdir, __concretize_string(path));
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fchdir(int fd) {
+  exe_file_t *f = __get_file(fd);
+  
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (f->dfile) {
+    klee_warning("symbolic file, ignoring (ENOENT)");
+    errno = ENOENT;
+    return -1;
+  } else {
+    int r = syscall(__NR_fchdir, f->fd);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+/* Sets mode and or errno and return appropriate result. */
+static int __df_chmod(exe_disk_file_t *df, mode_t mode) {
+  if (geteuid() == df->stat->st_uid) {
+    if (getgid() != df->stat->st_gid)
+      mode &= ~ S_ISGID;
+    df->stat->st_mode = ((df->stat->st_mode & ~07777) | 
+                         (mode & 07777));
+    return 0;
+  } else {
+    errno = EPERM;
+    return -1;
+  }
+}
+
+int chmod(const char *path, mode_t mode) {
+  static int n_calls = 0;
+
+  exe_disk_file_t *dfile = __get_sym_file(path);
+
+  n_calls++;
+  if (__exe_fs.max_failures && *__exe_fs.chmod_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+  if (dfile) {
+    return __df_chmod(dfile, mode);
+  } else {
+    int r = syscall(__NR_chmod, __concretize_string(path), mode);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fchmod(int fd, mode_t mode) {
+  static int n_calls = 0;
+
+  exe_file_t *f = __get_file(fd);
+  
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  n_calls++;
+  if (__exe_fs.max_failures && *__exe_fs.fchmod_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+
+  if (f->dfile) {
+    return __df_chmod(f->dfile, mode);
+  } else {
+    int r = syscall(__NR_fchmod, f->fd, mode);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }  
+}
+
+static int __df_chown(exe_disk_file_t *df, uid_t owner, gid_t group) {
+  klee_warning("symbolic file, ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int chown(const char *path, uid_t owner, gid_t group) {
+  exe_disk_file_t *df = __get_sym_file(path);
+
+  if (df) {
+    return __df_chown(df, owner, group);
+  } else {
+    int r = syscall(__NR_chown, __concretize_string(path), owner, group);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fchown(int fd, uid_t owner, gid_t group) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (f->dfile) {
+    return __df_chown(f->dfile, owner, group);
+  } else {
+    int r = syscall(__NR_fchown, fd, owner, group);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int lchown(const char *path, uid_t owner, gid_t group) {
+  /* XXX Ignores 'l' part */
+  exe_disk_file_t *df = __get_sym_file(path);
+
+  if (df) {
+    return __df_chown(df, owner, group);
+  } else {
+    int r = syscall(__NR_chown, __concretize_string(path), owner, group);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int __fd_fstat(int fd, struct stat64 *buf) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (!f->dfile) {
+    int r = syscall(__NR_fstat64, f->fd, buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+  
+  memcpy(buf, f->dfile->stat, sizeof(*f->dfile->stat));
+  return 0;
+}
+
+int __fd_ftruncate(int fd, off64_t length) {
+  static int n_calls = 0;
+  exe_file_t *f = __get_file(fd);
+
+  n_calls++;
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (__exe_fs.max_failures && *__exe_fs.ftruncate_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = EIO;
+    return -1;
+  }
+  
+  if (f->dfile) {
+    klee_warning("symbolic file, ignoring (EIO)");
+    errno = EIO;
+    return -1;
+  } else {
+    int r = syscall(__NR_ftruncate64, f->fd, length);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }  
+}
+
+int __fd_getdents(unsigned int fd, struct dirent64 *dirp, unsigned int count) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (f->dfile) {
+    klee_warning("symbolic file, ignoring (EINVAL)");
+    errno = EINVAL;
+    return -1;
+  } else {
+    if ((unsigned) f->off < 4096u) {
+      /* Return our dirents */
+      unsigned i, pad, bytes=0;
+
+      /* What happens for bad offsets? */
+      i = f->off / sizeof(*dirp);
+      if ((i * sizeof(*dirp) != f->off) ||
+          i > __exe_fs.n_sym_files) {
+        errno = EINVAL;
+        return -1;
+      } 
+      for (; i<__exe_fs.n_sym_files; ++i) {
+        exe_disk_file_t *df = &__exe_fs.sym_files[i];
+        dirp->d_ino = df->stat->st_ino;
+        dirp->d_reclen = sizeof(*dirp);
+        dirp->d_type = IFTODT(df->stat->st_mode);
+        dirp->d_name[0] = 'A' + i;
+        dirp->d_name[1] = '\0';
+        dirp->d_off = (i+1) * sizeof(*dirp);
+        bytes += dirp->d_reclen;
+        ++dirp;
+      }
+      
+      /* Fake jump to OS records by a "deleted" file. */
+      pad = count>=4096 ? 4096 : count;
+      dirp->d_ino = 0;
+      dirp->d_reclen = pad - bytes;
+      dirp->d_type = DT_UNKNOWN;
+      dirp->d_name[0] = '\0';
+      dirp->d_off = 4096;
+      bytes += dirp->d_reclen;
+      f->off = pad;
+      return bytes;
+    } else {
+      unsigned os_pos = f->off - 4096;
+      int res, s;
+
+      /* For reasons which I really don't understand, if I don't
+         memset this then sometimes the kernel returns d_ino==0 for
+         some valid entries? Am I crazy? Can writeback possibly be
+         failing? 
+      
+         Even more bizarre, interchanging the memset and the seek also
+         case strange behavior. Really should be debugged properly. */
+      memset(dirp, 0, count);
+      s = syscall(__NR_lseek, f->fd, (int) os_pos, SEEK_SET);
+      assert(s != (off64_t) -1);
+      res = syscall(__NR_getdents64, f->fd, dirp, count);
+      if (res == -1) {
+        errno = klee_get_errno();
+      } else {
+        int pos = 0;
+
+        f->off = syscall(__NR_lseek, f->fd, 0, SEEK_CUR) + 4096;
+
+        /* Patch offsets */
+        
+        while (pos < res) {
+          struct dirent64 *dp = (struct dirent64*) ((char*) dirp + pos);
+          dp->d_off += 4096;
+          pos += dp->d_reclen;
+        }
+      }
+      return res;
+    }
+  }
+}
+
+int ioctl(int fd, unsigned long request, ...) {
+  exe_file_t *f = __get_file(fd);
+  va_list ap;
+  void *buf;
+
+#if 0
+  printf("In ioctl(%d, ...)\n", fd);
+#endif
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  va_start(ap, request);
+  buf = va_arg(ap, void*);
+  va_end(ap);
+  
+  if (f->dfile) {
+    struct stat *stat = (struct stat*) f->dfile->stat;
+
+    switch (request) {
+    case TCGETS: {      
+      struct termios *ts = buf;
+
+      klee_warning_once("(TCGETS) symbolic file, incomplete model");
+
+      /* XXX need more data, this is ok but still not good enough */
+      if (S_ISCHR(stat->st_mode)) {
+        /* Just copied from my system, munged to match what fields
+           uclibc thinks are there. */
+        ts->c_iflag = 27906;
+        ts->c_oflag = 5;
+        ts->c_cflag = 1215;
+        ts->c_lflag = 35287;
+        ts->c_line = 0;
+        ts->c_cc[0] = '\x03';
+        ts->c_cc[1] = '\x1c';
+        ts->c_cc[2] = '\x7f';
+        ts->c_cc[3] = '\x15';
+        ts->c_cc[4] = '\x04';
+        ts->c_cc[5] = '\x00';
+        ts->c_cc[6] = '\x01';
+        ts->c_cc[7] = '\xff';
+        ts->c_cc[8] = '\x11';
+        ts->c_cc[9] = '\x13';
+        ts->c_cc[10] = '\x1a';
+        ts->c_cc[11] = '\xff';
+        ts->c_cc[12] = '\x12';
+        ts->c_cc[13] = '\x0f';
+        ts->c_cc[14] = '\x17';
+        ts->c_cc[15] = '\x16';
+        ts->c_cc[16] = '\xff';
+        ts->c_cc[17] = '\x0';
+        ts->c_cc[18] = '\x0';
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TCSETS: {
+      /* const struct termios *ts = buf; */
+      klee_warning_once("(TCSETS) symbolic file, silently ignoring");
+      if (S_ISCHR(stat->st_mode)) {
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TCSETSW: {
+      /* const struct termios *ts = buf; */
+      klee_warning_once("(TCSETSW) symbolic file, silently ignoring");
+      if (fd==0) {
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TCSETSF: {
+      /* const struct termios *ts = buf; */
+      klee_warning_once("(TCSETSF) symbolic file, silently ignoring");
+      if (S_ISCHR(stat->st_mode)) {        
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TIOCGWINSZ: {
+      struct winsize *ws = buf;
+      ws->ws_row = 24;
+      ws->ws_col = 80;
+      klee_warning_once("(TIOCGWINSZ) symbolic file, incomplete model");
+      if (S_ISCHR(stat->st_mode)) {
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case TIOCSWINSZ: {
+      /* const struct winsize *ws = buf; */
+      klee_warning_once("(TIOCSWINSZ) symbolic file, ignoring (EINVAL)");
+      if (S_ISCHR(stat->st_mode)) {
+        errno = EINVAL;
+        return -1;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case FIONREAD: {
+      int *res = buf;
+      klee_warning_once("(FIONREAD) symbolic file, incomplete model");
+      if (S_ISCHR(stat->st_mode)) {
+        if (f->off < f->dfile->size) {
+          *res = f->dfile->size - f->off;
+        } else {
+          *res = 0;
+        }
+        return 0;
+      } else {
+        errno = ENOTTY;
+        return -1;
+      }
+    }
+    case MTIOCGET: {
+      klee_warning("(MTIOCGET) symbolic file, ignoring (EINVAL)");
+      errno = EINVAL;
+      return -1;
+    }
+    default:
+      klee_warning("symbolic file, ignoring (EINVAL)");
+      errno = EINVAL;
+      return -1;
+    }
+  } else {
+    int r = syscall(__NR_ioctl, f->fd, request, buf );
+    if (r == -1) 
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fcntl(int fd, int cmd, ...) {
+  exe_file_t *f = __get_file(fd);
+  va_list ap;
+  unsigned arg; /* 32 bit assumption (int/ptr) */
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (cmd==F_GETFD || cmd==F_GETFL || cmd==F_GETOWN || cmd==F_GETSIG ||
+      cmd==F_GETLEASE || cmd==F_NOTIFY) {
+    arg = 0;
+  } else {
+    va_start(ap, cmd);
+    arg = va_arg(ap, int);
+    va_end(ap);
+  }
+
+  if (f->dfile) {
+    switch(cmd) {
+    case F_GETFD: {
+      int flags = 0;
+      if (f->flags & eCloseOnExec)
+        flags |= FD_CLOEXEC;
+      return flags;
+    } 
+    case F_SETFD: {
+      f->flags &= ~eCloseOnExec;
+      if (arg & FD_CLOEXEC)
+        f->flags |= eCloseOnExec;
+      return 0;
+    }
+    case F_GETFL: {
+      /* XXX (CrC): This should return the status flags: O_APPEND,
+	 O_ASYNC, O_DIRECT, O_NOATIME, O_NONBLOCK.  As of now, we
+	 discard these flags during open().  We should save them and
+	 return them here.  These same flags can be set by F_SETFL,
+	 which we could also handle properly. 
+      */
+      return 0;
+    }
+    default:
+      klee_warning("symbolic file, ignoring (EINVAL)");
+      errno = EINVAL;
+      return -1;
+    }
+  } else {
+    int r = syscall(__NR_fcntl, f->fd, cmd, arg );
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int __fd_statfs(const char *path, struct statfs *buf) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    /* XXX incorrect */
+    klee_warning("symbolic file, ignoring (ENOENT)");
+    errno = ENOENT;
+    return -1;
+  }
+
+  {
+    int r = syscall(__NR_statfs, __concretize_string(path), buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fstatfs(int fd, struct statfs *buf) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  }
+  
+  if (f->dfile) {
+    klee_warning("symbolic file, ignoring (EBADF)");
+    errno = EBADF;
+    return -1;
+  } else {
+    int r = syscall(__NR_fstatfs, f->fd, buf);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int fsync(int fd) {
+  exe_file_t *f = __get_file(fd);
+
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  } else if (f->dfile) {
+    return 0;
+  } else {
+    int r = syscall(__NR_fsync, f->fd);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+int dup2(int oldfd, int newfd) {
+  exe_file_t *f = __get_file(oldfd);
+
+  if (!f || !(newfd>=0 && newfd<MAX_FDS)) {
+    errno = EBADF;
+    return -1;
+  } else {
+    exe_file_t *f2 = &__exe_env.fds[newfd];
+    if (f2->flags & eOpen) close(newfd);
+
+    /* XXX Incorrect, really we need another data structure for open
+       files */
+    *f2 = *f;
+
+    f2->flags &= ~eCloseOnExec;
+      
+    /* I'm not sure it is wise, but we can get away with not dup'ng
+       the OS fd, since actually that will in many cases effect the
+       sharing of the open file (and the process should never have
+       access to it). */
+
+    return newfd;
+  }
+}
+
+int dup(int oldfd) {
+  exe_file_t *f = __get_file(oldfd);
+  if (!f) {
+    errno = EBADF;
+    return -1;
+  } else {
+    int fd;
+    for (fd = 0; fd < MAX_FDS; ++fd)
+      if (!(__exe_env.fds[fd].flags & eOpen))
+        break;
+    if (fd == MAX_FDS) {
+      errno = EMFILE;
+      return -1;
+    } else {
+      return dup2(oldfd, fd);
+    }
+  }
+}
+
+int rmdir(const char *pathname) {
+  exe_disk_file_t *dfile = __get_sym_file(pathname);
+  if (dfile) {
+    /* XXX check access */ 
+    if (S_ISDIR(dfile->stat->st_mode)) {
+      dfile->stat->st_ino = 0;
+      return 0;
+    } else {
+      errno = ENOTDIR;
+      return -1;
+    }
+  }
+
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int unlink(const char *pathname) {
+  exe_disk_file_t *dfile = __get_sym_file(pathname);
+  if (dfile) {
+    /* XXX check access */ 
+    if (S_ISREG(dfile->stat->st_mode)) {
+      dfile->stat->st_ino = 0;
+      return 0;
+    } else if (S_ISDIR(dfile->stat->st_mode)) {
+      errno = EISDIR;
+      return -1;
+    } else {
+      errno = EPERM;
+      return -1;
+    }
+  }
+
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+ssize_t readlink(const char *path, char *buf, size_t bufsize) {
+  exe_disk_file_t *dfile = __get_sym_file(path);
+  if (dfile) {
+    /* XXX We need to get the sym file name really, but since we don't
+       handle paths anyway... */
+    if (S_ISLNK(dfile->stat->st_mode)) {
+      buf[0] = path[0];
+      if (bufsize>1) buf[1] = '.';
+      if (bufsize>2) buf[2] = 'l';
+      if (bufsize>3) buf[3] = 'n';
+      if (bufsize>4) buf[4] = 'k';
+      return (bufsize>5) ? 5 : bufsize;
+    } else {
+      errno = EINVAL;
+      return -1;
+    }
+  } else {
+    int r = syscall(__NR_readlink, path, buf, bufsize);
+    if (r == -1)
+      errno = klee_get_errno();
+    return r;
+  }
+}
+
+#undef FD_SET
+#undef FD_CLR
+#undef FD_ISSET
+#undef FD_ZERO
+#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p)	memset((char *)(p), '\0', sizeof(*(p)))
+int select(int nfds, fd_set *read, fd_set *write,
+           fd_set *except, struct timeval *timeout) {
+  fd_set in_read, in_write, in_except, os_read, os_write, os_except;
+  int i, count = 0, os_nfds = 0;
+
+  if (read) {
+    in_read = *read;
+    FD_ZERO(read);
+  } else {
+    FD_ZERO(&in_read);
+  }
+
+  if (write) {
+    in_write = *write;
+    FD_ZERO(write);
+  } else {
+    FD_ZERO(&in_write);
+  }
+   
+  if (except) {
+    in_except = *except;
+    FD_ZERO(except);
+  } else {
+    FD_ZERO(&in_except);
+  }
+
+  FD_ZERO(&os_read);
+  FD_ZERO(&os_write);
+  FD_ZERO(&os_except);
+
+  /* Check for symbolic stuff */
+  for (i=0; i<nfds; i++) {    
+    if (FD_ISSET(i, &in_read) || FD_ISSET(i, &in_write) || FD_ISSET(i, &in_except)) {
+      exe_file_t *f = __get_file(i);
+      if (!f) {
+        errno = EBADF;
+        return -1;
+      } else if (f->dfile) {
+        /* Operations on this fd will never block... */
+        if (FD_ISSET(i, &in_read)) FD_SET(i, read);
+        if (FD_ISSET(i, &in_write)) FD_SET(i, write);
+        if (FD_ISSET(i, &in_except)) FD_SET(i, except);
+        ++count;
+      } else {
+        if (FD_ISSET(i, &in_read)) FD_SET(f->fd, &os_read);
+        if (FD_ISSET(i, &in_write)) FD_SET(f->fd, &os_write);
+        if (FD_ISSET(i, &in_except)) FD_SET(f->fd, &os_except);
+        if (f->fd >= os_nfds) os_nfds = f->fd + 1;
+      }
+    }
+  }
+
+  if (os_nfds > 0) {
+    /* Never allow blocking select. This is broken but what else can
+       we do. */
+    struct timeval tv = { 0, 0 };    
+    int r = syscall(__NR_select, os_nfds, 
+                    &os_read, &os_write, &os_except, &tv);
+    
+    if (r == -1) {
+      /* If no symbolic results, return error. Otherwise we will
+         silently ignore the OS error. */
+      if (!count) {
+        errno = klee_get_errno();
+        return -1;
+      }
+    } else {
+      count += r;
+
+      /* Translate resulting sets back */
+      for (i=0; i<nfds; i++) {
+        exe_file_t *f = __get_file(i);
+        if (f && !f->dfile) {
+          if (read && FD_ISSET(f->fd, &os_read)) FD_SET(i, read);
+          if (write && FD_ISSET(f->fd, &os_write)) FD_SET(i, write);
+          if (except && FD_ISSET(f->fd, &os_except)) FD_SET(i, except);
+        }
+      }
+    }
+  }
+
+  return count;
+}
+
+/*** Library functions ***/
+
+char *getcwd(char *buf, size_t size) {
+  static int n_calls = 0;
+  int r;
+
+  n_calls++;
+
+  if (__exe_fs.max_failures && *__exe_fs.getcwd_fail == n_calls) {
+    __exe_fs.max_failures--;
+    errno = ERANGE;
+    return NULL;
+  }
+
+  if (!buf) {
+    if (!size)
+      size = 1024;
+    buf = malloc(size);
+  }
+  
+  buf = __concretize_ptr(buf);
+  size = __concretize_size(size);
+  /* XXX In terms of looking for bugs we really should do this check
+     before concretization, at least once the routine has been fixed
+     to properly work with symbolics. */
+  klee_check_memory_access(buf, size);
+  r = syscall(__NR_getcwd, buf, size);
+  if (r == -1) {
+    errno = klee_get_errno();
+    return NULL;
+  }
+    
+  return buf;
+}
+
+/*** Helper functions ***/
+
+static void *__concretize_ptr(const void *p) {
+  /* XXX 32-bit assumption */
+  char *pc = (char*) klee_get_value((unsigned) (long) p);
+  klee_assume(pc == p);
+  return pc;
+}
+
+static size_t __concretize_size(size_t s) {
+  size_t sc = klee_get_value(s);
+  klee_assume(sc == s);
+  return sc;
+}
+
+static const char *__concretize_string(const char *s) {
+  char *sc = __concretize_ptr(s);
+  unsigned i;
+
+  for (i=0; ; ++i) {
+    char c = *sc;
+    if (!(i&(i-1))) {
+      if (!c) {
+        *sc++ = 0;
+        break;
+      } else if (c=='/') {
+        *sc++ = '/';
+      } 
+    } else {
+      char cc = (char) klee_get_value(c);
+      klee_assume(cc == c);
+      *sc++ = cc;
+      if (!cc) break;
+    }
+  }
+
+  return s;
+}
+
+
+
+/* Trivial model:
+   if path is "/" (basically no change) accept, otherwise reject
+*/
+int chroot(const char *path) {
+  if (path[0] == '\0') {
+    errno = ENOENT;
+    return -1;
+  }
+    
+  if (path[0] == '/' && path[1] == '\0') {
+    return 0;
+  }
+  
+  klee_warning("ignoring (ENOENT)");
+  errno = ENOENT;
+  return -1;
+}
diff --git a/runtime/POSIX/fd.h b/runtime/POSIX/fd.h
new file mode 100644
index 00000000..f2780143
--- /dev/null
+++ b/runtime/POSIX/fd.h
@@ -0,0 +1,90 @@
+//===-- fd.h ---------------------------------------------------*- C++ -*--===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __EXE_FD__
+#define __EXE_FD__
+
+#ifndef _LARGEFILE64_SOURCE
+#error "_LARGEFILE64_SOURCE should be defined"
+#endif
+#include <sys/types.h>
+#include <sys/statfs.h>
+#include <dirent.h>
+
+typedef struct {  
+  unsigned size;  /* in bytes */
+  char* contents;
+  struct stat64* stat;
+} exe_disk_file_t;
+
+typedef enum {
+  eOpen         = (1 << 0),
+  eCloseOnExec  = (1 << 1),
+  eReadable     = (1 << 2),
+  eWriteable    = (1 << 3)
+} exe_file_flag_t;
+
+typedef struct {      
+  int fd;                   /* actual fd if not symbolic */
+  unsigned flags;           /* set of exe_file_flag_t values. fields
+                               are only defined when flags at least
+                               has eOpen. */
+  off64_t off;              /* offset */
+  exe_disk_file_t* dfile;   /* ptr to file on disk, if symbolic */
+} exe_file_t;
+
+typedef struct {
+  unsigned n_sym_files; /* number of symbolic input files, excluding stdin */
+  exe_disk_file_t *sym_stdin, *sym_stdout;
+  unsigned stdout_writes; /* how many chars were written to stdout */
+  exe_disk_file_t *sym_files;
+  /* --- */
+  /* the maximum number of failures on one path; gets decremented after each failure */
+  unsigned max_failures; 
+
+  /* Which read, write etc. call should fail */
+  int *read_fail, *write_fail, *close_fail, *ftruncate_fail, *getcwd_fail;
+  int *chmod_fail, *fchmod_fail;
+} exe_file_system_t;
+
+#define MAX_FDS 32
+
+/* Note, if you change this structure be sure to update the
+   initialization code if necessary. New fields should almost
+   certainly be at the end. */
+typedef struct {
+  exe_file_t fds[MAX_FDS];
+  mode_t umask; /* process umask */
+  unsigned version;
+  /* If set, writes execute as expected.  Otherwise, writes extending
+     the file size only change the contents up to the initial
+     size. The file offset is always incremented correctly. */
+  int save_all_writes; 
+} exe_sym_env_t;
+
+extern exe_file_system_t __exe_fs;
+extern exe_sym_env_t __exe_env;
+
+void klee_init_fds(unsigned n_files, unsigned file_length, 
+		   int sym_stdout_flag, int do_all_writes_flag, 
+		   unsigned max_failures);
+void klee_init_env(int *argcPtr, char ***argvPtr);
+
+/* *** */
+
+int __fd_open(const char *pathname, int flags, mode_t mode);
+off64_t __fd_lseek(int fd, off64_t offset, int whence);
+int __fd_stat(const char *path, struct stat64 *buf);
+int __fd_lstat(const char *path, struct stat64 *buf);
+int __fd_fstat(int fd, struct stat64 *buf);
+int __fd_ftruncate(int fd, off64_t length);
+int __fd_statfs(const char *path, struct statfs *buf);
+int __fd_getdents(unsigned int fd, struct dirent64 *dirp, unsigned int count);
+
+#endif /* __EXE_FD__ */
diff --git a/runtime/POSIX/fd_32.c b/runtime/POSIX/fd_32.c
new file mode 100644
index 00000000..4eea1805
--- /dev/null
+++ b/runtime/POSIX/fd_32.c
@@ -0,0 +1,196 @@
+//===-- fd_32.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#include "fd.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/vfs.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <unistd.h>
+#include <dirent.h>
+
+/***/
+
+static void __stat64_to_stat(struct stat64 *a, struct stat *b) {
+  b->st_dev = a->st_dev;
+  b->st_ino = a->st_ino;
+  b->st_mode = a->st_mode;
+  b->st_nlink = a->st_nlink;
+  b->st_uid = a->st_uid;
+  b->st_gid = a->st_gid;
+  b->st_rdev = a->st_rdev;
+  b->st_size = a->st_size;
+  b->st_atime = a->st_atime;
+  b->st_mtime = a->st_mtime;
+  b->st_ctime = a->st_ctime;
+  b->st_blksize = a->st_blksize;
+  b->st_blocks = a->st_blocks;
+}
+
+/***/
+
+int open(const char *pathname, int flags, ...) {
+  mode_t mode = 0;
+
+  if (flags & O_CREAT) {
+    /* get mode */
+    va_list ap;
+    va_start(ap, flags);
+    mode = va_arg(ap, mode_t);
+    va_end(ap);
+  }
+
+  return __fd_open(pathname, flags, mode);
+}
+
+off_t lseek(int fd, off_t off, int whence) {
+  return (off_t) __fd_lseek(fd, off, whence);
+}
+
+int __xstat(int vers, const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_stat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int stat(const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_stat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int __lxstat(int vers, const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_lstat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int lstat(const char *path, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_lstat(path, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int __fxstat(int vers, int fd, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_fstat(fd, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int fstat(int fd, struct stat *buf) {
+  struct stat64 tmp;
+  int res = __fd_fstat(fd, &tmp);
+  __stat64_to_stat(&tmp, buf);
+  return res;
+}
+
+int ftruncate(int fd, off_t length) {
+  return __fd_ftruncate(fd, length);
+}
+
+int statfs(const char *path, struct statfs *buf32) {
+#if 0
+    struct statfs64 buf;
+
+    if (__fd_statfs(path, &buf) < 0)
+	return -1;
+
+    buf32->f_type = buf.f_type;
+    buf32->f_bsize = buf.f_bsize;
+    buf32->f_blocks = buf.f_blocks;
+    buf32->f_bfree = buf.f_bfree;
+    buf32->f_bavail = buf.f_bavail;
+    buf32->f_files = buf.f_files;
+    buf32->f_ffree = buf.f_ffree;
+    buf32->f_fsid = buf.f_fsid;
+    buf32->f_namelen = buf.f_namelen;
+
+    return 0;
+#else
+    return __fd_statfs(path, buf32);
+#endif
+}
+
+/* Based on uclibc version. We use getdents64 and then rewrite the
+   results over themselves, as dirent32s. */
+ssize_t getdents(int fd, struct dirent *dirp, size_t nbytes) {
+  struct dirent64 *dp64 = (struct dirent64*) dirp;
+  ssize_t res = __fd_getdents(fd, dp64, nbytes);
+
+  if (res>0) {
+    struct dirent64 *end = (struct dirent64*) ((char*) dp64 + res);
+    while (dp64 < end) {
+      struct dirent *dp = (struct dirent *) dp64;
+      unsigned name_len = (dp64->d_reclen - 
+                           (unsigned) &((struct dirent64*) 0)->d_name);
+      dp->d_ino = dp64->d_ino;
+      dp->d_off = dp64->d_off;
+      dp->d_reclen = dp64->d_reclen;
+      dp->d_type = dp64->d_type;
+      memmove(dp->d_name, dp64->d_name, name_len);
+      dp64 = (struct dirent64*) ((char*) dp64 + dp->d_reclen);
+    }
+  }
+
+  return res;
+}
+int __getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
+     __attribute__((alias("getdents")));
+
+/* Forward to 64 versions (uclibc expects versions w/o asm specifier) */
+
+int open64(const char *pathname, int flags, ...) __attribute__((weak));
+int open64(const char *pathname, int flags, ...) {
+  mode_t mode = 0;
+
+  if (flags & O_CREAT) {
+    /* get mode */
+    va_list ap;
+    va_start(ap, flags);
+    mode = va_arg(ap, mode_t);
+    va_end(ap);
+  }
+
+  return __fd_open(pathname, flags, mode);
+}
+
+off64_t lseek64(int fd, off64_t off, int whence) __attribute__((weak));
+off64_t lseek64(int fd, off64_t off, int whence) {
+  return __fd_lseek(fd, off, whence);
+}
+
+int stat64(const char *path, struct stat64 *buf) __attribute__((weak));
+int stat64(const char *path, struct stat64 *buf) {
+  return __fd_stat(path, buf);
+}
+
+int lstat64(const char *path, struct stat64 *buf) __attribute__((weak));
+int lstat64(const char *path, struct stat64 *buf) {
+  return __fd_lstat(path, buf);
+}
+
+int fstat64(int fd, struct stat64 *buf) __attribute__((weak));
+int fstat64(int fd, struct stat64 *buf) {
+  return __fd_fstat(fd, buf);
+}
diff --git a/runtime/POSIX/fd_64.c b/runtime/POSIX/fd_64.c
new file mode 100644
index 00000000..d0710caf
--- /dev/null
+++ b/runtime/POSIX/fd_64.c
@@ -0,0 +1,90 @@
+//===-- fd_64.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#define _FILE_OFFSET_BITS 64
+#include "fd.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <termios.h>
+#include <sys/select.h>
+#include <klee/klee.h>
+
+/*** Forward to actual implementations ***/
+
+int open(const char *pathname, int flags, ...) {
+  mode_t mode = 0;
+  
+  if (flags & O_CREAT) {
+    /* get mode */
+    va_list ap;
+    va_start(ap, flags);
+    mode = va_arg(ap, mode_t);
+    va_end(ap);
+  }
+
+  return __fd_open(pathname, flags, mode);
+}
+
+off64_t lseek(int fd, off64_t offset, int whence) {
+  return __fd_lseek(fd, offset, whence);
+}
+
+int __xstat(int vers, const char *path, struct stat *buf) {
+  return __fd_stat(path, (struct stat64*) buf);
+}
+
+int stat(const char *path, struct stat *buf) {
+  return __fd_stat(path, (struct stat64*) buf);
+}
+
+int __lxstat(int vers, const char *path, struct stat *buf) {
+  return __fd_lstat(path, (struct stat64*) buf);
+}
+
+int lstat(const char *path, struct stat *buf) {
+  return __fd_lstat(path, (struct stat64*) buf);
+}
+
+int __fxstat(int vers, int fd, struct stat *buf) {
+  return __fd_fstat(fd, (struct stat64*) buf);
+}
+
+int fstat(int fd, struct stat *buf) {
+  return __fd_fstat(fd, (struct stat64*) buf);
+}
+
+int ftruncate64(int fd, off64_t length) {
+  return __fd_ftruncate(fd, length);
+}
+
+int statfs(const char *path, struct statfs *buf) __attribute__((weak));
+int statfs(const char *path, struct statfs *buf) {
+  return __fd_statfs(path, buf);
+}
+
+int getdents64(unsigned int fd, struct dirent *dirp, unsigned int count) {
+  return __fd_getdents(fd, (struct dirent64*) dirp, count);
+}
+int __getdents64(unsigned int fd, struct dirent *dirp, unsigned int count)
+     __attribute__((alias("getdents64")));
diff --git a/runtime/POSIX/fd_init.c b/runtime/POSIX/fd_init.c
new file mode 100644
index 00000000..61e49893
--- /dev/null
+++ b/runtime/POSIX/fd_init.c
@@ -0,0 +1,161 @@
+//===-- fd_init.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LARGEFILE64_SOURCE
+#define _FILE_OFFSET_BITS 64
+#include "fd.h"
+#include <klee/klee.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+
+exe_file_system_t __exe_fs;
+
+/* NOTE: It is important that these are statically initialized
+   correctly, since things that run before main may hit them given the
+   current way things are linked. */
+
+/* XXX Technically these flags are initialized w.o.r. to the
+   environment we are actually running in. We could patch them in
+   klee_init_fds, but we still have the problem that uclibc calls
+   prior to main will get the wrong data. Not such a big deal since we
+   mostly care about sym case anyway. */
+
+
+exe_sym_env_t __exe_env = { 
+  {{ 0, eOpen | eReadable, 0, 0}, 
+   { 1, eOpen | eWriteable, 0, 0}, 
+   { 2, eOpen | eWriteable, 0, 0}},
+  022,
+  0,
+  0
+};
+
+static void __create_new_dfile(exe_disk_file_t *dfile, unsigned size, 
+                               const char *name, struct stat64 *defaults) {
+  struct stat64 *s = malloc(sizeof(*s));
+  const char *sp;
+  char sname[64];
+  for (sp=name; *sp; ++sp)
+    sname[sp-name] = *sp;
+  memcpy(&sname[sp-name], "-stat", 6);
+
+  assert(size);
+
+  dfile->size = size;
+  dfile->contents = malloc(dfile->size);
+  klee_make_symbolic_name(dfile->contents, dfile->size, name);
+  
+  klee_make_symbolic_name(s, sizeof(*s), sname);
+
+  /* For broken tests */
+  if (!klee_is_symbolic(s->st_ino) && 
+      (s->st_ino & 0x7FFFFFFF) == 0)
+    s->st_ino = defaults->st_ino;
+  
+  /* Important since we copy this out through getdents, and readdir
+     will otherwise skip this entry. For same reason need to make sure
+     it fits in low bits. */
+  klee_assume((s->st_ino & 0x7FFFFFFF) != 0);
+
+  /* uclibc opendir uses this as its buffer size, try to keep
+     reasonable. */
+  klee_assume((s->st_blksize & ~0xFFFF) == 0);
+
+  klee_prefer_cex(s, !(s->st_mode & ~(S_IFMT | 0777)));
+  klee_prefer_cex(s, s->st_dev == defaults->st_dev);
+  klee_prefer_cex(s, s->st_rdev == defaults->st_rdev);
+  klee_prefer_cex(s, (s->st_mode&0700) == 0600);
+  klee_prefer_cex(s, (s->st_mode&0070) == 0020);
+  klee_prefer_cex(s, (s->st_mode&0007) == 0002);
+  klee_prefer_cex(s, (s->st_mode&S_IFMT) == S_IFREG);
+  klee_prefer_cex(s, s->st_nlink == 1);
+  klee_prefer_cex(s, s->st_uid == defaults->st_uid);
+  klee_prefer_cex(s, s->st_gid == defaults->st_gid);
+  klee_prefer_cex(s, s->st_blksize == 4096);
+  klee_prefer_cex(s, s->st_atime == defaults->st_atime);
+  klee_prefer_cex(s, s->st_mtime == defaults->st_mtime);
+  klee_prefer_cex(s, s->st_ctime == defaults->st_ctime);
+
+  s->st_size = dfile->size;
+  s->st_blocks = 8;
+  dfile->stat = s;
+}
+
+static unsigned __sym_uint32(const char *name) {
+  unsigned x;
+  klee_make_symbolic_name(&x, sizeof x, name);
+  return x;
+}
+
+/* n_files: number of symbolic input files, excluding stdin
+   file_length: size in bytes of each symbolic file, including stdin
+   sym_stdout_flag: 1 if stdout should be symbolic, 0 otherwise
+   save_all_writes_flag: 1 if all writes are executed as expected, 0 if 
+                         writes past the initial file size are discarded 
+			 (file offset is always incremented)
+   max_failures: maximum number of system call failures */
+void klee_init_fds(unsigned n_files, unsigned file_length, 
+		   int sym_stdout_flag, int save_all_writes_flag,
+		   unsigned max_failures) {
+  unsigned k;
+  char name[7] = "?-data";
+  struct stat64 s;
+
+  stat64(".", &s);
+
+  __exe_fs.n_sym_files = n_files;
+  __exe_fs.sym_files = malloc(sizeof(*__exe_fs.sym_files) * n_files);
+  for (k=0; k < n_files; k++) {
+    name[0] = 'A' + k;
+    __create_new_dfile(&__exe_fs.sym_files[k], file_length, name, &s);
+  }
+  
+  /* setting symbolic stdin */
+  if (file_length) {
+    __exe_fs.sym_stdin = malloc(sizeof(*__exe_fs.sym_stdin));
+    __create_new_dfile(__exe_fs.sym_stdin, file_length, "stdin", &s);
+    __exe_env.fds[0].dfile = __exe_fs.sym_stdin;
+  }
+  else __exe_fs.sym_stdin = NULL;
+
+  __exe_fs.max_failures = max_failures;
+  if (__exe_fs.max_failures) {
+    __exe_fs.read_fail = malloc(sizeof(*__exe_fs.read_fail));
+    __exe_fs.write_fail = malloc(sizeof(*__exe_fs.write_fail));
+    __exe_fs.close_fail = malloc(sizeof(*__exe_fs.close_fail));
+    __exe_fs.ftruncate_fail = malloc(sizeof(*__exe_fs.ftruncate_fail));
+    __exe_fs.getcwd_fail = malloc(sizeof(*__exe_fs.getcwd_fail));
+
+    klee_make_symbolic_name(__exe_fs.read_fail, sizeof(*__exe_fs.read_fail), "read_fail");
+    klee_make_symbolic_name(__exe_fs.write_fail, sizeof(*__exe_fs.write_fail), "write_fail");
+    klee_make_symbolic_name(__exe_fs.close_fail, sizeof(*__exe_fs.close_fail), "close_fail");
+    klee_make_symbolic_name(__exe_fs.ftruncate_fail, sizeof(*__exe_fs.ftruncate_fail), "ftruncate_fail");
+    klee_make_symbolic_name(__exe_fs.getcwd_fail, sizeof(*__exe_fs.getcwd_fail), "getcwd_fail");
+  }
+
+  /* setting symbolic stdout */
+  if (sym_stdout_flag) {
+    __exe_fs.sym_stdout = malloc(sizeof(*__exe_fs.sym_stdout));
+    __create_new_dfile(__exe_fs.sym_stdout, 1024, "stdout", &s);
+    __exe_env.fds[1].dfile = __exe_fs.sym_stdout;
+    __exe_fs.stdout_writes = 0;
+  }
+  else __exe_fs.sym_stdout = NULL;
+  
+  __exe_env.save_all_writes = save_all_writes_flag;
+  __exe_env.version = __sym_uint32("model_version");
+  klee_assume(__exe_env.version == 1);
+}
diff --git a/runtime/POSIX/illegal.c b/runtime/POSIX/illegal.c
new file mode 100644
index 00000000..469ea623
--- /dev/null
+++ b/runtime/POSIX/illegal.c
@@ -0,0 +1,70 @@
+//===-- illegal.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/types.h>
+
+#include <klee/klee.h>
+
+void klee_warning(const char*);
+void klee_warning_once(const char*);
+
+int kill(pid_t pid, int sig) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int _setjmp (struct __jmp_buf_tag __env[1]) __attribute__((weak));
+int _setjmp (struct __jmp_buf_tag __env[1]) {
+  klee_warning_once("ignoring");
+  return 0;
+}
+
+void longjmp(jmp_buf env, int val) {
+  klee_report_error(__FILE__, __LINE__, "longjmp unsupported", "xxx.err");
+}
+
+/* Macro so function name from klee_warning comes out correct. */
+#define __bad_exec() \
+  (klee_warning("ignoring (EACCES)"),\
+   errno = EACCES,\
+   -1)
+
+/* This need to be weak because uclibc wants to define them as well,
+   but we will want to make sure a definition is around in case we
+   don't link with it. */
+
+int execl(const char *path, const char *arg, ...) __attribute__((weak));
+int execlp(const char *file, const char *arg, ...) __attribute__((weak));
+int execle(const char *path, const char *arg, ...) __attribute__((weak));
+int execv(const char *path, char *const argv[]) __attribute__((weak));
+int execvp(const char *file, char *const argv[]) __attribute__((weak));
+int execve(const char *file, char *const argv[], char *const envp[]) __attribute__((weak));
+
+int execl(const char *path, const char *arg, ...) { return __bad_exec(); }
+int execlp(const char *file, const char *arg, ...) { return __bad_exec(); }
+int execle(const char *path, const char *arg, ...)  { return __bad_exec(); }
+int execv(const char *path, char *const argv[]) { return __bad_exec(); }
+int execvp(const char *file, char *const argv[]) { return __bad_exec(); }
+int execve(const char *file, char *const argv[], char *const envp[]) { return __bad_exec(); }
+
+pid_t fork(void) {
+  klee_warning("ignoring (ENOMEM)");
+  errno = ENOMEM;
+  return -1;
+}
+
+pid_t vfork(void) {
+  return fork();
+}
diff --git a/runtime/POSIX/klee_init_env.c b/runtime/POSIX/klee_init_env.c
new file mode 100644
index 00000000..83e9fde6
--- /dev/null
+++ b/runtime/POSIX/klee_init_env.c
@@ -0,0 +1,181 @@
+//===-- klee_init_env.c ---------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/klee.h"
+#define _LARGEFILE64_SOURCE
+#include "fd.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static void __emit_error(const char *msg) {
+  klee_report_error(__FILE__, __LINE__, msg, "user.err");
+}
+
+/* Helper function that converts a string to an integer, and
+   terminates the program with an error message is the string is not a
+   proper number */   
+static long int __str_to_int(char *s, const char *error_msg) {
+  long int res = 0;
+  char c;
+
+  if (!*s) __emit_error(error_msg);
+
+  while ((c = *s++)) {
+    if (c == '\0') {
+      break;
+    } else if (c>='0' && c<='9') {
+      res = res*10 + (c - '0');
+    } else {
+      __emit_error(error_msg);
+    }
+  }
+  return res;
+}
+
+static int __isprint(const char c) {
+  /* Assume ASCII */
+  return (32 <= c && c <= 126);
+}
+
+static int __streq(const char *a, const char *b) {
+  while (*a == *b) {
+    if (!*a)
+      return 1;
+    a++;
+    b++;
+  }
+  return 0;
+}
+
+static char *__get_sym_str(int numChars, char *name) {
+  int i;
+  char *s = malloc(numChars+1);
+  klee_mark_global(s);
+  klee_make_symbolic_name(s, numChars+1, name);
+
+  for (i=0; i<numChars; i++)
+    klee_prefer_cex(s, __isprint(s[i]));
+  
+  s[numChars] = '\0';
+  return s;
+}
+
+static void __add_arg(int *argc, char **argv, char *arg, int argcMax) {
+  if (*argc==argcMax) {
+    __emit_error("too many arguments for klee_init_env");
+  } else {
+    argv[*argc] = arg;
+    (*argc)++;
+  }
+}
+
+void klee_init_env(int* argcPtr, char*** argvPtr) {
+  int argc = *argcPtr;
+  char** argv = *argvPtr;
+
+  int new_argc = 0, n_args;
+  char* new_argv[1024];
+  unsigned max_len, min_argvs, max_argvs;
+  unsigned sym_files = 0, sym_file_len = 0;
+  int sym_stdout_flag = 0;
+  int save_all_writes_flag = 0;
+  int fd_fail = 0;
+  char** final_argv;
+  char sym_arg_name[5] = "arg";
+  unsigned sym_arg_num = 0;
+  int k=0, i;
+
+  sym_arg_name[4] = '\0';
+
+  while (k < argc) {
+    if (__streq(argv[k], "--sym-arg") || __streq(argv[k], "-sym-arg")) {
+      const char *msg = "--sym-arg expects an integer argument <max-len>";
+      if (++k == argc)        
+	__emit_error(msg);
+		
+      max_len = __str_to_int(argv[k++], msg);
+      sym_arg_name[3] = '0' + sym_arg_num++;
+      __add_arg(&new_argc, new_argv, 
+                __get_sym_str(max_len, sym_arg_name),
+                1024);
+    }
+    else if (__streq(argv[k], "--sym-args") || __streq(argv[k], "-sym-args")) {
+      const char *msg = 
+        "--sym-args expects three integer arguments <min-argvs> <max-argvs> <max-len>";
+
+      if (k+3 >= argc)
+	__emit_error(msg);
+      
+      k++;
+      min_argvs = __str_to_int(argv[k++], msg);
+      max_argvs = __str_to_int(argv[k++], msg);
+      max_len = __str_to_int(argv[k++], msg);
+
+      n_args = klee_range(min_argvs, max_argvs+1, "n_args");
+      for (i=0; i < n_args; i++) {
+        sym_arg_name[3] = '0' + sym_arg_num++;
+        __add_arg(&new_argc, new_argv, 
+                  __get_sym_str(max_len, sym_arg_name),
+                  1024);
+      }
+    }
+    else if (__streq(argv[k], "--sym-files") || __streq(argv[k], "-sym-files")) {
+      const char* msg = "--sym-files expects two integer arguments <no-sym-files> <sym-file-len>";      
+
+      if (k+2 >= argc)
+	__emit_error(msg);
+      
+      k++;
+      sym_files = __str_to_int(argv[k++], msg);
+      sym_file_len = __str_to_int(argv[k++], msg);
+
+    }
+    else if (__streq(argv[k], "--sym-stdout") || __streq(argv[k], "-sym-stdout")) {
+      sym_stdout_flag = 1;
+      k++;
+    }
+    else if (__streq(argv[k], "--save-all-writes") || __streq(argv[k], "-save-all-writes")) {
+      save_all_writes_flag = 1;
+      k++;
+    }
+    else if (__streq(argv[k], "--fd-fail") || __streq(argv[k], "-fd-fail")) {
+      fd_fail = 1;
+      k++;
+    }
+    else if (__streq(argv[k], "--max-fail") || __streq(argv[k], "-max-fail")) {
+      const char *msg = "--max-fail expects an integer argument <max-failures>";
+      if (++k == argc)
+	__emit_error(msg);
+		
+      fd_fail = __str_to_int(argv[k++], msg);
+    }
+    else {
+      /* simply copy arguments */
+      __add_arg(&new_argc, new_argv, argv[k++], 1024);
+    }
+  }
+
+  final_argv = (char**) malloc((new_argc+1) * sizeof(*final_argv));
+  klee_mark_global(final_argv);
+  memcpy(final_argv, new_argv, new_argc * sizeof(*final_argv));
+  final_argv[new_argc] = 0;
+
+  *argcPtr = new_argc;
+  *argvPtr = final_argv;
+
+  klee_init_fds(sym_files, sym_file_len, 
+		sym_stdout_flag, save_all_writes_flag, 
+		fd_fail);
+}
+
diff --git a/runtime/POSIX/misc.c b/runtime/POSIX/misc.c
new file mode 100644
index 00000000..12ff2f58
--- /dev/null
+++ b/runtime/POSIX/misc.c
@@ -0,0 +1,87 @@
+//===-- misc.c ------------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <klee/klee.h>
+#include <string.h>
+
+#if 0
+#define MAX_SYM_ENV_SIZE 32
+typedef struct {
+  char name[MAX_SYM_ENV_SIZE];
+  char *value;
+} sym_env_var;
+
+static sym_env_var *__klee_sym_env = 0;
+static unsigned __klee_sym_env_count = 0;
+static unsigned __klee_sym_env_nvars = 0;
+static unsigned __klee_sym_env_var_size = 0;
+void __klee_init_environ(unsigned nvars, 
+                         unsigned var_size) {
+  assert(var_size);
+  __klee_sym_env = malloc(sizeof(*__klee_sym_env) * nvars);
+  assert(__klee_sym_env);
+
+  __klee_sym_env_nvars = nvars;
+  __klee_sym_env_var_size = var_size;  
+}
+
+static unsigned __strlen(const char *s) {
+  const char *s2 = s;
+  while (*s2) ++s2;
+  return s2-s;
+}
+
+extern char *__getenv(const char *name);
+char *getenv(const char *name) {
+  char *res = __getenv(name);
+
+  if (!__klee_sym_env_nvars)
+    return res;
+
+  /* If it exists in the system environment fork and return the actual
+     result or 0. */
+  if (res) {
+    return klee_range(0, 2, name) ? res : 0;
+  } else {
+    unsigned i, len = __strlen(name);
+
+    if (len>=MAX_SYM_ENV_SIZE) {
+      /* Don't deal with strings to large to fit in our name. */
+      return 0;
+    } else {
+      /* Check for existing entry */
+      for (i=0; i<__klee_sym_env_count; ++i)
+        if (memcmp(__klee_sym_env[i].name, name, len+1)==0)
+          return __klee_sym_env[i].value;
+      
+      /* Otherwise create if room and we choose to */
+      if (__klee_sym_env_count < __klee_sym_env_nvars) {
+        if (klee_range(0, 2, name)) {
+          char *s = malloc(__klee_sym_env_var_size+1);
+          klee_make_symbolic(s, __klee_sym_env_var_size+1);
+          s[__klee_sym_env_var_size] = '\0';
+          
+          memcpy(__klee_sym_env[__klee_sym_env_count].name, name, len+1);
+          __klee_sym_env[__klee_sym_env_count].value = s;
+          ++__klee_sym_env_count;
+          
+          return s;
+        }
+      }
+      
+      return 0;
+    }
+  }
+}
+#endif
diff --git a/runtime/POSIX/selinux.c b/runtime/POSIX/selinux.c
new file mode 100644
index 00000000..38acba6c
--- /dev/null
+++ b/runtime/POSIX/selinux.c
@@ -0,0 +1,80 @@
+//===-- selinux.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/* Very basic SELinux support */
+
+#include "klee/Config/config.h"
+
+#ifdef HAVE_SELINUX_SELINUX_H
+
+#include "klee/klee.h"
+
+#include <selinux/selinux.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/* for now, assume we run on an SELinux machine */
+int exe_selinux = 1;
+
+/* NULL is the default policy behavior */
+security_context_t create_con = NULL;
+
+
+int is_selinux_enabled() {
+  return exe_selinux;
+}
+
+
+/***/
+
+int getfscreatecon(security_context_t *context) {
+  *context = create_con;
+  return 0;
+}
+
+
+int setfscreatecon(security_context_t context) {
+  if (context == NULL) {
+    create_con = context;
+    return 0;
+  }
+
+  /* on my machine, setfscreatecon seems to incorrectly accept one
+     char strings.. Also, make sure mcstrans > 0.2.8 for replay 
+     (important bug fixed) */
+  if (context[0] != '\0' && context[1] == '\0')
+    klee_silent_exit(1);
+
+  return -1;
+}
+
+/***/
+
+int setfilecon(const char *path, security_context_t con) {
+  if (con)
+    return 0;
+  
+  errno = ENOSPC;
+  return -1;  
+}
+
+int lsetfilecon(const char *path, security_context_t con) {
+  return setfilecon(path, con);
+}
+
+int fsetfilecon(int fd, security_context_t con) {
+  return setfilecon("", con);
+}
+
+/***/
+
+void freecon(security_context_t con) {}
+void freeconary(security_context_t *con) {}
+
+#endif
diff --git a/runtime/POSIX/stubs.c b/runtime/POSIX/stubs.c
new file mode 100644
index 00000000..cf64f26b
--- /dev/null
+++ b/runtime/POSIX/stubs.c
@@ -0,0 +1,560 @@
+//===-- stubs.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <utime.h>
+#include <utmp.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "klee/Config/config.h"
+
+void klee_warning(const char*);
+void klee_warning_once(const char*);
+
+/* Silent ignore */
+
+int __syscall_rt_sigaction(int signum, const struct sigaction *act, 
+                           struct sigaction *oldact, size_t _something)
+     __attribute__((weak));
+
+int __syscall_rt_sigaction(int signum, const struct sigaction *act, 
+                           struct sigaction *oldact, size_t _something) {
+  klee_warning_once("silently ignoring");
+  return 0;
+}
+
+int sigaction(int signum, const struct sigaction *act, 
+              struct sigaction *oldact) __attribute__((weak));
+
+int sigaction(int signum, const struct sigaction *act, 
+              struct sigaction *oldact) {
+  klee_warning_once("silently ignoring");
+  return 0;
+}
+
+int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
+     __attribute__((weak));
+int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
+  klee_warning_once("silently ignoring");
+  return 0;
+}
+
+/* Not even worth warning about these */
+int fdatasync(int fd) __attribute__((weak));
+int fdatasync(int fd) {
+  return 0;
+}
+
+/* Not even worth warning about this */
+void sync(void) __attribute__((weak));
+void sync(void) {
+}
+
+/* Error ignore */
+
+extern int __fgetc_unlocked(FILE *f);
+extern int __fputc_unlocked(int c, FILE *f);
+
+int __socketcall(int type, int *args) __attribute__((weak));
+int __socketcall(int type, int *args) {
+  klee_warning("ignoring (EAFNOSUPPORT)");
+  errno = EAFNOSUPPORT;
+  return -1;
+}
+
+int _IO_getc(FILE *f) __attribute__((weak));
+int _IO_getc(FILE *f) {
+  return __fgetc_unlocked(f);
+}
+
+int _IO_putc(int c, FILE *f) __attribute__((weak));
+int _IO_putc(int c, FILE *f) {
+  return __fputc_unlocked(c, f);
+}
+
+int mkdir(const char *pathname, mode_t mode) __attribute__((weak));
+int mkdir(const char *pathname, mode_t mode) {
+  klee_warning("ignoring (EIO)");
+  errno = EIO;
+  return -1;
+}
+
+int mkfifo(const char *pathname, mode_t mode) __attribute__((weak));
+int mkfifo(const char *pathname, mode_t mode) {
+  klee_warning("ignoring (EIO)");
+  errno = EIO;
+  return -1;
+}
+
+int mknod(const char *pathname, mode_t mode, dev_t dev) __attribute__((weak));
+int mknod(const char *pathname, mode_t mode, dev_t dev) {
+  klee_warning("ignoring (EIO)");
+  errno = EIO;
+  return -1;
+}
+
+int pipe(int filedes[2]) __attribute__((weak));
+int pipe(int filedes[2]) {
+  klee_warning("ignoring (ENFILE)");
+  errno = ENFILE;
+  return -1;
+}
+
+int link(const char *oldpath, const char *newpath) __attribute__((weak));
+int link(const char *oldpath, const char *newpath) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int symlink(const char *oldpath, const char *newpath) __attribute__((weak));
+int symlink(const char *oldpath, const char *newpath) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int rename(const char *oldpath, const char *newpath) __attribute__((weak));
+int rename(const char *oldpath, const char *newpath) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;  
+}
+
+int nanosleep(const struct timespec *req, struct timespec *rem) __attribute__((weak));
+int nanosleep(const struct timespec *req, struct timespec *rem) {
+  return 0;
+}
+
+/* XXX why can't I call this internally? */
+int clock_gettime(clockid_t clk_id, struct timespec *res) __attribute__((weak));
+int clock_gettime(clockid_t clk_id, struct timespec *res) {
+  /* Fake */
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  res->tv_sec = tv.tv_sec;
+  res->tv_nsec = tv.tv_usec * 1000;
+  return 0;
+}
+
+int clock_settime(clockid_t clk_id, const struct timespec *res) __attribute__((weak));
+int clock_settime(clockid_t clk_id, const struct timespec *res) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+time_t time(time_t *t) {
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  if (t)
+    *t = tv.tv_sec;
+  return tv.tv_sec;
+}
+
+clock_t times(struct tms *buf) {
+  /* Fake */
+  buf->tms_utime = 0;
+  buf->tms_stime = 0;
+  buf->tms_cutime = 0;
+  buf->tms_cstime = 0;
+  return 0;
+}
+
+struct utmpx *getutxent(void) __attribute__((weak));
+struct utmpx *getutxent(void) {
+  return (struct utmpx*) getutent();
+}
+
+void setutxent(void) __attribute__((weak));
+void setutxent(void) {
+  setutent();
+}
+
+void endutxent(void) __attribute__((weak));
+void endutxent(void) {
+  endutent();
+}
+
+int utmpxname(const char *file) __attribute__((weak));
+int utmpxname(const char *file) {
+  utmpname(file);
+  return 0;
+}
+
+int euidaccess(const char *pathname, int mode) __attribute__((weak));
+int euidaccess(const char *pathname, int mode) {
+  return access(pathname, mode);
+}
+
+int eaccess(const char *pathname, int mode) __attribute__((weak));
+int eaccess(const char *pathname, int mode) {
+  return euidaccess(pathname, mode);
+}
+
+int group_member (gid_t __gid) __attribute__((weak));
+int group_member (gid_t __gid) {
+  return ((__gid == getgid ()) || (__gid == getegid ()));
+}
+
+int utime(const char *filename, const struct utimbuf *buf) __attribute__((weak));
+int utime(const char *filename, const struct utimbuf *buf) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int utimes(const char *filename, const struct timeval times[2]) __attribute__((weak));
+int utimes(const char *filename, const struct timeval times[2]) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int futimes(int fd, const struct timeval times[2]) __attribute__((weak));
+int futimes(int fd, const struct timeval times[2]) {
+  klee_warning("ignoring (EBADF)");
+  errno = EBADF;
+  return -1;
+}
+
+int strverscmp (__const char *__s1, __const char *__s2) {
+  return strcmp(__s1, __s2); /* XXX no doubt this is bad */
+}
+
+unsigned int gnu_dev_major(unsigned long long int __dev) __attribute__((weak));
+unsigned int gnu_dev_major(unsigned long long int __dev) {
+  return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff);
+}
+
+unsigned int gnu_dev_minor(unsigned long long int __dev) __attribute__((weak));
+unsigned int gnu_dev_minor(unsigned long long int __dev) {
+  return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff);
+}
+
+unsigned long long int gnu_dev_makedev(unsigned int __major, unsigned int __minor) __attribute__((weak));
+unsigned long long int gnu_dev_makedev(unsigned int __major, unsigned int __minor) {
+  return ((__minor & 0xff) | ((__major & 0xfff) << 8)
+	  | (((unsigned long long int) (__minor & ~0xff)) << 12)
+	  | (((unsigned long long int) (__major & ~0xfff)) << 32));
+}
+
+char *canonicalize_file_name (const char *name) __attribute__((weak));
+char *canonicalize_file_name (const char *name) {
+  char *res = malloc(PATH_MAX);
+  char *rp_res = realpath(name, res);
+  if (!rp_res)
+    free(res);
+  return rp_res;
+}
+
+int getloadavg(double loadavg[], int nelem) __attribute__((weak));
+int getloadavg(double loadavg[], int nelem) {
+  klee_warning("ignoring (-1 result)");
+  return -1;
+}
+
+pid_t wait(int *status) __attribute__((weak));
+pid_t wait(int *status) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t wait3(int *status, int options, struct rusage *rusage) __attribute__((weak));
+pid_t wait3(int *status, int options, struct rusage *rusage) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) __attribute__((weak));
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t waitpid(pid_t pid, int *status, int options) __attribute__((weak));
+pid_t waitpid(pid_t pid, int *status, int options) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) __attribute__((weak));
+pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) {
+  klee_warning("ignoring (ECHILD)");
+  errno = ECHILD;
+  return -1;
+}
+
+/* ACL */
+
+/* FIXME: We need autoconf magic for this. */
+
+#ifdef HAVE_SYS_ACL_H
+
+#include <sys/acl.h>
+
+int acl_delete_def_file(const char *path_p) __attribute__((weak));
+int acl_delete_def_file(const char *path_p) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int acl_extended_file(const char path_p) __attribute__((weak));
+int acl_extended_file(const char path_p) {
+  klee_warning("ignoring (ENOENT)");
+  errno = ENOENT;
+  return -1;
+}
+
+int acl_entries(acl_t acl) __attribute__((weak));
+int acl_entries(acl_t acl) {
+  klee_warning("ignoring (EINVAL)");
+  errno = EINVAL;
+  return -1;
+}
+
+acl_t acl_from_mode(mode_t mode) __attribute__((weak));
+acl_t acl_from_mode(mode_t mode) {
+  klee_warning("ignoring (ENOMEM)");
+  errno = ENOMEM;
+  return NULL;
+}
+
+acl_t acl_get_fd(int fd) __attribute__((weak));
+acl_t acl_get_fd(int fd) {
+  klee_warning("ignoring (ENOMEM)");
+  errno = ENOMEM;
+  return NULL;
+}
+
+acl_t acl_get_file(const char *pathname, acl_type_t type) __attribute__((weak));
+acl_t acl_get_file(const char *pathname, acl_type_t type) {
+  klee_warning("ignoring (ENONMEM)");
+  errno = ENOMEM;
+  return NULL;
+}
+
+int acl_set_fd(int fd, acl_t acl) __attribute__((weak));
+int acl_set_fd(int fd, acl_t acl) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) __attribute__((weak));
+int acl_set_file(const char *path_p, acl_type_t type, acl_t acl) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int acl_free(void *obj_p) __attribute__((weak));
+int acl_free(void *obj_p) {
+  klee_warning("ignoring (EINVAL)");
+  errno = EINVAL;
+  return -1;
+}
+
+#endif
+
+int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) __attribute__((weak));
+int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int umount(const char *target) __attribute__((weak));
+int umount(const char *target) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int umount2(const char *target, int flags) __attribute__((weak));
+int umount2(const char *target, int flags) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int swapon(const char *path, int swapflags) __attribute__((weak));
+int swapon(const char *path, int swapflags) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int swapoff(const char *path) __attribute__((weak));
+int swapoff(const char *path) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setgid(gid_t gid) __attribute__((weak));
+int setgid(gid_t gid) {
+  klee_warning("silently ignoring (returning 0)");
+  return 0;
+}
+
+int setgroups(size_t size, const gid_t *list) __attribute__((weak));
+int setgroups(size_t size, const gid_t *list) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int sethostname(const char *name, size_t len) __attribute__((weak));
+int sethostname(const char *name, size_t len) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setpgid(pid_t pid, pid_t pgid) __attribute__((weak));
+int setpgid(pid_t pid, pid_t pgid) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setpgrp(void) __attribute__((weak));
+int setpgrp(void) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setpriority(__priority_which_t which, id_t who, int prio) __attribute__((weak));
+int setpriority(__priority_which_t which, id_t who, int prio) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid) __attribute__((weak));
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid) __attribute__((weak));
+int setresuid(uid_t ruid, uid_t euid, uid_t suid) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlim) __attribute__((weak));
+int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlim) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setrlimit64(__rlimit_resource_t resource, const struct rlimit64 *rlim) __attribute__((weak));
+int setrlimit64(__rlimit_resource_t resource, const struct rlimit64 *rlim) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+pid_t setsid(void) __attribute__((weak));
+pid_t setsid(void) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz) __attribute__((weak));
+int settimeofday(const struct timeval *tv, const struct timezone *tz) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int setuid(uid_t uid) __attribute__((weak));
+int setuid(uid_t uid) {
+  klee_warning("silently ignoring (returning 0)");
+  return 0;
+}
+
+int reboot(int flag) __attribute__((weak));
+int reboot(int flag) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int mlock(const void *addr, size_t len) __attribute__((weak));
+int mlock(const void *addr, size_t len) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int munlock(const void *addr, size_t len) __attribute__((weak));
+int munlock(const void *addr, size_t len) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+int pause(void) __attribute__((weak));
+int pause(void) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+ssize_t readahead(int fd, off64_t *offset, size_t count) __attribute__((weak));
+ssize_t readahead(int fd, off64_t *offset, size_t count) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
+
+void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) __attribute__((weak));
+void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return (void*) -1;
+}
+
+void *mmap64(void *start, size_t length, int prot, int flags, int fd, off64_t offset) __attribute__((weak));
+void *mmap64(void *start, size_t length, int prot, int flags, int fd, off64_t offset) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return (void*) -1;
+}
+
+int munmap(void*start, size_t length) __attribute__((weak));
+int munmap(void*start, size_t length) {
+  klee_warning("ignoring (EPERM)");
+  errno = EPERM;
+  return -1;
+}
diff --git a/runtime/POSIX/testing-dir/a b/runtime/POSIX/testing-dir/a
new file mode 120000
index 00000000..dc1dc0cd
--- /dev/null
+++ b/runtime/POSIX/testing-dir/a
@@ -0,0 +1 @@
+/dev/null
\ No newline at end of file
diff --git a/runtime/POSIX/testing-dir/b b/runtime/POSIX/testing-dir/b
new file mode 120000
index 00000000..b9251ec6
--- /dev/null
+++ b/runtime/POSIX/testing-dir/b
@@ -0,0 +1 @@
+/dev/random
\ No newline at end of file
diff --git a/runtime/POSIX/testing-dir/c b/runtime/POSIX/testing-dir/c
new file mode 100755
index 00000000..2b45f6a5
--- /dev/null
+++ b/runtime/POSIX/testing-dir/c
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Hello world!"
diff --git a/runtime/POSIX/testing-dir/d b/runtime/POSIX/testing-dir/d
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/runtime/POSIX/testing-dir/d
diff --git a/runtime/POSIX/testing-env b/runtime/POSIX/testing-env
new file mode 100644
index 00000000..5a6e8eb8
--- /dev/null
+++ b/runtime/POSIX/testing-env
@@ -0,0 +1,27 @@
+# This file is sourced prior to running the testing environment, make
+# sure to quote things.
+
+export TERM="xterm"
+export SHELL="/bin/bash"
+export LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.flac=01;35:*.mp3=01;35:*.mpc=01;35:*.ogg=01;35:*.wav=01;35:"
+export PATH="/usr/local/bin:/usr/bin:/bin"
+export COLORTERM="gnome-terminal"
+export LC_ALL=C
+export TABSIZE=8
+export COLUMNS=80
+
+#       1 BLOCK_SIZE
+#       2 COLUMNS
+#       1 DF_BLOCK_SIZE
+#       1 DU_BLOCK_SIZE
+#       1 HOME
+#       1 LS_BLOCK_SIZE
+#       1 LS_COLORS
+#      11 POSIXLY_CORRECT
+#       1 QUOTING_STYLE
+#       3 SHELL
+#       4 SIMPLE_BACKUP_SUFFIX
+#       1 TABSIZE
+#       2 TERM
+#       2 TIME_STYLE
+#       4 TMPDIR
diff --git a/runtime/Runtest/Makefile b/runtime/Runtest/Makefile
new file mode 100644
index 00000000..dd21c4a9
--- /dev/null
+++ b/runtime/Runtest/Makefile
@@ -0,0 +1,19 @@
+#===-- runtime/Runtest/Makefile ----------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+USEDLIBS=kleeBasic.a
+LIBRARYNAME=kleeRuntest
+SHARED_LIBRARY=1
+LINK_LIBS_IN_SHARED = 1
+DONT_BUILD_RELINKED = 1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/Runtest/intrinsics.c b/runtime/Runtest/intrinsics.c
new file mode 100644
index 00000000..1a2fd030
--- /dev/null
+++ b/runtime/Runtest/intrinsics.c
@@ -0,0 +1,154 @@
+//===-- intrinsics.c ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/* Straight C for linking simplicity */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "klee/klee.h"
+
+#include "klee/Internal/ADT/BOut.h"
+
+static BOut *testData = 0;
+static unsigned testPosition = 0;
+
+static unsigned char rand_byte(void) {
+  unsigned x = rand();
+  x ^= x>>16;
+  x ^= x>>8;
+  return x & 0xFF;
+}
+
+void klee_make_symbolic_name(void *array, unsigned nbytes, const char *name) {
+  static int rand_init = -1;
+
+  if (rand_init == -1) {
+    if (getenv("KLEE_RANDOM")) {
+      struct timeval tv;
+      gettimeofday(&tv, 0);
+      rand_init = 1;
+      srand(tv.tv_sec ^ tv.tv_usec);
+    } else {
+      rand_init = 0;
+    }
+  }
+
+  if (rand_init) {
+    if (!strcmp(name,"syscall_a0")) {
+      unsigned long long *v = array;
+      assert(nbytes == 8);
+      *v = rand() % 69;
+    } else {
+      char *c = array;
+      unsigned i;
+      for (i=0; i<nbytes; i++)
+        c[i] = rand_byte();
+    }
+    return;
+  }
+
+  if (!testData) {
+    char tmp[256];
+    char *name = getenv("KLEE_RUNTEST");
+
+    if (!name) {
+      fprintf(stdout, "KLEE-RUNTIME: KLEE_RUNTEST not set, please enter .bout path: ");
+      fflush(stdout);
+      name = tmp;
+      if (!fgets(tmp, sizeof tmp, stdin) || !strlen(tmp)) {
+        fprintf(stderr, "KLEE-RUNTIME: cannot replay, no KLEE_RUNTEST or user input\n");
+        exit(1);
+      }
+      tmp[strlen(tmp)-1] = '\0'; /* kill newline */
+    }
+    testData = bOut_fromFile(name);
+    if (!testData) {
+      fprintf(stderr, "KLEE-RUNTIME: unable to open .bout file\n");
+      exit(1);
+    }
+  }
+
+  if (testPosition >= testData->numObjects) {
+    fprintf(stderr, "ERROR: out of inputs, using zero\n");
+    memset(array, 0, nbytes);
+  } else {
+    BOutObject *o = &testData->objects[testPosition++];
+    memcpy(array, o->bytes, nbytes<o->numBytes ? nbytes : o->numBytes);
+    if (nbytes != o->numBytes) {
+      fprintf(stderr, "ERROR: object sizes differ\n");
+      if (o->numBytes < nbytes) 
+        memset((char*) array + o->numBytes, 0, nbytes - o->numBytes);
+    }
+  }
+}
+
+void klee_make_symbolic(void *array, unsigned nbytes) {
+  klee_make_symbolic_name(array, nbytes, "unnamed");
+}
+
+void *klee_malloc_n(unsigned nelems, unsigned size, unsigned alignment) {
+#if 1
+  return mmap((void*) 0x90000000, nelems*size, PROT_READ|PROT_WRITE, 
+              MAP_PRIVATE
+#ifdef MAP_ANONYMOUS
+              |MAP_ANONYMOUS
+#endif
+              , 0, 0);
+#else
+  char *buffer = malloc(nelems*size + alignment - 1);
+  buffer += (alignment - (long)buffer % alignment);
+  return buffer;
+#endif
+}
+
+void klee_silent_exit(int x) {
+  exit(x);
+}
+
+unsigned klee_choose(unsigned n) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if(x >= n)
+    fprintf(stderr, "ERROR: max = %d, got = %d\n", n, x);
+  assert(x < n);
+  return x;
+}
+
+void klee_assume(unsigned x) {
+  if (!x) {
+    fprintf(stderr, "ERROR: invalid klee_assume\n");
+  }
+}
+
+unsigned klee_get_value(unsigned x) {
+  return x;
+}
+
+int klee_range_name(int begin, int end, const char* name) {
+  int x;
+  klee_make_symbolic_name(&x, sizeof x, name);
+  if (x<begin || x>=end) {
+    fprintf(stderr, 
+            "KLEE: ERROR: invalid klee_range(%u,%u,%s) value, got: %u\n", 
+            begin, end, name, x);
+    abort();
+  }
+  return x;
+}
+
+/* not sure we should even define.  is for debugging. */
+void klee_print_expr(const char *msg, ...) { }
+
+void klee_set_forking(unsigned enable) { }
diff --git a/runtime/klee-libc/Makefile b/runtime/klee-libc/Makefile
new file mode 100755
index 00000000..bcd61f73
--- /dev/null
+++ b/runtime/klee-libc/Makefile
@@ -0,0 +1,19 @@
+#===-- runtime/klee-libc/Makefile --------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+
+LIBRARYNAME=klee-libc
+DONT_BUILD_RELINKED=1
+BYTECODE_LIBRARY=1
+# Don't strip debug info from the module.
+DEBUG_RUNTIME=1
+NO_PEDANTIC=1
+
+include $(LEVEL)/Makefile.common
diff --git a/runtime/klee-libc/__cxa_atexit.c b/runtime/klee-libc/__cxa_atexit.c
new file mode 100644
index 00000000..e7982848
--- /dev/null
+++ b/runtime/klee-libc/__cxa_atexit.c
@@ -0,0 +1,49 @@
+//===-- __cxa_atexit.c ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/klee.h"
+
+#define MAX_ATEXIT 128
+
+static struct {
+  void (*fn)(void*);
+  void *arg;
+  void *dso_handle;
+} AtExit[MAX_ATEXIT];
+static unsigned NumAtExit = 0;
+
+static void RunAtExit(void) __attribute__((destructor));
+static void RunAtExit(void) {
+  unsigned i;
+
+  for (i=0; i<NumAtExit; ++i)
+    AtExit[i].fn(AtExit[i].arg);
+}
+
+int __cxa_atexit(void (*fn)(void*),
+                 void *arg,
+                 void *dso_handle) {
+  klee_warning_once("FIXME: __cxa_atexit being ignored");
+  
+  /* Better to just report an error here than return 1 (the defined
+   * semantics).
+   */
+  if (NumAtExit == MAX_ATEXIT)
+    klee_report_error(__FILE__,
+                      __LINE__,
+                      "__cxa_atexit: no room in array!",
+                      "exec");
+  
+  AtExit[NumAtExit].fn = fn;
+  AtExit[NumAtExit].arg = arg;
+  ++NumAtExit;
+  
+  return 0;
+}
+
diff --git a/runtime/klee-libc/abort.c b/runtime/klee-libc/abort.c
new file mode 100644
index 00000000..0332d095
--- /dev/null
+++ b/runtime/klee-libc/abort.c
@@ -0,0 +1,16 @@
+//===-- abort.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#include "klee/klee.h"
+
+void abort(void) {
+  klee_abort();
+}
diff --git a/runtime/klee-libc/atexit.c b/runtime/klee-libc/atexit.c
new file mode 100644
index 00000000..c71b2cd6
--- /dev/null
+++ b/runtime/klee-libc/atexit.c
@@ -0,0 +1,16 @@
+//===-- atexit.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int __cxa_atexit(void (*fn)(void*),
+                 void *arg,
+                 void *dso_handle);
+
+int atexit(void (*fn)(void)) {
+  return __cxa_atexit((void(*)(void*)) fn, 0, 0);
+}
diff --git a/runtime/klee-libc/atoi.c b/runtime/klee-libc/atoi.c
new file mode 100644
index 00000000..ab97bfbb
--- /dev/null
+++ b/runtime/klee-libc/atoi.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdlib.h>
+
+int atoi(const char *str) {
+  return (int)strtol(str, (char **)NULL, 10);
+}
diff --git a/runtime/klee-libc/calloc.c b/runtime/klee-libc/calloc.c
new file mode 100644
index 00000000..30b88b30
--- /dev/null
+++ b/runtime/klee-libc/calloc.c
@@ -0,0 +1,46 @@
+//===-- calloc.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+#include <string.h>
+
+// DWD - I prefer to be internal
+#if 0
+void *calloc(size_t nmemb, size_t size) {
+	unsigned nbytes = nmemb * size;
+	void *addr = malloc(nbytes);
+	if(addr)
+		memset(addr, 0, nbytes);
+	return addr;
+}
+// Always reallocate.
+void *realloc(void *ptr, size_t nbytes) {
+	if(!ptr)
+		return malloc(nbytes);
+
+	if(!nbytes) {
+		free(ptr);
+		return 0;
+	}
+
+        unsigned copy_nbytes = klee_get_obj_size(ptr);
+	//printf("REALLOC: current object = %d bytes!\n", copy_nbytes);
+
+	void *addr = malloc(nbytes);
+	if(addr) {
+		// shrinking
+		if(copy_nbytes > nbytes)
+			copy_nbytes = nbytes;
+		//printf("REALLOC: copying = %d bytes!\n", copy_nbytes);
+		memcpy(addr, ptr, copy_nbytes);
+		free(ptr);
+	} 
+	return addr;
+}
+#endif
diff --git a/runtime/klee-libc/htonl.c b/runtime/klee-libc/htonl.c
new file mode 100644
index 00000000..cec2d0f5
--- /dev/null
+++ b/runtime/klee-libc/htonl.c
@@ -0,0 +1,49 @@
+//===-- htonl.c -----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdint.h>
+
+#undef htons
+#undef htonl
+#undef ntohs
+#undef ntohl
+
+// Make sure we can recognize the endianness.
+#if (!defined(BYTE_ORDER) || !defined(BIG_ENDIAN) || !defined(LITTLE_ENDIAN))
+#error "Unknown platform endianness!"
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+uint16_t htons(uint16_t v) {
+  return (v >> 8) | (v << 8);
+}
+uint32_t htonl(uint32_t v) {
+  return htons(v >> 16) | (htons((uint16_t) v) << 16);
+}
+
+#else
+
+uint16_t htons(uint16_t v) {
+  return v;
+}
+uint32_t htonl(uint32_t v) {
+  return v;
+}
+
+#endif
+
+uint16_t ntohs(uint32_t v) {
+  return htons(v);
+}
+uint32_t ntohl(uint32_t v) {
+  return htonl(v);
+}
diff --git a/runtime/klee-libc/klee-choose.c b/runtime/klee-libc/klee-choose.c
new file mode 100644
index 00000000..106b4f89
--- /dev/null
+++ b/runtime/klee-libc/klee-choose.c
@@ -0,0 +1,20 @@
+//===-- klee-choose.c -----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "klee/klee.h"
+
+unsigned klee_choose(unsigned n) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+
+  // NB: this will *not* work if they don't compare to n values.
+  if(x >= n)
+    klee_silent_exit(0);
+  return x;
+}
diff --git a/runtime/klee-libc/memchr.c b/runtime/klee-libc/memchr.c
new file mode 100644
index 00000000..fe0670a7
--- /dev/null
+++ b/runtime/klee-libc/memchr.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+void *
+memchr(s, c, n)
+	const void *s;
+	int c;
+	size_t n;
+{
+	if (n != 0) {
+		const unsigned char *p = s;
+
+		do {
+			if (*p++ == c)
+				return ((void *)(p - 1));
+		} while (--n != 0);
+	}
+	return (NULL);
+}
diff --git a/runtime/klee-libc/memcmp.c b/runtime/klee-libc/memcmp.c
new file mode 100644
index 00000000..7562f4f7
--- /dev/null
+++ b/runtime/klee-libc/memcmp.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+/*
+ * Compare memory regions.
+ */
+int memcmp(const void *s1, const void *s2, size_t n) {
+  if (n != 0) {
+    const unsigned char *p1 = s1, *p2 = s2;
+    
+    do {
+      if (*p1++ != *p2++) {
+        return (*--p1 - *--p2);
+      }
+    } while (--n != 0);
+  }
+  return (0);
+}
diff --git a/runtime/klee-libc/memcpy.c b/runtime/klee-libc/memcpy.c
new file mode 100644
index 00000000..14b98ce6
--- /dev/null
+++ b/runtime/klee-libc/memcpy.c
@@ -0,0 +1,19 @@
+//===-- memcpy.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return destaddr;
+}
diff --git a/runtime/klee-libc/memmove.c b/runtime/klee-libc/memmove.c
new file mode 100644
index 00000000..c6e1ada9
--- /dev/null
+++ b/runtime/klee-libc/memmove.c
@@ -0,0 +1,28 @@
+//===-- memmove.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memmove(void *dst, const void *src, size_t count) {
+  char *a = dst;
+  const char *b = src;
+
+  if (src == dst)
+    return dst;
+
+  if (src>dst) {
+    while (count--) *a++ = *b++;
+  } else {
+    a+=count-1;
+    b+=count-1;
+    while (count--) *a-- = *b--;
+  }
+
+  return dst;
+}
diff --git a/runtime/klee-libc/mempcpy.c b/runtime/klee-libc/mempcpy.c
new file mode 100644
index 00000000..6327e748
--- /dev/null
+++ b/runtime/klee-libc/mempcpy.c
@@ -0,0 +1,19 @@
+//===-- mempcpy.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *mempcpy(void *destaddr, void const *srcaddr, unsigned int len) {
+  char *dest = destaddr;
+  char const *src = srcaddr;
+
+  while (len-- > 0)
+    *dest++ = *src++;
+  return dest;
+}
diff --git a/runtime/klee-libc/memset.c b/runtime/klee-libc/memset.c
new file mode 100644
index 00000000..ee9ecb87
--- /dev/null
+++ b/runtime/klee-libc/memset.c
@@ -0,0 +1,17 @@
+//===-- memset.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+void *memset(void * dst, int s, size_t count) {
+    char * a = dst;
+    while (count-- > 0)
+      *a++ = s;
+    return dst;
+}
diff --git a/runtime/klee-libc/putchar.c b/runtime/klee-libc/putchar.c
new file mode 100644
index 00000000..f3fcf01d
--- /dev/null
+++ b/runtime/klee-libc/putchar.c
@@ -0,0 +1,17 @@
+//===-- putchar.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <unistd.h>
+
+int putchar(int c) {
+  char x = c;
+  write(1, &x, 1);
+  return 1;
+}
diff --git a/runtime/klee-libc/stpcpy.c b/runtime/klee-libc/stpcpy.c
new file mode 100644
index 00000000..1f774f3d
--- /dev/null
+++ b/runtime/klee-libc/stpcpy.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999
+ *	David E. O'Brien
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+/* Defeat object checking stuff. */
+#undef stpcpy
+
+char *
+stpcpy(char * to, const char * from)
+{
+
+	for (; (*to = *from); ++from, ++to);
+	return(to);
+}
diff --git a/runtime/klee-libc/strcat.c b/runtime/klee-libc/strcat.c
new file mode 100644
index 00000000..195e9460
--- /dev/null
+++ b/runtime/klee-libc/strcat.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+/* Defeat object checking stuff. */
+#undef strcat
+
+char * strcat(char * s, const char * append) {
+	char *save = s;
+
+	for (; *s; ++s)
+		;
+	while ((*s++ = *append++))
+		;
+	return(save);
+}
diff --git a/runtime/klee-libc/strchr.c b/runtime/klee-libc/strchr.c
new file mode 100644
index 00000000..33f97bea
--- /dev/null
+++ b/runtime/klee-libc/strchr.c
@@ -0,0 +1,23 @@
+//===-- strchr.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+char *strchr(const char *p, int ch) {
+  char c;
+
+  c = ch;
+  for (;; ++p) {
+    if (*p == c) {
+      return ((char *)p);
+    } else if (*p == '\0') {
+      return 0;
+    }
+  }
+  /* NOTREACHED */  
+  return 0;
+}
diff --git a/runtime/klee-libc/strcmp.c b/runtime/klee-libc/strcmp.c
new file mode 100644
index 00000000..6b8c4e85
--- /dev/null
+++ b/runtime/klee-libc/strcmp.c
@@ -0,0 +1,14 @@
+//===-- strcmp.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int strcmp(const char *a, const char *b) {
+  while (*a && *a == *b)
+    ++a, ++b;
+  return *a - *b;
+}
diff --git a/runtime/klee-libc/strcoll.c b/runtime/klee-libc/strcoll.c
new file mode 100644
index 00000000..73d59f89
--- /dev/null
+++ b/runtime/klee-libc/strcoll.c
@@ -0,0 +1,15 @@
+//===-- strcoll.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+// according to the manpage, this is equiv in the POSIX/C locale.
+int strcoll(const char *s1, const char *s2) {
+  return strcmp(s1,s2);
+}
diff --git a/runtime/klee-libc/strcpy.c b/runtime/klee-libc/strcpy.c
new file mode 100644
index 00000000..0fbaf9a7
--- /dev/null
+++ b/runtime/klee-libc/strcpy.c
@@ -0,0 +1,17 @@
+//===-- strcpy.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+char *strcpy(char *to, const char *from) {
+  char *start = to;
+
+  while ((*to = *from))
+    ++to, ++from;
+
+  return start;
+}
diff --git a/runtime/klee-libc/strlen.c b/runtime/klee-libc/strlen.c
new file mode 100644
index 00000000..e298410c
--- /dev/null
+++ b/runtime/klee-libc/strlen.c
@@ -0,0 +1,17 @@
+//===-- strlen.c ----------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+size_t strlen(const char *str) {
+  const char *s = str;
+  while (*s)
+    ++s;
+  return s - str;
+}
diff --git a/runtime/klee-libc/strncmp.c b/runtime/klee-libc/strncmp.c
new file mode 100644
index 00000000..a8dc3749
--- /dev/null
+++ b/runtime/klee-libc/strncmp.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+
+int strncmp(const char *s1, const char *s2, size_t n)
+{
+
+	if (n == 0)
+		return (0);
+	do {
+		if (*s1 != *s2++)
+			return (*(unsigned char *)s1 -
+				*(unsigned char *)(s2 - 1));
+		if (*s1++ == 0)
+			break;
+	} while (--n != 0);
+	return (0);
+}
diff --git a/runtime/klee-libc/strncpy.c b/runtime/klee-libc/strncpy.c
new file mode 100644
index 00000000..62ab7993
--- /dev/null
+++ b/runtime/klee-libc/strncpy.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+/*
+ * Copy src to dst, truncating or null-padding to always copy n bytes.
+ * Return dst.
+ */
+char * strncpy(char * dst, const char * src, size_t n)
+{
+	if (n != 0) {
+		char *d = dst;
+		const char *s = src;
+
+		do {
+			if ((*d++ = *s++) == 0) {
+				/* NUL pad the remaining n-1 bytes */
+				while (--n != 0)
+					*d++ = 0;
+				break;
+			}
+		} while (--n != 0);
+	}
+	return (dst);
+}
diff --git a/runtime/klee-libc/strrchr.c b/runtime/klee-libc/strrchr.c
new file mode 100644
index 00000000..01128b48
--- /dev/null
+++ b/runtime/klee-libc/strrchr.c
@@ -0,0 +1,21 @@
+//===-- strrchr.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+char *strrchr(const char *t, int c) {
+  char ch;
+  const char *l=0;
+
+  ch = c;
+  for (;;) {
+    if (*t == ch) l=t; if (!*t) return (char*)l; ++t;
+  }
+  return (char*)l;
+}
diff --git a/runtime/klee-libc/strtol.c b/runtime/klee-libc/strtol.c
new file mode 100644
index 00000000..3be7fff3
--- /dev/null
+++ b/runtime/klee-libc/strtol.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long
+strtol(const char * nptr, char ** endptr, int base)
+{
+	const char *s;
+	unsigned long acc;
+	char c;
+	unsigned long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+	if (base < 2 || base > 36)
+		goto noconv;
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for longs is
+	 * [-2147483648..2147483647] and the input base is 10,
+	 * cutoff will be set to 214748364 and cutlim to either
+	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+	 * the number is too big, and we will return a range error.
+	 *
+	 * Set 'any' if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX
+	    : LONG_MAX;
+	cutlim = cutoff % base;
+	cutoff /= base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = neg ? LONG_MIN : LONG_MAX;
+		errno = ERANGE;
+	} else if (!any) {
+noconv:
+		errno = EINVAL;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/runtime/klee-libc/strtoul.c b/runtime/klee-libc/strtoul.c
new file mode 100644
index 00000000..f23d5b54
--- /dev/null
+++ b/runtime/klee-libc/strtoul.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(const char * nptr, char ** endptr, int base)
+{
+	const char *s;
+	unsigned long acc;
+	char c;
+	unsigned long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * See strtol for comments as to the logic used.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+	if (base < 2 || base > 36)
+		goto noconv;
+
+	cutoff = ULONG_MAX / base;
+	cutlim = ULONG_MAX % base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULONG_MAX;
+		errno = ERANGE;
+	} else if (!any) {
+noconv:
+		errno = EINVAL;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/runtime/klee-libc/tolower.c b/runtime/klee-libc/tolower.c
new file mode 100644
index 00000000..265f5deb
--- /dev/null
+++ b/runtime/klee-libc/tolower.c
@@ -0,0 +1,14 @@
+//===-- tolower.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int tolower(int ch) {
+  if ( (unsigned int)(ch - 'A') < 26u )
+    ch -= 'A' - 'a';
+  return ch;
+}
diff --git a/runtime/klee-libc/toupper.c b/runtime/klee-libc/toupper.c
new file mode 100644
index 00000000..37e5f9d6
--- /dev/null
+++ b/runtime/klee-libc/toupper.c
@@ -0,0 +1,14 @@
+//===-- toupper.c ---------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int toupper(int ch) {
+  if ( (unsigned int)(ch - 'a') < 26u )
+    ch += 'A' - 'a';
+  return ch;
+}
diff --git a/scripts/IStatsMerge.py b/scripts/IStatsMerge.py
new file mode 100755
index 00000000..1bd61c3e
--- /dev/null
+++ b/scripts/IStatsMerge.py
@@ -0,0 +1,175 @@
+#!/usr/bin/python
+
+from __future__ import division
+
+import sys, os
+
+class MergeError(Exception):
+    pass
+
+def checkAssemblies(directories):
+    def read(d):
+        try:
+            return open(os.path.join(d,'assembly.ll')).read()
+        except:
+            raise MergeError("unable to open assembly for: %s"%(`d`,))
+    
+    reference = read(directories[0])
+    for d in directories[1:]:
+        if reference != read(d):
+            return False
+    return True
+
+def allEqual(l):
+    return not [i for i in l if i!=l[0]]
+
+def merge(inputs, output, outputDir):
+    inputs = [[None,iter(i)] for i in inputs]
+
+    def getLine(elt):
+        la,i = elt
+        if la is None:
+            try:
+                ln = i.next()
+            except StopIteration:
+                ln = None
+            except:
+                raise MergeError("unexpected IO error")
+            return ln
+        else:
+            elt[0] = None
+            return la
+    def getLines():
+        return map(getLine,inputs)
+    def putback(ln,elt):
+        assert elt[0] is None
+        elt[0] = ln
+        
+    events = None
+    
+    # read header (up to ob=)
+    while 1:
+        lns = getLines()
+        ln = lns[0]
+        if ln.startswith('ob='):
+            if [l for l in lns if not l.startswith('ob=')]:
+                raise MergeError("headers differ")
+            output.write('ob=%s\n'%(os.path.join(outputDir,'assembly.ll'),))
+            break
+        else:
+            if ln.startswith('positions:'):
+                if ln!='positions: instr line\n':
+                    raise MergeError("unexpected 'positions' directive")
+            elif ln.startswith('events:'):
+                events = ln[len('events: '):].strip().split(' ')
+            if not allEqual(lns):
+                raise MergeError("headers differ")
+            output.write(ln)
+
+    if events is None:
+        raise MergeError('missing events directive')
+    boolTypes = set(['Icov','Iuncov'])
+    numEvents = len(events)
+    eventTypes = [e in boolTypes for e in events]
+
+    def mergeStats(datas):
+        if not allEqual([d[:2] for d in datas]):
+            raise MergeError("instruction or line specifications differ")
+        elif [d for d in datas if len(d)!=numEvents+2]:
+            raise MergeError("statistics differ in event counts")
+        
+        result = [datas[0][0],datas[0][1]]
+        for i,ev in enumerate(events):
+            s = sum([d[i+2] for d in datas])
+            if ev=='Icov':
+                result.append(max([d[i+2] for d in datas])) # true iff any are non-zero
+            elif ev=='Iuncov':
+                result.append(min([d[i+2] for d in datas])) # true iff any are non-zero
+            else:
+                result.append(s)
+        return result
+
+    def readCalls():
+        results = {}
+        for elt in inputs:
+            while 1:
+                ln = getLine(elt)
+                if ln is not None and (ln.startswith('cfl=') or ln.startswith('cfn=')):
+                    if ln.startswith('cfl='):
+                        cfl = ln
+                        cfn = getLine(elt)
+                        if not cfn.startswith('cfn='):
+                            raise MergeError("unexpected cfl directive without function")
+                    else:
+                        cfl = None
+                        cfn = ln
+                    target = getLine(elt)
+                    if not target.startswith('calls='):
+                        raise MergeError("unexpected cfn directive with calls")
+                    stat = map(int,getLine(elt).strip().split(' '))
+                    key = target
+                    existing = results.get(target)
+                    if existing is None:
+                        results[key] = [cfl,cfn,target,stat]
+                    else:
+                        if existing[0]!=cfl or existing[1]!=cfn:
+                            raise MergeError("multiple call descriptions for a single target")
+                        existing[3] = mergeStats([existing[3],stat])
+                else:
+                    putback(ln, elt)
+                    break
+        return results
+    
+    # read statistics
+    while 1:
+        lns = getLines()
+        ln = lns[0]
+        if ln is None:
+            if not allEqual(lns):
+                raise MergeError("unexpected end of input")
+            break
+        elif ln.startswith('fn') or ln.startswith('fl'):
+            if not allEqual(lns):
+                raise MergeError("files differ")
+            output.write(ln)
+        else:
+            # an actual statistic
+            data = [map(int,ln.strip().split(' ')) for ln in lns]
+            print >>output,' '.join(map(str,mergeStats(data)))
+
+            # read any associated calls
+            for cfl,cfn,calls,stat in readCalls().values():
+                if cfl is not None:
+                    output.write(cfl)
+                output.write(cfn)
+                output.write(calls)
+                print >>output,' '.join(map(str,stat))
+            
+def main(args):
+    from optparse import OptionParser
+    op = OptionParser("usage: %prog [options] directories+ output")
+    opts,args = op.parse_args()
+
+    output = args.pop()
+    directories = args
+
+    if len(directories)<=1:
+        op.error("incorrect number of arguments")
+
+    print 'Merging:',', '.join(directories)
+    print 'Into:',output
+
+    if not checkAssemblies(directories):
+        raise MergeError("executables differ")
+
+    if not os.path.exists(output):
+        os.mkdir(output)
+        
+    assembly = open(os.path.join(directories[0],'assembly.ll')).read()
+    open(os.path.join(output,'assembly.ll'),'w').write(assembly)
+
+    inputs = [open(os.path.join(d,'run.istats')) for d in directories]
+    merge(inputs, open(os.path.join(output,'run.istats'),'w'), output)
+
+if __name__=='__main__':
+    main(sys.argv)
diff --git a/scripts/IStatsSum.py b/scripts/IStatsSum.py
new file mode 100755
index 00000000..ce680c7b
--- /dev/null
+++ b/scripts/IStatsSum.py
@@ -0,0 +1,129 @@
+#!/usr/bin/python
+
+from __future__ import division
+
+import sys, os
+
+def getSummary(input):
+    inputs = [[None,iter(open(input))]]
+    def getLine(elt):
+        la,i = elt
+        if la is None:
+            try:
+                ln = i.next()
+            except StopIteration:
+                ln = None
+            except:
+                raise ValueError("unexpected IO error")
+            return ln
+        else:
+            elt[0] = None
+            return la
+    def getLines():
+        return map(getLine,inputs)
+    def putback(ln,elt):
+        assert elt[0] is None
+        elt[0] = ln
+        
+    events = None
+    
+    # read header (up to ob=)
+    while 1:
+        lns = getLines()
+        ln = lns[0]
+        if ln.startswith('ob='):
+            break
+        else:
+            if ln.startswith('positions:'):
+                if ln!='positions: instr line\n':
+                    raise ValueError("unexpected 'positions' directive")
+            elif ln.startswith('events:'):
+                events = ln[len('events: '):].strip().split(' ')
+
+    if events is None:
+        raise ValueError('missing events directive')
+    boolTypes = set(['Icov','Iuncov'])
+    numEvents = len(events)
+    eventTypes = [e in boolTypes for e in events]
+
+    def readCalls():
+        results = {}
+        for elt in inputs:
+            while 1:
+                ln = getLine(elt)
+                if ln is not None and (ln.startswith('cfl=') or ln.startswith('cfn=')):
+                    if ln.startswith('cfl='):
+                        cfl = ln
+                        cfn = getLine(elt)
+                        if not cfn.startswith('cfn='):
+                            raise ValueError("unexpected cfl directive without function")
+                    else:
+                        cfl = None
+                        cfn = ln
+                    target = getLine(elt)
+                    if not target.startswith('calls='):
+                        raise ValueError("unexpected cfn directive with calls")
+                    stat = map(int,getLine(elt).strip().split(' '))
+                    key = target
+                    existing = results.get(target)
+                    if existing is None:
+                        results[key] = [cfl,cfn,target,stat]
+                    else:
+                        if existing[0]!=cfl or existing[1]!=cfn:
+                            raise ValueError("multiple call descriptions for a single target")
+                        existing[3] = mergeStats([existing[3],stat])
+                else:
+                    putback(ln, elt)
+                    break
+        return results
+
+    summed = [0]*len(events)
+    
+    # read statistics
+    while 1:
+        lns = getLines()
+        ln = lns[0]
+        if ln is None:
+            break
+        elif ln.startswith('fn') or ln.startswith('fl'):
+            pass
+        elif ln.strip():
+            # an actual statistic
+            data = [map(int,ln.strip().split(' ')) for ln in lns][0]
+            summed = map(lambda a,b: a+b, data[2:], summed)
+
+            # read any associated calls
+            for cfl,cfn,calls,stat in readCalls().values():
+                pass
+
+    return events,summed
+    
+def main(args):
+    from optparse import OptionParser
+    op = OptionParser("usage: %prog [options] file")
+    opts,args = op.parse_args()
+
+    total = {}
+    for i in args:
+        events,summed = getSummary(i)
+        for e,s in zip(events,summed):
+            total[e] = total.get(e,[0,0])
+            total[e][0] += s
+            total[e][1] += 1
+        print '-- %s --'%(i,)
+        items = zip(events,summed)
+        items.sort()
+        for e,s in items:
+            print '%s: %s'%(e,s)
+
+    print '-- totals --'
+    items = total.items()
+    table = []    
+    for e,(s,N) in items:
+        table.append((str(e),str(s),str(N),str(s//N)))
+    w = map(lambda l: max(map(len,l)), zip(*table))
+    for (a,b,c,d) in table:
+        print '%-*s: %*s (in %*s files, avg: %*s)'%(w[0],a,w[1],b,w[2],c,w[3],d)
+
+if __name__=='__main__':
+    main(sys.argv)
diff --git a/scripts/PrintStats.py b/scripts/PrintStats.py
new file mode 100755
index 00000000..40994f87
--- /dev/null
+++ b/scripts/PrintStats.py
@@ -0,0 +1,231 @@
+#!/usr/bin/python
+
+from __future__ import division
+
+import sys
+import os
+    
+def getFile(dir):
+    return os.path.join(dir,'run.stats')
+
+def getLastRecord(dir):
+    f = open(getFile(dir))
+    try:
+        f.seek(-1024, 2)
+    except IOError:
+        pass # at beginning?
+    for ln in f.read(1024).split('\n')[::-1]:
+        ln = ln.strip()
+        if ln.startswith('(') and ln.endswith(')'):
+            if '(' in ln[1:]:
+                print >>sys.stderr, 'WARNING: corrupted line in file, out of disk space?'
+                ln = ln[ln.index('(',1):]
+            return eval(ln)
+    raise IOError
+
+
+class LazyEvalList:
+    def __init__(self, lines):
+        self.lines = lines
+
+    def __getitem__(self, index):
+        item = self.lines[index]
+        if isinstance(item,str):
+            item = self.lines[index] = eval(item)
+        return item
+
+    def __len__(self):
+        return len(self.lines)
+
+
+def getMatchedRecord(data,reference,key):
+    refKey = key(reference)
+    lo = 1 # header
+    hi = len(data)-1
+    while lo<hi:
+        mid = (lo+hi)//2
+        if key(data[mid])<=refKey:
+            lo = mid + 1
+        else:
+            hi = mid
+    return data[lo]
+
+
+def stripCommonPathPrefix(table, col):
+    paths = map(os.path.normpath, [row[col] for row in table])
+    pathElts = [p.split('/') for p in paths]
+    zipped = zip(*pathElts)
+    idx = 0
+    for idx,elts in enumerate(zipped):
+        if len(set(elts))>1:
+            break
+    paths = ['/'.join(elts[idx:]) for elts in pathElts]
+    for i,row in enumerate(table):
+        table[i] = row[:col] + (paths[i],) + row[col+1:]
+
+
+def getKeyIndex(keyName,labels):
+    def normalizedKey(key):
+        if key.endswith("(#)") or key.endswith("(%)") or key.endswith("(s)"):
+            key = key[:-3]
+        return key.lower()
+
+    keyIndex = None
+    for i,title in enumerate(labels):
+        if normalizedKey(title)==normalizedKey(keyName):
+            keyIndex = i
+            break
+    else:
+        raise ValueError,'invalid keyName to sort by: %s'%`keyName`
+    return keyIndex
+
+
+def sortTable(table, labels, keyName, ascending=False):   
+    indices = range(len(table))
+    keyIndex = getKeyIndex(keyName,labels)
+    indices.sort(key = lambda n: table[n][keyIndex])
+    if not ascending:
+        indices.reverse()
+    table[:] = [table[n] for n in indices]
+
+
+def printTable(table):
+    def strOrNone(ob):
+        if ob is None:
+            return ''
+        elif isinstance(ob,float):
+            return '%.2f'%ob
+        else:
+            return str(ob)
+    def printRow(row):
+        if row is None:
+            print header
+        else:
+            out.write('|')
+            for j,elt in enumerate(row):
+                if j:
+                    out.write(' %*s |'%(widths[j],elt))
+                else:
+                    out.write(' %-*s |'%(widths[j],elt))
+            out.write('\n')
+    maxLen = max([len(r) for r in table if r])
+    for i,row in enumerate(table):
+        if row:
+            table[i] = row + (None,)*(maxLen-len(row))
+    table = [row and map(strOrNone,row) or None for row in table]
+    tableLens = [map(len,row) for row in table if row]
+    from pprint import pprint
+    widths = map(max, zip(*tableLens))
+    out = sys.stdout
+    header = '-'*(sum(widths) + maxLen*3 + 1)
+    map(printRow, table)
+        
+
+def main(args):
+    from optparse import OptionParser
+    op = OptionParser(usage="usage: %prog [options] directories*",
+                      epilog=
+                      "LEGEND                                                                          " 
+                      "------                                                                          " 
+                      "Instrs:  Number of executed instructions                                        "
+                      "Time:    Total wall time (s)                                                    "
+                      "ICov:    Instruction coverage in the LLVM bitcode (%)                           "
+                      "BCov:    Branch coverage in the LLVM bitcode (%)                                "
+                      "ICount:  Total static instructions in the LLVM bitcode                          "
+                      "Solver:  Time spent in the constraint solver (%)                                "
+                      "States:  Number of currently active states                                      "
+                      "Mem:     Megabytes of memory currently used                                     "
+                      "Queries: Number of queries issued to STP                                        "
+                      "AvgQC:   Average number of query constructs per query                           "
+                      "Tcex:    Time spent in the counterexample caching code (%)                                        "
+                      "Tfork:   Time spent forking (%)                                                 ")
+
+    op.add_option('', '--print-more', dest='printMore',
+                  action='store_true', default=False,
+                  help='Print extra information (needed when monitoring an ongoing run).')
+    op.add_option('', '--print-all', dest='printAll',
+                  action='store_true', default=False,
+                  help='Print all available information.')
+    op.add_option('','--sort-by', dest='sortBy',
+                  help='key value to sort by, e.g. --sort-by=Instrs')
+    op.add_option('','--ascending', dest='ascending',
+                  action='store_true', default=False,
+                  help='sort in ascending order (default is descending)')
+    op.add_option('','--compare-by', dest='compBy',
+                  help="key value on which to compare runs to the reference one (which is the first one).  E.g., --compare-by=Instrs shows how each run compares to the reference run after executing the same number of instructions as the reference run.  If a run hasn't executed as many instructions as the reference one, we simply print the statistics at the end of that run.")
+    opts,dirs = op.parse_args()
+
+    actualDirs = []
+    for dir in dirs:
+        if os.path.exists(os.path.join(dir,'info')):
+            actualDirs.append(dir)
+        else:
+            for root,dirs,_ in os.walk(dir):
+                for d in dirs:
+                    p = os.path.join(root,d)
+                    if os.path.exists(os.path.join(p,'info')):
+                        actualDirs.append(p)
+    dirs = actualDirs
+    
+    summary = []
+    
+    if (opts.printAll):
+        labels = ('Path','Instrs','Time(s)','ICov(%)','BCov(%)','ICount','Solver(%)', 'States', 'Mem(MB)', 'Queries', 'AvgQC', 'Tcex(%)', 'Tfork(%)')
+    elif (opts.printMore):
+        labels = ('Path','Instrs','Time(s)','ICov(%)','BCov(%)','ICount','Solver(%)', 'States', 'Mem(MB)')
+    else:
+        labels = ('Path','Instrs','Time(s)','ICov(%)','BCov(%)','ICount','Solver(%)')
+
+
+    def addRecord(Path,rec):
+        (I,BFull,BPart,BTot,T,St,Mem,QTot,QCon,NObjs,Treal,SCov,SUnc,QT,Ts,Tcex,Tf) = rec
+        Mem=Mem/1024./1024.
+        AvgQC = int(QCon/max(1,QTot))
+        if (opts.printAll):
+            table.append((Path, I, Treal, 100.*SCov/(SCov+SUnc), 100.*(2*BFull+BPart)/(2.*BTot),
+                          SCov+SUnc, 100.*Ts/Treal, St, Mem, QTot, AvgQC, 100.*Tcex/Treal, 100.*Tf/Treal))
+        elif (opts.printMore):
+            table.append((Path, I, Treal, 100.*SCov/(SCov+SUnc), 100.*(2*BFull+BPart)/(2.*BTot),
+                          SCov+SUnc, 100.*Ts/Treal, St, Mem))
+        else:
+            table.append((Path, I, Treal, 100.*SCov/(SCov+SUnc), 100.*(2*BFull+BPart)/(2.*BTot),
+                          SCov+SUnc, 100.*Ts/Treal))
+        
+    def addRow(Path,data):
+        data = tuple(data[:17]) + (None,)*(17-len(data))
+        addRecord(Path,data)
+        if not summary:
+            summary[:] = list(data)
+        else:
+            summary[:] = [(a+b) for a,b in zip(summary,data)]
+
+    datas = [(dir,LazyEvalList(list(open(getFile(dir))))) for dir in dirs]
+    reference = datas[0][1][-1]
+
+    table = []    
+
+    for dir,data in datas:
+        try:
+            if opts.compBy:
+                addRow(dir,getMatchedRecord(data,reference,lambda f: f[getKeyIndex(opts.compBy,labels)-1]))
+            else: 
+                addRow(dir, data[len(data)-1])  #getLastRecord(dir))
+        except IOError:
+            print 'Unable to open: ',dir
+            continue
+
+    stripCommonPathPrefix(table, 0)
+    if opts.sortBy:
+        sortTable(table, labels, opts.sortBy, opts.ascending)
+    if not table:
+        sys.exit(1)
+    elif len(table)>1:
+        table.append(None)
+        addRecord('Total (%d)'%(len(table)-1,),summary)
+    table[0:0] = [None,labels,None]
+    table.append(None)
+    printTable(table)
+        
+        
+if __name__=='__main__':
+    main(sys.argv)
diff --git a/scripts/klee-control b/scripts/klee-control
new file mode 100755
index 00000000..50c1f82d
--- /dev/null
+++ b/scripts/klee-control
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+
+import os, signal, popen2
+
+def getPID(dir):
+    f = open(os.path.join(dir,'info'))
+    for ln in f.readlines():
+        if ln.startswith('PID: '):
+            return int(ln[5:])
+    return None
+
+def execCmd(pid, gdbCmd, opts):
+    cmd = ("gdb " +
+           "--batch " +
+           "--pid=%d " +
+           "--eval-command=\"%s\" " +
+           "--eval-command=detach")%(pid,gdbCmd)
+    cout,cin = popen2.popen2(cmd)
+    cin.close()
+    return cout.read()
+    
+def main():
+    from optparse import OptionParser
+    op = OptionParser("usage: %prog <PID | test directory>")
+    op.add_option('','--backtrace', dest='backtrace',
+                  action='store_true', default=False)
+    op.add_option('-s','--stop-forking', dest='stopForking',
+                  action='store_true', default=False)
+    op.add_option('-H','--halt-execution', dest='haltExecution',
+                  action='store_true', default=False)
+    op.add_option('-d','--dump-states', dest='dumpStates',
+                  action='store_true', default=False)
+    op.add_option('-t','--dump-tree', dest='dumpTree',
+                  action='store_true', default=False)
+    op.add_option('-i','--int', dest='int',
+                  action='store_true', default=False)
+    op.add_option('-k','--kill', dest='kill',
+                  action='store_true', default=False)
+    op.add_option('','--print-pid', dest='printPid',
+                  action='store_true', default=False)
+    op.add_option('','--print-ticks', dest='printTicks',
+                  action='store_true', default=False)
+    opts,args = op.parse_args()
+
+    if len(args) != 1:
+        op.error("invalid arguments")
+
+    try:
+        pid = int(args[0])
+    except:
+        pid = None
+
+    if pid is None:
+        try:
+            pid = getPID(args[0])
+        except:
+            pid = None
+            
+    if pid is None:
+        op.error("unable to determine PID (bad pid or test directory)")
+
+    if opts.printPid:
+        print pid
+        return
+    print 'pid: %d'%pid    
+    if opts.backtrace:
+        execCmd(pid, 'bt', opts)
+    if opts.dumpStates:
+        execCmd(pid, "p dumpStates = 1", opts)        
+    if opts.dumpTree:
+        execCmd(pid, "p dumpPTree = 1", opts)        
+    if opts.stopForking:
+        execCmd(pid, 'p stop_forking()', opts)    
+    if opts.haltExecution:
+        execCmd(pid, 'p halt_execution()', opts)
+    if opts.printTicks:
+        res = execCmd(pid, 'p timerTicks', opts)
+        lns = res.split('\n')
+        for ln in lns:
+            if ln.startswith('$1') and '=' in ln:
+                print ln.split('=',1)[1].strip()
+    if opts.int:    
+        os.kill(pid, signal.SIGINT)
+    if opts.kill:    
+        os.kill(pid, signal.SIGKILL)
+
+if __name__=='__main__':
+    main()
+
diff --git a/scripts/objdump b/scripts/objdump
new file mode 100755
index 00000000..45fe6384
--- /dev/null
+++ b/scripts/objdump
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+
+"""
+An objdump wrapper for use with klee & kcachegrind.
+
+This allows klee to output instruction level statistic information which
+kcachegrind can then display by intercepting kcachegrind's calls to objdump
+and returning the LLVM instructions in a format that it can parse.
+"""
+
+import os, sys
+
+kActualObjdump = os.path.join(os.path.dirname(__file__),'objdump.actual')
+if not os.path.exists(kActualObjdump):
+    for path in ['/usr/bin','/usr/local/bin']:
+        p = os.path.join(path,'objdump')
+        if os.path.exists(p):
+            kActualObjdump = p
+
+def fakeObjdumpOutput(file, start, end):
+    print 'Using fake objdump output:\n\n'
+    
+    lines = open(file).readlines()
+    for i in range(max(0,start-1),min(end-1,len(lines))):
+        print '%x: _ %s'%(i+1,lines[i])
+        
+def main(args):
+    # exact pattern match kcachegrind's calling sequence
+    if   (len(args)>=6 and
+          args[1]=='-C' and
+          args[2]=='-d' and
+          args[3].startswith('--start-address=') and
+          args[4].startswith('--stop-address=') and
+          args[5].endswith('.ll')):
+        fakeObjdumpOutput(args[5], eval(args[3].split('=',1)[1]), eval(args[4].split('=',1)[1]))
+    else:
+        os.execv(kActualObjdump, args)
+        raise RuntimeError
+    
+if __name__=='__main__':
+    main(sys.argv)
diff --git a/stp/AST/AST.cpp b/stp/AST/AST.cpp
new file mode 100644
index 00000000..ab290395
--- /dev/null
+++ b/stp/AST/AST.cpp
@@ -0,0 +1,1587 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "AST.h"
+namespace BEEV {
+  //some global variables that are set through commandline options. it
+  //is best that these variables remain global. Default values set
+  //here
+  //
+  //collect statistics on certain functions
+  bool stats = false;
+  //print DAG nodes
+  bool print_nodes = false;
+  //tentative global var to allow for variable activity optimization
+  //in the SAT solver. deprecated.
+  bool variable_activity_optimize = false;
+  //run STP in optimized mode
+  bool optimize = true;
+  //do sat refinement, i.e. underconstraint the problem, and feed to
+  //SAT. if this works, great. else, add a set of suitable constraints
+  //to re-constraint the problem correctly, and call SAT again, until
+  //all constraints have been added.
+  bool arrayread_refinement = true;
+  //flag to control write refinement
+  bool arraywrite_refinement = true;
+  //check the counterexample against the original input to STP
+  bool check_counterexample = false;
+  //construct the counterexample in terms of original variable based
+  //on the counterexample returned by SAT solver
+  bool construct_counterexample = true;
+  bool print_counterexample = false;
+  //if this option is true then print the way dawson wants using a
+  //different printer. do not use this printer.
+  bool print_arrayval_declaredorder = false;
+  //flag to decide whether to print "valid/invalid" or not
+  bool print_output = false;
+  //do linear search in the array values of an input array. experimental
+  bool linear_search = false;
+  //print the variable order chosen by the sat solver while it is
+  //solving.
+  bool print_sat_varorder = false; 
+  //turn on word level bitvector solver
+  bool wordlevel_solve = true;
+  //turn off XOR flattening
+  bool xor_flatten = false;
+
+  //the smtlib parser has been turned on
+  bool smtlib_parser_enable = false;
+  //print the input back
+  bool print_STPinput_back = false;
+  
+  //global BEEVMGR for the parser
+  BeevMgr * globalBeevMgr_for_parser;
+
+  void (*vc_error_hdlr)(const char* err_msg) = NULL;
+  /** This is reusable empty vector, for representing empty children arrays */
+  ASTVec _empty_ASTVec;  
+  ////////////////////////////////////////////////////////////////
+  //  ASTInternal members
+  ////////////////////////////////////////////////////////////////  
+  /** Trivial but virtual destructor */
+  ASTInternal::~ASTInternal() { }
+
+  ////////////////////////////////////////////////////////////////
+  //  ASTInterior members
+  ////////////////////////////////////////////////////////////////
+  /** Copy constructor */
+  // ASTInterior::ASTInterior(const ASTInterior &int_node)
+  // {
+  //   _kind = int_node._kind;
+  //   _children = int_node._children;
+  // }
+  
+  /** Trivial but virtual destructor */
+  ASTInterior::~ASTInterior() { }
+  
+  // FIXME: Darn it! I think this ends up copying the children twice!
+  /** Either return an old node or create it if it doesn't exist. 
+      Note that nodes are physically allocated in the hash table. */
+  
+  // There is  an inelegance here that  I don't know how  to solve.  I'd
+  // like to heap allocate and do some other initialization on keys only
+  // if  they aren't  in  the hash  table.   It would  be  great if  the
+  // "insert"  method took a  "creator" class  so that  I could  do that
+  // between  when it  notices that  the key  is not  there and  when it
+  // inserts it.  Alternatively, it would be great if I could insert the
+  // temporary key and replace it  if it actually got inserted.  But STL
+  // hash_set  doesn't have  the creator  feature  and paternalistically
+  // declares that keys are immutable, even though (it seems to me) that
+  // they  could be  mutated if  the hash  value and  eq values  did not
+  // change.
+  
+  ASTInterior *BeevMgr::LookupOrCreateInterior(ASTInterior *n_ptr) {
+    ASTInteriorSet::iterator it;
+    
+    if ((it = _interior_unique_table.find(n_ptr)) == _interior_unique_table.end()) {
+      // Make a new ASTInterior node
+      // We want (NOT alpha) always to have alpha.nodenum + 1.
+      if (n_ptr->GetKind() == NOT) {
+	n_ptr->SetNodeNum(n_ptr->GetChildren()[0].GetNodeNum()+1);
+      }
+      else {
+	n_ptr->SetNodeNum(NewNodeNum());
+      }
+      pair<ASTInteriorSet::const_iterator, bool> p = _interior_unique_table.insert(n_ptr);
+      return *(p.first);
+    }
+    else
+      // Delete the temporary node, and return the found node.
+      delete n_ptr;
+      return *it;
+  }
+  
+  size_t ASTInterior::ASTInteriorHasher::operator() (const ASTInterior *int_node_ptr) const {
+    //size_t hashval = 0;
+    size_t hashval = ((size_t) int_node_ptr->GetKind());
+    const ASTVec &ch = int_node_ptr->GetChildren();
+    ASTVec::const_iterator iend = ch.end();
+    for (ASTVec::const_iterator i = ch.begin(); i != iend; i++) {
+      //Using "One at a time hash" by Bob Jenkins
+      hashval += i->Hash();
+      hashval += (hashval << 10);
+      hashval ^= (hashval >> 6);
+    }
+
+    hashval += (hashval << 3);
+    hashval ^= (hashval >> 11);
+    hashval += (hashval << 15);
+    return hashval;
+    //return hashval += ((size_t) int_node_ptr->GetKind());
+  }
+  
+
+  void ASTInterior::CleanUp() {
+    // cout << "Deleting node " << this->GetNodeNum() << endl;
+    _bm._interior_unique_table.erase(this);
+    delete this;
+  }
+
+  ////////////////////////////////////////////////////////////////
+  //  ASTNode members
+  ////////////////////////////////////////////////////////////////
+  //ASTNode constructors are inlined in AST.h
+  bool ASTNode::IsAlreadyPrinted() const {
+    BeevMgr &bm = GetBeevMgr();
+    return (bm.AlreadyPrintedSet.find(*this) != bm.AlreadyPrintedSet.end());
+  }
+
+  void ASTNode::MarkAlreadyPrinted() const {
+    // FIXME: Fetching BeevMgr is annoying.  Can we put this in lispprinter class?
+    BeevMgr &bm = GetBeevMgr();
+    bm.AlreadyPrintedSet.insert(*this);
+  }
+
+  // Get the name from a symbol (char *).  It's an error if kind != SYMBOL
+  const char * const ASTNode::GetName() const {
+    if (GetKind() != SYMBOL)
+      FatalError("GetName: Called GetName on a non-symbol: ", *this);
+    return ((ASTSymbol *) _int_node_ptr)->GetName();    
+  }
+  
+  // Print in lisp format
+  ostream &ASTNode::LispPrint(ostream &os, int indentation) const {
+    // Clear the PrintMap
+    BeevMgr& bm = GetBeevMgr(); 
+    bm.AlreadyPrintedSet.clear();
+    return LispPrint_indent(os, indentation);
+  }
+
+  // Print newline and indentation, then print the thing.
+  ostream &ASTNode::LispPrint_indent(ostream &os,
+				     int indentation) const
+  {
+    os << endl << spaces(indentation);
+    LispPrint1(os, indentation);
+    return os;
+  }
+  
+  /** Internal function to print in lisp format.  Assume newline
+      and indentation printed already before first line.  Recursive
+      calls will have newline & indent, though */
+  ostream &ASTNode::LispPrint1(ostream &os, int indentation) const {
+    if (!IsDefined()) {
+      os << "<undefined>";
+      return os;
+    }
+    Kind kind = GetKind();
+    // FIXME: figure out how to avoid symbols with same names as kinds.
+//    if (kind == READ) {
+//      const ASTVec &children = GetChildren();
+//      children[0].LispPrint1(os, indentation);
+//	os << "[" << children[1] << "]";
+//    } else 
+    if(kind == BVGETBIT) {
+      const ASTVec &children = GetChildren();
+      // child 0 is a symbol.  Print without the NodeNum.
+      os << GetNodeNum() << ":";
+
+
+
+      children[0]._int_node_ptr->nodeprint(os);
+      //os << "{" << children[1].GetBVConst() << "}";
+      os << "{";
+      children[1]._int_node_ptr->nodeprint(os);
+      os << "}";
+    } else if (kind == NOT) {
+      const ASTVec &children = GetChildren();
+      os << GetNodeNum() << ":";	
+      os << "(NOT ";
+      children[0].LispPrint1(os, indentation);
+      os << ")";
+    }
+    else if (Degree() == 0) {
+      // Symbol or a kind with no children print as index:NAME if shared,
+      // even if they have been printed before.	
+      os << GetNodeNum() << ":";
+      _int_node_ptr->nodeprint(os); 
+      // os << "(" << _int_node_ptr->_ref_count << ")";
+      // os << "{" << GetValueWidth() << "}";
+    }
+    else if (IsAlreadyPrinted()) {
+      // print non-symbols as "[index]" if seen before.
+      os << "[" << GetNodeNum() << "]";
+      //	   << "(" << _int_node_ptr->_ref_count << ")";
+    }
+    else {
+      MarkAlreadyPrinted();
+      const ASTVec &children = GetChildren();
+      os << GetNodeNum() << ":"
+	//<< "(" << _int_node_ptr->_ref_count << ")" 
+	 << "(" << kind << " ";
+      // os << "{" << GetValueWidth() << "}";
+      ASTVec::const_iterator iend = children.end();
+      for (ASTVec::const_iterator i = children.begin(); i != iend; i++) {
+	i->LispPrint_indent(os, indentation+2);
+	}
+      os << ")";	
+    }
+    return os;
+  }
+
+  //print in PRESENTATION LANGUAGE
+  //
+  //two pass algorithm: 
+  //
+  //1. In the first pass, letize this Node, N: i.e. if a node
+  //1. appears more than once in N, then record this fact.
+  //
+  //2. In the second pass print a "global let" and then print N
+  //2. as follows: Every occurence of a node occuring more than
+  //2. once is replaced with the corresponding let variable.
+  ostream& ASTNode::PL_Print(ostream &os,
+			     int indentation) const {
+    // Clear the PrintMap
+    BeevMgr& bm = GetBeevMgr(); 
+    bm.PLPrintNodeSet.clear();
+    bm.NodeLetVarMap.clear();
+    bm.NodeLetVarVec.clear();
+    bm.NodeLetVarMap1.clear();
+
+    //pass 1: letize the node
+    LetizeNode();
+
+    //pass 2: 
+    //
+    //2. print all the let variables and their counterpart expressions
+    //2. as follows (LET var1 = expr1, var2 = expr2, ...
+    //
+    //3. Then print the Node itself, replacing every occurence of
+    //3. expr1 with var1, expr2 with var2, ...
+    //os << "(";
+    if(0 < bm.NodeLetVarMap.size()) {
+      //ASTNodeMap::iterator it=bm.NodeLetVarMap.begin();
+      //ASTNodeMap::iterator itend=bm.NodeLetVarMap.end();
+      std::vector<pair<ASTNode,ASTNode> >::iterator it = bm.NodeLetVarVec.begin();
+      std::vector<pair<ASTNode,ASTNode> >::iterator itend = bm.NodeLetVarVec.end();
+
+      os << "(LET ";      
+      //print the let var first
+      it->first.PL_Print1(os,indentation,false);
+      os << " = ";
+      //print the expr
+      it->second.PL_Print1(os,indentation,false);
+
+      //update the second map for proper printing of LET
+      bm.NodeLetVarMap1[it->second] = it->first;
+
+      for(it++;it!=itend;it++) {
+        os << "," << endl;
+	//print the let var first
+	it->first.PL_Print1(os,indentation,false);
+	os << " = ";
+	//print the expr
+	it->second.PL_Print1(os,indentation,false);
+
+        //update the second map for proper printing of LET
+        bm.NodeLetVarMap1[it->second] = it->first;
+      }
+    
+      os << " IN " << endl;      
+      PL_Print1(os,indentation, true);
+      os << ") ";
+    }
+    else
+      PL_Print1(os,indentation, false);
+    //os << " )";
+    os << " ";
+    return os;
+  } //end of PL_Print()
+
+  //traverse "*this", and construct "let variables" for terms that
+  //occur more than once in "*this".
+  void ASTNode::LetizeNode(void) const {
+    Kind kind = this->GetKind();
+
+    if(kind == SYMBOL  || 
+       kind == BVCONST ||
+       kind == FALSE   ||
+       kind == TRUE)
+      return;
+
+    //FIXME: this is ugly.
+    BeevMgr& bm = GetBeevMgr();     
+    const ASTVec &c = this->GetChildren();
+    for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++){
+      ASTNode ccc = *it;
+      if(bm.PLPrintNodeSet.find(ccc) == bm.PLPrintNodeSet.end()){
+	//If branch: if *it is not in NodeSet then,
+	//
+	//1. add it to NodeSet
+	//
+	//2. Letize its childNodes
+
+	//FIXME: Fetching BeevMgr is annoying.  Can we put this in
+	//some kind of a printer class
+	bm.PLPrintNodeSet.insert(ccc);
+	//debugging
+	//cerr << ccc;
+	ccc.LetizeNode();
+      } 
+      else{
+	Kind k = ccc.GetKind();
+	if(k == SYMBOL  || 
+	   k == BVCONST ||
+	   k == FALSE   ||
+	   k == TRUE)
+	  continue;
+	
+	//0. Else branch: Node has been seen before
+	//
+	//1. Check if the node has a corresponding letvar in the
+	//1. NodeLetVarMap.
+	//
+	//2. if no, then create a new var and add it to the
+	//2. NodeLetVarMap
+	if(bm.NodeLetVarMap.find(ccc) == bm.NodeLetVarMap.end()) {
+	  //Create a new symbol. Get some name. if it conflicts with a
+	  //declared name, too bad. 
+	  int sz = bm.NodeLetVarMap.size();
+	  ostringstream oss;
+	  oss << "let_k_" << sz;
+
+	  ASTNode CurrentSymbol = bm.CreateSymbol(oss.str().c_str());
+	  CurrentSymbol.SetValueWidth(this->GetValueWidth());
+	  CurrentSymbol.SetIndexWidth(this->GetIndexWidth());	  
+	  /* If for some reason the variable being created here is
+	   * already declared by the user then the printed output will
+	   * not be a legal input to the system. too bad. I refuse to
+	   * check for this.  [Vijay is the author of this comment.]
+	   */
+	  
+	  bm.NodeLetVarMap[ccc] = CurrentSymbol;
+	  std::pair<ASTNode,ASTNode> node_letvar_pair(CurrentSymbol,ccc);
+	  bm.NodeLetVarVec.push_back(node_letvar_pair);
+	}
+      }    
+    }
+  } //end of LetizeNode()
+
+  void ASTNode::PL_Print1(ostream& os,
+			  int indentation, 
+			  bool letize) const {
+    //os << spaces(indentation);
+    //os << endl << spaces(indentation);
+    if (!IsDefined()) {
+      os << "<undefined>";
+      return;
+    }
+    
+    //if this node is present in the letvar Map, then print the letvar
+    BeevMgr &bm = GetBeevMgr();
+
+    //this is to print letvars for shared subterms inside the printing
+    //of "(LET v0 = term1, v1=term1@term2,...
+    if((bm.NodeLetVarMap1.find(*this) != bm.NodeLetVarMap1.end()) && !letize) {
+      (bm.NodeLetVarMap1[*this]).PL_Print1(os,indentation,letize);
+      return;
+    }
+
+    //this is to print letvars for shared subterms inside the actual
+    //term to be printed
+    if((bm.NodeLetVarMap.find(*this) != bm.NodeLetVarMap.end()) && letize) {
+      (bm.NodeLetVarMap[*this]).PL_Print1(os,indentation,letize);
+      return;
+    }
+    
+    //otherwise print it normally
+    Kind kind = GetKind();
+    const ASTVec &c = GetChildren();     
+    switch(kind) {
+    case BVGETBIT:
+      c[0].PL_Print1(os,indentation,letize);
+      os << "{";
+      c[1].PL_Print1(os,indentation,letize);
+      os << "}";
+      break;
+    case BITVECTOR:
+      os << "BITVECTOR(";
+      unsigned char * str;
+      str = CONSTANTBV::BitVector_to_Hex(c[0].GetBVConst());
+      os << str << ")";
+      CONSTANTBV::BitVector_Dispose(str);
+      break;
+    case BOOLEAN:
+      os << "BOOLEAN";
+      break;
+    case FALSE:
+    case TRUE:
+      os << kind;
+      break;
+    case BVCONST:
+    case SYMBOL:
+      _int_node_ptr->nodeprint(os); 
+      break;
+    case READ:
+      c[0].PL_Print1(os, indentation,letize);
+      os << "[";
+      c[1].PL_Print1(os,indentation,letize);
+      os << "]";
+      break;
+    case WRITE:
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << " WITH [";
+      c[1].PL_Print1(os,indentation,letize);
+      os << "] := ";
+      c[2].PL_Print1(os,indentation,letize);
+      os << ")";
+      os << endl;
+      break;
+    case BVUMINUS:
+      os << kind << "( ";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ")";
+      break;
+    case NOT:
+      os << "NOT(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ") " << endl;
+      break;
+    case BVNEG:
+      os << " ~(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ")";
+      break;
+    case BVCONCAT:
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << " @ ";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")" << endl;
+      break;
+    case BVOR:
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << " | ";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")";
+      break;
+    case BVAND:
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << " & ";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")";
+      break;
+    case BVEXTRACT:
+      c[0].PL_Print1(os,indentation,letize);
+      os << "[";
+      os << GetUnsignedConst(c[1]);
+      os << ":";
+      os << GetUnsignedConst(c[2]);
+      os << "]";
+      break;
+    case BVLEFTSHIFT:
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << " << ";
+      os << GetUnsignedConst(c[1]);
+      os << ")";
+      break;
+    case BVRIGHTSHIFT:
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << " >> ";
+      os << GetUnsignedConst(c[1]);
+      os << ")";
+      break;
+    case BVMULT:
+    case BVSUB:
+    case BVPLUS:
+    case SBVDIV:      
+    case SBVMOD:
+    case BVDIV:      
+    case BVMOD:
+      os << kind << "(";
+      os << this->GetValueWidth();
+      for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	os << ", " << endl;
+	it->PL_Print1(os,indentation,letize);	
+      }
+      os << ")" << endl;
+      break;    
+    case ITE:
+      os << "IF(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ")" << endl;
+      os << "THEN ";
+      c[1].PL_Print1(os,indentation,letize);
+      os << endl << "ELSE ";
+      c[2].PL_Print1(os,indentation,letize);
+      os << endl << "ENDIF";
+      break;
+    case BVLT:
+    case BVLE:
+    case BVGT:
+    case BVGE:
+    case BVXOR:
+    case BVNAND:
+    case BVNOR:
+    case BVXNOR:
+      os << kind << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ",";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")" << endl;
+      break;
+    case BVSLT:
+      os << "SBVLT" << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ",";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")" << endl;
+      break;
+    case BVSLE:
+      os << "SBVLE" << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ",";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")" << endl;
+      break;
+    case BVSGT:
+      os << "SBVGT" << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ",";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")" << endl;
+      break;
+    case BVSGE:
+      os << "SBVGE" << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ",";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")" << endl;
+      break;
+    case EQ:
+      c[0].PL_Print1(os,indentation,letize);
+      os << " = ";
+      c[1].PL_Print1(os,indentation,letize);      
+      os << endl;
+      break;
+    case NEQ:
+      c[0].PL_Print1(os,indentation,letize);
+      os << " /= ";
+      c[1].PL_Print1(os,indentation,letize);      
+      os << endl;
+      break;
+    case AND:
+    case OR:
+    case NAND:
+    case NOR:
+    case XOR: {
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      ASTVec::const_iterator it=c.begin();
+      ASTVec::const_iterator itend=c.end();
+
+      it++;
+      for(;it!=itend;it++) {
+	os << " " << kind << " ";
+	it->PL_Print1(os,indentation,letize);
+	os << endl;
+      }
+      os << ")";
+      break;
+    }
+    case IFF:
+      os << "(";
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ")";
+      os << " <=> ";
+      os << "(";
+      c[1].PL_Print1(os,indentation,letize);      
+      os << ")";
+      os << ")";
+      os << endl;
+      break;
+    case IMPLIES:
+      os << "(";
+      os << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ")";
+      os << " => ";
+      os << "(";
+      c[1].PL_Print1(os,indentation,letize);
+      os << ")";
+      os << ")";
+      os << endl;
+      break;
+    case BVSX:
+      os << kind << "(";
+      c[0].PL_Print1(os,indentation,letize);
+      os << ",";
+      os << this->GetValueWidth();
+      os << ")" << endl;
+      break;
+    default:
+      //remember to use LispPrinter here. Otherwise this function will
+      //go into an infinite loop. Recall that "<<" is overloaded to
+      //the lisp printer. FatalError uses lispprinter
+      FatalError("PL_Print1: printing not implemented for this kind: ",*this);
+      break;
+    }
+  } //end of PL_Print1()
+
+  ////////////////////////////////////////////////////////////////
+  //  BeevMgr members
+  ////////////////////////////////////////////////////////////////
+  ASTNode BeevMgr::CreateNode(Kind kind, const ASTVec & back_children) {
+    // create a new node.  Children will be modified.
+    ASTInterior *n_ptr = new ASTInterior(kind, *this);
+
+    // insert all of children at end of new_children.
+    ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
+    return n;
+  }
+  
+  ASTNode BeevMgr::CreateNode(Kind kind,
+			      const ASTNode& child0,
+			      const ASTVec & back_children) {
+
+    ASTInterior *n_ptr = new ASTInterior(kind, *this);
+    ASTVec &front_children = n_ptr->_children;
+    front_children.push_back(child0);
+    ASTNode n(CreateInteriorNode(kind, n_ptr,  back_children));
+    return n;
+  }
+  
+  ASTNode BeevMgr::CreateNode(Kind kind,
+			      const ASTNode& child0,
+			      const ASTNode& child1,
+			      const ASTVec & back_children) {
+
+    ASTInterior *n_ptr = new ASTInterior(kind, *this);
+    ASTVec &front_children = n_ptr->_children;
+    front_children.push_back(child0);
+    front_children.push_back(child1);
+    ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
+    return n;
+  }
+  
+  
+  ASTNode BeevMgr::CreateNode(Kind kind,
+			      const ASTNode& child0,
+			      const ASTNode& child1,
+			      const ASTNode& child2,
+			      const ASTVec & back_children) {
+    ASTInterior *n_ptr = new ASTInterior(kind, *this);
+    ASTVec &front_children = n_ptr->_children;
+    front_children.push_back(child0);
+    front_children.push_back(child1);
+    front_children.push_back(child2);
+    ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
+    return n;
+  }
+  
+  
+  ASTInterior *BeevMgr::CreateInteriorNode(Kind kind,
+					   // children array of this node will be modified.
+					   ASTInterior *n_ptr,
+					   const ASTVec & back_children) {
+
+    // insert back_children at end of front_children
+    ASTVec &front_children = n_ptr->_children;
+
+    front_children.insert(front_children.end(), back_children.begin(), back_children.end());
+
+    // check for undefined nodes.
+    ASTVec::const_iterator it_end = front_children.end();
+    for (ASTVec::const_iterator it = front_children.begin(); it != it_end; it++) {
+      if (it->IsNull())
+	FatalError("CreateInteriorNode: Undefined childnode in CreateInteriorNode: ", ASTUndefined);      
+    }
+
+    return LookupOrCreateInterior(n_ptr);
+  }
+    
+  /** Trivial but virtual destructor */
+  ASTSymbol::~ASTSymbol() {}
+  
+  ostream &operator<<(ostream &os, const ASTNodeMap &nmap)
+  {
+    ASTNodeMap::const_iterator iend = nmap.end();
+    for (ASTNodeMap::const_iterator i = nmap.begin(); i!=iend; i++) {
+      os << "Key: " << i->first << endl;
+      os << "Value: " << i->second << endl;
+    }
+    return os;
+  }
+  
+  ////////////////////////////////////////////////////////////////
+  // BeevMgr member functions to create ASTSymbol and ASTBVConst
+  ////////////////////////////////////////////////////////////////
+  ASTNode BeevMgr::CreateSymbol(const char * const name) 
+  { 
+    ASTSymbol temp_sym(name, *this);
+    ASTNode n(LookupOrCreateSymbol(temp_sym));
+    return n;
+  }
+
+#ifndef NATIVE_C_ARITH
+  //Create a ASTBVConst node
+  ASTNode BeevMgr::CreateBVConst(unsigned int width, 
+				 unsigned long long int bvconst){ 
+    if(width > (sizeof(unsigned long long int)<<3) || width <= 0)
+      FatalError("CreateBVConst: trying to create a bvconst of width: ", ASTUndefined, width);
+    
+
+    CBV bv = CONSTANTBV::BitVector_Create(width, true);
+    unsigned long c_val = (0x00000000ffffffffLL) & bvconst;
+    unsigned int copied = 0;
+
+    // sizeof(unsigned long) returns the number of bytes in unsigned
+    // long. In order to convert it to bits, we need to shift left by
+    // 3. Hence, sizeof(unsigned long) << 3
+
+    //The algo below works as follows: It starts by copying the
+    //lower-order bits of the input "bvconst" in chunks of size =
+    //number of bits in unsigned long. The variable "copied" keeps
+    //track of the number of chunks copied so far
+
+    while(copied + (sizeof(unsigned long)<<3) < width){
+      CONSTANTBV::BitVector_Chunk_Store(bv, sizeof(unsigned long)<<3,copied,c_val);
+      bvconst = bvconst >> (sizeof(unsigned long) << 3);
+      c_val = (0x00000000ffffffffLL) & bvconst;
+      copied += sizeof(unsigned long) << 3;
+    }
+    CONSTANTBV::BitVector_Chunk_Store(bv,width - copied,copied,c_val);
+    return CreateBVConst(bv,width);
+  }
+
+  //Create a ASTBVConst node from std::string
+  ASTNode BeevMgr::CreateBVConst(const char* const strval, int base) {
+    size_t width = strlen((const char *)strval);    
+    if(!(2 == base || 10 == base || 16 == base)){
+      FatalError("CreateBVConst: unsupported base: ",ASTUndefined,base);
+    }
+    //FIXME Tim: Earlier versions of the code assume that the length of
+    //binary strings is 32 bits.
+    if(10 == base) width = 32;
+    if(16 == base) width = width * 4;
+
+    //checking if the input is in the correct format
+    CBV bv = CONSTANTBV::BitVector_Create(width,true);
+    CONSTANTBV::ErrCode e;
+    if(2 == base){
+      e = CONSTANTBV::BitVector_from_Bin(bv, (unsigned char*)strval);
+    }else if(10 == base){
+      e = CONSTANTBV::BitVector_from_Dec(bv, (unsigned char*)strval);
+    }else if(16 == base){
+      e = CONSTANTBV::BitVector_from_Hex(bv, (unsigned char*)strval);
+    }else{
+      e = CONSTANTBV::ErrCode_Pars;
+    }
+
+    if(0 != e) {
+      cerr << "CreateBVConst: " << BitVector_Error(e);
+      FatalError("",ASTUndefined);
+    }
+
+    //FIXME 
+    return CreateBVConst(bv, width);
+  }
+  
+
+  //FIXME Code currently assumes that it will destroy the bitvector passed to it
+  ASTNode BeevMgr::CreateBVConst(CBV bv, unsigned width){
+     ASTBVConst temp_bvconst(bv, width, *this);
+     ASTNode n(LookupOrCreateBVConst(temp_bvconst));
+     
+     CONSTANTBV::BitVector_Destroy(bv);
+     
+     return n;
+  }
+
+  ASTNode BeevMgr::CreateZeroConst(unsigned width) {
+    CBV z = CONSTANTBV::BitVector_Create(width, true);
+    return CreateBVConst(z, width);
+  }
+  
+  ASTNode BeevMgr::CreateOneConst(unsigned width) {
+    CBV o = CONSTANTBV::BitVector_Create(width, true);
+    CONSTANTBV::BitVector_increment(o);
+    
+    return CreateBVConst(o,width);
+  }
+
+  ASTNode BeevMgr::CreateTwoConst(unsigned width) {
+    CBV two = CONSTANTBV::BitVector_Create(width, true);
+    CONSTANTBV::BitVector_increment(two);
+    CONSTANTBV::BitVector_increment(two);
+
+    return CreateBVConst(two,width);
+  }
+
+  ASTNode BeevMgr::CreateMaxConst(unsigned width) {
+    CBV max = CONSTANTBV::BitVector_Create(width, false);
+    CONSTANTBV::BitVector_Fill(max);
+
+    return CreateBVConst(max,width);
+  }
+
+  //To ensure unique BVConst nodes, lookup the node in unique-table
+  //before creating a new one.
+  ASTBVConst *BeevMgr::LookupOrCreateBVConst(ASTBVConst &s) {
+    ASTBVConst *s_ptr = &s;  // it's a temporary key.
+    
+    // Do an explicit lookup to see if we need to create a copy of the string.    
+    ASTBVConstSet::const_iterator it;
+    if ((it = _bvconst_unique_table.find(s_ptr)) == _bvconst_unique_table.end()) {
+      // Make a new ASTBVConst with duplicated string (can't assign
+      // _name because it's const).  Can cast the iterator to
+      // non-const -- carefully.
+
+      ASTBVConst * s_copy = new ASTBVConst(s);      
+      s_copy->SetNodeNum(NewNodeNum());
+      
+      pair<ASTBVConstSet::const_iterator, bool> p = _bvconst_unique_table.insert(s_copy);
+      return *p.first;
+    }
+    else{
+      // return symbol found in table.
+      return *it;
+    }
+  }
+
+  // Inline because we need to wait until unique_table is defined
+  void ASTBVConst::CleanUp() {
+    //  cout << "Deleting node " << this->GetNodeNum() << endl;
+    _bm._bvconst_unique_table.erase(this);
+    delete this;
+  }
+
+  // Get the value of bvconst from a bvconst.  It's an error if kind != BVCONST
+  CBV const ASTNode::GetBVConst() const {
+    if(GetKind() != BVCONST)
+      FatalError("GetBVConst: non bitvector-constant: ",*this);
+    return ((ASTBVConst *) _int_node_ptr)->GetBVConst();      
+  }
+#else
+  //Create a ASTBVConst node
+  ASTNode BeevMgr::CreateBVConst(const unsigned int width, 
+				 const unsigned long long int bvconst) { 
+    if(width > 64 || width <= 0)
+      FatalError("Fatal Error: CreateBVConst: trying to create a bvconst of width:", ASTUndefined, width);
+    
+    //64 bit mask
+    unsigned long long int mask = 0xffffffffffffffffLL;
+    mask = mask >> (64 - width);
+
+    unsigned long long int bv = bvconst;
+    bv = bv & mask;
+
+    ASTBVConst temp_bvconst(bv, *this);
+    temp_bvconst._value_width = width;    
+    ASTNode n(LookupOrCreateBVConst(temp_bvconst));
+    n.SetValueWidth(width);
+    n.SetIndexWidth(0);
+    return n;
+  }
+  //Create a ASTBVConst node from std::string
+  ASTNode BeevMgr::CreateBVConst(const char* strval, int base) {    
+    if(!(base == 2 || base == 16 || base == 10))
+      FatalError("CreateBVConst: This base is not supported: ", ASTUndefined, base);
+
+    if(10 != base) {
+      unsigned int width = (base == 2) ? strlen(strval) : strlen(strval)*4;
+      unsigned long long int val =  strtoull(strval, NULL, base);
+      ASTNode bvcon = CreateBVConst(width, val);
+      return bvcon;
+    }
+    else {
+      //this is an ugly hack to accomodate SMTLIB format
+      //restrictions. SMTLIB format represents bitvector constants in
+      //base 10 (what a terrible idea, but i have no choice but to
+      //support it), and make an implicit assumption that the length
+      //is 32 (another terrible idea).
+      unsigned width = 32;
+      unsigned long long int val = strtoull(strval, NULL, base);
+      ASTNode bvcon = CreateBVConst(width, val);
+      return bvcon;
+    }
+  }
+  
+  //To ensure unique BVConst nodes, lookup the node in unique-table
+  //before creating a new one.
+  ASTBVConst *BeevMgr::LookupOrCreateBVConst(ASTBVConst &s) {
+    ASTBVConst *s_ptr = &s;	// it's a temporary key.
+
+    // Do an explicit lookup to see if we need to create a copy of the
+    // string.
+    ASTBVConstSet::const_iterator it;
+    if ((it = _bvconst_unique_table.find(s_ptr)) == _bvconst_unique_table.end()) {
+      // Make a new ASTBVConst. Can cast the iterator to non-const --
+      // carefully.
+      unsigned int width = s_ptr->_value_width;
+      ASTBVConst * s_ptr1 = new ASTBVConst(s_ptr->GetBVConst(), *this);
+      s_ptr1->SetNodeNum(NewNodeNum());
+      s_ptr1->_value_width = width;
+      pair<ASTBVConstSet::const_iterator, bool> p = _bvconst_unique_table.insert(s_ptr1);
+      return *p.first;
+    }
+    else
+      // return BVConst found in table.
+      return *it;
+  }
+
+  // Inline because we need to wait until unique_table is defined
+  void ASTBVConst::CleanUp() {
+    //  cout << "Deleting node " << this->GetNodeNum() << endl;
+    _bm._bvconst_unique_table.erase(this);
+    delete this;
+  }
+
+  // Get the value of bvconst from a bvconst.  It's an error if kind
+  // != BVCONST
+  unsigned long long int ASTNode::GetBVConst() const {
+    if(GetKind() != BVCONST)
+      FatalError("GetBVConst: non bitvector-constant: ", *this);
+    return ((ASTBVConstTmp *) _int_node_ptr)->GetBVConst();
+  }
+
+  ASTNode BeevMgr::CreateZeroConst(unsigned width) {
+    return CreateBVConst(width,0);
+  }
+  
+  ASTNode BeevMgr::CreateOneConst(unsigned width) {
+    return CreateBVConst(width,1);
+  }
+
+  ASTNode BeevMgr::CreateTwoConst(unsigned width) {
+    return CreateBVConst(width,2);
+  }
+
+  ASTNode BeevMgr::CreateMaxConst(unsigned width) {
+    std::string s;
+    s.insert(s.end(),width,'1');
+    return CreateBVConst(s.c_str(),2);
+  }
+
+#endif  
+
+  // FIXME: _name is now a constant field, and this assigns to it
+  // because it tries not to copy the string unless it needs to.  How
+  // do I avoid copying children in ASTInterior?  Perhaps I don't!
+  
+  // Note: There seems to be a limitation of hash_set, in that insert
+  // returns a const iterator to the value.  That prevents us from
+  // modifying the name (in a hash-preserving way) after the symbol is
+  // inserted.  FIXME: Is there a way to do this with insert?  Need a
+  // function to make a new object in the middle of insert.  Read STL
+  // documentation.
+  
+  ASTSymbol *BeevMgr::LookupOrCreateSymbol(ASTSymbol& s) {
+    ASTSymbol *s_ptr = &s;  // it's a temporary key.
+    
+    // Do an explicit lookup to see if we need to create a copy of the string.    
+    ASTSymbolSet::const_iterator it;
+    if ((it = _symbol_unique_table.find(s_ptr)) == _symbol_unique_table.end()) {
+      // Make a new ASTSymbol with duplicated string (can't assign
+      // _name because it's const).  Can cast the iterator to
+      // non-const -- carefully.
+      //std::string strname(s_ptr->GetName());
+      ASTSymbol * s_ptr1 = new ASTSymbol(strdup(s_ptr->GetName()), *this);
+      s_ptr1->SetNodeNum(NewNodeNum());
+      s_ptr1->_value_width = s_ptr->_value_width;
+      pair<ASTSymbolSet::const_iterator, bool> p = _symbol_unique_table.insert(s_ptr1);
+      return *p.first;
+    }
+    else
+      // return symbol found in table.
+      return *it;    
+  }
+
+  bool BeevMgr::LookupSymbol(ASTSymbol& s) {
+    ASTSymbol* s_ptr = &s;  // it's a temporary key.
+
+    if(_symbol_unique_table.find(s_ptr) == _symbol_unique_table.end()) 
+      return false;
+    else
+      return true;
+  }
+
+  // Inline because we need to wait until unique_table is defined
+  void ASTSymbol::CleanUp() {
+    //  cout << "Deleting node " << this->GetNodeNum() << endl;
+    _bm._symbol_unique_table.erase(this);
+    //FIXME This is a HUGE free to invoke.
+    //TEST IT!
+    free((char*) this->_name);
+    delete this;
+  }
+  
+  ////////////////////////////////////////////////////////////////
+  //
+  //  IO manipulators for Lisp format printing of AST.
+  //
+  ////////////////////////////////////////////////////////////////
+  
+  // FIXME: Additional controls
+  //   * Print node numbers  (addresses/nums)
+  //   * Printlength limit
+  //   * Printdepth limit
+  
+  /** Print a vector of ASTNodes in lisp format */
+  ostream &LispPrintVec(ostream &os, const ASTVec &v, int indentation)
+  {
+    // Print the children
+    ASTVec::const_iterator iend = v.end();
+    for (ASTVec::const_iterator i = v.begin(); i != iend; i++) {
+      i->LispPrint_indent(os, indentation);
+    }
+    return os;
+  }
+
+  // FIXME: Made non-ref in the hope that it would work better.
+  void lp(ASTNode node)
+  {
+    cout << lisp(node) << endl;
+  }
+
+  void lpvec(const ASTVec &vec)
+  {
+    vec[0].GetBeevMgr().AlreadyPrintedSet.clear();
+    LispPrintVec(cout, vec, 0);
+    cout << endl;
+  }
+
+  // Copy constructor.  Maintain _ref_count
+  ASTNode::ASTNode(const ASTNode &n) : _int_node_ptr(n._int_node_ptr) {
+#ifndef SMTLIB    
+    if (n._int_node_ptr) {
+      n._int_node_ptr->IncRef();
+    }
+#endif
+  }
+  
+
+  /* FUNCTION: Typechecker for terms and formulas
+   * 
+   * TypeChecker: Assumes that the immediate Children of the input
+   * ASTNode have been typechecked. This function is suitable in
+   * scenarios like where you are building the ASTNode Tree, and you
+   * typecheck as you go along. It is not suitable as a general
+   * typechecker      
+   */
+  void BeevMgr::BVTypeCheck(const ASTNode& n) {
+    Kind k = n.GetKind();
+    //The children of bitvector terms are in turn bitvectors.
+    ASTVec v = n.GetChildren();
+    if(is_Term_kind(k)) {
+      switch(k) {
+      case BVCONST:
+	if(BITVECTOR_TYPE != n.GetType())
+	  FatalError("BVTypeCheck: The term t does not typecheck, where t = \n",n);
+	break;
+      case SYMBOL:
+	return;
+      case ITE:     
+	if(BOOLEAN_TYPE != n[0].GetType() && 
+	   BITVECTOR_TYPE != n[1].GetType() &&
+	   BITVECTOR_TYPE != n[2].GetType())
+	  FatalError("BVTypeCheck: The term t does not typecheck, where t = \n",n);
+	if(n[1].GetValueWidth() != n[2].GetValueWidth())
+	  FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n",n);
+	if(n[1].GetIndexWidth() != n[2].GetIndexWidth())
+	  FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n",n);
+	break;
+      case READ:
+	if(n[0].GetIndexWidth() != n[1].GetValueWidth()) {
+	  cerr << "Length of indexwidth of array: " << n[0] << " is : " << n[0].GetIndexWidth() << endl;
+	  cerr << "Length of the actual index is: " << n[1] << " is : " << n[1].GetValueWidth() << endl;
+	  FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n",n);
+	}
+	break;      
+      case WRITE:
+	if(n[0].GetIndexWidth() != n[1].GetValueWidth())
+	  FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n",n);
+	if(n[0].GetValueWidth() != n[2].GetValueWidth())
+	  FatalError("BVTypeCheck: valuewidth of array != length of actual value in the term t = \n",n);
+	break;      
+      case BVOR:
+      case BVAND:
+      case BVXOR:
+      case BVNOR:
+      case BVNAND:
+      case BVXNOR: 
+      case BVPLUS: 
+      case BVMULT:
+      case BVDIV:
+      case BVMOD:
+      case BVSUB: {
+	if(!(v.size() >= 2))
+	  FatalError("BVTypeCheck:bitwise Booleans and BV arith operators must have atleast two arguments\n",n);
+	unsigned int width = n.GetValueWidth();
+	for(ASTVec::iterator it=v.begin(),itend=v.end();it!=itend;it++){
+	  if(width != it->GetValueWidth()) {
+	    cerr << "BVTypeCheck:Operands of bitwise-Booleans and BV arith operators must be of equal length\n";
+	    cerr << n << endl;
+	    cerr << "width of term:" << width << endl;
+	    cerr << "width of offending operand:" << it->GetValueWidth() << endl;
+	    FatalError("BVTypeCheck:Offending operand:\n",*it);
+	  }
+	  if(BITVECTOR_TYPE != it->GetType())
+	    FatalError("BVTypeCheck: ChildNodes of bitvector-terms must be bitvectors\n",n);
+	}
+	break;
+      }
+      case BVSX:
+	//in BVSX(n[0],len), the length of the BVSX term must be
+	//greater than the length of n[0]
+	if(n[0].GetValueWidth() >= n.GetValueWidth()) {
+	  FatalError("BVTypeCheck: BVSX(t,bvsx_len) : length of 't' must be <= bvsx_len\n",n);
+	} 
+	break;
+      default:
+	for(ASTVec::iterator it=v.begin(),itend=v.end();it!=itend;it++)
+	  if(BITVECTOR_TYPE != it->GetType()) {
+	    cerr << "The type is: " << it->GetType() << endl;
+	    FatalError("BVTypeCheck:ChildNodes of bitvector-terms must be bitvectors\n",n);
+	  }
+	break;
+      }
+      
+      switch(k) {
+      case BVCONCAT:
+	if(n.Degree() != 2)
+	  FatalError("BVTypeCheck: should have exactly 2 args\n",n);
+	if(n.GetValueWidth() != n[0].GetValueWidth() + n[1].GetValueWidth())
+	  FatalError("BVTypeCheck:BVCONCAT: lengths do not add up\n",n);	
+	break;
+      case BVUMINUS:
+      case BVNEG:
+	if(n.Degree() != 1)
+	  FatalError("BVTypeCheck: should have exactly 1 args\n",n);
+	break;
+      case BVEXTRACT:
+	if(n.Degree() != 3)
+	  FatalError("BVTypeCheck: should have exactly 3 args\n",n);
+	if(!(BVCONST == n[1].GetKind() && BVCONST == n[2].GetKind()))
+	  FatalError("BVTypeCheck: indices should be BVCONST\n",n);
+	if(n.GetValueWidth() != GetUnsignedConst(n[1])- GetUnsignedConst(n[2])+1)
+	  FatalError("BVTypeCheck: length mismatch\n",n);
+	break;
+      case BVLEFTSHIFT:
+      case BVRIGHTSHIFT:
+	if(n.Degree() != 2)
+	  FatalError("BVTypeCheck: should have exactly 2 args\n",n);
+	break;
+	//case BVVARSHIFT:
+	//case BVSRSHIFT:
+	break;
+      default:
+	break;
+      }
+    }
+    else {
+      if(!(is_Form_kind(k) && BOOLEAN_TYPE == n.GetType()))
+	FatalError("BVTypeCheck: not a formula:",n);
+      switch(k){
+      case TRUE:
+      case FALSE:
+      case SYMBOL:
+	return;
+      case EQ:
+      case NEQ:	 
+	if(!(n[0].GetValueWidth() == n[1].GetValueWidth() &&
+	     n[0].GetIndexWidth() == n[1].GetIndexWidth())) {
+	  cerr << "valuewidth of lhs of EQ: " << n[0].GetValueWidth() << endl;
+	  cerr << "valuewidth of rhs of EQ: " << n[1].GetValueWidth() << endl;
+	  cerr << "indexwidth of lhs of EQ: " << n[0].GetIndexWidth() << endl;
+	  cerr << "indexwidth of rhs of EQ: " << n[1].GetIndexWidth() << endl;
+	  FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
+	}
+	break;
+      case BVLT:
+      case BVLE:
+      case BVGT:
+      case BVGE:
+      case BVSLT:
+      case BVSLE:
+      case BVSGT:
+      case BVSGE:	
+	if(BITVECTOR_TYPE != n[0].GetType() && BITVECTOR_TYPE != n[1].GetType())
+	  FatalError("BVTypeCheck: terms in atomic formulas must be bitvectors",n);
+	if(n[0].GetValueWidth() != n[1].GetValueWidth())
+	  FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
+	if(n[0].GetIndexWidth() != n[1].GetIndexWidth())
+	  FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
+	break;
+      case NOT:
+	if(1 != n.Degree())
+	  FatalError("BVTypeCheck: NOT formula can have exactly one childNode",n);
+	break;
+      case AND:
+      case OR:
+      case XOR:
+      case NAND:
+      case NOR:
+	if(2 > n.Degree())
+	  FatalError("BVTypeCheck: AND/OR/XOR/NAND/NOR: must have atleast 2 ChildNodes",n);
+	break;
+      case IFF:
+      case IMPLIES:	
+	if(2 != n.Degree())
+	  FatalError("BVTypeCheck:IFF/IMPLIES must have exactly 2 ChildNodes",n);
+	break;
+      case ITE:
+	if(3 != n.Degree())
+	  FatalError("BVTypeCheck:ITE must have exactly 3 ChildNodes",n);		
+	break;
+      default:
+	FatalError("BVTypeCheck: Unrecognized kind: ",ASTUndefined);
+	break;
+      }
+    }
+  } //End of TypeCheck function
+
+  //add an assertion to the current logical context
+  void BeevMgr::AddAssert(const ASTNode& assert) {
+    if(!(is_Form_kind(assert.GetKind()) && BOOLEAN_TYPE == assert.GetType())) {
+      FatalError("AddAssert:Trying to assert a non-formula:",assert);
+    }
+      
+    ASTVec * v;
+    //if the stack of ASTVec is not empty, then take the top ASTVec
+    //and add the input assert to it
+    if(!_asserts.empty()) {
+      v = _asserts.back();
+      //v->push_back(TransformFormula(assert));
+      v->push_back(assert);
+    }
+    else {
+      //else create a logical context, and add it to the top of the
+      //stack
+      v = new ASTVec();
+      //v->push_back(TransformFormula(assert));
+      v->push_back(assert);
+      _asserts.push_back(v);	
+    }
+  }
+  
+  void BeevMgr::Push(void) {
+    ASTVec * v;
+    v = new ASTVec();
+    _asserts.push_back(v);
+  }
+  
+  void BeevMgr::Pop(void) {
+    if(!_asserts.empty()) {
+       ASTVec * c = _asserts.back();
+             //by calling the clear function we ensure that the ref count is
+             //decremented for the ASTNodes stored in c
+             c->clear();
+             delete c;
+      _asserts.pop_back();
+    }
+  }
+
+  void BeevMgr::AddQuery(const ASTNode& q) {
+    //_current_query = TransformFormula(q);
+    //cerr << "\nThe current query is: " << q << endl;
+    _current_query = q;
+  }
+    
+  const ASTNode BeevMgr::PopQuery() {
+    ASTNode q = _current_query;
+    _current_query = ASTTrue;
+    return q;
+  }
+   
+  const ASTNode BeevMgr::GetQuery() {
+    return _current_query;
+  }
+  
+  const ASTVec BeevMgr::GetAsserts(void) {
+    vector<ASTVec *>::iterator it = _asserts.begin();
+    vector<ASTVec *>::iterator itend = _asserts.end();
+    
+    ASTVec v;
+    for(;it!=itend;it++) {
+      if(!(*it)->empty())
+	  v.insert(v.end(),(*it)->begin(),(*it)->end());
+    }
+    return v;
+  }
+
+  //Create a new variable of ValueWidth 'n'
+  ASTNode BeevMgr::NewArrayVar(unsigned int index, unsigned int value) {
+    std:: string c("v");
+    char d[32];
+    sprintf(d,"%d",_symbol_count++);
+    std::string ccc(d);
+    c += "_writearray_" + ccc;
+    
+    ASTNode CurrentSymbol = CreateSymbol(c.c_str());
+    CurrentSymbol.SetValueWidth(value);
+    CurrentSymbol.SetIndexWidth(index);
+    return CurrentSymbol;
+  } //end of NewArrayVar()
+
+
+  //Create a new variable of ValueWidth 'n'
+  ASTNode BeevMgr::NewVar(unsigned int value) {
+    std:: string c("v");
+    char d[32];
+    sprintf(d,"%d",_symbol_count++);
+    std::string ccc(d);
+    c += "_new_stp_var_" + ccc;
+    
+    ASTNode CurrentSymbol = CreateSymbol(c.c_str());
+    CurrentSymbol.SetValueWidth(value);
+    CurrentSymbol.SetIndexWidth(0);
+    _introduced_symbols.insert(CurrentSymbol);
+    return CurrentSymbol;
+  } //end of NewVar()
+
+  //prints statistics for the ASTNode
+  void BeevMgr::ASTNodeStats(const char * c, const ASTNode& a){
+    if(!stats)
+      return;
+
+    StatInfoSet.clear();
+    //print node size:
+    cout << endl << "Printing: " << c;
+    if(print_nodes) {
+      //a.PL_Print(cout,0);
+      //cout << endl;
+      cout << a << endl;
+    }
+    cout << "Node size is: ";
+    cout << NodeSize(a) << endl << endl;    
+  }
+
+  unsigned int BeevMgr::NodeSize(const ASTNode& a, bool clearStatInfo) {    
+    if(clearStatInfo)
+      StatInfoSet.clear();
+
+    ASTNodeSet::iterator it;
+    if((it = StatInfoSet.find(a)) != StatInfoSet.end())
+      //has already been counted
+      return 0;
+
+    //record that you have seen this node already
+    StatInfoSet.insert(a);
+    
+    //leaf node has a size of 1
+    if(a.Degree() == 0)
+      return 1;
+
+    unsigned newn = 1;
+    ASTVec c = a.GetChildren();
+    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++)
+      newn += NodeSize(*it);
+    return newn;
+  }
+
+  void BeevMgr::ClearAllTables(void) {
+    //clear all tables before calling toplevelsat
+    _ASTNode_to_SATVar.clear();
+    _SATVar_to_AST.clear();
+
+    for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),
+	  itend=_ASTNode_to_Bitvector.end();it!=itend;it++) {
+      delete it->second;
+    }
+    _ASTNode_to_Bitvector.clear();
+    
+    /* OLD Destructor
+     * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
+	  ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+      ivec->second.clear();
+    }*/
+
+    /*What should I do here? For ASTNodes?
+     * for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
+	  ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+      ivec->second.clear();
+    }*/
+    BBTermMemo.clear();
+    BBFormMemo.clear();
+    NodeLetVarMap.clear();
+    NodeLetVarMap1.clear();
+    PLPrintNodeSet.clear();
+    AlreadyPrintedSet.clear();
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    SolverMap.clear();
+    AlwaysTrueFormMap.clear();
+    _arrayread_ite.clear();
+    _arrayread_symbol.clear();
+    _introduced_symbols.clear();
+    TransformMap.clear();
+    _letid_expr_map.clear();
+    CounterExampleMap.clear();
+    ComputeFormulaMap.clear();
+    StatInfoSet.clear();
+
+    // for(std::vector<ASTVec *>::iterator it=_asserts.begin(),
+    // 	  itend=_asserts.end();it!=itend;it++) {
+    //       (*it)->clear();
+    //     }
+    _asserts.clear();
+    for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), 
+	  iset_end = _arrayname_readindices.end();
+	iset!=iset_end;iset++) {
+      iset->second.clear();
+    }
+
+    _arrayname_readindices.clear();
+    _interior_unique_table.clear();
+    _symbol_unique_table.clear();
+    _bvconst_unique_table.clear();
+  }
+
+  void BeevMgr::ClearAllCaches(void) {
+    //clear all tables before calling toplevelsat
+    _ASTNode_to_SATVar.clear();
+    _SATVar_to_AST.clear();
+
+
+    for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),
+	  itend=_ASTNode_to_Bitvector.end();it!=itend;it++) {
+      delete it->second;
+    }
+    _ASTNode_to_Bitvector.clear();
+    
+    /*OLD destructor
+     * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
+	  ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+      ivec->second.clear();
+    }*/
+
+    /*What should I do here?
+     *for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
+	  ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+      ivec->second.clear();
+    }*/
+    BBTermMemo.clear();
+    BBFormMemo.clear();
+    NodeLetVarMap.clear();
+    NodeLetVarMap1.clear();
+    PLPrintNodeSet.clear();
+    AlreadyPrintedSet.clear();
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    SolverMap.clear();
+    AlwaysTrueFormMap.clear();
+    _arrayread_ite.clear();
+    _arrayread_symbol.clear();
+    _introduced_symbols.clear();
+    TransformMap.clear();
+    _letid_expr_map.clear();
+    CounterExampleMap.clear();
+    ComputeFormulaMap.clear();
+    StatInfoSet.clear();
+
+    for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), 
+	  iset_end = _arrayname_readindices.end();
+	iset!=iset_end;iset++) {
+      iset->second.clear();
+    }
+
+    _arrayname_readindices.clear();
+    //_interior_unique_table.clear();
+    //_symbol_unique_table.clear();
+    //_bvconst_unique_table.clear();
+  }
+
+  void BeevMgr::CopySolverMap_To_CounterExample(void) {
+    if(!SolverMap.empty()) {
+      CounterExampleMap.insert(SolverMap.begin(),SolverMap.end());
+    }
+  }
+
+  void FatalError(const char * str, const ASTNode& a, int w) {
+    if(a.GetKind() != UNDEFINED) {
+      cerr << "Fatal Error: " << str << endl << a << endl;
+      cerr << w << endl;
+    }
+    else {
+      cerr << "Fatal Error: " << str << endl;
+      cerr << w << endl;
+    }
+    if (vc_error_hdlr)
+      vc_error_hdlr(str);
+    exit(-1);
+    //assert(0);
+  }
+
+  void FatalError(const char * str) {
+    cerr << "Fatal Error: " << str << endl;
+    if (vc_error_hdlr)
+      vc_error_hdlr(str);
+    exit(-1);
+    //assert(0);
+  }
+
+  //Variable Order Printer: A global function which converts a MINISAT
+  //var into a ASTNODE var. It then prints this var along with
+  //variable order dcisions taken by MINISAT.
+  void Convert_MINISATVar_To_ASTNode_Print(int minisat_var, 
+  					   int decision_level, int polarity) {
+    BEEV::ASTNode vv = globalBeevMgr_for_parser->_SATVar_to_AST[minisat_var];
+    cout << spaces(decision_level);
+    if(polarity) {
+      cout << "!";
+    }
+    vv.PL_Print(cout,0);
+    cout << endl;
+  }
+
+  void SortByExprNum(ASTVec& v) {
+    sort(v.begin(), v.end(), exprless);
+  }
+
+  bool isAtomic(Kind kind) {
+    if(TRUE == kind ||
+       FALSE == kind ||
+       EQ == kind ||
+       NEQ == kind ||
+       BVLT == kind ||
+       BVLE == kind ||
+       BVGT == kind ||
+       BVGE == kind ||
+       BVSLT == kind ||
+       BVSLE == kind ||
+       BVSGT == kind ||
+       BVSGE == kind ||
+       SYMBOL == kind ||
+       BVGETBIT == kind)
+      return true;
+    return false;
+  }
+
+  BeevMgr::~BeevMgr() {
+    ClearAllTables();
+  }
+}; // end namespace
+
diff --git a/stp/AST/AST.h b/stp/AST/AST.h
new file mode 100644
index 00000000..53ed7016
--- /dev/null
+++ b/stp/AST/AST.h
@@ -0,0 +1,1805 @@
+// -*- c++ -*-
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+
+#ifndef AST_H
+#define AST_H
+#include <vector>
+#ifdef EXT_HASH_MAP
+#include <ext/hash_set>
+#include <ext/hash_map>
+#else
+#include <hash_set>
+#include <hash_map>
+#endif
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <map>
+#include <set>
+#include "ASTUtil.h"
+#include "ASTKind.h"
+#include "../sat/Solver.h"
+#include "../sat/SolverTypes.h"
+#include <cstdlib>
+#ifndef NATIVE_C_ARITH
+#include "../constantbv/constantbv.h"
+#endif
+/*****************************************************************************
+ * LIST OF CLASSES DECLARED IN THIS FILE:
+ *
+ * class BeevMgr;  
+ * class ASTNode; 
+ * class ASTInternal;  
+ * class ASTInterior;  
+ * class ASTSymbol;
+ * class ASTBVConst;
+ *****************************************************************************/
+namespace BEEV {
+  using namespace std; 
+  using namespace MINISAT;
+#ifdef EXT_HASH_MAP
+  using namespace __gnu_cxx;
+#endif
+
+  //return types for the GetType() function in ASTNode class
+  enum types {
+    BOOLEAN_TYPE = 0,
+    BITVECTOR_TYPE,
+    ARRAY_TYPE,
+    UNKNOWN_TYPE
+  };
+  
+  class BeevMgr;  
+  class ASTNode; 
+  class ASTInternal;  
+  class ASTInterior;  
+  class ASTSymbol;
+  class ASTBVConst;
+  class BVSolver;
+
+  //Vector of ASTNodes, used for child nodes among other things.  
+  typedef vector<ASTNode> ASTVec;
+  extern ASTVec _empty_ASTVec;
+  extern BeevMgr * globalBeevMgr_for_parser;
+
+  typedef unsigned int * CBV;
+
+  /***************************************************************************/
+  /*  Class ASTNode: Smart pointer to actual ASTNode internal datastructure. */
+  /***************************************************************************/
+  class ASTNode {
+    friend class BeevMgr;
+    friend class vector<ASTNode>;
+    //Print the arguments in lisp format.
+    friend ostream &LispPrintVec(ostream &os, 
+				 const ASTVec &v, int indentation = 0); 
+
+  private:
+    // FIXME: make this into a reference?
+    ASTInternal * _int_node_ptr;	// The real data.
+
+    // Usual constructor.  
+    ASTNode(ASTInternal *in);
+
+    //Check if it points to a null node
+    bool IsNull () const { return _int_node_ptr == NULL; }
+
+    //Equal iff ASTIntNode pointers are the same.
+    friend bool operator==(const ASTNode node1, const ASTNode node2){
+      return ((size_t) node1._int_node_ptr) == ((size_t) node2._int_node_ptr);
+    }
+    
+    /* FIXME:  Nondeterministic code *** */
+    /** questionable pointer comparison function */
+    friend bool operator<(const ASTNode node1, const ASTNode node2){
+      return ((size_t) node1._int_node_ptr) < ((size_t) node2._int_node_ptr);
+    }
+
+  public:
+    // This is for sorting by expression number (used in Boolean
+    //optimization)
+    friend bool exprless(const ASTNode n1, const ASTNode n2) {
+      Kind k1 = n1.GetKind();
+      Kind k2 = n2.GetKind();
+      
+      if(BVCONST == k1 && BVCONST != k2){
+	return true;
+      }
+      if(BVCONST != k1 && BVCONST == k2){
+	return false;
+      }
+      
+      if(SYMBOL == k1 && SYMBOL != k2) {
+      	return true;
+      }
+      
+      if(SYMBOL != k1 && SYMBOL == k2) {
+      	return false;
+      }
+
+      return (n1.GetNodeNum() < n2.GetNodeNum());
+    }//end of exprless 
+    
+    // Internal lisp-form printer that does not clear _node_print_table
+    ostream &LispPrint1(ostream &os, int indentation) const;
+
+    ostream &LispPrint_indent(ostream &os, int indentation) const;
+
+    // For lisp DAG printing.  Has it been printed already, so we can
+    // just print the node number?
+    bool IsAlreadyPrinted() const;
+    void MarkAlreadyPrinted() const;
+
+  public:
+    // Default constructor.  This gets used when declaring an ASTVec
+    // of a given size, in the hash table, etc.  For faster
+    // refcounting, create a symbol node for NULL.  Give it a big
+    // initial refcount.  Never free it.  also check, for ref-count
+    // overflow?
+    ASTNode() : _int_node_ptr(NULL) { };
+
+    // Copy constructor
+    ASTNode(const ASTNode &n);
+
+    // Destructor
+    ~ASTNode();
+
+    // Assignment (for ref counting)
+    ASTNode& operator=(const ASTNode& n);
+
+    BeevMgr &GetBeevMgr() const;
+
+    // Access node number
+    int GetNodeNum() const;
+
+    // Access kind.  Inlined later because of declaration ordering problems.
+    Kind GetKind() const;
+
+    // access Children
+    const ASTVec &GetChildren() const;
+    
+    // Return the number of child nodes
+    size_t Degree() const{ 
+      return GetChildren().size(); 
+    };    
+
+    // Get indexth childNode.
+    const ASTNode operator[](size_t index) const { 
+      return GetChildren()[index]; 
+    };    
+
+    // Get begin() iterator for child nodes
+    ASTVec::const_iterator begin() const{ 
+      return GetChildren().begin(); 
+    };  
+
+    // Get end() iterator for child nodes
+    ASTVec::const_iterator end() const{ 
+      return GetChildren().end(); 
+    };
+
+    //Get back() element for child nodes
+    const ASTNode back() const{
+      return GetChildren().back();
+    };  
+
+    // Get the name from a symbol (char *).  It's an error if kind != SYMBOL
+    const char * const GetName() const;
+
+    //Get the BVCONST value
+#ifndef NATIVE_C_ARITH
+    const CBV GetBVConst() const;
+#else
+    unsigned long long int GetBVConst() const;
+#endif
+
+    /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
+     *
+     *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
+     *
+     *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
+     *
+     *both indexwidth and valuewidth should never be less than 0
+     */
+    unsigned int GetIndexWidth () const;
+
+    // FIXME: This function is dangerous.  Try to eliminate it's use.
+    void SetIndexWidth (unsigned int iw) const;
+
+    unsigned int GetValueWidth () const;
+
+    // FIXME: This function is dangerous.  Try to eliminate it's use.
+    void SetValueWidth (unsigned int vw) const;
+
+    //return the type of the ASTNode
+    //0 iff BOOLEAN
+    //1 iff BITVECTOR
+    //2 iff ARRAY
+
+    /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
+     *
+     *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
+     *
+     *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
+     *
+     *both indexwidth and valuewidth should never be less than 0
+     */    
+    types GetType(void) const;
+
+    // Hash is pointer value of _int_node_ptr.
+    const size_t Hash() const{ 
+      return (size_t) _int_node_ptr; 
+      //return GetNodeNum(); 
+    }
+
+    // lisp-form printer 
+    ostream& LispPrint(ostream &os, int indentation = 0) const;
+
+    //Presentation Language Printer
+    ostream& PL_Print(ostream &os, int indentation = 0) const;
+
+    void PL_Print1(ostream &os, int indentation = 0, bool b = false) const;
+
+    //Construct let variables for shared subterms
+    void LetizeNode(void) const;
+
+    // Attempt to define something that will work in the gdb
+    friend void lp(ASTNode &node);
+    friend void lpvec(const ASTVec &vec);
+
+    friend ostream &operator<<(ostream &os, const ASTNode &node) { 
+      node.LispPrint(os, 0); 
+      return os; 
+    };
+    
+    // Check whether the ASTNode points to anything.  Undefined nodes
+    // are created by the default constructor.  In binding table (for
+    // lambda args, etc.), undefined nodes are used to represent
+    // deleted entries.
+    bool IsDefined() const { return _int_node_ptr != NULL; }        
+
+    /* Hasher class for STL hash_maps and hash_sets that use ASTNodes
+     * as keys.  Needs to be public so people can define hash tables
+     * (and use ASTNodeMap class)*/
+    class ASTNodeHasher {
+    public:
+      size_t operator() (const ASTNode& n) const{ 
+	return (size_t) n._int_node_ptr; 
+	//return (size_t)n.GetNodeNum();
+      };
+    }; //End of ASTNodeHasher
+  
+    /* Equality for ASTNode hash_set and hash_map. Returns true iff
+     * internal pointers are the same.  Needs to be public so people
+     * can define hash tables (and use ASTNodeSet class)*/
+    class ASTNodeEqual {
+    public:
+      bool operator()(const ASTNode& n1, const ASTNode& n2) const{ 
+	return (n1._int_node_ptr == n2._int_node_ptr); 
+      }
+    }; //End of ASTNodeEqual
+  }; //End of Class ASTNode
+
+  void FatalError(const char * str, const ASTNode& a, int w = 0);
+  void FatalError(const char * str);
+  void SortByExprNum(ASTVec& c);
+  bool exprless(const ASTNode n1, const ASTNode n2);
+  bool isAtomic(Kind k);
+
+  /***************************************************************************/
+  /*  Class ASTInternal:Abstract base class for internal node representation.*/
+  /*                    Requires Kind and ChildNodes so same traversal works */
+  /*                    on all nodes.                                        */
+  /***************************************************************************/
+  class ASTInternal {
+
+    friend class ASTNode;
+
+  protected:    
+
+    // reference count.
+    int _ref_count;
+
+    // Kind.  It's a type tag and the operator.
+    Kind _kind;  
+
+    // The vector of children (*** should this be in ASTInterior? ***)
+    ASTVec _children;
+
+    // Manager object.  Having this backpointer means it's easy to
+    // find the manager when we need it.
+    BeevMgr &_bm;
+
+    //Nodenum is a unique positive integer for the node.  The nodenum
+    //of a node should always be greater than its descendents (which
+    //is easily achieved by incrementing the number each time a new
+    //node is created).
+    int _node_num;
+
+    // Length of bitvector type for array index.  The term is an
+    // array iff this is positive.  Otherwise, the term is a bitvector
+    // or a bit.
+    unsigned int _index_width;
+
+    // Length of bitvector type for scalar value or array element.
+    // If this is one, the term represents a single bit (same as a bitvector
+    // of length 1).  It must be 1 or greater.
+    unsigned int _value_width;
+
+    // Increment refcount.
+#ifndef SMTLIB
+    void IncRef() { ++_ref_count; }
+#else
+    void IncRef() { }
+#endif
+
+    // DecRef is a potentially expensive, because it has to delete 
+    // the node from the unique table, in addition to freeing it.
+    // FIXME:  Consider putting in a backpointer (iterator) to the hash
+    // table entry so it can be deleted without looking it up again.
+    void DecRef();
+
+    virtual const Kind GetKind() const { return _kind; }
+
+    virtual ASTVec const &GetChildren() const { return _children; }
+
+    int GetNodeNum() const { return _node_num; }
+
+    void SetNodeNum(int nn) { _node_num = nn; };
+
+    // Constructor (bm only)
+    ASTInternal(BeevMgr &bm, int nodenum = 0) :
+      _ref_count(0),
+      _kind(UNDEFINED),
+      _bm(bm),
+      _node_num(nodenum),
+      _index_width(0),
+      _value_width(0) { }
+
+    // Constructor (kind only, empty children, int nodenum) 
+    ASTInternal(Kind kind, BeevMgr &bm, int nodenum = 0) : 
+      _ref_count(0),
+      _kind(kind),
+      _bm(bm),
+      _node_num(nodenum),
+      _index_width(0),
+      _value_width(0) { } 
+
+    // Constructor (kind and children).  This copies the contents of
+    // the child nodes.
+    // FIXME: is there a way to avoid repeating these?
+    ASTInternal(Kind kind, const ASTVec &children, BeevMgr &bm, int nodenum = 0) : 
+      _ref_count(0),
+      _kind(kind),
+      _children(children),
+      _bm(bm),
+      _node_num(nodenum),
+      _index_width(0),
+      _value_width(0) { } 
+
+    // Copy constructor.  This copies the contents of the child nodes
+    // array, along with everything else.  Assigning the smart pointer,
+    // ASTNode, does NOT invoke this; This should only be used for 
+    // temporary hash keys before uniquefication.
+    // FIXME:  I don't think children need to be copied.
+    ASTInternal(const ASTInternal &int_node, int nodenum = 0) :
+      _ref_count(0),
+      _kind(int_node._kind),
+      _children(int_node._children),
+      _bm(int_node._bm),
+      _node_num(int_node._node_num), 
+      _index_width(int_node._index_width),
+      _value_width(int_node._value_width) { } 
+
+    // Copying assign operator.  Also copies contents of children.
+    ASTInternal& operator=(const ASTInternal &int_node);
+
+    // Cleanup function for removing from hash table
+    virtual void CleanUp() = 0;
+
+    // Destructor (does nothing, but is declared virtual here.
+    virtual ~ASTInternal();
+
+    // Abstract virtual print function for internal node.
+    virtual void nodeprint(ostream& os) { os << "*"; };
+  }; //End of Class ASTInternal
+
+  // FIXME: Should children be only in interior node type?
+  /***************************************************************************
+    Class ASTInterior: Internal representation of an interior
+       ASTNode.  Generally, these nodes should have at least one
+      child
+  ***************************************************************************/
+  class ASTInterior : public ASTInternal {    
+
+    friend class BeevMgr;
+    friend class ASTNodeHasher;
+    friend class ASTNodeEqual;   
+
+  private:
+
+    // Hasher for ASTInterior pointer nodes
+    class ASTInteriorHasher {
+    public:
+      size_t operator()(const ASTInterior *int_node_ptr) const;
+    };
+
+    // Equality for ASTInterior nodes
+    class ASTInteriorEqual {
+    public:
+      bool operator()(const ASTInterior *int_node_ptr1, 
+		      const ASTInterior *int_node_ptr2) const{
+	return (*int_node_ptr1 == *int_node_ptr2);
+      }
+    };
+
+    // Used in Equality class for hash tables
+    friend bool operator==(const ASTInterior &int_node1, 
+			   const ASTInterior &int_node2){
+      return (int_node1._kind == int_node2._kind) && 
+	(int_node1._children == int_node2._children);
+    }
+
+    // Call this when deleting a node that has been stored in the
+    // the unique table
+    virtual void CleanUp();
+
+    // Returns kinds.  "lispprinter" handles printing of parenthesis
+    // and childnodes.
+    virtual void nodeprint(ostream& os) {
+      os << _kind_names[_kind];
+    }
+    public:
+
+    // FIXME: This should not be public, but has to be because the
+    // ASTInterior hash table insists on it.  I can't seem to make the
+    // private destructor visible to hash_set.  It does not even work
+    // to put "friend class hash_set<ASTInterior, ...>" in here.
+
+    // Basic constructors
+    ASTInterior(Kind kind,  BeevMgr &bm) :
+      ASTInternal(kind, bm) {  }    
+
+    ASTInterior(Kind kind, ASTVec &children, BeevMgr &bm) :
+      ASTInternal(kind, children, bm) {  }    
+
+    //Copy constructor.  This copies the contents of the child nodes
+    //array, along with everything else. Assigning the smart pointer,
+    //ASTNode, does NOT invoke this.
+    ASTInterior(const ASTInterior &int_node) : ASTInternal(int_node) { }
+
+    // Destructor (does nothing, but is declared virtual here.
+    virtual ~ASTInterior();
+
+  }; //End of ASTNodeInterior
+
+
+  /***************************************************************************/
+  /*  Class ASTSymbol:  Class to represent internals of Symbol node.         */
+  /***************************************************************************/
+  class ASTSymbol : public ASTInternal{
+    friend class BeevMgr;
+    friend class ASTNode;
+    friend class ASTNodeHasher;
+    friend class ASTNodeEqual;
+
+  private:
+    // The name of the symbol
+    const char * const _name;
+    
+    class ASTSymbolHasher{
+    public:
+      size_t operator() (const ASTSymbol *sym_ptr) const{ 
+	hash<char*> h; 
+	return h(sym_ptr->_name); 
+      };
+    };
+
+    // Equality for ASTInternal nodes
+    class ASTSymbolEqual{
+    public:
+      bool operator()(const ASTSymbol *sym_ptr1, const ASTSymbol *sym_ptr2) const{ 
+	return (*sym_ptr1 == *sym_ptr2); 
+      }
+    };
+
+    friend bool operator==(const ASTSymbol &sym1, const ASTSymbol &sym2){
+      return (strcmp(sym1._name, sym2._name) == 0);
+    }
+
+    const char * const GetName() const{return _name;}  
+
+    // Print function for symbol -- return name */
+    virtual void nodeprint(ostream& os) { os << _name;}
+
+    // Call this when deleting a node that has been stored in the
+    // the unique table
+    virtual void CleanUp();
+
+    public:
+
+    // Default constructor
+    ASTSymbol(BeevMgr &bm) : ASTInternal(bm), _name(NULL) { }
+
+    // Constructor.  This does NOT copy its argument.
+    ASTSymbol(const char * const name, BeevMgr &bm) : ASTInternal(SYMBOL, bm), 
+						      _name(name) { }
+    
+    // Destructor (does nothing, but is declared virtual here.
+    virtual ~ASTSymbol();
+    
+    // Copy constructor
+    // FIXME: seems to be calling default constructor for astinternal
+    ASTSymbol(const ASTSymbol &sym) :
+      ASTInternal(sym._kind, sym._children, sym._bm), 
+      _name(sym._name) { } 
+  }; //End of ASTSymbol
+  
+
+  /***************************************************************************/
+  /*  Class ASTBVConst:  Class to represent internals of a bitvectorconst    */
+  /***************************************************************************/
+
+#ifndef NATIVE_C_ARITH
+
+  class ASTBVConst : public ASTInternal {
+    friend class BeevMgr;
+    friend class ASTNode;
+    friend class ASTNodeHasher;
+    friend class ASTNodeEqual;
+    
+  private:
+    //This is the private copy of a bvconst currently
+    //This should not be changed at any point
+    CBV _bvconst;
+
+    class ASTBVConstHasher{
+    public:
+      size_t operator() (const ASTBVConst * bvc) const {
+        return CONSTANTBV::BitVector_Hash(bvc->_bvconst);
+      };
+    };
+
+    class ASTBVConstEqual{
+    public:
+      bool operator()(const ASTBVConst * bvc1, const ASTBVConst  * bvc2) const { 
+        if( bvc1->_value_width != bvc2->_value_width){
+	  return false;
+	}  
+	return (0==CONSTANTBV::BitVector_Compare(bvc1->_bvconst,bvc2->_bvconst));
+      }
+    };
+    
+    //FIXME Keep an eye on this function
+    ASTBVConst(CBV bv, unsigned int width, BeevMgr &bm) :
+      ASTInternal(BVCONST, bm)
+    {
+      _bvconst = CONSTANTBV::BitVector_Clone(bv);
+      _value_width = width;
+    }
+
+    friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2){
+      if(bvc1._value_width != bvc2._value_width)
+        return false;
+      return (0==CONSTANTBV::BitVector_Compare(bvc1._bvconst,bvc2._bvconst));
+    }
+    // Call this when deleting a node that has been stored in the
+    // the unique table
+    virtual void CleanUp();
+
+    // Print function for bvconst -- return _bvconst value in bin format
+    virtual void nodeprint(ostream& os) {
+      unsigned char *res;
+      const char *prefix;
+
+      if (_value_width%4 == 0) {
+        res = CONSTANTBV::BitVector_to_Hex(_bvconst);
+        prefix = "0hex";
+      } else {      
+        res = CONSTANTBV::BitVector_to_Bin(_bvconst);
+        prefix = "0bin";
+      }
+      if (NULL == res) {
+        os << "nodeprint: BVCONST : could not convert to string" << _bvconst;
+        FatalError("");
+      }
+      os << prefix << res;
+      CONSTANTBV::BitVector_Dispose(res);
+    }
+
+    // Copy constructor.     
+    ASTBVConst(const ASTBVConst &sym) : 
+      ASTInternal(sym._kind, sym._children, sym._bm)
+    {
+      _bvconst = CONSTANTBV::BitVector_Clone(sym._bvconst);
+      _value_width = sym._value_width;
+    }
+    
+  public:
+    virtual ~ASTBVConst(){
+       CONSTANTBV::BitVector_Destroy(_bvconst);
+    }
+
+    CBV GetBVConst() const {return _bvconst;}
+  }; //End of ASTBVConst
+
+  //FIXME This function is DEPRICATED
+  //Do not use in the future
+  inline unsigned int GetUnsignedConst(const ASTNode n) {
+    if(32 < n.GetValueWidth())
+      FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");
+        
+    return (unsigned int) *((unsigned int *)n.GetBVConst());
+  }
+#else
+  class ASTBVConst : public ASTInternal {
+    friend class BeevMgr;
+    friend class ASTNode;
+    friend class ASTNodeHasher;
+    friend class ASTNodeEqual;
+
+  private:
+    // the bitvector contents. bitvector contents will be in two
+    // modes. one mode where all bitvectors are NATIVE and in this
+    // mode we use native unsigned long long int to represent the
+    // 32/64 bitvectors. The other for arbitrary length bitvector
+    // operations.
+    const unsigned long long int _bvconst;
+
+    class ASTBVConstHasher{
+    public:
+      size_t operator() (const ASTBVConst * bvc) const{ 
+	//Thomas Wang's 64 bit Mix Function
+	unsigned long long int key(bvc->_bvconst);
+	key += ~(key << 32);
+	key ^= (key  >> 22);
+	key += ~(key << 13);
+	key ^= (key  >> 8);
+	key += (key  << 3);
+	key ^= (key  >> 15);
+	key += ~(key << 27);
+	key ^= (key  >> 31);
+	
+	size_t return_key = key;
+	return return_key;
+      };
+    };
+
+    class ASTBVConstEqual{
+    public:
+      bool operator()(const ASTBVConst * bvc1, const ASTBVConst  * bvc2) const { 
+	return ((bvc1->_bvconst == bvc2->_bvconst) 
+		&& (bvc1->_value_width == bvc2->_value_width));
+      }
+    };
+
+    // Call this when deleting a node that has been stored in the
+    // the unique table
+    virtual void CleanUp();
+  public:
+    // Default constructor
+    ASTBVConst(const unsigned long long int bv, BeevMgr &bm) : 
+      ASTInternal(BVCONST, bm), _bvconst(bv) { 
+    }
+
+    // Copy constructor. FIXME: figure out how this is supposed to
+    // work.
+    ASTBVConst(const ASTBVConst &sym) : 
+      ASTInternal(sym._kind, sym._children, sym._bm), 
+      _bvconst(sym._bvconst) { 
+      _value_width = sym._value_width;
+    } 
+
+    // Destructor (does nothing, but is declared virtual here)
+    virtual ~ASTBVConst() { } 
+    
+    friend bool operator==(const ASTBVConst &sym1, const ASTBVConst &sym2){
+      return ((sym1._bvconst == sym2._bvconst) && 
+	      (sym1._value_width == sym2._value_width));
+    }
+
+    // Print function for bvconst -- return _bvconst value in binary format
+    virtual void nodeprint(ostream& os) {
+      string s = "0bin";
+      unsigned long long int bitmask = 0x8000000000000000LL;
+      bitmask = bitmask >> (64-_value_width);
+
+      for (; bitmask > 0; bitmask >>= 1)
+	s += (_bvconst & bitmask) ? '1' : '0';	
+      os << s;
+    }
+    
+    unsigned long long int GetBVConst() const  {return _bvconst;}
+  }; //End of ASTBVConst
+
+  //return value of bvconst
+  inline unsigned int GetUnsignedConst(const ASTNode n) {
+    if(32 < n.GetValueWidth())
+      FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");    
+    return (unsigned int)n.GetBVConst();
+  }
+#endif
+/*
+#else
+  // the bitvector contents. bitvector contents will be in two
+  // modes. one mode where all bitvectors are NATIVE and in this mode
+  // we use native unsigned long long int to represent the 32/64
+  // bitvectors. The other for arbitrary length bitvector operations.
+
+  //BVCONST defined for arbitrary length bitvectors
+  class ASTBVConst : public ASTInternal{
+    friend class BeevMgr;
+    friend class ASTNode;
+    friend class ASTNodeHasher;
+    friend class ASTNodeEqual;
+
+  private:
+    const char * const _bvconst;
+
+    class ASTBVConstHasher{
+    public:
+      size_t operator() (const ASTBVConst * bvc) const{ 
+	hash<char*> h;	
+	return h(bvc->_bvconst);
+      };
+    };
+
+    class ASTBVConstEqual{
+    public:
+      bool operator()(const ASTBVConst * bvc1, const ASTBVConst  * bvc2) const { 
+	if(bvc1->_value_width != bvc2->_value_width)
+	  return false;
+	return (0 == strncmp(bvc1->_bvconst,bvc2->_bvconst,bvc1->_value_width));
+      }
+    };
+    
+    ASTBVConst(const char * bv, BeevMgr &bm) : 
+      ASTInternal(BVCONST, bm), _bvconst(bv) { 
+      //_value_width = strlen(bv);
+    }
+
+    friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2){
+      if(bvc1._value_width != bvc2._value_width)
+	return false;
+      return (0 == strncmp(bvc1._bvconst,bvc2._bvconst,bvc1._value_width));
+    }
+
+    // Call this when deleting a node that has been stored in the
+    // the unique table
+    virtual void CleanUp();
+
+    // Print function for bvconst -- return _bvconst value in binary format
+    virtual void nodeprint(ostream& os) {
+      if(_value_width%4 == 0) {
+	unsigned int *  iii = CONSTANTBV::BitVector_Create(_value_width,true);
+	CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,(unsigned char*)_bvconst);
+	//error printing
+	if(0 != e) {
+	  os << "nodeprint: BVCONST : wrong hex value: " << BitVector_Error(e);
+	  FatalError("");
+	}
+	unsigned char * ccc = CONSTANTBV::BitVector_to_Hex(iii);
+	os << "0hex" << ccc;
+	CONSTANTBV::BitVector_Destroy(iii);
+      }
+      else {
+	std::string s(_bvconst,_value_width);
+	s = "0bin" + s;
+	os << s;
+      }
+    }
+
+    // Copy constructor.     
+    ASTBVConst(const ASTBVConst &sym) : ASTInternal(sym._kind, sym._children, sym._bm),_bvconst(sym._bvconst) { 
+      //checking if the input is in the correct format
+      for(unsigned int jj=0;jj<sym._value_width;jj++)
+	if(!(sym._bvconst[jj] == '0' || sym._bvconst[jj] == '1')) {
+	  cerr << "Fatal Error: wrong input to ASTBVConst copy constructor:" << sym._bvconst << endl;
+	  FatalError("");
+	}
+      _value_width = sym._value_width;
+    } 
+  public:
+    // Destructor (does nothing, but is declared virtual here)
+    virtual ~ASTBVConst(){}
+
+    const char * const GetBVConst() const {return _bvconst;}
+  }; //End of ASTBVConst
+
+  unsigned int * ConvertToCONSTANTBV(const char * s);
+
+  //return value of bvconst
+  inline unsigned int GetUnsignedConst(const ASTNode n) {
+    if(32 < n.GetValueWidth())
+      FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");    
+    std::string s(n.GetBVConst(), n.GetValueWidth());
+      unsigned int output = strtoul(s.c_str(),NULL,2);
+      return output;
+  } //end of ASTBVConst class
+#endif
+*/
+  /***************************************************************************
+   * Typedef ASTNodeMap:  This is a hash table from ASTNodes to ASTNodes.
+   * It is very convenient for attributes that are not speed-critical
+   **************************************************************************/
+  // These are generally useful for storing ASTNodes or attributes thereof
+  // Hash table from ASTNodes to ASTNodes
+  typedef hash_map<ASTNode, ASTNode, 
+		   ASTNode::ASTNodeHasher, 
+		   ASTNode::ASTNodeEqual> ASTNodeMap;
+
+  // Function to dump contents of ASTNodeMap
+  ostream &operator<<(ostream &os, const ASTNodeMap &nmap);
+  
+  /***************************************************************************
+   Typedef ASTNodeSet:  This is a hash set of ASTNodes.  Very useful
+   for representing things like "visited nodes"
+  ***************************************************************************/
+  typedef hash_set<ASTNode, 
+		   ASTNode::ASTNodeHasher, 
+		   ASTNode::ASTNodeEqual> ASTNodeSet;
+
+  typedef hash_multiset<ASTNode, 
+			ASTNode::ASTNodeHasher, 
+			ASTNode::ASTNodeEqual> ASTNodeMultiSet;
+
+  //external parser table for declared symbols.
+  //FIXME: move to a more appropriate place
+  extern ASTNodeSet _parser_symbol_table;
+  
+  /***************************************************************************
+    Class LispPrinter:  iomanipulator for printing ASTNode or ASTVec       
+  ***************************************************************************/
+  class LispPrinter {
+
+  public:
+    ASTNode _node;
+
+    // number of spaces to print before first real character of
+    // object.
+    int _indentation;  
+
+    // FIXME: pass ASTNode by reference
+    // Constructor to build the LispPrinter object
+    LispPrinter(ASTNode node, int indentation): _node(node), _indentation(indentation) { }    
+
+    friend ostream &operator<<(ostream &os, const LispPrinter &lp){ 
+      return lp._node.LispPrint(os, lp._indentation); 
+    };
+
+  }; //End of ListPrinter
+  
+  //This is the IO manipulator.  It builds an object of class
+  //"LispPrinter" that has a special overloaded "<<" operator.
+  inline LispPrinter lisp(const ASTNode &node, int indentation = 0){
+    LispPrinter lp(node, indentation);
+    return lp;
+  }
+  
+  /***************************************************************************/
+  /*  Class LispVecPrinter:iomanipulator for printing vector of ASTNodes     */
+  /***************************************************************************/
+  class LispVecPrinter {
+
+  public:
+    const ASTVec * _vec;
+    // number of spaces to print before first real
+    // character of object.    
+    int _indentation;
+    
+    // Constructor to build the LispPrinter object
+    LispVecPrinter(const ASTVec &vec, int indentation){
+      _vec = &vec; _indentation = indentation; 
+    }
+    
+    friend ostream &operator<<(ostream &os, const LispVecPrinter &lvp){
+    LispPrintVec(os, *lvp._vec, lvp._indentation);
+    return os;
+    };
+  }; //End of Class ListVecPrinter
+
+  //iomanipulator. builds an object of class "LisPrinter" that has a
+  //special overloaded "<<" operator.
+  inline LispVecPrinter lisp(const ASTVec &vec, int indentation = 0){
+    LispVecPrinter lvp(vec, indentation);
+    return lvp;
+  }
+
+
+  /*****************************************************************
+   * INLINE METHODS from various classed, declared here because of
+   * dependencies on classes that are declared later.
+   *****************************************************************/
+  // ASTNode accessor function.
+  inline Kind ASTNode::GetKind() const { 
+    //cout << "GetKind: " << _int_node_ptr; 
+    return _int_node_ptr->GetKind(); 
+  }
+
+  // FIXME: should be const ASTVec const?  
+  // Declared here because of same ordering problem as  GetKind.
+  inline const ASTVec &ASTNode::GetChildren() const { 
+    return _int_node_ptr->GetChildren(); 
+  }
+
+  // Access node number
+  inline int ASTNode::GetNodeNum() const { 
+    return _int_node_ptr->_node_num; 
+  }
+
+  inline unsigned int ASTNode::GetIndexWidth () const { 
+    return _int_node_ptr->_index_width; 
+  }
+  
+  inline void ASTNode::SetIndexWidth (unsigned int iw) const { 
+    _int_node_ptr->_index_width = iw;
+  }
+  
+  inline unsigned int ASTNode::GetValueWidth () const { 
+    return _int_node_ptr->_value_width; 
+  }
+  
+  inline void ASTNode::SetValueWidth (unsigned int vw) const {
+    _int_node_ptr->_value_width = vw; 
+  }
+
+  //return the type of the ASTNode: 0 iff BOOLEAN; 1 iff BITVECTOR; 2
+  //iff ARRAY; 3 iff UNKNOWN;
+  inline types ASTNode::GetType() const {
+    if((GetIndexWidth() == 0) && (GetValueWidth() == 0)) //BOOLEAN
+      return BOOLEAN_TYPE;
+    if((GetIndexWidth() == 0) && (GetValueWidth() > 0))  //BITVECTOR
+      return BITVECTOR_TYPE;
+    if((GetIndexWidth() > 0) && (GetValueWidth() > 0)) //ARRAY
+      return ARRAY_TYPE;
+    return UNKNOWN_TYPE; 
+  }
+
+  // Constructor; creates a new pointer, increments refcount of
+  // pointed-to object.
+#ifndef SMTLIB
+  inline ASTNode::ASTNode(ASTInternal *in) : _int_node_ptr(in) { 
+    if (in) in->IncRef(); 
+  }
+#else
+  inline ASTNode::ASTNode(ASTInternal *in) : _int_node_ptr(in) { };
+#endif
+
+  // Assignment.  Increment refcount of new value, decrement refcount
+  // of old value and destroy if this was the last pointer.  FIXME:
+  // accelerate this by creating an intnode with a ref counter instead
+  // of pointing to NULL.  Need a special check in CleanUp to make
+  // sure the null node never gets freed.
+
+#ifndef SMTLIB
+  inline ASTNode& ASTNode::operator=(const ASTNode& n) {
+    if (n._int_node_ptr) {
+      n._int_node_ptr->IncRef();
+    }
+    if (_int_node_ptr) {
+      _int_node_ptr->DecRef();
+    }
+    _int_node_ptr = n._int_node_ptr;
+    return *this;
+  }
+#else
+  inline ASTNode& ASTNode::operator=(const ASTNode& n) {
+    _int_node_ptr = n._int_node_ptr;
+    return *this;
+  }
+#endif
+
+#ifndef SMTLIB
+  inline void ASTInternal::DecRef()
+  {
+    if (--_ref_count == 0) {
+      // Delete node from unique table and kill it.
+      CleanUp();
+    }
+  }
+
+  // Destructor
+  inline ASTNode::~ASTNode()
+  {
+    if (_int_node_ptr) {
+      _int_node_ptr->DecRef();
+    }
+  };
+#else
+  // No refcounting
+  inline void ASTInternal::DecRef()
+  {
+  }
+
+  // Destructor
+  inline ASTNode::~ASTNode()
+  {
+  };
+#endif
+
+  inline BeevMgr& ASTNode::GetBeevMgr() const { return _int_node_ptr->_bm; }
+
+  /***************************************************************************
+   * Class BeevMgr.  This holds all "global" variables for the system, such as
+   * unique tables for the various kinds of nodes.
+   ***************************************************************************/
+  class BeevMgr {
+    friend class ASTNode;	// ASTNode modifies AlreadyPrintedSet
+				// in BeevMgr
+    friend class ASTInterior;
+    friend class ASTBVConst;
+    friend class ASTSymbol;
+
+    // FIXME: The values appear to be the same regardless of the value of SMTLIB
+    // initial hash table sizes, to save time on resizing.
+#ifdef SMTLIB
+    static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
+    static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
+    static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
+    static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
+    static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
+
+    static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
+    static const int INITIAL_SOLVER_MAP_SIZE = 100;
+    static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
+    static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
+#else
+    // these are the STL defaults
+    static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
+    static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
+    static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
+    static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
+    static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
+
+    static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
+    static const int INITIAL_SOLVER_MAP_SIZE = 100;
+    static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
+    static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
+#endif
+
+  private:
+    // Typedef for unique Interior node table. 
+    typedef hash_set<ASTInterior *, 
+		     ASTInterior::ASTInteriorHasher, 
+		     ASTInterior::ASTInteriorEqual> ASTInteriorSet;
+
+    // Typedef for unique Symbol node (leaf) table.
+    typedef hash_set<ASTSymbol *, 
+		     ASTSymbol::ASTSymbolHasher, 
+		     ASTSymbol::ASTSymbolEqual> ASTSymbolSet;
+
+    // Unique tables to share nodes whenever possible.
+    ASTInteriorSet _interior_unique_table;
+    //The _symbol_unique_table is also the symbol table to be used
+    //during parsing/semantic analysis
+    ASTSymbolSet _symbol_unique_table;
+    
+    //Typedef for unique BVConst node (leaf) table.
+    typedef hash_set<ASTBVConst *, 
+		     ASTBVConst::ASTBVConstHasher,
+		     ASTBVConst::ASTBVConstEqual> ASTBVConstSet;
+
+    //table to uniquefy bvconst
+    ASTBVConstSet _bvconst_unique_table;
+
+    // type of memo table.
+    typedef hash_map<ASTNode, ASTVec,
+		     ASTNode::ASTNodeHasher, 
+		     ASTNode::ASTNodeEqual> ASTNodeToVecMap;
+
+    typedef hash_map<ASTNode,ASTNodeSet,
+		     ASTNode::ASTNodeHasher,
+		     ASTNode::ASTNodeEqual> ASTNodeToSetMap;
+    
+    // Memo table for bit blasted terms.  If a node has already been
+    // bitblasted, it is mapped to a vector of Boolean formulas for
+    // the bits.
+    
+    //OLD: ASTNodeToVecMap BBTermMemo;
+    ASTNodeMap BBTermMemo;
+    
+    // Memo table for bit blasted formulas.  If a node has already
+    // been bitblasted, it is mapped to a node representing the
+    // bitblasted equivalent
+    ASTNodeMap BBFormMemo;
+    
+    //public:
+    // Get vector of Boolean formulas for sum of two
+    // vectors of Boolean formulas
+    void BBPlus2(ASTVec& sum, const ASTVec& y, ASTNode cin);
+    // Increment
+    ASTVec BBInc(ASTVec& x);
+    // Add one bit to a vector of bits.
+    ASTVec BBAddOneBit(ASTVec& x, ASTNode cin);
+    // Bitwise complement
+    ASTVec BBNeg(const ASTVec& x);
+    // Unary minus
+    ASTVec BBUminus(const ASTVec& x);
+    // Multiply.
+    ASTVec BBMult(const ASTVec& x, const ASTVec& y);
+    // AND each bit of vector y with single bit b and return the result.
+    // (used in BBMult)
+    ASTVec BBAndBit(const ASTVec& y, ASTNode b);
+    // Returns ASTVec for result - y.  This destroys "result".
+    void BBSub(ASTVec& result, const ASTVec& y);
+    // build ITE's (ITE cond then[i] else[i]) for each i.
+    ASTVec BBITE(const ASTNode& cond, 
+		 const ASTVec& thn, const ASTVec& els);
+    // Build a vector of zeros.
+    ASTVec BBfill(unsigned int width, ASTNode fillval);
+    // build an EQ formula
+    ASTNode BBEQ(const ASTVec& left, const ASTVec& right);
+
+    // This implements a variant of binary long division.
+    // q and r are "out" parameters.  rwidth puts a bound on the
+    // recursion depth.   Unsigned only, for now.
+    void BBDivMod(const ASTVec &y,
+		  const ASTVec &x,
+		  ASTVec &q,
+		  ASTVec &r,
+		  unsigned int rwidth);
+    
+    // Return formula for majority function of three formulas.
+    ASTNode Majority(const ASTNode& a, const ASTNode& b, const ASTNode& c);
+
+    // Internal bit blasting routines.
+    ASTNode BBBVLE(const ASTVec& x, const ASTVec& y, bool is_signed);
+
+    // Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc. 
+    ASTNode BBcompare(const ASTNode& form);
+
+    // Left and right shift one.  Writes into x.
+    void BBLShift(ASTVec& x);
+    void BBRShift(ASTVec& x);
+
+  public:
+    // Simplifying create functions
+    ASTNode CreateSimpForm(Kind kind, ASTVec &children);
+    ASTNode CreateSimpForm(Kind kind, const ASTNode& child0);
+    ASTNode CreateSimpForm(Kind kind,
+				    const ASTNode& child0,
+				    const ASTNode& child1);
+    ASTNode CreateSimpForm(Kind kind,
+				    const ASTNode& child0,
+				    const ASTNode& child1,
+				    const ASTNode& child2);
+
+    ASTNode CreateSimpNot(const ASTNode& form);
+
+    // These are for internal use only.
+    // FIXME: Find a way to make this local to SimpBool, so they're
+    // not in AST.h
+    ASTNode CreateSimpXor(const ASTNode& form1,
+			  const ASTNode& form2);
+    ASTNode CreateSimpXor(ASTVec &children);
+    ASTNode CreateSimpAndOr(bool isAnd,
+				     const ASTNode& form1,
+				     const ASTNode& form2);
+    ASTNode CreateSimpAndOr(bool IsAnd, ASTVec &children);
+    ASTNode CreateSimpFormITE(const ASTNode& child0,
+				       const ASTNode& child1,
+				       const ASTNode& child2);
+    
+
+    // Declarations of BitBlaster functions (BitBlast.cpp)
+  public:
+    // Adds or removes a NOT as necessary to negate a literal.
+    ASTNode Negate(const ASTNode& form);
+
+    // Bit blast a bitvector term.  The term must have a kind for a
+    // bitvector term.  Result is a ref to a vector of formula nodes
+    // representing the boolean formula.
+    const ASTNode BBTerm(const ASTNode& term);
+
+    const ASTNode BBForm(const ASTNode& formula);
+
+    // Declarations of CNF conversion (ToCNF.cpp)
+  public:
+    // ToCNF converts a bit-blasted Boolean formula to Conjunctive
+    // 	Normal Form, suitable for many SAT solvers.  Our CNF representation
+    // 	is an STL vector of STL vectors, for independence from any particular
+    // 	SAT solver's representation.  There needs to be a separate driver to
+    // 	convert our clauselist to the representation used by the SAT solver.    
+    // 	Currently, there is only one such solver and its driver is "ToSAT"
+    
+    // Datatype for clauses
+    typedef ASTVec * ClausePtr;
+    
+    // Datatype for Clauselists
+    typedef vector<ClausePtr> ClauseList;
+
+    // Convert a Boolean formula to an equisatisfiable CNF formula.
+    ClauseList *ToCNF(const ASTNode& form);
+
+    // Print function for debugging
+    void PrintClauseList(ostream& os, ClauseList& cll); 
+
+    // Free the clause list and all its clauses.
+    void DeleteClauseList(BeevMgr::ClauseList *cllp);
+
+    // Map from formulas to representative literals, for debugging.
+    ASTNodeMap RepLitMap;
+
+  private:
+    // Global for assigning new node numbers.
+    int _max_node_num;
+    
+    const ASTNode ASTFalse, ASTTrue, ASTUndefined;
+    
+    // I just did this so I could put it in as a fake return value in
+    // methods that return a ASTNode &, to make -Wall shut up.
+    ASTNode dummy_node;
+
+    //BeevMgr Constructor, Destructor and other misc. functions
+  public:
+
+    int NewNodeNum() { _max_node_num += 2; return _max_node_num; } 
+    
+    // Table for DAG printing.
+    ASTNodeSet AlreadyPrintedSet;
+
+    //Tables for Presentation language printing
+
+    //Nodes seen so far
+    ASTNodeSet PLPrintNodeSet;
+
+    //Map from ASTNodes to LetVars
+    ASTNodeMap NodeLetVarMap;
+    
+    //This is a vector which stores the Node to LetVars pairs. It
+    //allows for sorted printing, as opposed to NodeLetVarMap
+    std::vector<pair<ASTNode,ASTNode> > NodeLetVarVec;
+
+    //a partial Map from ASTNodes to LetVars. Needed in order to
+    //correctly print shared subterms inside the LET itself
+    ASTNodeMap NodeLetVarMap1;
+
+    //functions to lookup nodes from the memo tables. these should be
+    //private.
+  private:
+    //Destructively appends back_child nodes to front_child nodes.
+    //If back_child nodes is NULL, no appending is done.  back_child
+    //nodes are not modified.  Then it returns the hashed copy of the
+    //node, which is created if necessary.
+    ASTInterior *CreateInteriorNode(Kind kind,
+				    ASTInterior *new_node,
+				    // this is destructively modified.
+				    const ASTVec & back_children = _empty_ASTVec);
+
+    // Create unique ASTInterior node.
+    ASTInterior *LookupOrCreateInterior(ASTInterior *n);
+
+    // Create unique ASTSymbol node. 
+    ASTSymbol *LookupOrCreateSymbol(ASTSymbol& s);
+    
+    // Called whenever we want to make sure that the Symbol is
+    // declared during semantic analysis
+    bool LookupSymbol(ASTSymbol& s);
+      
+    // Called by ASTNode constructors to uniqueify ASTBVConst
+    ASTBVConst *LookupOrCreateBVConst(ASTBVConst& s);
+
+    //Public functions for CreateNodes and Createterms
+  public:
+    // Create and return an ASTNode for a symbol
+    ASTNode CreateSymbol(const char * const name);
+
+    // Create and return an ASTNode for a symbol
+    // Width is number of bits.
+    ASTNode CreateBVConst(unsigned int width, unsigned long long int bvconst);
+    ASTNode CreateZeroConst(unsigned int width);
+    ASTNode CreateOneConst(unsigned int width);
+    ASTNode CreateTwoConst(unsigned int width);
+    ASTNode CreateMaxConst(unsigned int width);
+
+    // Create and return an ASTNode for a symbol
+    // Optional base was a problem because 0 could be an int or char *,
+    // so CreateBVConst was ambiguous.
+    ASTNode CreateBVConst(const char *strval, int base);
+
+    //FIXME This is a dangerous function 
+    ASTNode CreateBVConst(CBV bv, unsigned width);
+
+    // Create and return an interior ASTNode
+    ASTNode CreateNode(Kind kind, const ASTVec &children = _empty_ASTVec);
+
+    ASTNode CreateNode(Kind kind,
+		       const ASTNode& child0,
+		       const ASTVec &children = _empty_ASTVec);
+
+    ASTNode CreateNode(Kind kind,
+		       const ASTNode& child0,
+		       const ASTNode& child1,
+		       const ASTVec &children = _empty_ASTVec);    
+
+    ASTNode CreateNode(Kind kind,
+		       const ASTNode& child0,
+		       const ASTNode& child1,
+		       const ASTNode& child2,
+		       const ASTVec &children = _empty_ASTVec);
+
+    // Create and return an ASTNode for a term
+    inline ASTNode CreateTerm(Kind kind, 
+		       unsigned int width, 
+		       const ASTVec &children = _empty_ASTVec) {
+      if(!is_Term_kind(kind))
+	FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
+      ASTNode n = CreateNode(kind, children);
+      n.SetValueWidth(width);
+
+      //by default we assume that the term is a Bitvector. If
+      //necessary the indexwidth can be changed later
+      n.SetIndexWidth(0);
+      return n;
+    }
+
+    inline ASTNode CreateTerm(Kind kind,
+		       unsigned int width,
+		       const ASTNode& child0,
+		       const ASTVec &children = _empty_ASTVec) {
+      if(!is_Term_kind(kind))
+	FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
+      ASTNode n = CreateNode(kind, child0, children);
+      n.SetValueWidth(width);
+      return n;
+    }
+     
+    inline ASTNode CreateTerm(Kind kind,
+		       unsigned int width,
+		       const ASTNode& child0,
+		       const ASTNode& child1,
+		       const ASTVec &children = _empty_ASTVec) {
+      if(!is_Term_kind(kind))
+	FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
+      ASTNode n = CreateNode(kind, child0, child1, children);
+      n.SetValueWidth(width);
+      return n;
+    }
+
+    inline ASTNode CreateTerm(Kind kind,
+		       unsigned int width,
+		       const ASTNode& child0,
+		       const ASTNode& child1,
+		       const ASTNode& child2,
+		       const ASTVec &children = _empty_ASTVec) {
+      if(!is_Term_kind(kind))
+	FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
+      ASTNode n = CreateNode(kind, child0, child1, child2, children);
+      n.SetValueWidth(width);
+      return n;
+    }
+
+    ASTNode SimplifyFormula_NoRemoveWrites(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyFormula_TopLevel(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyTerm_TopLevel(const ASTNode& b);
+    ASTNode SimplifyTerm(const ASTNode& a);
+    void CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output);    
+  private:
+    //memo table for simplifcation
+    ASTNodeMap SimplifyMap;
+    ASTNodeMap SimplifyNegMap;
+    ASTNodeMap SolverMap;
+    ASTNodeSet AlwaysTrueFormMap;
+    ASTNodeMap MultInverseMap;
+
+  public:
+    ASTNode SimplifyAtomicFormula(const ASTNode& a, bool pushNeg);
+    ASTNode CreateSimplifiedEQ(const ASTNode& t1, const ASTNode& t2);
+    ASTNode ITEOpt_InEqs(const ASTNode& in1);
+    ASTNode CreateSimplifiedTermITE(const ASTNode& t1, const ASTNode& t2, const ASTNode& t3);
+    ASTNode CreateSimplifiedINEQ(Kind k, const ASTNode& a0, const ASTNode& a1, bool pushNeg);
+    ASTNode SimplifyNotFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyAndOrFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyXorFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyNandFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyNorFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyImpliesFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyIffFormula(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyIteFormula(const ASTNode& a, bool pushNeg);
+    ASTNode FlattenOneLevel(const ASTNode& a);
+    ASTNode FlattenAndOr(const ASTNode& a);
+    ASTNode CombineLikeTerms(const ASTNode& a);
+    ASTNode LhsMinusRhs(const ASTNode& eq);
+    ASTNode DistributeMultOverPlus(const ASTNode& a, 
+				   bool startdistribution=false);
+    ASTNode ConvertBVSXToITE(const ASTNode& a);
+    //checks if the input constant is odd or not
+    bool BVConstIsOdd(const ASTNode& c);
+    //computes the multiplicatve inverse of the input
+    ASTNode MultiplicativeInverse(const ASTNode& c);
+ 
+    void ClearAllTables(void);
+    void ClearAllCaches(void);
+    int  BeforeSAT_ResultCheck(const ASTNode& q);
+    int  CallSAT_ResultCheck(MINISAT::Solver& newS, 
+			     const ASTNode& q, const ASTNode& orig_input);   
+    int  SATBased_ArrayReadRefinement(MINISAT::Solver& newS, 
+				      const ASTNode& q, const ASTNode& orig_input);
+    int SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input);
+    //creates array write axiom only for the input term or formula, if
+    //necessary. If there are no axioms to produce then it simply
+    //generates TRUE
+    ASTNode Create_ArrayWriteAxioms(const ASTNode& array_readoverwrite_term, const ASTNode& array_newname);
+    ASTVec ArrayWrite_RemainingAxioms;
+    //variable indicates that counterexample will now be checked by
+    //the counterexample checker, and hence simplifyterm must switch
+    //off certain optimizations. In particular, array write
+    //optimizations
+    bool start_abstracting;
+    bool Begin_RemoveWrites;
+    bool SimplifyWrites_InPlace_Flag;
+
+    void CopySolverMap_To_CounterExample(void);
+    //int LinearSearch(const ASTNode& orig_input);    
+    //Datastructures and functions needed for counterexample
+    //generation, and interface with MINISAT
+  private:
+    /* MAP: This is a map from ASTNodes to MINISAT::Vars. 
+     *
+     * The map is populated while ASTclauses are read from the AST
+     * ClauseList returned by CNF converter. For every new boolean
+     * variable in ASTClause a new MINISAT::Var is created (these vars
+     * typedefs for ints)
+     */
+    typedef hash_map<ASTNode, MINISAT::Var, 
+		     ASTNode::ASTNodeHasher, 
+		     ASTNode::ASTNodeEqual> ASTtoSATMap;        
+    ASTtoSATMap _ASTNode_to_SATVar;
+
+  public:  
+    //converts the clause to SAT and calls SAT solver
+    bool toSATandSolve(MINISAT::Solver& S, ClauseList& cll);
+
+    ///print SAT solver statistics
+    void PrintStats(MINISAT::SolverStats& stats);
+
+    //accepts query and returns the answer. if query is valid, return
+    //true, else return false. Automatically constructs counterexample
+    //for invalid queries, and prints them upon request.
+    int TopLevelSAT(const ASTNode& query, const ASTNode& asserts);
+
+    // Debugging function to find problems in BitBlast and ToCNF.
+    // See body in ToSAT.cpp for more explanation.
+    ASTNode CheckBBandCNF(MINISAT::Solver& newS, ASTNode form);
+
+    // Internal recursive body of above.
+    ASTNode CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form);
+
+    // Helper function for CheckBBandCNF
+    ASTNode SymbolTruthValue(MINISAT::Solver &newS, ASTNode form); 
+
+    //looksup a MINISAT var from the minisat-var memo-table. if none
+    //exists, then creates one.
+    const MINISAT::Var LookupOrCreateSATVar(MINISAT::Solver& S, const ASTNode& n);
+
+    // Memo table for CheckBBandCNF debugging function
+    ASTNodeMap CheckBBandCNFMemo;
+
+
+    //Data structures for Array Read Transformations
+  private:
+    /* MAP: This is a map from Array Names to list of array-read
+     * indices in the input. This map is used by the TransformArray()
+     * function
+     *
+     * This map is useful in converting array reads into nested ITE
+     * constructs. Suppose there are two array reads in the input
+     * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
+     * symbolic constant, say v1, and Read(A,j) is replaced with the
+     * following ITE:
+     *
+     * ITE(i=j,v1,v2)
+     */
+    //CAUTION: I tried using a set instead of vector for
+    //readindicies. for some odd reason the performance went down
+    //considerably. this is totally inexplicable.
+    ASTNodeToVecMap _arrayname_readindices;
+        
+    /* MAP: This is a map from Array Names to nested ITE constructs,
+     * which are built as described below. This map is used by the
+     * TransformArray() function
+     *
+     * This map is useful in converting array reads into nested ITE
+     * constructs. Suppose there are two array reads in the input
+     * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
+     * symbolic constant, say v1, and Read(A,j) is replaced with the
+     * following ITE:
+     *
+     * ITE(i=j,v1,v2)
+     */
+    ASTNodeMap _arrayread_ite;
+
+    /*MAP: This is a map from array-reads to symbolic constants. This
+     *map is used by the TransformArray()
+     */
+    ASTNodeMap _arrayread_symbol;
+
+    ASTNodeSet _introduced_symbols;
+
+    /*Memoization map for TransformFormula/TransformTerm/TransformArray function
+     */
+    ASTNodeMap TransformMap;
+    
+    //count to keep track of new symbolic constants introduced
+    //corresponding to Array Reads
+    unsigned int _symbol_count;
+
+    //Formula/Term Transformers. Let Expr Manager, Type Checker
+  public:
+    //Functions that Transform ASTNodes
+    ASTNode TransformFormula(const ASTNode& query);
+    ASTNode TransformTerm(const ASTNode& term);
+    ASTNode TransformArray(const ASTNode& term);
+    ASTNode TranslateSignedDivMod(const ASTNode& term);
+
+    //LET Management
+  private:
+    // MAP: This map is from bound IDs that occur in LETs to
+    // expression. The map is useful in checking replacing the IDs
+    // with the corresponding expressions.
+    ASTNodeMap _letid_expr_map;
+  public:
+
+    ASTNode ResolveID(const ASTNode& var);
+
+    //Functions that are used to manage LET expressions
+    void LetExprMgr(const ASTNode& var, const ASTNode& letExpr);
+
+    //Delete Letid Map
+    void CleanupLetIDMap(void);
+
+    //Allocate LetID map
+    void InitializeLetIDMap(void);
+
+    //Substitute Let-vars with LetExprs
+    ASTNode SubstituteLetExpr(ASTNode inExpr);
+
+    /* MAP: This is a map from MINISAT::Vars to ASTNodes
+     *
+     * This is a reverse map, useful in constructing
+     * counterexamples. MINISAT returns a model in terms of MINISAT
+     * Vars, and this map helps us convert it to a model over ASTNode
+     * variables.
+     */    
+    vector<ASTNode> _SATVar_to_AST;
+
+  private:        
+    /* MAP: This is a map from ASTNodes to vectors of bits
+     *
+     * This map is used in constructing and printing
+     * counterexamples. MINISAT returns values for each bit (a
+     * BVGETBIT Node), and this maps allows us to assemble the bits
+     * into bitvectors.
+     */    
+    typedef hash_map<ASTNode, hash_map<unsigned int, bool> *, 
+		     ASTNode::ASTNodeHasher, 
+		     ASTNode::ASTNodeEqual> ASTtoBitvectorMap;        
+    ASTtoBitvectorMap _ASTNode_to_Bitvector;
+
+    //Data structure that holds the counter-model
+    ASTNodeMap CounterExampleMap;
+
+    //Checks if the counter_example is ok. In order for the
+    //counter_example to be ok, Every assert must evaluate to true 
+    //w.r.t couner_example and the query must evaluate to
+    //false. Otherwise the counter_example is bogus.
+    void CheckCounterExample(bool t);    
+
+    //Converts a vector of bools to a BVConst
+    ASTNode BoolVectoBVConst(hash_map<unsigned,bool> * w, unsigned int l);
+
+    //accepts a term and turns it into a constant-term w.r.t counter_example 
+    ASTNode TermToConstTermUsingModel(const ASTNode& term, bool ArrayReadFlag = true);
+    ASTNode Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool ArrayReadFlag = true);
+    //Computes the truth value of a formula w.r.t counter_example
+    ASTNode ComputeFormulaUsingModel(const ASTNode& form);
+
+    //Replaces WRITE(Arr,i,val) with ITE(j=i, val, READ(Arr,j))
+    ASTNode RemoveWrites_TopLevel(const ASTNode& term);
+    ASTNode RemoveWrites(const ASTNode& term);
+    ASTNode SimplifyWrites_InPlace(const ASTNode& term);
+    ASTNode ReadOverWrite_To_ITE(const ASTNode& term);
+
+    ASTNode NewArrayVar(unsigned int index, unsigned int value);
+    ASTNode NewVar(unsigned int valuewidth);
+    //For ArrayWrite Abstraction: map from read-over-write term to
+    //newname.
+    ASTNodeMap ReadOverWrite_NewName_Map;
+    //For ArrayWrite Refinement: Map new arraynames to Read-Over-Write
+    //terms
+    ASTNodeMap NewName_ReadOverWrite_Map;
+    
+  public:
+    //print the STP solver output
+    void PrintOutput(bool true_iff_valid);
+
+    //Converts MINISAT counterexample into an AST memotable (i.e. the
+    //function populates the datastructure CounterExampleMap)
+    void ConstructCounterExample(MINISAT::Solver& S);
+
+    //Prints the counterexample to stdout
+    void PrintCounterExample(bool t,std::ostream& os=cout);
+
+    //Prints the counterexample to stdout
+    void PrintCounterExample_InOrder(bool t);
+
+    //queries the counterexample, and returns the value corresponding
+    //to e
+    ASTNode GetCounterExample(bool t, const ASTNode& e);
+
+    int CounterExampleSize(void) const {return CounterExampleMap.size();}
+
+    //FIXME: This is bloody dangerous function. Hack attack to take
+    //care of requests from users who want to store complete
+    //counter-examples in their own data structures.
+    ASTNodeMap GetCompleteCounterExample() {return CounterExampleMap;}
+
+    // prints MINISAT assigment one bit at a time, for debugging.
+    void PrintSATModel(MINISAT::Solver& S);
+
+    //accepts constant input and normalizes it. 
+    ASTNode BVConstEvaluator(const ASTNode& t);
+
+    //FUNCTION TypeChecker: Assumes that the immediate Children of the
+    //input ASTNode have been typechecked. This function is suitable
+    //in scenarios like where you are building the ASTNode Tree, and
+    //you typecheck as you go along. It is not suitable as a general
+    //typechecker
+    void BVTypeCheck(const ASTNode& n);
+    
+  private:
+    //stack of Logical Context. each entry in the stack is a logical
+    //context. A logical context is a vector of assertions. The
+    //logical context is represented by a ptr to a vector of
+    //assertions in that logical context. Logical contexts are created
+    //by PUSH/POP
+    std::vector<ASTVec *>  _asserts;
+    //The query for the current logical context.
+    ASTNode _current_query;
+
+    //this flag, when true, indicates that counterexample is being
+    //checked by the counterexample checker
+    bool counterexample_checking_during_refinement;
+
+    //this flag indicates as to whether the input has been determined to
+    //be valid or not by this tool
+    bool ValidFlag;
+
+    //this flag, when true, indicates that a BVDIV divide by zero
+    //exception occured. However, the program must not exit with a
+    //fatalerror. Instead, it should evaluate the whole formula (which
+    //contains the BVDIV term) to be FALSE.
+    bool bvdiv_exception_occured;
+
+  public:
+    //set of functions that manipulate Logical Contexts.
+    //
+    //add an assertion to the current logical context
+    void AddAssert(const ASTNode& assert);
+    void Push(void);
+    void Pop(void);
+    void AddQuery(const ASTNode& q);    
+    const ASTNode PopQuery();
+    const ASTNode GetQuery();
+    const ASTVec GetAsserts(void);
+
+    //reports node size.  Second arg is "clearstatinfo", whatever that is.
+    unsigned int NodeSize(const ASTNode& a, bool t = false);
+
+  private:
+    //This memo map is used by the ComputeFormulaUsingModel()
+    ASTNodeMap ComputeFormulaMap;
+    //Map for statiscal purposes
+    ASTNodeSet StatInfoSet;
+
+
+    ASTNodeMap TermsAlreadySeenMap;
+    ASTNode CreateSubstitutionMap(const ASTNode& a);
+  public:
+    //prints statistics for the ASTNode. can add a prefix string c
+    void ASTNodeStats(const char * c, const ASTNode& a);
+
+    //substitution
+    bool CheckSubstitutionMap(const ASTNode& a, ASTNode& output);  
+    bool CheckSubstitutionMap(const ASTNode& a);
+    bool UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1);
+    //if (a > b) in the termorder, then return 1
+    //elseif (a < b) in the termorder, then return -1
+    //else return 0
+    int TermOrder(const ASTNode& a, const ASTNode& b);
+    //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
+    //and index is a BVCONST
+    void FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1);
+    bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
+
+    //functions for checking and updating simplifcation map
+    bool CheckSimplifyMap(const ASTNode& key, ASTNode& output, bool pushNeg);
+    void UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg);
+    bool CheckAlwaysTrueFormMap(const ASTNode& key);
+    void UpdateAlwaysTrueFormMap(const ASTNode& val);
+    bool CheckMultInverseMap(const ASTNode& key, ASTNode& output);
+    void UpdateMultInverseMap(const ASTNode& key, const ASTNode& value);
+
+    //Map for solved variables
+    bool CheckSolverMap(const ASTNode& a, ASTNode& output);
+    bool CheckSolverMap(const ASTNode& a);
+    bool UpdateSolverMap(const ASTNode& e0, const ASTNode& e1);
+  public:
+    //FIXME: HACK_ATTACK. this vector was hacked into the code to
+    //support a special request by Dawson' group. They want the
+    //counterexample to be printed in the order of variables declared.
+    //TO BE COMMENTED LATER (say by 1st week of march,2006)
+    ASTVec _special_print_set;
+
+    //prints the initial activity levels of variables
+    void PrintActivityLevels_Of_SATVars(char * init_msg, MINISAT::Solver& newS);
+
+    //this function biases the activity levels of MINISAT variables.
+    void ChangeActivityLevels_Of_SATVars(MINISAT::Solver& n);
+
+    // Constructor
+    BeevMgr() : _interior_unique_table(INITIAL_INTERIOR_UNIQUE_TABLE_SIZE),
+		_symbol_unique_table(INITIAL_SYMBOL_UNIQUE_TABLE_SIZE),
+		_bvconst_unique_table(INITIAL_BVCONST_UNIQUE_TABLE_SIZE),
+		BBTermMemo(INITIAL_BBTERM_MEMO_TABLE_SIZE),
+		BBFormMemo(INITIAL_BBFORM_MEMO_TABLE_SIZE),
+		_max_node_num(0),
+		ASTFalse(CreateNode(FALSE)),
+		ASTTrue(CreateNode(TRUE)),
+		ASTUndefined(CreateNode(UNDEFINED)),
+		SimplifyMap(INITIAL_SIMPLIFY_MAP_SIZE),
+		SimplifyNegMap(INITIAL_SIMPLIFY_MAP_SIZE),
+		SolverMap(INITIAL_SOLVER_MAP_SIZE),
+		_arrayread_symbol(INITIAL_ARRAYREAD_SYMBOL_SIZE),
+		_introduced_symbols(INITIAL_INTRODUCED_SYMBOLS_SIZE),
+		_symbol_count(0) { 
+      _current_query = ASTUndefined;
+      ValidFlag = false;
+      bvdiv_exception_occured = false;
+      counterexample_checking_during_refinement = false;
+      start_abstracting = false;
+      Begin_RemoveWrites = false;
+      SimplifyWrites_InPlace_Flag = false;
+    };
+    
+    //destructor
+    ~BeevMgr();
+  }; //End of Class BeevMgr
+
+
+  class CompleteCounterExample {
+    ASTNodeMap counterexample;
+    BeevMgr * bv;
+  public:
+    CompleteCounterExample(ASTNodeMap a, BeevMgr* beev) : counterexample(a), bv(beev){} 
+    ASTNode GetCounterExample(ASTNode e) {
+      if(BOOLEAN_TYPE == e.GetType() && SYMBOL != e.GetKind()) {
+	FatalError("You must input a term or propositional variables\n",e);
+      }
+      if(counterexample.find(e) != counterexample.end()) {
+	return counterexample[e];
+      }
+      else {
+	if(SYMBOL == e.GetKind() && BOOLEAN_TYPE == e.GetType()) {
+	  return bv->CreateNode(BEEV::FALSE);
+	}
+
+	if(SYMBOL == e.GetKind()) {
+	  ASTNode z = bv->CreateZeroConst(e.GetValueWidth());
+	  return z;
+	}
+
+	return e;	  
+      }
+    }
+  };
+
+}; // end namespace BEEV
+#endif
diff --git a/stp/AST/ASTKind.kinds b/stp/AST/ASTKind.kinds
new file mode 100644
index 00000000..03112eb8
--- /dev/null
+++ b/stp/AST/ASTKind.kinds
@@ -0,0 +1,71 @@
+#Please refer LICENSE FILE in the home directory for licensing information
+# name minkids maxkids cat1 cat2 ...
+Categories:	Term	Form
+
+# Leaf nodes.
+UNDEFINED	0	0
+SYMBOL		0	0	Term	Form 
+
+# These always produce terms
+BVCONST		0	0	Term
+BVNEG		1	1	Term
+BVCONCAT	2	-	Term
+BVOR		1	-	Term
+BVAND		1	-	Term
+BVXOR		1	-	Term
+BVNAND		1	-	Term
+BVNOR		1	-	Term
+BVXNOR		1	-	Term
+BVEXTRACT	3	3	Term
+BVLEFTSHIFT	3	3	Term
+BVRIGHTSHIFT	3	3	Term
+BVSRSHIFT	3	3	Term
+BVVARSHIFT	3	3	Term
+BVPLUS		1	-	Term
+BVSUB		2	2	Term
+BVUMINUS	1	1	Term
+BVMULTINVERSE	1	1	Term
+BVMULT		1	-	Term
+BVDIV		2	2	Term
+BVMOD		2	2	Term
+SBVDIV		2	2	Term
+SBVMOD		2	2	Term
+BVSX		1	1	Term
+BOOLVEC         0       -       Term
+
+# Formula OR term, depending on context
+ITE		3	3	Term	Form
+
+# These produce formulas.
+BVGETBIT	2	2	Form
+BVLT		2	2	Form
+BVLE		2	2	Form
+BVGT		2	2	Form
+BVGE		2	2	Form
+BVSLT		2	2	Form
+BVSLE		2	2	Form
+BVSGT		2	2	Form
+BVSGE		2	2	Form
+EQ		2	2	Form
+NEQ		2	2	Form
+FALSE		0	0	Form
+TRUE		0	0	Form
+NOT		1	1	Form
+AND		1	-	Form
+OR		1	-	Form
+NAND		1	-	Form
+NOR		1	-	Form
+XOR		1	-	Form
+IFF		1	-	Form
+IMPLIES		2	2	Form
+
+# array operations
+READ		2	2	Term
+WRITE		3	3	Term
+
+#Types: These kinds are used only in the API. Once processed inside
+#the API, they are never used again in the system 
+ARRAY           0       0
+BITVECTOR       0       0
+BOOLEAN         0       0
+
diff --git a/stp/AST/ASTUtil.cpp b/stp/AST/ASTUtil.cpp
new file mode 100644
index 00000000..bc36812c
--- /dev/null
+++ b/stp/AST/ASTUtil.cpp
@@ -0,0 +1,45 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "ASTUtil.h"
+#include <ostream>
+
+namespace BEEV {
+  ostream &operator<<(ostream &os, const Spacer &sp) {
+    // Instead of wrapping lines with hundreds of spaces, prints
+    // a "+" at the beginning of the line for each wrap-around.
+    // so lines print like: +14+		(XOR ...
+    int blanks = sp._spaces % 60;
+    int wraps = sp._spaces / 60;
+    if (wraps > 0) {
+      os << "+" << wraps;
+    }
+    for (int i = 0; i < blanks; i++)
+      os << " ";  
+    return os;
+  }
+   
+  //this function accepts the name of a function (as a char *), and
+  //records some stats about it. if the input is "print_func_stats",
+  //the function will then print the stats that it has collected.
+  void CountersAndStats(const char * functionname) {
+    if(!stats)
+      return;
+    static function_counters s;
+    
+    if(!strcmp(functionname,"print_func_stats")) {
+      cout << endl;
+      for(hash_map<const char*,int,hash<const char*>,eqstr>::iterator it=s.begin(),itend=s.end();
+	  it!=itend;it++)
+	cout << "Number of times the function: " << it->first << ": is called: " << it->second << endl;
+      return;
+    }
+    s[functionname] += 1;
+  }
+};// end of namespace
diff --git a/stp/AST/ASTUtil.h b/stp/AST/ASTUtil.h
new file mode 100644
index 00000000..0ed6bfa2
--- /dev/null
+++ b/stp/AST/ASTUtil.h
@@ -0,0 +1,107 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#ifndef ASTUTIL_H
+#define ASTUTIL_H
+
+#include <cstring>
+#include <iostream>
+#include <vector>
+#ifdef EXT_HASH_MAP
+#include <ext/hash_set>
+#include <ext/hash_map>
+#else
+#include <hash_set>
+#include <hash_map>
+#endif
+
+using namespace std; 
+namespace BEEV {
+#ifdef EXT_HASH_MAP
+  using namespace __gnu_cxx;
+#endif
+  //some global variables that are set through commandline options. it
+  //is best that these variables remain global. Default values set
+  //here
+  //
+  //collect statistics on certain functions
+  extern bool stats;
+  //print DAG nodes
+  extern bool print_nodes;
+  //tentative global var to allow for variable activity optimization
+  //in the SAT solver. deprecated.
+  extern bool variable_activity_optimize;
+  //run STP in optimized mode
+  extern bool optimize;
+  //do sat refinement, i.e. underconstraint the problem, and feed to
+  //SAT. if this works, great. else, add a set of suitable constraints
+  //to re-constraint the problem correctly, and call SAT again, until
+  //all constraints have been added.
+  extern bool arrayread_refinement;
+  //switch to control write refinements
+  extern bool arraywrite_refinement;
+  //check the counterexample against the original input to STP
+  extern bool check_counterexample;
+  //construct the counterexample in terms of original variable based
+  //on the counterexample returned by SAT solver
+  extern bool construct_counterexample;
+  extern bool print_counterexample;
+  //if this option is true then print the way dawson wants using a
+  //different printer. do not use this printer.
+  extern bool print_arrayval_declaredorder;
+  //flag to decide whether to print "valid/invalid" or not
+  extern bool print_output;
+  //do linear search in the array values of an input array. experimental
+  extern bool linear_search;
+  //print the variable order chosen by the sat solver while it is
+  //solving.
+  extern bool print_sat_varorder; 
+  //turn on word level bitvector solver
+  extern bool wordlevel_solve;
+  //XOR flattening optimizations.
+  extern bool xor_flatten;
+  //this flag indicates that the BVSolver() succeeded
+  extern bool toplevel_solved;
+  //the smtlib parser has been turned on
+  extern bool smtlib_parser_enable;
+  //print the input back
+  extern bool print_STPinput_back;
+
+  extern void (*vc_error_hdlr)(const char* err_msg);
+  /*Spacer class is basically just an int, but the new class allows
+    overloading of << with a special definition that prints the int as
+    that many spaces. */
+  class Spacer {
+  public:
+    int _spaces;
+    Spacer(int spaces) { _spaces = spaces; }
+    friend ostream& operator<<(ostream& os, const Spacer &ind);
+  };
+
+  inline Spacer spaces(int width) {
+    Spacer sp(width);
+    return sp;
+  }
+
+  struct eqstr {
+    bool operator()(const char* s1, const char* s2) const {
+      return strcmp(s1, s2) == 0;
+    }
+  };
+  
+  typedef hash_map<const char*,int, 
+		   hash<const char *>,eqstr> function_counters;
+  void CountersAndStats(const char * functionname);
+
+  //global function which accepts an integer and looks up the
+  //corresponding ASTNode and prints a char* of that ASTNode
+  void Convert_MINISATVar_To_ASTNode_Print(int minisat_var, 
+					   int decision, int polarity=0);
+}; // end namespace.
+#endif
diff --git a/stp/AST/BitBlast.cpp b/stp/AST/BitBlast.cpp
new file mode 100644
index 00000000..de78ec74
--- /dev/null
+++ b/stp/AST/BitBlast.cpp
@@ -0,0 +1,812 @@
+/********************************************************************
+ * AUTHORS: David L. Dill, Vijay Ganesh
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+// BitBlast -- convert bitvector terms and formulas to boolean
+// formulas.  A term is something that can represent a multi-bit
+// bitvector, such as BVPLUS or BVXOR (or a BV variable or constant).
+// A formula (form) represents a boolean value, such as EQ or BVLE.
+// Bit blasting a term representing an n-bit bitvector with BBTerm
+// yields a vector of n boolean formulas (returning ASTVec).
+// Bit blasting a formula returns a single boolean formula (type ASTNode).
+
+// A bitblasted term is a vector of ASTNodes for formulas.
+// The 0th element of the vector corresponds to bit 0 -- the low-order bit.
+
+#include "AST.h"
+namespace BEEV {
+  //  extern void lpvec(ASTVec &vec);
+
+// FIXME: Assert no zero-length bit vectors!!!
+// FIXME: Need top-level functions that create and destroy the memo tables.
+// FIXME:  Check resource limits and generate an exception when exceeded.
+// FIXME:  THis does a lot of unnecessary copying of vectors.
+//    Had to be careful not to modify memoized vectors!
+// FIXME:  Might be some redundant variables.
+
+// accepts a term, and returns a vector of bitblasted bits(ASTVec)
+
+ASTNode ASTJunk;
+const ASTNode BeevMgr::BBTerm(const ASTNode& term) {
+  //CHANGED TermMemo is now an ASTNodeMap. Based on BBFormMemo
+  ASTNodeMap::iterator it = BBTermMemo.find(term);
+  if (it != BBTermMemo.end()) {
+    // already there.  Just return it.
+    return it->second;
+  }
+
+//  ASTNode& result = ASTJunk;
+  ASTNode result;
+
+  Kind k = term.GetKind();
+  if (!is_Term_kind(k))
+    FatalError("BBTerm: Illegal kind to BBTerm",term);
+
+  ASTVec::const_iterator kids_end = term.end(); 
+  unsigned int num_bits = term.GetValueWidth();
+  switch (k) {
+  case BVNEG: {
+    // bitwise complement
+    // bitblast the child.
+    //FIXME Uses a tempory const ASTNode
+    const ASTNode& bbkids = BBTerm(term[0]);
+    result = CreateNode(BOOLVEC, BBNeg(bbkids.GetChildren()));
+    break;
+  }
+  case BVSRSHIFT:
+  case BVVARSHIFT: 
+    FatalError("BBTerm: These kinds have not been implemented in the BitBlaster: ", term);
+    break;
+  case ITE: {
+    // Term version of ITE.
+
+    // Blast the args
+    // FIXME Uses temporary const ASTNodes and an ASTVec&
+    const ASTNode& cond = BBForm(term[0]);
+    const ASTNode& thn = BBTerm(term[1]);
+    const ASTNode& els = BBTerm(term[2]);
+    result = 
+       CreateNode(BOOLVEC, BBITE(cond, thn.GetChildren(), els.GetChildren()));
+    break;
+  }
+  case BVSX: {
+    // Replicate high-order bit as many times as necessary.
+    // Arg 0 is expression to be sign extended.
+    const ASTNode& arg = term[0];
+    unsigned long result_width = term.GetValueWidth();
+    unsigned long arg_width = arg.GetValueWidth();
+    //FIXME Uses a temporary const ASTNode reference
+    const ASTNode& bbarg = BBTerm(arg);
+
+    if (result_width == arg_width) {
+      //nothing to sign extend
+      break;
+    }
+    else {
+      //we need to sign extend
+      const ASTNode& msbX = bbarg.back();
+      //const ASTNode& msb1 = msbX;
+      
+      ASTVec ccc = msbX.GetChildren();
+      const ASTNode& msb = CreateSimpForm(msbX.GetKind(),ccc);
+
+     //  Old version
+     //  ASTNode msb = bbarg.back();
+     //  const ASTNode msb1 = msb;
+      
+     //  ASTVec ccc = msb.GetChildren();
+     //  msb = CreateSimpForm(msb.GetKind(),ccc);
+
+      // DD 1/14/07 Simplify silently drops all but first two args of XOR.
+      // I expanded XOR to N args with flattening optimization.
+      // This bug took 2 days to track down!
+
+      // msb = SimplifyFormula(msb,false);
+
+      // cout << "!!!!!!!!!!!!!!!!" << endl
+      // << "Simplify msb:" << msb2 << endl
+      // << "Simplify result:" << msb << endl;
+
+      //FIXME Dynamically allocate the result vector?
+      //Is this doing multiple copies?
+      //ASTVec& tmp_res = *(new ASTVec(result_width));
+      ASTVec tmp_res(result_width);
+
+      //FIXME Should these be gotten from result?
+      ASTVec::const_iterator bb_it = bbarg.begin();
+      ASTVec::iterator res_it = tmp_res.begin();
+      ASTVec::iterator res_ext = res_it+arg_width; // first bit of extended part
+      ASTVec::iterator res_end = tmp_res.end();
+      // copy LSBs directly from bbvec
+      for( ; res_it < res_ext; (res_it++, bb_it++)) {
+	*res_it = *bb_it;
+      }
+      // repeat MSB to fill up rest of result.
+      for( ; res_it < res_end; (res_it++, bb_it++)) {
+	*res_it = msb;
+      }
+      
+       //Temporary debugging code
+       //    cout << "Sign extending:" << endl 
+       //	        << "  Vec ";
+       //    lpvec( bbarg.GetChildren() );
+       //    cout << "  Extended to ";
+       //    lp(result);
+       //    cout << endl;
+      
+      result = CreateNode(BOOLVEC, tmp_res);
+
+      break;
+    }
+  }
+  case BVEXTRACT: {
+    // bitblast the child, then extract the relevant bits.
+    // Note: This could be optimized by not bitblasting the bits
+    // that aren't fetched.  But that would be tricky, especially
+    // with memo-ization.
+
+    //FIXME Using const ASTNode w/out reference
+    const ASTNode& bbkids = BBTerm(term[0]); 
+    unsigned int high = GetUnsignedConst(term[1]);
+    unsigned int low = GetUnsignedConst(term[2]);
+
+    ASTVec::const_iterator bbkfit = bbkids.begin();
+    // I should have used pointers to ASTVec, to avoid this crock
+    
+    //FIXME Creates a new local ASTVec and does the CreateNode from that
+    result = CreateNode(BOOLVEC, ASTVec(bbkfit+low, bbkfit+high+1));
+    break;
+  }
+  case BVCONCAT: {
+    //FIXME Using temporary const ASTNodes 
+    const ASTNode& vec1 = BBTerm(term[0]);
+    const ASTNode& vec2 = BBTerm(term[1]);
+
+    //FIXME This has to be an unnessecary copy and a memory leak
+    //Leaking ASTVec tmp_res = *(new ASTVec(vec2.GetChildren()));
+    ASTVec tmp_res(vec2.GetChildren());
+    tmp_res.insert(tmp_res.end(), vec1.begin(), vec1.end());
+    result = CreateNode(BOOLVEC, tmp_res);
+    break;
+  }
+  case BVPLUS: {
+    // ASSERT: at least one child.
+    // ASSERT: all children and result are the same size.
+    // Previous phase must make sure this is true.
+    // Add children pairwise and accumulate in BBsum
+
+    // FIXME: Unnecessary array copies.
+    ASTVec::const_iterator it = term.begin();
+    ASTVec tmp_res = BBTerm(*it).GetChildren();
+    for (++it; it < kids_end; it++) {
+      const ASTVec& tmp = BBTerm(*it).GetChildren();
+      BBPlus2(tmp_res, tmp, ASTFalse);
+    }
+
+    result = CreateNode(BOOLVEC, tmp_res);
+    break;
+  }
+  case BVUMINUS: {
+    //FIXME Using const ASTNode reference
+    const ASTNode& bbkid = BBTerm(term[0]);
+    result = CreateNode(BOOLVEC, BBUminus(bbkid.GetChildren()));
+    break;
+  }
+  case BVSUB: {
+    // complement of subtrahend
+    // copy, since BBSub writes into it.
+    
+    //FIXME: Unnecessary array copies?
+    ASTVec tmp_res = BBTerm(term[0]).GetChildren(); 
+
+    const ASTVec& bbkid1 = BBTerm(term[1]).GetChildren();
+    BBSub(tmp_res, bbkid1);
+    result = CreateNode(BOOLVEC, tmp_res);
+    break;
+  }
+  case BVMULT: {
+    // ASSERT 2 arguments, same length, result is same length.
+
+    const ASTNode& t0 = term[0];
+    const ASTNode& t1 = term[1];
+
+    const ASTNode& mpcd1 = BBTerm(t0);
+    const ASTNode& mpcd2 = BBTerm(t1);
+    //Reverese the order of the nodes w/out the need for temporaries
+    //This is needed because t0 an t1 must be const
+    if ((BVCONST != t0.GetKind()) && (BVCONST == t1.GetKind())) {
+      result = CreateNode(BOOLVEC, 
+        BBMult(mpcd2.GetChildren(), mpcd1.GetChildren()) );
+    }else{
+      result = CreateNode(BOOLVEC, 
+        BBMult(mpcd1.GetChildren(), mpcd2.GetChildren()) );
+    }
+    break;
+  }
+  case BVDIV:
+  case BVMOD: {
+    const ASTNode& dvdd = BBTerm(term[0]);
+    const ASTNode& dvsr = BBTerm(term[1]);
+    unsigned int width = dvdd.Degree();
+    ASTVec q(width); 
+    ASTVec r(width); 
+    BBDivMod(dvdd.GetChildren(),  dvsr.GetChildren(), q, r, width);
+    if (k == BVDIV)
+      result = CreateNode(BOOLVEC, q);    
+    else
+      result = CreateNode(BOOLVEC, r);
+    break;
+  }
+  //  n-ary bitwise operators.
+  case BVXOR:
+  case BVXNOR:
+  case BVAND:
+  case BVOR:
+  case BVNOR:
+  case BVNAND: {
+    // Add children pairwise and accumulate in BBsum
+    ASTVec::const_iterator it = term.begin();
+    Kind bk = UNDEFINED;  // Kind of individual bit op.
+    switch (k) {
+    case BVXOR: bk = XOR;  break;
+    case BVXNOR: bk = IFF; break;
+    case BVAND: bk = AND; break;
+    case BVOR: bk = OR; break;
+    case BVNOR: bk = NOR; break;
+    case BVNAND: bk = NAND; break;
+    default:
+      FatalError("BBTerm: Illegal kind to BBTerm",term);
+      break;
+    }
+
+    // Sum is destructively modified in the loop, so make a copy of value
+    // returned by BBTerm.
+    ASTNode temp = BBTerm(*it);
+    ASTVec sum(temp.GetChildren());	// First operand.
+
+    // Iterate over remaining bitvector term operands
+    for (++it; it < kids_end; it++) {
+      //FIXME FIXME FIXME: Why does using a temp. var change the behavior?
+      temp = BBTerm(*it);
+      const ASTVec& y = temp.GetChildren();
+      
+      // Iterate over bits
+      // FIXME: Why is this not using an iterator???
+      int n = y.size();
+      for (int i = 0; i < n; i++) {
+	sum[i] = CreateSimpForm(bk, sum[i], y[i]);
+      }
+    }
+    result = CreateNode(BOOLVEC, sum);
+    break;
+  }
+  case SYMBOL: {
+    // ASSERT: IndexWidth = 0?  Semantic analysis should check.
+    //Leaking ASTVec& bbvec = *(new ASTVec);
+    
+    //FIXME Why is isn't this ASTVEC bbvec(num_bits) ?
+    ASTVec bbvec;
+    for (unsigned int i = 0; i < num_bits; i++) {
+      ASTNode bit_node =
+	CreateNode(BVGETBIT, term, CreateBVConst(32,i));
+      bbvec.push_back(bit_node); 
+    }
+    result = CreateNode(BOOLVEC, bbvec);
+    break;
+  }
+  case BVCONST: {
+    ASTVec tmp_res(num_bits);
+#ifndef NATIVE_C_ARITH
+    CBV bv = term.GetBVConst();
+    for(unsigned int i = 0; i < num_bits; i++){
+      tmp_res[i] = CONSTANTBV::BitVector_bit_test(bv,i) ? ASTTrue : ASTFalse; 
+    }  
+#else
+    const unsigned long long int c = term.GetBVConst();
+    unsigned long long int bitmask = 0x00000000000000001LL;
+    for (unsigned int i = 0; i < num_bits; i++, bitmask <<= 1)
+      tmp_res[i] = ((c & (bitmask)) ? ASTTrue : ASTFalse);    
+#endif
+    result = CreateNode(BOOLVEC, tmp_res);
+    break;
+  }		  
+  case BOOLVEC: {
+    cerr << "Hit a boolvec! what to do?" << endl;
+    break;
+  }
+  default:
+    FatalError("BBTerm: Illegal kind to BBTerm",term);
+  }
+
+  //if(result == ASTJunk)
+  //  cout<<"result does not change"<<endl;
+  // cout << "================" << endl << "BBTerm:" << term << endl;
+  // cout << "----------------" << endl << "BBTerm result:";
+  // lpvec(result);
+  // cout << endl;
+
+  return (BBTermMemo[term] = result);
+
+}
+
+// bit blast a formula (boolean term).  Result is one bit wide,
+// so it returns a single ASTNode.
+// FIXME:  Add IsNegated flag.
+const ASTNode BeevMgr::BBForm(const ASTNode& form)
+{
+
+  ASTNodeMap::iterator it = BBFormMemo.find(form);
+  if (it != BBFormMemo.end()) {
+    // already there.  Just return it.
+    return it->second;
+  }
+
+  ASTNode result = ASTUndefined;
+
+  Kind k = form.GetKind();
+  if (!is_Form_kind(k)) {
+    FatalError("BBForm: Illegal kind: ",form);
+  }
+
+  //  Not returning until end, and memoizing everything, makes it easier
+  // to trace coherently.
+    
+  // Various special cases
+  switch (k) {
+  case TRUE:
+  case FALSE: {
+    result = form;
+    break;
+  }
+
+  case SYMBOL:
+    if (form.GetType() != BOOLEAN_TYPE) {
+      FatalError("BBForm: Symbol represents more than one bit", form);
+    }
+
+    result = form;
+    break;
+
+  case BVGETBIT: {
+    // exactly two children
+    const ASTNode bbchild = BBTerm(form[0]);
+    unsigned int index =  GetUnsignedConst(form[1]);
+    result = bbchild[index];
+    break;
+  }
+
+  case NOT:
+    result = CreateSimpNot(BBForm(form[0]));
+    break;  
+
+  case ITE:
+    // FIXME: SHould this be CreateSimpITE?
+    result = CreateNode(ITE, BBForm(form[0]), BBForm(form[1]), BBForm(form[2]));
+    break;
+
+  case AND: 
+  case OR: 
+  case NAND: 
+  case NOR: 
+  case IFF: 
+  case XOR:
+  case IMPLIES: {
+    ASTVec bbkids;		// bit-blasted children (formulas)
+
+    // FIXME: Put in fast exits for AND/OR/NAND/NOR/IMPLIES
+    ASTVec::const_iterator kids_end = form.end(); 
+    for (ASTVec::const_iterator it = form.begin(); it != kids_end; it++) {
+      bbkids.push_back(BBForm(*it));
+    }
+    result = CreateSimpForm(k, bbkids);
+    break;
+  }
+
+  case NEQ: {
+    ASTNode bbkid = BBForm(CreateNode(EQ, form.GetChildren()));
+    result = CreateSimpNot(bbkid);
+    break;
+  }
+
+  case EQ: {
+    // Common code for binary operations
+    // FIXME:  This ought to be in a semantic analysis phase.
+    const ASTNode left = BBTerm(form[0]);
+    const ASTNode right = BBTerm(form[1]);
+    if (left.Degree() != right.Degree()) {
+      cerr << "BBForm: Size mismatch" << endl << form[0] << endl << form[1] << endl;
+      FatalError("",ASTUndefined);
+    }
+    result = BBEQ(left.GetChildren(), right.GetChildren());
+    break;
+  }
+
+  case BVLE: 
+  case BVGE: 
+  case BVGT: 
+  case BVLT: 
+  case BVSLE:
+  case BVSGE:
+  case BVSGT:
+  case BVSLT: {
+    result = BBcompare(form);
+    break;
+  }
+  default:
+    FatalError("BBForm: Illegal kind: ", form);
+    break;
+  }
+
+  // cout << "================" << endl
+  // << "BBForm: " << form << endl
+  // << "----------------" << endl
+  // << "BBForm Result: " << result << endl;
+
+  return (BBFormMemo[form] = result);
+}
+  
+// Bit blast a sum of two equal length BVs.
+// Update sum vector destructively with new sum.
+void BeevMgr::BBPlus2(ASTVec& sum, const ASTVec& y, ASTNode cin)
+{
+//   cout << "Bitblasting plus.  Operand 1: " << endl;
+//   lpvec(sum);
+//   cout << endl << " operand 2: " << endl;
+//   lpvec(y);
+//   cout << endl << "carry: " << endl << cin << endl;
+
+
+  int n = sum.size();
+  // ASSERT: y.size() == x.size()
+  // FIXME: Don't bother computing i+1 carry, which is discarded.
+  for (int i = 0; i < n; i++) {
+    ASTNode nextcin = Majority(sum[i], y[i], cin); 
+    sum[i] = CreateSimpForm(XOR, CreateSimpForm(XOR, sum[i], y[i]), cin);
+    cin = nextcin;
+  }
+
+//   cout << "----------------" << endl << "Result: " << endl;
+//   lpvec(sum);
+//   cout << endl;
+
+}
+
+// Stores result - x in result, destructively
+void BeevMgr::BBSub(ASTVec& result, const ASTVec& y)
+{
+  ASTVec compsubtrahend  = BBNeg(y);
+  BBPlus2(result, compsubtrahend, ASTTrue);
+}
+
+// Add one bit
+ASTVec BeevMgr::BBAddOneBit(ASTVec& x, ASTNode cin)
+{
+  ASTVec result = ASTVec(0);
+  ASTVec::const_iterator itend = x.end();
+  for (ASTVec::const_iterator it = x.begin(); it < itend; it++) {
+    ASTNode nextcin = CreateSimpForm(AND, *it, cin); 
+    result.push_back(CreateSimpForm(XOR, *it, cin));
+    cin = nextcin;
+  }
+  // FIXME: unnecessary array copy on return?
+  return result;
+}
+
+// Increment bit-blasted vector and return result.
+ASTVec BeevMgr::BBInc(ASTVec& x)
+{
+  return BBAddOneBit(x, ASTTrue);
+}
+
+// Return formula for majority function of three bits.
+// Pass arguments by reference to reduce refcounting.
+ASTNode BeevMgr::Majority(const ASTNode& a, const ASTNode& b,const ASTNode& c)
+{
+  // Checking explicitly for constant a, b and c could
+  // be more efficient, because they are repeated in the logic.
+  if (ASTTrue == a) {
+    return CreateSimpForm(OR, b, c);
+  }
+  else if (ASTFalse == a) {
+    return CreateSimpForm(AND, b, c);
+  }
+  else if (ASTTrue == b) {
+    return CreateSimpForm(OR, a, c);
+  }
+  else if (ASTFalse == b) {
+    return CreateSimpForm(AND, a, c);
+  }
+  else if (ASTTrue == c) {
+    return CreateSimpForm(OR, a, b);
+  }
+  else if (ASTFalse == c) {
+    return CreateSimpForm(AND, a, b);
+  }
+  // there are lots more simplifications, but I'm not sure they're
+  // worth doing explicitly (e.g., a = b, a = ~b, etc.) 
+  else {
+    return
+      CreateSimpForm(OR,
+		     CreateSimpForm(AND, a, b),
+		     CreateSimpForm(AND, b, c),
+		     CreateSimpForm(AND, a, c));
+  }
+}
+
+
+// Bitwise complement
+ASTVec BeevMgr::BBNeg(const ASTVec& x)
+{
+  ASTVec result = ASTVec(0);		// FIXME: faster to preallocate n entries?
+  // Negate each bit.
+  ASTVec::const_iterator xend = x.end();
+  for (ASTVec::const_iterator it = x.begin(); it < xend; it++) {
+    result.push_back(CreateSimpNot(*it));
+  }
+  // FIXME: unecessary array copy when it returns?
+  return result;
+}
+
+// Compute unary minus
+ASTVec BeevMgr::BBUminus(const ASTVec& x)
+{
+  ASTVec xneg = BBNeg(x);
+  return BBInc(xneg);
+}
+
+// Multiply two bitblasted numbers
+ASTVec BeevMgr::BBMult(const ASTVec& x, const ASTVec& y)
+{
+  ASTVec ycopy(y);
+  ASTVec::const_iterator xend = x.end();
+  ASTVec::const_iterator xit = x.begin();
+  // start prod with first partial product.
+  // FIXME: This is unnecessary. Clean it up.
+  ASTVec prod = ASTVec(BBAndBit(y, *xit));
+  // start loop at next bit.
+  for(xit++; xit < xend; xit++) {
+    // shift first
+    BBLShift(ycopy);
+
+    if (ASTFalse == *xit) {
+      // If this bit is zero, the partial product will
+      // be zero.  No reason to add that in.
+      continue;
+    }
+
+    ASTVec pprod = BBAndBit(ycopy, *xit);
+    // accumulate in the product.
+    BBPlus2(prod, pprod, ASTFalse);
+  }
+  return prod;
+}
+
+// This implements a variant of binary long division.
+// q and r are "out" parameters.  rwidth puts a bound on the
+// recursion depth.
+void BeevMgr::BBDivMod(const ASTVec &y, const ASTVec &x, ASTVec &q, ASTVec &r, unsigned int rwidth)
+{
+  unsigned int width = y.size();
+  if (rwidth == 0) {
+    // When we have shifted the entire width, y is guaranteed to be 0.
+    q = BBfill(width, ASTFalse);
+    r = BBfill(width, ASTFalse);
+  }
+  else {
+    ASTVec q1, r1;
+    ASTVec yrshift1(y);
+    BBRShift(yrshift1);
+
+    // recursively divide y/2 by x.
+    BBDivMod(yrshift1, x, q1, r1, rwidth-1);
+
+    ASTVec q1lshift1(q1);
+    BBLShift(q1lshift1);
+
+    ASTVec r1lshift1(r1);
+    BBLShift(r1lshift1);
+    
+    ASTVec r1lshift1plusyodd = BBAddOneBit(r1lshift1, y[0]);
+    ASTVec rminusx(r1lshift1plusyodd);
+    BBSub(rminusx, x);
+
+    // Adjusted q, r values when when r is too large.
+    ASTNode rtoolarge = BBBVLE(x, r1lshift1plusyodd, false);
+    ASTVec ygtrxqval = BBITE(rtoolarge, BBInc(q1lshift1), q1lshift1);
+    ASTVec ygtrxrval = BBITE(rtoolarge, rminusx, r1lshift1plusyodd);
+
+    // q & r values when y >= x
+    ASTNode yeqx = BBEQ(y, x);
+    // *** Problem: the bbfill for qval is wrong.  Should be 1, not -1.
+    ASTVec one = BBfill(width, ASTFalse);
+    one[0] = ASTTrue;
+    ASTVec notylessxqval = BBITE(yeqx, one, ygtrxqval);
+    ASTVec notylessxrval = BBITE(yeqx, BBfill(width, ASTFalse), ygtrxrval);
+    // y < x <=> not x >= y.
+    ASTNode ylessx = CreateSimpNot(BBBVLE(x, y, false));
+    // final values of q and r
+    q = BBITE(ylessx, BBfill(width, ASTFalse), notylessxqval);
+    r = BBITE(ylessx, y, notylessxrval);
+  }
+}
+
+// build ITE's (ITE cond then[i] else[i]) for each i.
+ASTVec BeevMgr::BBITE(const ASTNode& cond, const ASTVec& thn, const ASTVec& els)
+{
+  // Fast exits.
+  if (ASTTrue == cond) {
+    return thn;
+  }
+  else if (ASTFalse == cond) {
+    return els;
+  }
+
+  ASTVec result(0);
+  ASTVec::const_iterator th_it_end = thn.end();
+  ASTVec::const_iterator el_it = els.begin();
+  for (ASTVec::const_iterator th_it = thn.begin(); th_it < th_it_end; th_it++, el_it++) {
+    result.push_back(CreateSimpForm(ITE, cond, *th_it, *el_it));
+  }
+  return result;
+}
+// AND each bit of vector y with single bit b and return the result.
+ASTVec BeevMgr::BBAndBit(const ASTVec& y, ASTNode b)
+{
+  ASTVec result(0); 
+
+  if (ASTTrue == b) {
+    return y;
+  }
+  // FIXME: put in fast exits when b is constant 0. 
+
+  ASTVec::const_iterator yend = y.end();
+  for(ASTVec::const_iterator yit = y.begin(); yit < yend; yit++) {
+    result.push_back(CreateSimpForm(AND, *yit, b));
+  }
+  return result;
+}
+
+
+// Workhorse for comparison routines.  This does a signed BVLE if is_signed
+// is true, else it's unsigned.  All other comparison operators can be reduced
+// to this by swapping args or complementing the result bit.
+// FIXME:  If this were done MSB first, it would enable a fast exit sometimes
+// when the MSB is constant, deciding the result without looking at the rest
+// of the bits.
+ASTNode BeevMgr::BBBVLE(const ASTVec& left, const ASTVec& right, bool is_signed)
+{
+  // "thisbit" represents BVLE of the suffixes of the BVs
+  // from that position .  if R < L, return TRUE, else if L < R
+  // return FALSE, else return BVLE of lower-order bits.  MSB is
+  // treated separately, because signed comparison is done by
+  // complementing the MSB of each BV, then doing an unsigned
+  // comparison.
+  ASTVec::const_iterator lit = left.begin();
+  ASTVec::const_iterator litend = left.end();
+  ASTVec::const_iterator rit = right.begin();
+  ASTNode prevbit = ASTTrue;
+  for ( ; lit  < litend-1; lit++, rit++) {
+    ASTNode neglit = CreateSimpNot(*lit);
+    ASTNode thisbit =
+      CreateSimpForm(OR,
+		 CreateSimpForm(AND,neglit,*rit), // TRUE if l < r
+		 CreateSimpForm(AND,
+			    CreateSimpForm(OR, neglit, *rit), // false if not equal
+			    prevbit)); // else prevbit
+    prevbit = thisbit;
+  }
+
+  // Handle MSB -- negate MSBs if signed comparison
+  // FIXME: make into refs after it's debugged.
+  ASTNode lmsb = *lit;
+  ASTNode rmsb = *rit;
+  if (is_signed) {
+    lmsb = CreateSimpNot(*lit);
+    rmsb = CreateSimpNot(*rit);
+  }
+
+  ASTNode neglmsb = CreateSimpNot(lmsb);
+  ASTNode msb =
+    CreateSimpForm(OR,
+	       CreateSimpForm(AND,neglmsb, rmsb), // TRUE if l < r
+	       CreateSimpForm(AND,
+			  CreateSimpForm(OR, neglmsb, rmsb), // false if not equal
+			  prevbit)); // else prevbit
+  return msb;
+}
+
+// Left shift by 1 within fixed field inserting zeros at LSB.
+// Writes result into first argument.
+// Fixme: generalize to n bits
+void BeevMgr::BBLShift(ASTVec& x)
+{
+  // left shift x (destructively) within width.
+  // loop backwards so that copy to self works correctly. (DON'T use STL insert!)
+  ASTVec::iterator xbeg = x.begin();
+  for(ASTVec::iterator xit = x.end()-1; xit > xbeg; xit--) {
+    *xit = *(xit-1);
+  }
+  *xbeg = ASTFalse;		// new LSB is zero.
+  // cout << "Shifted result" << endl;
+  // lpvec(x);
+}
+
+// Right shift by 1 within fixed field, inserting new zeros at MSB.
+// Writes result into first argument.
+// Fixme: generalize to n bits.
+void BeevMgr::BBRShift(ASTVec& x)
+{
+  ASTVec::iterator xend = x.end() - 1;
+  ASTVec::iterator xit = x.begin();
+  for( ; xit < xend; xit++) {
+    *xit = *(xit+1);
+  }
+  *xit = ASTFalse;		// new MSB is zero.
+}
+
+
+// Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc. 
+ASTNode BeevMgr::BBcompare(const ASTNode& form) {
+  const ASTNode lnode = BBTerm(form[0]);
+  const ASTNode rnode = BBTerm(form[1]);
+  const ASTVec& left = lnode.GetChildren();
+  const ASTVec& right = rnode.GetChildren();
+
+  //const ASTVec& left = BBTerm(form[0]).GetChildren();
+  //const ASTVec& right = BBTerm(form[1]).GetChildren();
+
+  Kind k = form.GetKind();
+  switch(k) {
+  case BVLE: { return BBBVLE(left, right, false); break; }
+  case BVGE: { return BBBVLE(right, left, false); break; }
+  case BVGT: { return CreateSimpNot(BBBVLE(left, right, false)); break; }
+  case BVLT: { return CreateSimpNot(BBBVLE(right, left, false)); break; }
+  case BVSLE: { return BBBVLE(left, right, true); break; }
+  case BVSGE: { return BBBVLE(right, left, true); break; }
+  case BVSGT: { return CreateSimpNot(BBBVLE(left, right, true)); break; }
+  case BVSLT: { return CreateSimpNot(BBBVLE(right, left, true)); break; }
+  default:
+    cerr << "BBCompare: Illegal kind" << form << endl;    
+    FatalError("",ASTUndefined);
+  }
+  return ASTUndefined;
+}
+
+
+// return a vector with n copies of fillval
+ASTVec BeevMgr::BBfill(unsigned int width, ASTNode fillval)
+{
+  ASTVec zvec(width, fillval);
+  return zvec;
+}
+
+ASTNode BeevMgr::BBEQ(const ASTVec& left, const ASTVec& right)
+{
+  ASTVec andvec;
+  ASTVec::const_iterator lit = left.begin();
+  ASTVec::const_iterator litend = left.end();
+  ASTVec::const_iterator rit = right.begin();
+  
+  if(left.size() > 1) {
+    for(; lit != litend; lit++, rit++) {
+      ASTNode biteq = CreateSimpForm(IFF, *lit, *rit);
+      // fast path exit
+      if (biteq == ASTFalse) {
+	return ASTFalse;
+      }
+      else {
+	andvec.push_back(biteq);
+      }
+    }
+    ASTNode n = CreateSimpForm(AND, andvec);  
+    return n;
+  }
+  else
+    return CreateSimpForm(IFF,*lit,*rit);
+}
+} // BEEV namespace
diff --git a/stp/AST/Makefile b/stp/AST/Makefile
new file mode 100644
index 00000000..0218510b
--- /dev/null
+++ b/stp/AST/Makefile
@@ -0,0 +1,54 @@
+include ../Makefile.common
+
+SRCS = AST.cpp ASTKind.cpp  ASTUtil.cpp BitBlast.cpp SimpBool.cpp  ToCNF.cpp ToSAT.cpp Transform.cpp
+OBJS = $(SRCS:.cpp=.o)
+
+#Make the ast library for use by other modules
+libast.a:	$(OBJS)
+	-rm -rf $@
+	$(AR) rc libast.a $(OBJS)
+	$(RANLIB) libast.a
+
+ASTKind.o: ASTKind.h ASTKind.cpp
+	$(CXX) $(CXXFLAGS)   -c -o ASTKind.o ASTKind.cpp
+
+# ASTKind.h and ASTKind.cpp are automatically generated
+ASTKind.h ASTKind.cpp:	ASTKind.kinds genkinds.pl
+	./genkinds.pl
+
+# cnftest:	cnftest.o ToCNF.o AST.o ASTUtil.o ASTKind.o BitBlast.o AST.h
+#	$(CC) $(LDFLAGS) ToCNF.o BitBlast.o ASTKind.o  ASTUtil.o AST.o  cnftest.o  -o cnftest 
+
+# bbtest: $(OBJS)
+#	$(CC) $(LDFLAGS) BitBlast.o ASTKind.o  ASTUtil.o AST.o  bbtest.o -o bbtest 
+
+# asttest: $(OBJS)
+#	$(CC) $(LDFLAGS) ASTKind.o  ASTUtil.o AST.o asttest.o  -lstdc++ -o asttest
+
+clean:
+	rm -rf *.o *~ bbtest asttest cnftest *.a  ASTKind.h ASTKind.cpp .#*
+
+depend:
+	makedepend -Y -- $(CFLAGS) -- $(SRCS)
+# DO NOT DELETE
+
+AST.o: AST.h ASTUtil.h ASTKind.h ../sat/Solver.h ../sat/SolverTypes.h
+AST.o: ../sat/Global.h ../sat/VarOrder.h ../sat/Solver.h ../sat/Heap.h
+AST.o: ../AST/ASTUtil.h ../sat/SolverTypes.h ../constantbv/constantbv.h
+ASTUtil.o: ASTUtil.h
+BitBlast.o: AST.h ASTUtil.h ASTKind.h ../sat/Solver.h ../sat/SolverTypes.h
+BitBlast.o: ../sat/Global.h ../sat/VarOrder.h ../sat/Solver.h ../sat/Heap.h
+BitBlast.o: ../AST/ASTUtil.h ../sat/SolverTypes.h ../constantbv/constantbv.h
+SimpBool.o: AST.h ASTUtil.h ASTKind.h ../sat/Solver.h ../sat/SolverTypes.h
+SimpBool.o: ../sat/Global.h ../sat/VarOrder.h ../sat/Solver.h ../sat/Heap.h
+SimpBool.o: ../AST/ASTUtil.h ../sat/SolverTypes.h ../constantbv/constantbv.h
+ToCNF.o: AST.h ASTUtil.h ASTKind.h ../sat/Solver.h ../sat/SolverTypes.h
+ToCNF.o: ../sat/Global.h ../sat/VarOrder.h ../sat/Solver.h ../sat/Heap.h
+ToCNF.o: ../AST/ASTUtil.h ../sat/SolverTypes.h ../constantbv/constantbv.h
+ToSAT.o: AST.h ASTUtil.h ASTKind.h ../sat/Solver.h ../sat/SolverTypes.h
+ToSAT.o: ../sat/Global.h ../sat/VarOrder.h ../sat/Solver.h ../sat/Heap.h
+ToSAT.o: ../AST/ASTUtil.h ../sat/SolverTypes.h ../constantbv/constantbv.h
+ToSAT.o: ../simplifier/bvsolver.h ../AST/AST.h
+Transform.o: AST.h ASTUtil.h ASTKind.h ../sat/Solver.h ../sat/SolverTypes.h
+Transform.o: ../sat/Global.h ../sat/VarOrder.h ../sat/Solver.h ../sat/Heap.h
+Transform.o: ../AST/ASTUtil.h ../sat/SolverTypes.h ../constantbv/constantbv.h
diff --git a/stp/AST/STLport_config.h b/stp/AST/STLport_config.h
new file mode 100644
index 00000000..9b7bc14f
--- /dev/null
+++ b/stp/AST/STLport_config.h
@@ -0,0 +1,20 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+// STLport debug checking, if we use STLport threads flag is to get
+// rid of link errors, since iostreams compiles with threads.  alloc
+// and uninitialized are extra checks Later on, if used with Purify or
+// Valgrind, may want to set flags to prevent reporting of false
+// leaks.  For some reason, _STLP_THREADS works on the command line
+// but not here (?)
+#define _STLP_THREADS
+#define _STLP_DEBUG 1
+#define _STLP_DEBUG_LEVEL _STLP_STANDARD_DBG_LEVEL 
+#define _STLP_DEBUG_ALLOC 1
+#define _STLP_DEBUG_UNINITIALIZED 1
diff --git a/stp/AST/SimpBool.cpp b/stp/AST/SimpBool.cpp
new file mode 100644
index 00000000..67f9825d
--- /dev/null
+++ b/stp/AST/SimpBool.cpp
@@ -0,0 +1,408 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: April, 2006
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+
+// -*- c++ -*-
+
+// Simplifying create methods for Boolean operations.
+// These are only very simple local simplifications.
+
+// This is somewhat redundant with Vijay's simplifier code.  They
+// need to be merged.
+// FIXME: control with optimize flag.
+
+static bool _trace_simpbool = 0;
+static bool _disable_simpbool = 0;
+
+#include "AST.h"
+
+// SMTLIB experimental hack.  Try allocating a single stack here for
+// children to reduce growing of vectors.
+//BEEV::ASTVec child_stack;
+
+namespace BEEV {
+
+  ASTNode BeevMgr::CreateSimpForm(Kind kind, ASTVec &children = _empty_ASTVec) {
+    if (_disable_simpbool) {
+      return CreateNode(kind, children);
+    }
+    else {
+      switch (kind) {
+      case NOT: return CreateSimpNot(children[0]); break; 
+      case AND: return CreateSimpAndOr(1, children); break; 
+      case OR: return CreateSimpAndOr(0, children); break;
+      case NAND: return CreateSimpNot(CreateSimpAndOr(1, children)); break;
+      case NOR: return CreateSimpNot(CreateSimpAndOr(0, children)); break;
+      case IFF: {
+	// Not sure children can ever be empty, but what the heck.
+	//	if (children.size() == 0) {
+	//	  return ASTTrue;
+	//	}
+	// Convert IFF to XOR ASAP.  IFF is not associative, so this makes
+	// flattening much easier.
+	children[0] = CreateSimpNot(children[0]);
+	return CreateSimpXor(children); break;
+      }
+      case XOR: 
+	return CreateSimpXor(children); break;
+	// FIXME: Earlier, check that this only has two arguments
+      case IMPLIES: return CreateSimpAndOr(0, CreateSimpNot(children[0]), children[1]); break;
+      case ITE: return CreateSimpFormITE(children[0], children[1], children[2]);
+      default: return CreateNode(kind, children);
+      }
+    }
+  }
+
+  // specialized versions
+  
+  ASTNode BeevMgr::CreateSimpForm(Kind kind,
+				  const ASTNode& child0) {
+    ASTVec children;
+    //child_stack.clear();	// could just reset top pointer.
+    children.push_back(child0);
+    //child_stack.push_back(child0);
+    return CreateSimpForm(kind, children);
+    //return CreateSimpForm(kind, child_stack);
+  }
+  
+  ASTNode BeevMgr::CreateSimpForm(Kind kind,
+				  const ASTNode& child0,
+				  const ASTNode& child1) {
+    ASTVec children;
+    //child_stack.clear();	// could just reset top pointer.
+    children.push_back(child0);
+    //child_stack.push_back(child0);
+    children.push_back(child1);
+    //child_stack.push_back(child1);
+    return CreateSimpForm(kind, children);
+    //return CreateSimpForm(kind, child_stack);
+  }
+  
+  
+  ASTNode BeevMgr::CreateSimpForm(Kind kind,
+				  const ASTNode& child0,
+				  const ASTNode& child1,
+				  const ASTNode& child2) {
+    ASTVec children;
+    //child_stack.clear();	// could just reset top pointer.
+    children.push_back(child0);
+    //child_stack.push_back(child0);
+    children.push_back(child1);
+    //child_stack.push_back(child1);
+    children.push_back(child2);
+    //child_stack.push_back(child2);
+    return CreateSimpForm(kind, children);
+    //return CreateSimpForm(kind, child_stack);
+  }
+    
+  ASTNode BeevMgr::CreateSimpNot(const ASTNode& form) {
+    Kind k = form.GetKind();
+    switch (k) {
+    case FALSE: { return ASTTrue; }
+    case TRUE: { return ASTFalse; }
+    case NOT: { return form[0]; } // NOT NOT cancellation
+    case XOR: {
+      // Push negation down in this case.
+      // FIXME: Separate pre-pass to push negation down?
+      // CreateSimp should be local, and this isn't.  
+      // It isn't memoized.  Arg.
+      ASTVec children = form.GetChildren();
+      children[0] = CreateSimpNot(children[0]);
+      return CreateSimpXor(children);
+    }
+    default: { return CreateNode(NOT, form); }
+    }
+  }
+
+  // I don't think this is even called, since it called
+  // CreateSimpAndOr instead of CreateSimpXor until 1/9/07 with no
+  // ill effects.  Calls seem to go to the version that takes a vector
+  // of children.
+  ASTNode BeevMgr::CreateSimpXor(const ASTNode& form1, const ASTNode& form2) {
+    ASTVec children;
+    children.push_back(form1);
+    children.push_back(form2);
+    return CreateSimpXor(children);
+  }
+
+
+  ASTNode BeevMgr::CreateSimpAndOr(bool IsAnd, const ASTNode& form1, const ASTNode& form2) {
+    ASTVec children;
+    children.push_back(form1);
+    children.push_back(form2);
+    return CreateSimpAndOr(IsAnd, children);
+  }
+
+  ASTNode BeevMgr::CreateSimpAndOr(bool IsAnd, ASTVec &children) {
+
+    if (_trace_simpbool) {
+      cout << "========" << endl << "CreateSimpAndOr " << (IsAnd ? "AND " : "OR ") ;
+      lpvec(children);
+      cout << endl;
+    }
+
+    ASTVec new_children;
+
+    // sort so that identical nodes occur in sequential runs, followed by
+    // their negations.
+
+    SortByExprNum(children);
+    
+    ASTNode annihilator = (IsAnd ? ASTFalse : ASTTrue);
+    ASTNode identity = (IsAnd ? ASTTrue : ASTFalse);
+
+    ASTNode retval;
+
+    ASTVec::const_iterator it_end = children.end();
+    ASTVec::const_iterator next_it;
+    for(ASTVec::const_iterator it = children.begin(); it != it_end; it = next_it) {
+      next_it = it + 1;
+      bool nextexists = (next_it < it_end);
+
+      if (*it == annihilator) {
+	retval = annihilator;
+	if (_trace_simpbool) {
+	  cout << "returns " << retval << endl;
+	}
+	return retval;
+      }
+      else if (*it == identity) {
+	// just drop it
+      }
+      else if (nextexists && (*next_it == *it)) {
+	// drop it
+	//	cout << "Dropping [" << it->GetNodeNum() << "]" << endl;
+      }
+      else if (nextexists && (next_it->GetKind() == NOT) && ((*next_it)[0] == *it)) {
+	// form and negation -- return FALSE for AND, TRUE for OR.
+	retval = annihilator;
+	// cout << "X and/or NOT X" << endl; 
+	if (_trace_simpbool) {
+	  cout << "returns " << retval << endl;
+	}
+	return retval;
+      }
+      else {
+	// add to children
+	new_children.push_back(*it);
+      }
+    }
+
+    // If we get here, we saw no annihilators, and children should
+    // be only the non-True nodes.
+    if (new_children.size() < 2) {
+      if (0 == new_children.size()) {
+	retval = identity;
+      }
+      else {
+	// there is just one child
+	retval = new_children[0];
+      }
+    }
+    else {
+      // 2 or more children.  Create a new node.
+      retval = CreateNode(IsAnd ? AND : OR, new_children);
+    }
+    if (_trace_simpbool) {
+      cout << "returns " << retval << endl;
+    }
+    return retval;
+  }
+
+
+  // Constant children are accumulated in "accumconst".  
+  ASTNode BeevMgr::CreateSimpXor(ASTVec &children) {
+
+    if (_trace_simpbool) {
+      cout << "========" << endl
+	   << "CreateSimpXor ";
+      lpvec(children);
+      cout << endl;
+    }
+
+    // Change this not to init to children if flattening code is present.
+    // ASTVec flat_children = children;		// empty vector
+
+    ASTVec flat_children;		// empty vector
+
+    ASTVec::const_iterator it_end = children.end();
+
+    if (xor_flatten) {
+
+      bool fflag = 0;		// ***Temp debugging
+      
+      // Experimental flattening code.
+      
+      for(ASTVec::iterator it = children.begin(); it != it_end; it++) {
+	Kind ck = it->GetKind();
+	const ASTVec &gchildren = it->GetChildren();
+	if (XOR == ck) {
+	  fflag = 1;
+	  // append grandchildren to children
+	  flat_children.insert(flat_children.end(), gchildren.begin(), gchildren.end());
+	}
+	else {
+	  flat_children.push_back(*it);
+	}
+      }
+      
+      if (_trace_simpbool && fflag) {
+	cout << "========" << endl;
+	cout << "Flattening: " << endl;
+	lpvec(children);
+	
+	cout << "--------" << endl;
+	cout << "Flattening result: " << endl;
+	lpvec(flat_children);
+      }
+    }
+    else {
+      flat_children = children;
+    }
+      
+
+    // sort so that identical nodes occur in sequential runs, followed by
+    // their negations.
+    SortByExprNum(flat_children);
+
+    ASTNode retval;
+
+    // This is the C Boolean value of all constant args seen.  It is initially
+    // 0.  TRUE children cause it to change value.
+    bool accumconst = 0;
+
+    ASTVec new_children;
+
+    it_end = flat_children.end();
+    ASTVec::iterator next_it;
+    for(ASTVec::iterator it = flat_children.begin(); it != it_end; it++) {
+      next_it = it + 1;
+      bool nextexists = (next_it < it_end);
+
+      if (ASTTrue == *it) {
+	accumconst = !accumconst;
+      }
+      else if (ASTFalse == *it) {
+	// Ignore it
+      }
+      else if (nextexists && (*next_it == *it)) {
+	// x XOR x = FALSE.  Skip current, write "false" into next_it
+	// so that it gets tossed, too.
+	*next_it = ASTFalse;
+      }
+      else if (nextexists && (next_it->GetKind() == NOT) && ((*next_it)[0] == *it)) {
+	// x XOR NOT x = TRUE.  Skip current, write "true" into next_it
+	// so that it gets tossed, too.
+	*next_it = ASTTrue;
+      }
+      else if (NOT == it->GetKind()) {
+	// If child is (NOT alpha), we can flip accumconst and use alpha.
+	// This is ok because (NOT alpha) == TRUE XOR alpha
+	accumconst = !accumconst;
+	// CreateSimpNot just takes child of not.
+	new_children.push_back(CreateSimpNot(*it));
+      }
+      else {
+	new_children.push_back(*it);
+      }
+    }
+
+    // Children should be non-constant.
+    if (new_children.size() < 2) {
+      if (0 == new_children.size()) {
+	// XOR(TRUE, FALSE) -- accumconst will be 1.
+	if (accumconst) {
+	  retval = ASTTrue;
+	}
+	else {
+	  retval = ASTFalse;
+	}
+      }
+      else {
+	// there is just one child
+	// XOR(x, TRUE) -- accumconst will be 1.
+	if (accumconst) {
+	  retval =  CreateSimpNot(new_children[0]);
+	}
+	else {
+	  retval = new_children[0];
+	}
+      }
+    }
+    else {
+      // negate first child if accumconst == 1
+      if (accumconst) {
+	new_children[0] = CreateSimpNot(new_children[0]);
+      }
+      retval = CreateNode(XOR, new_children);
+    }
+
+    if (_trace_simpbool) {    
+      cout << "returns " << retval << endl;
+    }
+    return retval;
+  }
+
+  // FIXME:  How do I know whether ITE is a formula or not?
+  ASTNode BeevMgr::CreateSimpFormITE(const ASTNode& child0,
+				     const ASTNode& child1,
+				     const ASTNode& child2) {
+
+    ASTNode retval;
+    
+    if (_trace_simpbool) {
+      cout << "========" << endl << "CreateSimpFormITE "
+	   << child0 
+	   << child1 
+	   << child2 << endl;
+    }
+
+    if (ASTTrue == child0) {
+      retval = child1;
+    }
+    else if (ASTFalse == child0) {
+      retval = child2;
+    }
+    else if (child1 == child2) {
+      retval = child1;
+    }    
+    // ITE(x, TRUE, y ) == x OR y
+    else if (ASTTrue == child1) {
+      retval = CreateSimpAndOr(0, child0, child2);
+    }
+    // ITE(x, FALSE, y ) == (!x AND y)
+    else if (ASTFalse == child1) {
+      retval = CreateSimpAndOr(1, CreateSimpNot(child0), child2); 
+    }
+    // ITE(x, y, TRUE ) == (!x OR y)
+    else if (ASTTrue == child2) {
+      retval = CreateSimpAndOr(0, CreateSimpNot(child0), child1); 
+    }
+    // ITE(x, y, FALSE ) == (x AND y)
+    else if (ASTFalse == child2) {
+      retval = CreateSimpAndOr(1, child0, child1); 
+    }
+    // ITE (x, !y, y) == x XOR y
+//     else if (NOT == child1.GetKind() && (child1[0] == child2)) {
+//       retval = CreateSimpXor(child0, child2);
+//     }
+//     // ITE (x, y, !y) == x IFF y.  I think other cases are covered
+//     // by XOR/IFF optimizations
+//     else if (NOT == child2.GetKind() && (child2[0] == child1)) {
+//       retval = CreateSimpXor(CreateSimpNot(child0), child2);
+//     }
+    else {
+      retval = CreateNode(ITE, child0, child1, child2);
+    }
+
+    if (_trace_simpbool) {
+      cout << "returns " << retval << endl;
+    }
+
+    return retval;
+  }
+} // BEEV namespace
diff --git a/stp/AST/ToCNF.cpp b/stp/AST/ToCNF.cpp
new file mode 100644
index 00000000..2a18b3f5
--- /dev/null
+++ b/stp/AST/ToCNF.cpp
@@ -0,0 +1,506 @@
+/********************************************************************
+ * AUTHORS: David L. Dill, Vijay Ganesh 
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+// THEORY: This code translates an arbitrary Boolean DAG, generated by
+// the BitBlast.cpp, to an equi-satisfiable CNF formula.  There are
+// four kinds of variables in the CNF formula: (1) propositional
+// variables from the original formula; (2) BVGETBIT formulas from the
+// original formula (a precondition is that the BVGETBIT can only be
+// applied to bitvector-valued variables, array reads, or
+// uninterpreted functions); (3) TRUE; or (4) representative variables
+// (see below).  Each literal in the CNF formula is one of these or
+// its negation.  
+
+// It is convenient (though not perfectly efficient) to be able to add
+// TRUE and FALSE constants to clauses, which is not allowed in CNF.
+// So, there is a "dummy variable" representing TRUE, which is used in
+// its place (so FALSE is represented by the negation of the dummy
+// var).  The CNF formula has a unit clause containing this dummy
+// variable, so that any satisfying assignment must make the dummy var
+// TRUE.
+
+// Every sub-formula of the input formula has a "representative
+// literal."  A truth assignment satisfies the CNF formula iff the
+// restriction of that assignment to the original variables satisfies
+// the original formula, AND the rep lits have the same truth values
+// as the subformulas they represent in the original formula.  In the
+// trivial cases, the representative literal is the input variable, or
+// dummy true var, or its negation.  Representative literals may be
+// negated variables -- essentially, only AND formulas are translated,
+// and everything else is handled by rewriting or negating formulas.
+// The representative for (NOT alpha) is the negation of the
+// representative for alpha.
+
+// The translation is performed by ToCNF_int, which traverses the original
+// formula.  ToCNF adds clauses that constrain the representative variables
+// to be equal to the truth values of the formulas they represent.
+// ToCNF always returns a literal whose value must be equivalent to the formula
+// it translated.  In trivial cases, this literal is a literal from the original
+// formula, or the dummy true/false literals.  If the formula is of the form
+// (not alpha), ToCNF_int negates the literal representing alpha (which may
+// itself be a negative literal) and returns it.  Otherwise, ToCNF_int assigns
+// a new rep var, adds the clauses, and returns the new var.  ToCNF_int is
+// memoized so that it doesn't assign more than one variable to a subformula,
+// and to prevent exponential numbers of redundant visits to shared subformulas.
+
+// In reality, only AND/OR/NOT formulas are translated directly.  Everything
+// else (XOR, IFF, IMPLIES) is rewritten on-the-fly into these forms.  I
+// could have done that in bit-blasting, but I thought that, in the future,
+// we might be able to translate these operations differently in different
+// contexts to optimize the CNF formula.
+
+// FIXME: Inspection of the clauses is kind of horrifying.  In
+// addition to true/false, there are duplicate literals and duplicate
+// clauses all over the place.
+#include "AST.h"
+static bool CNF_trace = false;
+namespace BEEV {
+/**  Statistics class.  Total number of variables is best tracked in
+     ToSAT.  Number of clauses is just cll.size() */
+
+class CNFstats {
+public:
+  int _num_new_rep_vars;
+  int _num_clauses;
+  
+  // constructor
+  CNFstats() : _num_new_rep_vars(0), _num_clauses(0) {}
+
+  void printStats() {
+    if(stats) {
+      cout << "ToCNF statistics:" << endl;
+      cout << "Number of new representative variables: "
+	   << _num_new_rep_vars << endl;
+      cout << "Number of new clauses: "
+	   << _num_clauses << endl;
+    }
+  }
+
+};
+
+
+/** This class contains private data and function members for the
+    CNF conversion */
+class CNFMgr {
+
+  friend class BeevMgr;
+
+public:    
+
+  // Needed in the body of BeevMgr::ToCNF.  It's not visible outside
+  // this file, though.
+  ASTNode dummy_true_var;
+
+  // CNF Pre-pass
+  ASTNodeMap ToCNFPrePassMemo;
+
+  // CNF Memo Table.
+  ASTNodeMap CNFMemo;
+
+
+private:
+
+  // Pointer back to BeevMgr with the node tables, etc.
+  BeevMgr *bm;
+  
+  // For ToCNF conversion.  This holds a dummy variable representing
+  // "True".  It is added as a unit clause, so that it will be assigned
+  // to true and propagated immediately by any CNF solver.
+
+  ASTNode dummy_false_var;	// not of dummy_true_var
+
+  CNFstats stats;
+
+  // constructor
+  CNFMgr(BeevMgr *bmgr)
+  {
+    bm = bmgr;
+
+    // Dummy variable so TRUE can be a literal.
+    dummy_true_var = bm->CreateSymbol("*TrueDummy*");
+    dummy_false_var = bm->CreateSimpNot(dummy_true_var);
+  }
+  
+  // Returns true iff result has been memoized.
+  // if it returns true, result is returned in by-ref parameter "result"
+  // Consider just putitng this in-line.
+  bool CNFIsMemoized(ASTNode &form, ASTNode &result)
+  {
+    ASTNodeMap::iterator it = CNFMemo.find(form);
+    if (it != CNFMemo.end()) {
+      result = it->second;  //already there. Just return it.
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+
+
+  // Convert a big XOR to a bunch of AND/ORs.  Assumes subformulas have
+  // already been converted.
+  ASTNode convertXORs(ASTVec children)
+  {
+    ASTNode accum = children[0];
+    ASTVec::iterator itend = children.end();
+    for (ASTVec::iterator it = children.begin()+1; it < itend; it++) {
+      // a XOR b -> (a | b) & (!a | !b)
+
+      // For each XOR node with k children, creates approximately
+      // 5*(k-1) nodes. AND + 2 OR + 2 NOT.
+
+      ASTNode or1 = bm->CreateNode(OR, accum, *it);
+      ASTNode or2 = bm->CreateNode(OR, bm->CreateSimpNot(accum), bm->CreateSimpNot(*it));
+      accum = bm->CreateNode(AND, or1, or2);
+      
+    }
+    
+    return accum;
+  }
+
+
+  // Do preliminary transformations on bitblasted formula to make 
+  // CNF conversion easier.
+  // Converts XORs to AND/OR form.
+  ASTNode ToCNFPrePass(const ASTNode &form)
+  {
+
+    // Check memo table
+    ASTNodeMap::iterator mem_it = ToCNFPrePassMemo.find(form);
+    if (mem_it != ToCNFPrePassMemo.end()) {
+      return mem_it->second;
+    }
+    
+    ASTNode result;
+
+    ASTVec new_children;
+    ASTVec::const_iterator endit = form.end();
+    for (ASTVec::const_iterator it = form.begin(); it != endit; it++) {
+      ASTNode ch = ToCNFPrePass(*it);
+      new_children.push_back(ch);
+    }
+
+    Kind k = form.GetKind();
+
+    switch (k) {
+    case FALSE: 
+    case TRUE:
+    case SYMBOL: 
+    case BVGETBIT: {
+      result = form;
+      break;
+    }
+    case XOR: {
+      // convertXORs can only be called once per XOR node.
+      result = convertXORs(new_children);
+
+      // cout << "convertXORs num args: "  << new_children.size() << endl;
+      // temporary node for node count.
+      // ASTNode tmp = bm->CreateNode(XOR, new_children );
+      // cout << "convertXORs size of [" << form.GetNodeNum() << "] " << bm->NodeSize(form, true) << endl;
+      // cout << "convertXORs before size: " << bm->NodeSize(tmp, true) << endl;
+      // cout << "convertXORs after size: " << bm->NodeSize(result, true) << endl;
+      break;
+    }
+    default: {
+      // Be cautious about using CreateSimpForm -- It makes big xors!
+      result = bm->CreateNode(k, new_children);
+    }
+    }
+
+//     cout << "================" << endl
+// 	 << "ToCNFPrePass:" << form << endl
+// 	 << "----------------" << endl
+// 	 << "ToCNFPrePass Result:" << result << endl;
+    
+    return (ToCNFPrePassMemo[form] = result);
+    
+  }
+
+  // Memoize and return formula value
+  ASTNode CNFMemoize(ASTNode& form, ASTNode result)
+  {
+    CNFMemo[form] = result;
+    return result;    
+  }
+
+ 
+  // Create a representative variable for an original formula.
+  // The convention is that the variable will have the same truth
+  // value as the expression numbered "num."  
+  ASTNode RepLit(const char *name, int exprnum)
+  {
+    // FIXME: can this be done more efficiently with string type?
+    ostringstream oss;
+    oss << name << "{" << exprnum << "}";
+    ASTNode t = bm->CreateSymbol(oss.str().c_str());
+
+    // Track how many we're generating.
+    stats._num_new_rep_vars++;
+    
+    //ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
+    t.SetIndexWidth(0);
+    t.SetValueWidth(0);
+    return t;
+  }
+
+  // Handle the cases where it's necessary to do n children.
+  // This code translates ANDs, and converts NAND, NOR, OR by negating
+  // the inputs or outputs of the AND.
+  ASTNode ToCNF_AndLike(Kind k, BeevMgr::ClauseList& cll, ASTNode form)
+  {  
+    // Build vectors of positive and negative rep lits for children
+    ASTVec kidlits(0);
+    ASTVec negkidlits(0);
+    ASTVec::const_iterator kids_end = form.end();
+    for (ASTVec::const_iterator it = form.begin(); it != kids_end; it++) {
+      ASTNode kidreplit = ToCNF_int(cll, *it);
+      kidlits.push_back(kidreplit);
+      negkidlits.push_back(bm->CreateSimpNot(kidreplit));
+    }
+    
+    ASTNode replit;
+    // translate the AND, negating inputs as appropriate.
+    if (k == OR || k == NOR) {
+      replit = ToCNF_AND(cll, form.GetNodeNum(), negkidlits, kidlits);
+    }
+    else {
+      replit = ToCNF_AND(cll, form.GetNodeNum(), kidlits, negkidlits);
+    }
+    
+    // Reduce NAND/OR to AND by negating result.
+    if (k == NAND || k == OR) {
+      return CNFMemoize(form, bm->CreateSimpNot(replit));
+    }
+    else {
+      return CNFMemoize(form, replit);
+    }
+  }
+
+  ASTNode ToCNF_AND(BeevMgr::ClauseList& cll, int nodenum, ASTVec& kidlits, ASTVec& negkidlits)
+  {
+    // Translate an AND, given rep lits for children
+    // Build clauses for (replit <-> a AND b AND c)
+
+    ASTNode replit = RepLit("cnf", nodenum);
+    ASTNode notreplit = bm->CreateSimpNot(replit);
+
+    if (CNF_trace) {
+      cout << "Translating AND" << endl << "-----------------------" << endl
+	   << "Rep lit =" <<  replit << endl
+	   << "-----------------------";
+    }
+
+    // (a AND b AND c -> replit) ==   (~a OR ~b OR ~c OR replit)
+    BeevMgr::ClausePtr clp = new ASTVec(negkidlits);
+    clp->push_back(replit);
+
+    if (CNF_trace) {
+      LispPrintVec(cout, *clp, 0);
+      cout << endl << "-----------------------" << endl;
+    }
+
+    cll.push_back(clp);
+
+    // (replit -> (a AND b AND c)) == 
+    //     (~replit OR a) AND (~replit OR b) AND (~replit OR c)
+    ASTVec::const_iterator kidlits_end = kidlits.end();
+    for (ASTVec::iterator it = kidlits.begin(); it != kidlits_end; it++) {
+      clp = new ASTVec();
+      clp->push_back(notreplit);
+      clp->push_back(*it);
+
+      if (CNF_trace) {
+	LispPrintVec(cout, *clp, 0);
+	cout << endl << "-----------------------" << endl;
+      }
+
+      cll.push_back(clp);
+    }
+
+    return replit;
+  }
+
+public:
+   
+  /** Builds clauses globally and returns a literal.
+      The literal can be a leaf from the expression, or a rep var
+      made up to represent the subexpression. */
+  ASTNode ToCNF_int(BeevMgr::BeevMgr::ClauseList& cll, ASTNode form) {
+    // FIXME: assert indexwidth= 0, valuewidth = 1
+
+    // FIXME:  rewriting is top-down, which is not efficient.
+    // It rewrites the top node of the tree, then does the children.
+    // Either rewrite in a separate pass, or translate children
+    // before rewriting somehow (might require handling rep lits
+    // as though they were real lits, which is probably ok).
+    
+    // Return memoized value if seen before.
+    ASTNode result;
+    Kind k = form.GetKind();
+
+    if (CNFIsMemoized(form, result)) {
+      return result;
+    }
+
+    switch (k) {
+      // handle the trivial cases here.  If none apply, call the
+      // heavy-duty function.  If a constant or literal, just return
+      // without creating a clause.
+    case FALSE: {
+      result = dummy_false_var;
+      break;
+    }
+    case TRUE: {
+      result =  dummy_true_var;
+      break;
+    }
+    case SYMBOL: 
+    case BVGETBIT: {
+      result = form;
+      break;
+    }
+      
+    case NOT: {
+	ASTNode replit = ToCNF_int(cll, form[0]);
+	result = bm->CreateSimpNot(replit);
+      break;
+    }
+      
+      // For these, I can't think of anything better than expanding into ANDs/ORs
+    case ITE: {
+      // (ite a b c) == (~a OR b) AND (a OR c)
+      ASTNode l = bm->CreateNode(OR, bm->CreateSimpNot(form[0]), form[1]);
+      ASTNode r = bm->CreateNode(OR, form[0], form[2]);
+      ASTNode andor = bm->CreateNode(AND, l, r);
+      if (CNF_trace) {
+	cout << "Rewriting " << form << endl
+	     << "to" << andor << endl
+	     << "-------------------" << endl;
+      }
+      result = ToCNF_int(cll, andor);
+      break;
+    }
+    case IMPLIES: {
+      // Just rewrite into (~a OR b)
+      ASTNode l = bm->CreateSimpNot(form[0]);
+      ASTNode andor = bm->CreateNode(OR, l, form[1]);
+      if (CNF_trace) {
+	cout << "Rewriting " << form << endl
+	     << "to" << andor << endl
+	     << "-------------------" << endl;
+      }
+      result = ToCNF_int(cll, andor);
+      break;
+    }
+    case XOR: {
+      FatalError("ToCNF_int: XORs should have been converted to AND/OR by this point.");
+      break;
+    }
+
+    case IFF: {
+      FatalError("BitBlaster failed to eliminate all IFFs.");
+      break;
+    }
+    
+    case AND:
+    case OR:
+    case NOR:
+    case NAND: {
+      result = ToCNF_AndLike(k, cll, form);
+      break;
+    }
+    default:
+      cerr << "ToCNF: can't handle this kind: " << k << endl;
+      FatalError("");
+    }
+
+    if (CNF_trace) {
+      cout << "ToCNF_int: Literal " << result << " represents formula " <<
+	form << endl << "---------------" << endl;
+    }
+
+    return CNFMemoize(form, result);
+  } //end of ToCNF_int()
+
+
+}; // end of CNFMgr class
+
+  // These are the bodies of functions in the BeevMgr that are part of
+  // the public interface.
+
+  // Debug printing function.
+  void BeevMgr::PrintClauseList(ostream& os, BeevMgr::ClauseList& cll)
+  {
+    int num_clauses = cll.size();
+    os << "Clauses: " << endl << "=========================================" << endl;
+    for(int i=0; i < num_clauses; i++) {
+      os << "Clause " << i << endl
+	 << "-------------------------------------------" << endl;
+      LispPrintVec(os, *cll[i], 0);
+      os << endl
+	 << "-------------------------------------------" << endl;
+    }
+  }
+
+  void BeevMgr::DeleteClauseList(BeevMgr::ClauseList *cllp)
+  {
+    BeevMgr::ClauseList::const_iterator iend = cllp->end();
+    for (BeevMgr::ClauseList::const_iterator i = cllp->begin(); i < iend; i++) {
+      delete *i;
+    }
+    delete cllp;
+  }
+
+  // Top level conversion function
+  BeevMgr::ClauseList *BeevMgr::ToCNF(const ASTNode& form) 
+  {
+
+    // FIXME: This is leaked as well.
+    CNFMgr *cm = new CNFMgr(this);
+   
+    // Prepass
+    ASTNode form1 = cm->ToCNFPrePass(form);
+
+    // cout << "Number of nodes after ToCNFPrePass" << NodeSize(form1, true) << endl;
+
+    // cout << "ToCNF: After ToCNFPrePass" << form1 << endl;
+
+    // FIXME: Assert CNFMemo is empty.
+
+    // The clause list we will be building up.
+    // FIXME: This is never freed.
+    ClauseList *cllp = new ClauseList();
+
+    BeevMgr::ClausePtr dummy_true_unit_clause = new ASTVec();
+    dummy_true_unit_clause->push_back(cm->dummy_true_var);
+    cllp->push_back(dummy_true_unit_clause);
+
+    // This is where the translation happens.
+    ASTNode toplit = cm->ToCNF_int(*cllp, form1);
+
+    // Add the top literal as a unit clause, since it must
+    // be true when original formula is satsfied.
+    BeevMgr::ClausePtr clp = new ASTVec(0);
+    clp->push_back(toplit);
+    cllp->push_back(clp);
+
+    cm->stats._num_clauses = cllp->size();
+    cm->stats.printStats();
+
+    RepLitMap = cm->CNFMemo;	// Save memo table for debugging (DD 1/13/07).
+
+    cm->CNFMemo.clear();   // Important to do this so nodes get freed.
+
+    delete cm;
+
+    return cllp;
+  }
+
+} // end namespace
diff --git a/stp/AST/ToSAT.cpp b/stp/AST/ToSAT.cpp
new file mode 100644
index 00000000..7a164c9c
--- /dev/null
+++ b/stp/AST/ToSAT.cpp
@@ -0,0 +1,1385 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+#include "AST.h"
+#include "ASTUtil.h"
+#include "../simplifier/bvsolver.h"
+#include <math.h>
+
+
+namespace BEEV {
+  /* FUNCTION: lookup or create a new MINISAT literal
+   * lookup or create new MINISAT Vars from the global MAP
+   * _ASTNode_to_SATVar.
+   */
+  const MINISAT::Var BeevMgr::LookupOrCreateSATVar(MINISAT::Solver& newS, const ASTNode& n) {  
+    ASTtoSATMap::iterator it;  
+    MINISAT::Var v;
+    
+    //look for the symbol in the global map from ASTNodes to ints. if
+    //not found, create a S.newVar(), else use the existing one.
+    if((it = _ASTNode_to_SATVar.find(n)) == _ASTNode_to_SATVar.end()) {
+      v = newS.newVar();
+      _ASTNode_to_SATVar[n] = v;	
+      
+      //ASSUMPTION: I am assuming that the newS.newVar() call increments v
+      //by 1 each time it is called, and the initial value of a
+      //MINISAT::Var is 0.
+      _SATVar_to_AST.push_back(n);
+    }
+    else
+      v = it->second;
+    return v;
+  }
+  
+  /* FUNCTION: convert ASTClauses to MINISAT clauses and solve.
+   * Accepts ASTClauses and converts them to MINISAT clauses. Then adds
+   * the newly minted MINISAT clauses to the local SAT instance, and
+   * calls solve(). If solve returns unsat, then stop and return
+   * unsat. else continue.
+   */  
+  // FIXME: Still need to deal with TRUE/FALSE in clauses!
+ bool BeevMgr::toSATandSolve(MINISAT::Solver& newS, BeevMgr::ClauseList& cll)
+ {
+    CountersAndStats("SAT Solver");
+
+    //iterate through the list (conjunction) of ASTclauses cll
+    BeevMgr::ClauseList::const_iterator i = cll.begin(), iend = cll.end();
+    
+    if(i == iend)
+      FatalError("toSATandSolve: Nothing to Solve",ASTUndefined);
+    
+    //turnOffSubsumption
+    newS.turnOffSubsumption();
+
+    // (*i) is an ASTVec-ptr which denotes an ASTclause
+    for(; i!=iend; i++) {    
+      //Clause for the SATSolver
+      MINISAT::vec<MINISAT::Lit> satSolverClause;
+      
+      //now iterate through the internals of the ASTclause itself
+      ASTVec::const_iterator j = (*i)->begin(), jend = (*i)->end();
+      //j is a disjunct in the ASTclause (*i)
+      for(;j!=jend;j++) {
+
+	bool negate = (NOT == j->GetKind()) ? true : false;		
+	ASTNode n = negate ? (*j)[0] : *j;
+	
+	//Lookup or create the MINISAT::Var corresponding to the Booelan
+	//ASTNode Variable, and push into sat Solver clause
+	MINISAT::Var v = LookupOrCreateSATVar(newS,n);
+	MINISAT::Lit l(v, negate);
+	satSolverClause.push(l);
+      }
+      newS.addClause(satSolverClause);
+      // clause printing.
+      // (printClause<MINISAT::vec<MINISAT::Lit> >)(satSolverClause);
+      // cout << " 0 ";
+      // cout << endl;
+      
+      if(newS.okay()) {
+	continue;
+      }
+      else {
+	PrintStats(newS.stats);
+	return false;
+      }
+      
+      if(!newS.simplifyDB(false)) {
+      	PrintStats(newS.stats);
+      	return false;
+      }
+    }
+
+    // if input is UNSAT return false, else return true    
+    if(!newS.simplifyDB(false)) {
+      PrintStats(newS.stats);
+      return false;
+    }
+    
+    //PrintActivityLevels_Of_SATVars("Before SAT:",newS);
+    //ChangeActivityLevels_Of_SATVars(newS);
+    //PrintActivityLevels_Of_SATVars("Before SAT and after initial bias:",newS); 
+    newS.solve();
+    //PrintActivityLevels_Of_SATVars("After SAT",newS);
+
+    PrintStats(newS.stats);
+    if (newS.okay())
+      return true;
+    else
+      return false;
+  }
+
+  // GLOBAL FUNCTION: Prints statistics from the MINISAT Solver   
+  void BeevMgr::PrintStats(MINISAT::SolverStats& s) {
+    if(!stats)
+      return;
+    double  cpu_time = MINISAT::cpuTime();
+    MINISAT::int64   mem_used = MINISAT::memUsed();
+    reportf("restarts              : %"I64_fmt"\n", s.starts);
+    reportf("conflicts             : %-12"I64_fmt"   (%.0f /sec)\n", s.conflicts   , s.conflicts   /cpu_time);
+    reportf("decisions             : %-12"I64_fmt"   (%.0f /sec)\n", s.decisions   , s.decisions   /cpu_time);
+    reportf("propagations          : %-12"I64_fmt"   (%.0f /sec)\n", s.propagations, s.propagations/cpu_time);
+    reportf("conflict literals     : %-12"I64_fmt"   (%4.2f %% deleted)\n", 
+	    s.tot_literals, 
+	    (s.max_literals - s.tot_literals)*100 / (double)s.max_literals);
+    if (mem_used != 0) reportf("Memory used           : %.2f MB\n", mem_used / 1048576.0);
+    reportf("CPU time              : %g s\n", cpu_time);
+  }
+  
+  // Prints Satisfying assignment directly, for debugging.
+  void BeevMgr::PrintSATModel(MINISAT::Solver& newS) {
+    if(!newS.okay())
+      FatalError("PrintSATModel: NO COUNTEREXAMPLE TO PRINT",ASTUndefined);
+    // FIXME: Don't put tests like this in the print functions.  The print functions
+    // should print unconditionally.  Put a conditional around the call if you don't 
+    // want them to print
+    if(!(stats && print_nodes))
+      return;
+
+    int num_vars = newS.nVars();
+    cout << "Satisfying assignment: " << endl;
+    for (int i = 0; i < num_vars; i++) {
+      if (newS.model[i] == MINISAT::l_True) {
+	ASTNode s = _SATVar_to_AST[i];
+	cout << s << endl;
+      }
+      else if (newS.model[i] == MINISAT::l_False) {
+	ASTNode s = _SATVar_to_AST[i];
+	cout << CreateNode(NOT, s) << endl;
+      }
+    }
+  }
+
+
+  // Looks up truth value of ASTNode SYMBOL in MINISAT satisfying assignment.
+  // Returns ASTTrue if true, ASTFalse if false or undefined.
+  ASTNode BeevMgr::SymbolTruthValue(MINISAT::Solver &newS, ASTNode form) 
+  {
+    MINISAT::Var satvar = _ASTNode_to_SATVar[form];
+    if (newS.model[satvar] == MINISAT::l_True) {
+      return ASTTrue;
+    }
+    else if (newS.model[satvar] == MINISAT::l_False){
+      // False
+      return ASTFalse;
+    }
+    else {
+      return (rand() > 4096) ? ASTTrue : ASTFalse; 
+    }
+  }
+
+
+  // This function is for debugging problems with BitBlast and especially
+  // ToCNF. It evaluates the bit-blasted formula in the satisfying
+  // assignment.  While doing that, it checks that every subformula has
+  // the same truth value as its representative literal, if it has one.
+  // If this condition is violated, it halts immediately (on the leftmost
+  // lowest term).
+  // Use CreateSimpForm to evaluate, even though it's expensive, so that
+  // we can use the partial truth assignment.
+  ASTNode BeevMgr::CheckBBandCNF(MINISAT::Solver& newS, ASTNode form)
+  {
+    // Clear memo table (in case newS has changed).
+    CheckBBandCNFMemo.clear();
+    // Call recursive version that does the work.
+    return CheckBBandCNF_int(newS, form);
+  }
+
+  // Recursive body CheckBBandCNF
+  // FIXME:  Modify this to just check if result is true, and print mismatch 
+  // if not.   Might have a trace flag for the other stuff.
+  ASTNode BeevMgr::CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form)
+  {
+
+    //    cout << "++++++++++++++++" << endl << "CheckBBandCNF_int form = " <<
+    //      form << endl;
+  
+    ASTNodeMap::iterator memoit = CheckBBandCNFMemo.find(form);
+    if (memoit != CheckBBandCNFMemo.end()) {
+      // found it.  Return memoized value.
+      return memoit->second;
+    }
+
+    ASTNode result;		// return value, to memoize.
+
+    Kind k = form.GetKind();
+    switch (k) {
+    case TRUE:
+    case FALSE: {
+      return form;
+      break;
+    }
+    case SYMBOL: 
+    case BVGETBIT:  {
+      // Look up the truth value
+      // ASTNode -> Sat -> Truthvalue -> ASTTrue or ASTFalse;
+      // FIXME: Could make up a fresh var in undefined case.
+
+      result = SymbolTruthValue(newS, form);
+
+      cout << "================" << endl << "Checking BB formula:" << form << endl;
+      cout << "----------------" << endl << "Result:" << result << endl;
+
+      break;
+    }
+    default: {
+      // Evaluate the children recursively.
+      ASTVec eval_children;
+      ASTVec ch = form.GetChildren();
+      ASTVec::iterator itend = ch.end();
+      for(ASTVec::iterator it = ch.begin(); it < itend; it++) {
+	eval_children.push_back(CheckBBandCNF_int(newS, *it));
+      }
+      result = CreateSimpForm(k, eval_children);
+
+      cout << "================" << endl << "Checking BB formula:" << form << endl;
+      cout << "----------------" << endl << "Result:" << result << endl;
+
+      ASTNode replit_eval;
+      // Compare with replit, if there is one.
+      ASTNodeMap::iterator replit_it = RepLitMap.find(form);
+      if (replit_it != RepLitMap.end()) {
+	ASTNode replit = RepLitMap[form];
+	// Replit is symbol or not symbol.
+	if (SYMBOL == replit.GetKind()) {
+	  replit_eval = SymbolTruthValue(newS, replit);
+	}
+	else {
+	  // It's (NOT sym).  Get value of sym and complement.
+	  replit_eval = CreateSimpNot(SymbolTruthValue(newS, replit[0]));
+	}
+
+	cout << "----------------" << endl << "Rep lit: " << replit << endl;
+	cout << "----------------" << endl << "Rep lit value: " << replit_eval << endl;
+
+	if (result != replit_eval) {
+	  // Hit the panic button.
+	  FatalError("Truth value of BitBlasted formula disagrees with representative literal in CNF.");
+	}
+      }
+      else {
+	cout << "----------------" << endl << "No rep lit" << endl;
+      }
+
+    }
+    }
+
+    return (CheckBBandCNFMemo[form] = result);
+  }
+
+  /*FUNCTION: constructs counterexample from MINISAT counterexample
+   * step1 : iterate through MINISAT counterexample and assemble the
+   * bits for each AST term. Store it in a map from ASTNode to vector
+   * of bools (bits).
+   *
+   * step2: Iterate over the map from ASTNodes->Vector-of-Bools and
+   * populate the CounterExampleMap data structure (ASTNode -> BVConst)
+   */
+  void BeevMgr::ConstructCounterExample(MINISAT::Solver& newS) {
+    //iterate over MINISAT counterexample and construct a map from AST
+    //terms to vector of bools. We need this iteration step because
+    //MINISAT might return the various bits of a term out of
+    //order. Therfore, we need to collect all the bits and assemble
+    //them properly
+    
+    if(!newS.okay())
+      return;
+    if(!construct_counterexample)
+      return;    
+
+    CopySolverMap_To_CounterExample();
+    for (int i = 0; i < newS.nVars(); i++) {
+      //Make sure that the MINISAT::Var is defined
+      if (newS.model[i] != MINISAT::l_Undef) {
+	
+	//mapping from MINISAT::Vars to ASTNodes. We do not need to
+	//print MINISAT vars or CNF vars.
+	ASTNode s = _SATVar_to_AST[i];
+	
+	//assemble the counterexample here
+	if(s.GetKind() == BVGETBIT && s[0].GetKind() == SYMBOL) {
+	  ASTNode symbol = s[0];
+	  unsigned int symbolWidth = symbol.GetValueWidth();
+	  
+	  //'v' is the map from bit-index to bit-value
+	  hash_map<unsigned,bool> * v;	
+	  if(_ASTNode_to_Bitvector.find(symbol) == _ASTNode_to_Bitvector.end())
+	    _ASTNode_to_Bitvector[symbol] = new hash_map<unsigned,bool>(symbolWidth);	
+	  
+	  //v holds the map from bit-index to bit-value
+	  v = _ASTNode_to_Bitvector[symbol];
+	  
+	  //kk is the index of BVGETBIT
+	  unsigned int kk = GetUnsignedConst(s[1]); 	
+	  
+	  //Collect the bits of 'symbol' and store in v. Store in reverse order.
+	  if(newS.model[i]==MINISAT::l_True)
+	    (*v)[(symbolWidth-1) - kk] = true;
+	  else
+	    (*v)[(symbolWidth-1) - kk] = false;
+	}
+	else {	 
+	  if(s.GetKind() == SYMBOL && s.GetType() == BOOLEAN_TYPE) {
+	    const char * zz = s.GetName();
+	    //if the variables are not cnf variables then add them to the counterexample
+	    if(0 != strncmp("cnf",zz,3) && 0 != strcmp("*TrueDummy*",zz)) {
+	      if(newS.model[i]==MINISAT::l_True)
+		CounterExampleMap[s] = ASTTrue;
+	      else
+		CounterExampleMap[s] = ASTFalse;	    
+	    }
+	  }
+	}
+      }
+    }
+
+    //iterate over the ASTNode_to_Bitvector data-struct and construct
+    //the the aggregate value of the bitvector, and populate the
+    //CounterExampleMap datastructure
+    for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),itend=_ASTNode_to_Bitvector.end();
+	it!=itend;it++) {
+      ASTNode var = it->first;      
+      //debugging
+      //cerr << var;
+      if(SYMBOL != var.GetKind())
+	FatalError("ConstructCounterExample: error while constructing counterexample: not a variable: ",var);
+
+      //construct the bitvector value
+      hash_map<unsigned,bool> * w = it->second;
+      ASTNode value = BoolVectoBVConst(w, var.GetValueWidth());      
+      //debugging
+      //cerr << value;
+
+      //populate the counterexample datastructure. add only scalars
+      //variables which were declared in the input and newly
+      //introduced variables for array reads
+      CounterExampleMap[var] = value;
+    }
+    
+    //In this loop, we compute the value of each array read, the
+    //corresponding ITE against the counterexample generated above.
+    for(ASTNodeMap::iterator it=_arrayread_ite.begin(),itend=_arrayread_ite.end();
+	it!=itend;it++){
+      //the array read
+      ASTNode arrayread = it->first;
+      ASTNode value_ite = _arrayread_ite[arrayread];
+      
+      //convert it to a constant array-read and store it in the
+      //counter-example. First convert the index into a constant. then
+      //construct the appropriate array-read and store it in the
+      //counterexample
+      ASTNode arrayread_index = TermToConstTermUsingModel(arrayread[1]);
+      ASTNode key = CreateTerm(READ,arrayread.GetValueWidth(),arrayread[0],arrayread_index);
+
+      //Get the ITE corresponding to the array-read and convert it
+      //to a constant against the model
+      ASTNode value = TermToConstTermUsingModel(value_ite);
+      //save the result in the counter_example
+      if(!CheckSubstitutionMap(key))
+	CounterExampleMap[key] = value;      
+    }
+  } //End of ConstructCounterExample
+
+  // FUNCTION: accepts a non-constant term, and returns the
+  // corresponding constant term with respect to a model. 
+  //
+  // term READ(A,i) is treated as follows:
+  //
+  //1. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
+  //1. has value in counterexample), then return the value of the
+  //1. arrayread.
+  //
+  //2. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
+  //2. doesn't have value in counterexample), then return the
+  //2. arrayread itself (normalized such that arrayread has a constant
+  //2. index)
+  //
+  //3. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
+  //3. has a value in the counterexample then return the value of the
+  //3. arrayread.
+  //
+  //4. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
+  //4. doesn't have a value in the counterexample then return 0 as the
+  //4. value of the arrayread.
+  ASTNode BeevMgr::TermToConstTermUsingModel(const ASTNode& t, bool ArrayReadFlag) {
+    Begin_RemoveWrites = false;
+    SimplifyWrites_InPlace_Flag = false;
+    //ASTNode term = SimplifyTerm(t);
+    ASTNode term = t;
+    Kind k = term.GetKind();
+    
+
+    //cerr << "Input to TermToConstTermUsingModel: " << term << endl;
+    if(!is_Term_kind(k)) {
+      FatalError("TermToConstTermUsingModel: The input is not a term: ",term);
+    }
+    if(k == WRITE) {
+      FatalError("TermToConstTermUsingModel: The input has wrong kind: WRITE : ",term);
+    }
+    if(k == SYMBOL && BOOLEAN_TYPE == term.GetType()) {
+      FatalError("TermToConstTermUsingModel: The input has wrong kind: Propositional variable : ",term);
+    }
+
+    ASTNodeMap::iterator it1;
+    if((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end()) {
+      ASTNode val = it1->second;
+      if(BVCONST != val.GetKind()) {
+	//CounterExampleMap has two maps rolled into
+	//one. SubstitutionMap and SolverMap.
+	//
+	//recursion is fine here. There are two maps that are checked
+	//here. One is the substitutionmap. We garuntee that the value
+	//of a key in the substitutionmap is always a constant.
+	//
+	//in the SolverMap we garuntee that "term" does not occur in
+	//the value part of the map
+	if(term == val) {
+	  FatalError("TermToConstTermUsingModel: The input term is stored as-is "
+		     "in the CounterExample: Not ok: ",term);    
+	}
+	return TermToConstTermUsingModel(val,ArrayReadFlag);
+      }
+      else {
+	return val;
+      }
+    }
+
+    ASTNode output;
+    switch(k) {
+    case BVCONST:
+      output = term;
+      break;
+    case SYMBOL: {
+      if(term.GetType() == ARRAY_TYPE) {
+	return term;
+      }
+
+      //when all else fails set symbol values to some constant by
+      //default. if the variable is queried the second time then add 1
+      //to and return the new value.
+      ASTNode zero = CreateZeroConst(term.GetValueWidth());
+      output = zero;
+      break;    
+    }
+    case READ: {      
+      ASTNode arrName = term[0];
+      ASTNode index = term[1];
+      if(0 == arrName.GetIndexWidth()) {
+	FatalError("TermToConstTermUsingModel: array has 0 index width: ",arrName);
+      }
+      
+      //READ over a WRITE
+      if(WRITE == arrName.GetKind()) {
+	ASTNode wrtterm = Expand_ReadOverWrite_UsingModel(term, ArrayReadFlag);
+	if(wrtterm == term) {
+	  FatalError("TermToConstTermUsingModel: Read_Over_Write term must be expanded into an ITE", term);
+	}
+	ASTNode rtterm = TermToConstTermUsingModel(wrtterm,ArrayReadFlag);	
+	return rtterm;
+      } 
+      //READ over an ITE
+      if(ITE == arrName.GetKind()) {
+	arrName = TermToConstTermUsingModel(arrName,ArrayReadFlag);
+      }
+
+      ASTNode modelentry;
+      if(CounterExampleMap.find(index) != CounterExampleMap.end()) {	
+	//index has a const value in the CounterExampleMap
+	ASTNode indexVal = CounterExampleMap[index];
+	modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexVal);
+      }
+      else { 
+	//index does not have a const value in the CounterExampleMap. compute it.
+	ASTNode indexconstval = TermToConstTermUsingModel(index,ArrayReadFlag);
+	//update model with value of the index
+	//CounterExampleMap[index] = indexconstval;
+	modelentry = CreateTerm(READ,arrName.GetValueWidth(), arrName,indexconstval);	
+      }
+      //modelentry is now an arrayread over a constant index
+      BVTypeCheck(modelentry);
+      
+      //if a value exists in the CounterExampleMap then return it
+      if(CounterExampleMap.find(modelentry) != CounterExampleMap.end()) {
+	output = TermToConstTermUsingModel(CounterExampleMap[modelentry],ArrayReadFlag);
+      }
+      else if(ArrayReadFlag) {
+	//return the array read over a constantindex
+	output = modelentry;
+      }
+      else {
+	//when all else fails set symbol values to some constant by
+	//default. if the variable is queried the second time then add 1
+	//to and return the new value.
+	ASTNode zero = CreateZeroConst(modelentry.GetValueWidth());
+	output = zero;
+      }
+      break;
+    }
+    case ITE: {
+      ASTNode condcompute = ComputeFormulaUsingModel(term[0]);
+      if(ASTTrue == condcompute) {
+	output = TermToConstTermUsingModel(term[1],ArrayReadFlag);
+      }
+      else if(ASTFalse == condcompute) {
+	output = TermToConstTermUsingModel(term[2],ArrayReadFlag);
+      } 
+      else {
+	cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl; 
+	FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ",term);
+      }
+      break;
+    }
+    default: {
+      ASTVec c = term.GetChildren();
+      ASTVec o;
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode ff = TermToConstTermUsingModel(*it,ArrayReadFlag);
+	o.push_back(ff);
+      }
+      output = CreateTerm(k,term.GetValueWidth(),o);
+      //output is a CONST expression. compute its value and store it
+      //in the CounterExampleMap
+      ASTNode oo = BVConstEvaluator(output);
+      //the return value
+      output = oo;
+      break;
+    }
+    }
+
+    //when this flag is false, we should compute the arrayread to a
+    //constant. this constant is stored in the counter_example
+    //datastructure
+    if(!ArrayReadFlag) {
+      CounterExampleMap[term] = output;
+    }
+    
+    //cerr << "Output to TermToConstTermUsingModel: " << output << endl;
+    return output;
+  } //End of TermToConstTermUsingModel
+
+  //Expands read-over-write by evaluating (readIndex=writeIndex) for
+  //every writeindex until, either it evaluates to TRUE or all
+  //(readIndex=writeIndex) evaluate to FALSE
+  ASTNode BeevMgr::Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool arrayread_flag) {
+    if(READ != term.GetKind() && 
+       WRITE != term[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
+    }
+
+    ASTNode output;
+    ASTNodeMap::iterator it1;    
+    if((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end()) {
+      ASTNode val = it1->second;
+      if(BVCONST != val.GetKind()) {
+	//recursion is fine here. There are two maps that are checked
+	//here. One is the substitutionmap. We garuntee that the value
+	//of a key in the substitutionmap is always a constant.
+	if(term == val) {
+	  FatalError("TermToConstTermUsingModel: The input term is stored as-is "
+		     "in the CounterExample: Not ok: ",term);    
+	}
+	return TermToConstTermUsingModel(val,arrayread_flag);
+      }
+      else {
+	return val;
+      }
+    }
+
+    unsigned int width = term.GetValueWidth();
+    ASTNode writeA = ASTTrue; 
+    ASTNode newRead = term;
+    ASTNode readIndex = TermToConstTermUsingModel(newRead[1],false);
+    //iteratively expand read-over-write, and evaluate against the
+    //model at every iteration
+    do {
+      ASTNode write = newRead[0];
+      writeA = write[0];
+      ASTNode writeIndex = TermToConstTermUsingModel(write[1],false);
+      ASTNode writeVal = TermToConstTermUsingModel(write[2],false);
+      
+      ASTNode cond = ComputeFormulaUsingModel(CreateSimplifiedEQ(writeIndex,readIndex));
+      if(ASTTrue == cond) {
+	//found the write-value. return it
+	output = writeVal;
+	CounterExampleMap[term] = output;
+	return output;
+      }
+
+      newRead = CreateTerm(READ,width,writeA,readIndex);
+    } while(READ == newRead.GetKind() && WRITE == newRead[0].GetKind());
+    
+    output = TermToConstTermUsingModel(newRead,arrayread_flag);
+        
+    //memoize
+    CounterExampleMap[term] = output;
+    return output;  
+  } //Exand_ReadOverWrite_To_ITE_UsingModel()
+
+  /* FUNCTION: accepts a non-constant formula, and checks if the
+   * formula is ASTTrue or ASTFalse w.r.t to a model
+   */
+  ASTNode BeevMgr::ComputeFormulaUsingModel(const ASTNode& form) {
+    ASTNode in = form;
+    Kind k = form.GetKind();
+    if(!(is_Form_kind(k) && BOOLEAN_TYPE == form.GetType())) {
+      FatalError(" ComputeConstFormUsingModel: The input is a non-formula: ", form);
+    }
+
+    //cerr << "Input to ComputeFormulaUsingModel:" << form << endl;
+    ASTNodeMap::iterator it1;
+    if((it1 = ComputeFormulaMap.find(form)) != ComputeFormulaMap.end()) {
+      ASTNode res = it1->second;
+      if(ASTTrue == res || ASTFalse == res) {
+	return res;
+      }
+      else {
+	FatalError("ComputeFormulaUsingModel: The value of a formula must be TRUE or FALSE:", form);
+      }
+    }
+    
+    ASTNode t0,t1;
+    ASTNode output = ASTFalse;
+    switch(k) {
+    case TRUE:
+    case FALSE:
+      output = form;      
+      break;
+    case SYMBOL:
+      if(BOOLEAN_TYPE != form.GetType())
+	FatalError(" ComputeFormulaUsingModel: Non-Boolean variables are not formulas",form);
+      if(CounterExampleMap.find(form) != CounterExampleMap.end()) {
+	ASTNode counterexample_val = CounterExampleMap[form];
+	if(!VarSeenInTerm(form,counterexample_val)) {
+	  output = ComputeFormulaUsingModel(counterexample_val);
+	}
+	else {
+	  output = counterexample_val;
+	}
+      }
+      else
+	output = ASTFalse;
+      break;  
+    case EQ:
+    case NEQ:
+    case BVLT:
+    case BVLE:
+    case BVGT:
+    case BVGE:
+    case BVSLT:
+    case BVSLE:
+    case BVSGT:
+    case BVSGE:
+      //convert form[0] into a constant term
+      t0 = TermToConstTermUsingModel(form[0],false);
+      //convert form[0] into a constant term
+      t1 = TermToConstTermUsingModel(form[1],false);
+      output = BVConstEvaluator(CreateNode(k,t0,t1));
+      
+      //evaluate formula to false if bvdiv execption occurs while
+      //counterexample is being checked during refinement.
+      if(bvdiv_exception_occured && 
+	 counterexample_checking_during_refinement) {
+	output = ASTFalse;
+      }
+      break;   
+    case NAND: {
+      ASTNode o = ASTTrue;
+      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++)
+	if(ASTFalse == ComputeFormulaUsingModel(*it)) {
+	  o = ASTFalse;
+	  break;
+	}      
+      if(o == ASTTrue) 
+	output = ASTFalse;
+      else 
+	output = ASTTrue;
+      break;
+    }
+    case NOR: {
+      ASTNode o = ASTFalse;
+      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++)
+	if(ASTTrue == ComputeFormulaUsingModel(*it)) {
+	  o = ASTTrue;
+	  break;
+	}
+      if(o == ASTTrue) 
+	output = ASTFalse;
+      else 
+	output = ASTTrue;
+      break;
+    }
+    case NOT:
+      if(ASTTrue == ComputeFormulaUsingModel(form[0]))
+	output = ASTFalse;
+      else
+	output = ASTTrue;
+      break;
+    case OR:
+      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++) 
+	if(ASTTrue == ComputeFormulaUsingModel(*it))
+	  output = ASTTrue;
+      break;
+    case AND:
+      output = ASTTrue;
+      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++) {
+	if(ASTFalse == ComputeFormulaUsingModel(*it)) {	    
+	  output = ASTFalse;
+	  break;	  
+	}
+      }
+      break;
+    case XOR:
+      t0 = ComputeFormulaUsingModel(form[0]);
+      t1 = ComputeFormulaUsingModel(form[1]);
+      if((ASTTrue == t0 && ASTTrue == t1) || (ASTFalse == t0 && ASTFalse == t1))
+	output = ASTFalse;
+      else
+	output = ASTTrue;
+      break;
+    case IFF:
+      t0 = ComputeFormulaUsingModel(form[0]);
+      t1 = ComputeFormulaUsingModel(form[1]);
+      if((ASTTrue == t0 && ASTTrue == t1) || (ASTFalse == t0 && ASTFalse == t1))
+	output = ASTTrue;
+      else
+	output = ASTFalse;
+      break;
+    case IMPLIES:
+      t0 = ComputeFormulaUsingModel(form[0]);
+      t1 = ComputeFormulaUsingModel(form[1]);
+      if((ASTFalse == t0) || (ASTTrue == t0 && ASTTrue == t1))
+	output = ASTTrue;
+      else
+	output = ASTFalse;
+      break;    
+    case ITE:
+      t0 = ComputeFormulaUsingModel(form[0]);
+      if(ASTTrue == t0)
+	output = ComputeFormulaUsingModel(form[1]);
+      else if(ASTFalse == t0)
+	output = ComputeFormulaUsingModel(form[2]);
+      else 
+	FatalError("ComputeFormulaUsingModel: ITE: something is wrong with the formula: ",form);
+      break;
+    default:
+      FatalError(" ComputeFormulaUsingModel: the kind has not been implemented", ASTUndefined);
+      break;
+    }
+
+    //cout << "ComputeFormulaUsingModel output is:" << output << endl;
+    ComputeFormulaMap[form] = output;
+    return output;
+  }
+
+  void BeevMgr::CheckCounterExample(bool t) {
+    // FIXME:  Code is more useful if enable flags are check OUTSIDE the method.
+    // If I want to check a counterexample somewhere, I don't want to have to set
+    // the flag in order to make it actualy happen!
+
+    if(!check_counterexample) {
+      return;
+    }
+
+    //input is valid, no counterexample to check
+    if(ValidFlag)
+      return;
+
+    //t is true if SAT solver generated a counterexample, else it is false
+    if(!t)
+      FatalError("CheckCounterExample: No CounterExample to check", ASTUndefined);
+    const ASTVec c = GetAsserts();    
+    for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++)
+      if(ASTFalse == ComputeFormulaUsingModel(*it))
+	FatalError("CheckCounterExample:counterexample bogus:"\
+		   "assert evaluates to FALSE under counterexample: NOT OK",*it);
+        
+    if(ASTTrue == ComputeFormulaUsingModel(_current_query))
+      FatalError("CheckCounterExample:counterexample bogus:"\
+		 "query evaluates to TRUE under counterexample: NOT OK",_current_query);
+  }
+
+  /* FUNCTION: prints a counterexample for INVALID inputs.  iterate
+   * through the CounterExampleMap data structure and print it to
+   * stdout
+   */
+  void BeevMgr::PrintCounterExample(bool t, std::ostream& os) {
+    //global command-line option
+    // FIXME: This should always print the counterexample.  If you want
+    // to turn it off, check the switch at the point of call.
+    if(!print_counterexample)
+      return;
+
+    //input is valid, no counterexample to print
+    if(ValidFlag)
+      return;
+
+    //if this option is true then print the way dawson wants using a
+    //different printer. do not use this printer.
+    if(print_arrayval_declaredorder)
+      return;
+
+    //t is true if SAT solver generated a counterexample, else it is
+    //false
+    if(!t) {
+      cerr << "PrintCounterExample: No CounterExample to print: " << endl;
+      return;
+    }
+
+    //os << "\nCOUNTEREXAMPLE: \n" << endl;
+    ASTNodeMap::iterator it  = CounterExampleMap.begin();
+    ASTNodeMap::iterator itend = CounterExampleMap.end();
+    for(;it!=itend;it++) {
+      ASTNode f = it->first;
+      ASTNode se = it->second;
+      
+      if(ARRAY_TYPE == se.GetType()) {
+	FatalError("TermToConstTermUsingModel: entry in counterexample is an arraytype. bogus:",se);
+      }
+
+      //skip over introduced variables
+      if(f.GetKind() == SYMBOL && (_introduced_symbols.find(f) != _introduced_symbols.end())) 
+	continue;
+      if(f.GetKind() == SYMBOL || 
+	 (f.GetKind() == READ && f[0].GetKind() == SYMBOL && f[1].GetKind() == BVCONST)) {
+	os << "ASSERT( ";
+	f.PL_Print(os,0);
+	os << " = ";	
+	if(BITVECTOR_TYPE == se.GetType()) {
+	  TermToConstTermUsingModel(se,false).PL_Print(os,0);
+	}
+	else {
+	  se.PL_Print(os,0);
+	}
+	os << " );" << endl;
+      }
+    }	      
+    //os << "\nEND OF COUNTEREXAMPLE" << endl;
+  } //End of PrintCounterExample
+
+  /* iterate through the CounterExampleMap data structure and print it
+   * to stdout. this function prints only the declared array variables
+   * IN the ORDER in which they were declared. It also assumes that
+   * the variables are of the form 'varname_number'. otherwise it will
+   * not print anything. This function was specifically written for
+   * Dawson Engler's group (bug finding research group at Stanford)
+   */
+  void BeevMgr::PrintCounterExample_InOrder(bool t) {
+    //global command-line option to print counterexample. we do not
+    //want both counterexample printers to print at the sametime.
+    // FIXME: This should always print the counterexample.  If you want
+    // to turn it off, check the switch at the point of call.
+    if(print_counterexample)
+      return;
+
+    //input is valid, no counterexample to print
+    if(ValidFlag)
+      return;
+    
+    //print if the commandline option is '-q'. allows printing the
+    //counterexample in order.
+    if(!print_arrayval_declaredorder)
+      return;
+
+    //t is true if SAT solver generated a counterexample, else it is
+    //false
+    if(!t) {
+      cerr << "PrintCounterExample: No CounterExample to print: " << endl;
+      return;
+    }
+    
+    //vector to store the integer values
+    std::vector<int> out_int;	
+    cout << "% ";
+    for(ASTVec::iterator it=_special_print_set.begin(),itend=_special_print_set.end();
+	it!=itend;it++) {
+      if(ARRAY_TYPE == it->GetType()) {
+	//get the name of the variable
+	const char * c = it->GetName();
+	std::string ss(c);
+	if(!(0 == strncmp(ss.c_str(),"ini_",4)))
+	  continue;
+	reverse(ss.begin(),ss.end());
+
+	//cout << "debugging: " << ss;
+	size_t pos = ss.find('_',0);
+	if(!(0 < pos && pos < ss.size()))
+	  continue;
+
+	//get the associated length
+	std::string sss = ss.substr(0,pos);
+	reverse(sss.begin(),sss.end());
+	int n = atoi(sss.c_str());
+
+	it->PL_Print(cout,2);
+	for(int j=0;j < n; j++) {
+	  ASTNode index = CreateBVConst(it->GetIndexWidth(),j);
+	  ASTNode readexpr = CreateTerm(READ,it->GetValueWidth(),*it,index);
+	  ASTNode val = GetCounterExample(t, readexpr);
+	  //cout << "ASSERT( ";
+	  //cout << " = ";	  
+	  out_int.push_back(GetUnsignedConst(val));
+	  //cout << "\n";
+	}
+      }
+    }
+    cout << endl;
+    for(unsigned int jj=0; jj < out_int.size();jj++)
+      cout << out_int[jj] << endl;
+    cout << endl;
+  } //End of PrintCounterExample_InOrder
+
+  /* FUNCTION: queries the CounterExampleMap object with 'expr' and
+   * returns the corresponding counterexample value.
+   */
+  ASTNode BeevMgr::GetCounterExample(bool t, const ASTNode& expr) {    
+    //input is valid, no counterexample to get
+    if(ValidFlag)
+      return ASTUndefined;
+    
+    if(BOOLEAN_TYPE == expr.GetType()) {
+      return ComputeFormulaUsingModel(expr);
+    }
+
+    if(BVCONST == expr.GetKind()) {
+      return expr;
+    }
+
+    ASTNodeMap::iterator it;
+    ASTNode output;
+    if((it = CounterExampleMap.find(expr)) != CounterExampleMap.end())
+      output =  TermToConstTermUsingModel(CounterExampleMap[expr],false);
+    else
+      output = CreateZeroConst(expr.GetValueWidth());
+    return output;
+  } //End of GetCounterExample
+
+  // FIXME:  Don't use numeric codes.  Use an enum type!
+  //Acceps a query, calls the SAT solver and generates Valid/InValid.
+  //if returned 0 then input is INVALID
+  //if returned 1 then input is VALID
+  //if returned 2 then ERROR
+  int BeevMgr::TopLevelSAT( const ASTNode& inputasserts, const ASTNode& query) {  
+    /******start solving**********/
+    ASTNode q = CreateNode(AND, inputasserts, CreateNode(NOT,query));
+    ASTNode orig_input = q;
+    ASTNodeStats("input asserts and query: ", q);
+ 
+    ASTNode newq = q;
+    //round of substitution, solving, and simplification. ensures that
+    //DAG is minimized as much as possibly, and ideally should
+    //garuntee that all liketerms in BVPLUSes have been combined.
+    BVSolver bvsolver(this);
+    SimplifyWrites_InPlace_Flag = false;
+    Begin_RemoveWrites = false;
+    start_abstracting = false;    
+    TermsAlreadySeenMap.clear();
+    do {
+      q = newq;
+      newq = CreateSubstitutionMap(newq);
+      //ASTNodeStats("after pure substitution: ", newq);
+      newq = SimplifyFormula_TopLevel(newq,false);
+      //ASTNodeStats("after simplification: ", newq);
+      //newq = bvsolver.TopLevelBVSolve(newq);
+      //ASTNodeStats("after solving: ", newq);      
+    }while(q!=newq);
+
+    ASTNodeStats("Before SimplifyWrites_Inplace begins: ", newq);
+    SimplifyWrites_InPlace_Flag = true;
+    Begin_RemoveWrites = false;
+    start_abstracting = false;
+    TermsAlreadySeenMap.clear();
+    do {
+      q = newq;
+      //newq = CreateSubstitutionMap(newq);
+      //ASTNodeStats("after pure substitution: ", newq);
+      newq = SimplifyFormula_TopLevel(newq,false);
+      //ASTNodeStats("after simplification: ", newq);
+      newq = bvsolver.TopLevelBVSolve(newq);
+      //ASTNodeStats("after solving: ", newq);      
+    }while(q!=newq);
+    ASTNodeStats("After SimplifyWrites_Inplace: ", newq);        
+
+    start_abstracting = (arraywrite_refinement) ? true : false;
+    SimplifyWrites_InPlace_Flag = false;
+    Begin_RemoveWrites = (start_abstracting) ? false : true;    
+    if(start_abstracting) {
+      ASTNodeStats("before abstraction round begins: ", newq);
+    }
+
+    TermsAlreadySeenMap.clear();
+    do {
+      q = newq;
+      //newq = CreateSubstitutionMap(newq);
+      //Begin_RemoveWrites = true;
+      //ASTNodeStats("after pure substitution: ", newq);
+      newq = SimplifyFormula_TopLevel(newq,false);
+      //ASTNodeStats("after simplification: ", newq);
+      //newq = bvsolver.TopLevelBVSolve(newq);
+      //ASTNodeStats("after solving: ", newq);
+    }while(q!=newq);
+
+    if(start_abstracting) {
+      ASTNodeStats("After abstraction: ", newq);
+    }
+    start_abstracting = false;
+    SimplifyWrites_InPlace_Flag = false;
+    Begin_RemoveWrites = false;    
+    
+    newq = TransformFormula(newq);
+    ASTNodeStats("after transformation: ", newq);
+    TermsAlreadySeenMap.clear();
+
+    int res;    
+    //solver instantiated here
+    MINISAT::Solver newS;
+    if(arrayread_refinement) {
+      counterexample_checking_during_refinement = true;
+    }
+    
+    //call SAT and check the result
+    res = CallSAT_ResultCheck(newS,newq,orig_input);
+    if(2 != res) {
+      CountersAndStats("print_func_stats");
+      return res;
+    }
+
+    res = SATBased_ArrayReadRefinement(newS,newq,orig_input);
+    if(2 != res) {
+      CountersAndStats("print_func_stats");
+      return res;
+    }
+ 
+    res = SATBased_ArrayWriteRefinement(newS,orig_input);
+    if(2 != res) {
+      CountersAndStats("print_func_stats");
+      return res;
+    }          
+
+    res = SATBased_ArrayReadRefinement(newS,newq,orig_input);
+    if(2 != res) {
+      CountersAndStats("print_func_stats");
+      return res;
+    }
+
+    FatalError("TopLevelSAT: reached the end without proper conclusion:" 
+	       "either a divide by zero in the input or a bug in STP");
+    //bogus return to make the compiler shut up
+    return 2;
+  } //End of TopLevelSAT
+
+  //go over the list of indices for each array, and generate Leibnitz
+  //axioms. Then assert these axioms into the SAT solver. Check if the
+  //addition of the new constraints has made the bogus counterexample
+  //go away. if yes, return the correct answer. if no, continue adding
+  //Leibnitz axioms systematically.
+  // FIXME:  What it really does is, for each array, loop over each index i.
+  // inside that loop, it finds all the true and false axioms with i as first
+  // index.  When it's got them all, it adds the false axioms to the formula
+  // and re-solves, and returns if the result is correct.  Otherwise, it
+  // goes on to the next index.
+  // If it gets through all the indices without a correct result (which I think
+  // is impossible, but this is pretty confusing), it then solves with all
+  // the true axioms, too.
+  // This is not the most obvious way to do it, and I don't know how it 
+  // compares with other approaches (e.g., one false axiom at a time or
+  // all the false axioms each time).
+  int BeevMgr::SATBased_ArrayReadRefinement(MINISAT::Solver& newS, 
+					    const ASTNode& q, const ASTNode& orig_input) {
+    if(!arrayread_refinement)
+      FatalError("SATBased_ArrayReadRefinement: Control should not reach here");
+
+    ASTVec FalseAxiomsVec, RemainingAxiomsVec;
+    RemainingAxiomsVec.push_back(ASTTrue);   
+    FalseAxiomsVec.push_back(ASTTrue);
+
+    //in these loops we try to construct Leibnitz axioms and add it to
+    //the solve(). We add only those axioms that are false in the
+    //current counterexample. we keep adding the axioms until there
+    //are no more axioms to add
+    //
+    //for each array, fetch its list of indices seen so far
+    for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), iset_end = _arrayname_readindices.end();
+	iset!=iset_end;iset++) {
+      ASTVec listOfIndices = iset->second;
+      //loop over the list of indices for the array and create LA, and add to q
+      for(ASTVec::iterator it=listOfIndices.begin(),itend=listOfIndices.end();it!=itend;it++) {
+	if(BVCONST == it->GetKind()) {
+	  continue;
+	}	
+
+	ASTNode the_index = *it;
+	//get the arrayname
+	ASTNode ArrName = iset->first;
+	// if(SYMBOL != ArrName.GetKind())
+	// 	  FatalError("SATBased_ArrayReadRefinement: arrname is not a SYMBOL",ArrName);
+	ASTNode arr_read1 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index);
+	//get the variable corresponding to the array_read1
+	ASTNode arrsym1 = _arrayread_symbol[arr_read1];
+	if(!(SYMBOL == arrsym1.GetKind() || BVCONST == arrsym1.GetKind()))
+	  FatalError("TopLevelSAT: refinementloop:term arrsym1 corresponding to READ must be a var", arrsym1);
+
+	//we have nonconst index here. create Leibnitz axiom for it
+	//w.r.t every index in listOfIndices
+	for(ASTVec::iterator it1=listOfIndices.begin(),itend1=listOfIndices.end();
+	    it1!=itend1;it1++) {
+	  ASTNode compare_index = *it1;
+	  //do not compare with yourself
+	  if(the_index == compare_index)
+	    continue;
+	  
+	  //prepare for SAT LOOP 
+	  //first construct the antecedent for the LA axiom
+	  ASTNode eqOfIndices = 
+	    (exprless(the_index,compare_index)) ? 
+	    CreateSimplifiedEQ(the_index,compare_index) : CreateSimplifiedEQ(compare_index,the_index);
+	  	  
+	  ASTNode arr_read2 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, compare_index);
+	  //get the variable corresponding to the array_read2
+	  ASTNode arrsym2 = _arrayread_symbol[arr_read2];
+	  if(!(SYMBOL == arrsym2.GetKind() || BVCONST == arrsym2.GetKind()))
+	    FatalError("TopLevelSAT: refinement loop:"
+		       "term arrsym2 corresponding to READ must be a var", arrsym2);
+	  
+	  ASTNode eqOfReads = CreateSimplifiedEQ(arrsym1,arrsym2);
+	  //construct appropriate Leibnitz axiom
+	  ASTNode LeibnitzAxiom = CreateNode(IMPLIES, eqOfIndices, eqOfReads);
+	  if(ASTFalse == ComputeFormulaUsingModel(LeibnitzAxiom))
+	    //FalseAxioms = CreateNode(AND,FalseAxioms,LeibnitzAxiom);
+	    FalseAxiomsVec.push_back(LeibnitzAxiom);
+	  else
+	    //RemainingAxioms = CreateNode(AND,RemainingAxioms,LeibnitzAxiom);
+	    RemainingAxiomsVec.push_back(LeibnitzAxiom);
+	}
+	ASTNode FalseAxioms = (FalseAxiomsVec.size()>1) ? CreateNode(AND,FalseAxiomsVec) : FalseAxiomsVec[0];
+	ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms);  
+	int res2 = CallSAT_ResultCheck(newS,FalseAxioms,orig_input);
+	if(2!=res2) {
+	  return res2;
+	}	
+      }
+    }
+    ASTNode RemainingAxioms = (RemainingAxiomsVec.size()>1) ? CreateNode(AND,RemainingAxiomsVec):RemainingAxiomsVec[0];
+    ASTNodeStats("adding remaining readaxioms to SAT: ", RemainingAxioms);  
+    return CallSAT_ResultCheck(newS,RemainingAxioms,orig_input);
+  } //end of SATBased_ArrayReadRefinement
+
+  ASTNode BeevMgr::Create_ArrayWriteAxioms(const ASTNode& term, const ASTNode& newvar) {
+    if(READ != term.GetKind() && WRITE != term[0].GetKind()) {
+      FatalError("Create_ArrayWriteAxioms: Input must be a READ over a WRITE",term);
+    }
+    
+    ASTNode lhs = newvar;
+    ASTNode rhs = term;
+    ASTNode arraywrite_axiom = CreateSimplifiedEQ(lhs,rhs);
+    return arraywrite_axiom;
+  }//end of Create_ArrayWriteAxioms()
+
+  int BeevMgr::SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input) {
+    ASTNode writeAxiom;
+    ASTNodeMap::iterator it = ReadOverWrite_NewName_Map.begin();
+    ASTNodeMap::iterator itend = ReadOverWrite_NewName_Map.end();
+    //int count = 0;
+    //int num_write_axioms = ReadOverWrite_NewName_Map.size();
+
+    ASTVec FalseAxioms, RemainingAxioms;
+    FalseAxioms.push_back(ASTTrue);
+    RemainingAxioms.push_back(ASTTrue);
+    for(;it!=itend;it++) {
+      //Guided refinement starts here
+      ComputeFormulaMap.clear();      
+      writeAxiom = Create_ArrayWriteAxioms(it->first,it->second);
+      if(ASTFalse == ComputeFormulaUsingModel(writeAxiom)) {
+	writeAxiom = TransformFormula(writeAxiom);
+	FalseAxioms.push_back(writeAxiom);
+      }
+      else {
+	writeAxiom = TransformFormula(writeAxiom);
+	RemainingAxioms.push_back(writeAxiom);
+      }
+    }
+      
+    writeAxiom = (FalseAxioms.size() != 1) ? CreateNode(AND,FalseAxioms) : FalseAxioms[0];
+    ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom);
+    int res2 = CallSAT_ResultCheck(newS,writeAxiom,orig_input);
+    if(2!=res2) {
+      return res2;
+    }
+    
+    writeAxiom = (RemainingAxioms.size() != 1) ? CreateNode(AND,RemainingAxioms) : RemainingAxioms[0];
+    ASTNodeStats("adding remaining writeaxiom to SAT: ", writeAxiom);
+    res2 = CallSAT_ResultCheck(newS,writeAxiom,orig_input);
+    if(2!=res2) {
+	return res2;
+    }
+    
+    return 2;
+  } //end of SATBased_ArrayWriteRefinement
+
+  //Check result after calling SAT FIXME: Document arguments in
+  //comments, and give them meaningful names.  How is anyone supposed
+  //to know what "q" is?
+  int BeevMgr::CallSAT_ResultCheck(MINISAT::Solver& newS, 
+				   const ASTNode& q, const ASTNode& orig_input) {
+    //Bitblast, CNF, call SAT now
+    ASTNode BBFormula = BBForm(q);
+    //ASTNodeStats("after bitblasting", BBFormula);    
+    ClauseList *cllp = ToCNF(BBFormula);
+    // if(stats && print_nodes) {
+    //       cout << "\nClause list" << endl;
+    //       PrintClauseList(cout, *cllp);
+    //       cerr << "\n finished printing clauselist\n";
+    //     }
+
+    bool sat = toSATandSolve(newS,*cllp);    
+    // Temporary debugging call.
+    // CheckBBandCNF(newS, BBFormula);
+
+    DeleteClauseList(cllp);
+    if(!sat) {
+      PrintOutput(true);
+      return 1;
+    }
+    else if(newS.okay()) {
+      CounterExampleMap.clear();
+      ConstructCounterExample(newS);
+      if (stats && print_nodes) {
+	PrintSATModel(newS);
+      }
+      //check if the counterexample is good or not
+      ComputeFormulaMap.clear();
+      if(counterexample_checking_during_refinement)
+	bvdiv_exception_occured = false;
+      ASTNode orig_result = ComputeFormulaUsingModel(orig_input);
+      if(!(ASTTrue == orig_result || ASTFalse == orig_result))
+      	FatalError("TopLevelSat: Original input must compute to true or false against model");
+      
+//       if(!arrayread_refinement && !(ASTTrue == orig_result)) {
+// 	print_counterexample = true;
+// 	PrintCounterExample(true);
+//       	FatalError("counterexample bogus : arrayread_refinement is switched off: " 
+//       		   "EITHER all LA axioms have not been added OR bitblaster() or ToCNF()"
+// 		   "or satsolver() or counterexamplechecker() have a bug");
+//       }
+
+      // if the counterexample is indeed a good one, then return
+      // invalid
+      if(ASTTrue == orig_result) {
+	CheckCounterExample(newS.okay());
+	PrintOutput(false);
+	PrintCounterExample(newS.okay());
+	PrintCounterExample_InOrder(newS.okay());
+	return 0;	
+      }
+      // counterexample is bogus: flag it
+      else {
+	if(stats && print_nodes) {
+	  cout << "Supposedly bogus one: \n";
+	  bool tmp = print_counterexample;
+	  print_counterexample = true;
+	  PrintCounterExample(true);
+	  print_counterexample = tmp;
+	}
+
+	return 2;
+      }
+    }
+    else {
+      PrintOutput(true);
+      return -100;
+    }
+  } //end of CALLSAT_ResultCheck
+
+
+  //FUNCTION: this function accepts a boolvector and returns a BVConst   
+  ASTNode BeevMgr::BoolVectoBVConst(hash_map<unsigned,bool> * w, unsigned int l) {    
+    unsigned len = w->size();
+    if(l < len)
+      FatalError("BoolVectorBVConst : length of bitvector does not match hash_map size:",ASTUndefined,l);
+    std::string cc;
+    for(unsigned int jj = 0; jj < l; jj++) {
+      if((*w)[jj] == true)
+	cc += '1';
+      else if((*w)[jj] == false)
+	cc += '0';
+      else 
+	cc += '0';
+    }
+    return CreateBVConst(cc.c_str(),2);
+  }
+
+  void BeevMgr::PrintActivityLevels_Of_SATVars(char * init_msg, MINISAT::Solver& newS) {
+    if(!print_sat_varorder)
+      return;
+
+    ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();   
+    ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
+   
+    cout << init_msg;
+    cout << ": Printing activity levels of variables\n";
+    for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
+      cout << (it->second) << "  :  ";
+      (it->first).PL_Print(cout,0);
+      cout << "   :   ";
+      cout << newS.returnActivity(it->second) << endl;
+    }
+  }
+
+  //this function biases the activity levels of MINISAT variables.
+  void BeevMgr::ChangeActivityLevels_Of_SATVars(MINISAT::Solver& newS) {
+    if(!variable_activity_optimize)
+      return;
+
+    ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();   
+    ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
+   
+    unsigned int index=1;
+    double base = 2;
+    for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
+      ASTNode n = it->first;
+
+      if(BVGETBIT == n.GetKind() || NOT == n.GetKind()) {
+      	if(BVGETBIT == n.GetKind())
+      	  index = GetUnsignedConst(n[1]);
+      	else if (NOT == n.GetKind() && BVGETBIT == n[0].GetKind())
+      	  index = GetUnsignedConst(n[0][1]);
+      	else 
+      	  index = 0;
+	double initial_activity = pow(base,(double)index);
+	newS.updateInitialActivity(it->second,initial_activity);
+      } 
+      else {
+	double initial_activity = pow(base,pow(base,(double)index));
+	newS.updateInitialActivity(it->second,initial_activity);	
+      }    
+    }
+  }
+
+  //This function prints the output of the STP solver
+  void BeevMgr::PrintOutput(bool true_iff_valid) {
+    //self-explanatory
+    if(true_iff_valid) {
+      ValidFlag = true;
+      if(print_output) {
+	if(smtlib_parser_enable)
+	  cout << "unsat\n";
+	else
+	  cout << "Valid.\n";
+      }
+    }
+    else {
+      ValidFlag = false;
+      if(print_output) {
+	if(smtlib_parser_enable)
+	  cout << "sat\n";
+	else
+	  cout << "Invalid.\n";
+      }
+    }
+  }
+}; //end of namespace BEEV
diff --git a/stp/AST/Transform.cpp b/stp/AST/Transform.cpp
new file mode 100644
index 00000000..598b831e
--- /dev/null
+++ b/stp/AST/Transform.cpp
@@ -0,0 +1,492 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "AST.h"
+#include <stdlib.h>
+#include <stdio.h>
+namespace BEEV {  
+  
+  //Translates signed BVDIV/BVMOD into unsigned variety
+  ASTNode BeevMgr::TranslateSignedDivMod(const ASTNode& in) {
+    if(!(SBVMOD == in.GetKind() || SBVDIV == in.GetKind())) {
+      FatalError("TranslateSignedDivMod: input must be signed DIV/MOD\n",in);
+    }
+
+    ASTNode dividend = in[0];
+    ASTNode divisor  = in[1];      
+    unsigned len = in.GetValueWidth();
+    if(SBVMOD == in.GetKind()) {
+      //if(TopBit(dividend)==1) 
+      //
+      //then -BVMOD(-dividend,abs(divisor)) 
+      //
+      //else BVMOD(dividend,abs(divisor))
+
+      //create the condition for the dividend
+      ASTNode hi1  = CreateBVConst(32,len-1);
+      ASTNode one  = CreateOneConst(1);
+      ASTNode cond = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1));
+
+      //create the condition and conditional for the divisor
+      ASTNode cond_divisor = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1));
+      ASTNode pos_divisor  = CreateTerm(ITE,len,cond_divisor,CreateTerm(BVUMINUS,len,divisor),divisor);
+
+      //create the modulus term for each case
+      ASTNode modnode = CreateTerm(BVMOD,len,dividend,pos_divisor);
+      ASTNode minus_modnode = CreateTerm(BVMOD,len,CreateTerm(BVUMINUS,len,dividend),pos_divisor);
+      minus_modnode = CreateTerm(BVUMINUS,len,minus_modnode);
+
+      //put everything together, simplify, and return
+      ASTNode n = CreateTerm(ITE,len,cond,minus_modnode,modnode);
+      return SimplifyTerm_TopLevel(n);
+    }
+    
+    //now handle the BVDIV case
+    //if topBit(dividend) is 1 and topBit(divisor) is 0
+    //
+    //then output is -BVDIV(-dividend,divisor)
+    //
+    //elseif topBit(dividend) is 0 and topBit(divisor) is 1
+    //
+    //then output is -BVDIV(dividend,-divisor)
+    //
+    //elseif topBit(dividend) is 1 and topBit(divisor) is 1
+    //
+    // then output is BVDIV(-dividend,-divisor)
+    //
+    //else simply output BVDIV(dividend,divisor)
+    ASTNode hi1 = CreateBVConst(32,len-1);
+    ASTNode zero = CreateZeroConst(1);
+    ASTNode one = CreateOneConst(1);
+    ASTNode divnode = CreateTerm(BVDIV, len, dividend, divisor);
+
+    ASTNode cond1 = CreateNode(AND,
+			       CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
+			       CreateNode(EQ,one, CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
+    ASTNode minus_divnode1 = CreateTerm(BVDIV,len,
+					dividend,
+					CreateTerm(BVUMINUS,len,divisor));
+    minus_divnode1 = CreateTerm(BVUMINUS,len,minus_divnode1);
+
+    ASTNode cond2 = CreateNode(AND,
+			       CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
+			       CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
+    ASTNode minus_divnode2 = CreateTerm(BVDIV,len,
+					CreateTerm(BVUMINUS,len,dividend),
+					divisor);
+    minus_divnode2 = CreateTerm(BVUMINUS,len,minus_divnode2);
+
+    ASTNode cond3 = CreateNode(AND,
+			       CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
+			       CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
+    ASTNode minus_divnode3 = CreateTerm(BVDIV,len,
+					CreateTerm(BVUMINUS,len,dividend),
+					CreateTerm(BVUMINUS,len,divisor));
+    ASTNode n = CreateTerm(ITE,len,
+			   cond1,
+			   minus_divnode1,
+			   CreateTerm(ITE,len,
+				      cond2,
+				      minus_divnode2,
+				      CreateTerm(ITE,len,
+						 cond3,
+						 minus_divnode3,
+						 divnode)));
+  return SimplifyTerm_TopLevel(n);
+  }//end of TranslateSignedDivMod()
+
+  ASTNode BeevMgr::TransformFormula(const ASTNode& form) {
+    ASTNode result;
+
+    ASTNode simpleForm = form;
+    Kind k = simpleForm.GetKind();
+    if(!(is_Form_kind(k) && BOOLEAN_TYPE == simpleForm.GetType())) {
+      //FIXME: "You have inputted a NON-formula"?
+      FatalError("TransformFormula: You have input a NON-formula",simpleForm);
+    }
+
+    ASTNodeMap::iterator iter;
+    if((iter = TransformMap.find(simpleForm)) != TransformMap.end())
+      return iter->second;
+
+    switch(k) {
+    case TRUE:
+    case FALSE: {
+      result = simpleForm;
+      break;
+    }
+    case NOT: {
+      ASTVec c;
+      c.push_back(TransformFormula(simpleForm[0]));
+      result = CreateNode(NOT,c);      
+      break;
+    }
+    case BVLT:
+    case BVLE:
+    case BVGT:
+    case BVGE:
+    case BVSLT:
+    case BVSLE:
+    case BVSGT:
+    case BVSGE:      
+    case NEQ: {
+      ASTVec c;
+      c.push_back(TransformTerm(simpleForm[0]));      
+      c.push_back(TransformTerm(simpleForm[1]));
+      result = CreateNode(k,c);
+      break;
+    }
+    case EQ: {
+      ASTNode term1 = TransformTerm(simpleForm[0]);      
+      ASTNode term2 = TransformTerm(simpleForm[1]);
+      result = CreateSimplifiedEQ(term1,term2);     
+      break;
+    }
+    case AND:
+    case OR: 
+    case NAND:
+    case NOR:
+    case IFF:
+    case XOR:
+    case ITE:
+    case IMPLIES: {
+      ASTVec vec;
+      ASTNode o;
+      for (ASTVec::const_iterator it = simpleForm.begin(),itend=simpleForm.end(); it != itend; it++){
+	o = TransformFormula(*it);	
+	vec.push_back(o);
+      }
+
+      result = CreateNode(k, vec);
+      break;
+    }
+    default:
+      if(k == SYMBOL && BOOLEAN_TYPE == simpleForm.GetType())
+	result = simpleForm;      
+      else {
+	cerr << "The input is: " << simpleForm << endl;
+	cerr << "The valuewidth of input is : " << simpleForm.GetValueWidth() << endl;
+	FatalError("TransformFormula: Illegal kind: ",ASTUndefined, k);
+      }
+      break;    
+    } 
+    //BVTypeCheck(result);
+    TransformMap[simpleForm] = result;
+    return result;
+  } //End of TransformFormula
+
+  ASTNode BeevMgr::TransformTerm(const ASTNode& inputterm) {
+    ASTNode result;
+    ASTNode term = inputterm;
+
+    Kind k = term.GetKind();
+    if(!is_Term_kind(k))
+      FatalError("TransformTerm: Illegal kind: You have input a nonterm:", inputterm, k);
+    ASTNodeMap::iterator iter;
+    if((iter = TransformMap.find(term)) != TransformMap.end())
+      return iter->second;
+    switch(k) {
+    case SYMBOL: {
+      // ASTNodeMap::iterator itsym;
+//       if((itsym = CounterExampleMap.find(term)) != CounterExampleMap.end())	
+//       	result = itsym->second;
+//       else
+	result = term;
+      break;
+    }
+    case BVCONST:
+      result = term;
+      break;
+    case WRITE:
+      FatalError("TransformTerm: this kind is not supported",term);
+      break;
+    case READ:
+      result = TransformArray(term);
+      break;
+    case ITE: {
+      ASTNode cond = term[0];
+      ASTNode thn  = term[1];
+      ASTNode els  = term[2];
+      cond = TransformFormula(cond);
+      thn = TransformTerm(thn);
+      els = TransformTerm(els);
+      //result = CreateTerm(ITE,term.GetValueWidth(),cond,thn,els);
+      result = CreateSimplifiedTermITE(cond,thn,els);
+      result.SetIndexWidth(term.GetIndexWidth());
+      break;
+    }
+    default: {
+      ASTVec c = term.GetChildren();
+      ASTVec::iterator it = c.begin();
+      ASTVec::iterator itend = c.end();
+      unsigned width = term.GetValueWidth();
+      unsigned indexwidth = term.GetIndexWidth();
+      ASTVec o;
+      for(;it!=itend;it++) {
+	o.push_back(TransformTerm(*it));
+      }
+
+      result = CreateTerm(k,width,o);
+      result.SetIndexWidth(indexwidth);
+
+      if(SBVDIV == result.GetKind() || SBVMOD == result.GetKind()) {
+	result = TranslateSignedDivMod(result);
+      }
+      break;
+    }
+    }
+
+    TransformMap[term] = result;
+    if(term.GetValueWidth() != result.GetValueWidth())
+      FatalError("TransformTerm: result and input terms are of different length", result);
+    if(term.GetIndexWidth() != result.GetIndexWidth()) {
+      cerr << "TransformTerm: input term is : " << term << endl;
+      FatalError("TransformTerm: result and input terms have different index length", result);
+    }
+    return result;
+  } //End of TransformTerm
+
+  /* This function transforms Array Reads, Read over Writes, Read over
+   * ITEs into flattened form.
+   *
+   * Transform1: Suppose there are two array reads in the input
+   * Read(A,i) and Read(A,j) over the same array. Then Read(A,i) is
+   * replaced with a symbolic constant, say v1, and Read(A,j) is
+   * replaced with the following ITE:
+   *
+   * ITE(i=j,v1,v2)
+   *
+   * Transform2:
+   * 
+   * Transform3:
+   */
+  ASTNode BeevMgr::TransformArray(const ASTNode& term) {
+    ASTNode result = term;
+
+    unsigned int width = term.GetValueWidth();
+    Kind k = term.GetKind();
+    if (!is_Term_kind(k))
+      FatalError("TransformArray: Illegal kind: You have input a nonterm:", ASTUndefined, k);
+    ASTNodeMap::iterator iter;
+    if((iter = TransformMap.find(term)) != TransformMap.end())
+      return iter->second;
+
+    switch(k) {
+      //'term' is of the form READ(arrName, readIndex) 
+    case READ: {
+      ASTNode arrName = term[0];
+      switch (arrName.GetKind()) {
+      case SYMBOL: {
+	/* input is of the form: READ(A, readIndex)
+	 * 
+	 * output is of the from: A1, if this is the first READ over A
+         *                           
+	 *                        ITE(previous_readIndex=readIndex,A1,A2)
+	 *                        
+         *                        .....
+	 */
+
+	//  Recursively transform read index, which may also contain reads.
+	ASTNode readIndex = TransformTerm(term[1]);	
+	ASTNode processedTerm = CreateTerm(READ,width,arrName,readIndex);
+	
+	//check if the 'processedTerm' has a corresponding ITE construct
+	//already. if so, return it. else continue processing.
+	ASTNodeMap::iterator it;
+	if((it = _arrayread_ite.find(processedTerm)) != _arrayread_ite.end()) {
+	  result = it->second;	
+	  break;
+	}
+	//Constructing Symbolic variable corresponding to 'processedTerm'
+	ASTNode CurrentSymbol;
+	ASTNodeMap::iterator it1;
+	// First, check if read index is constant and it has a constant value in the substitution map.
+	if(CheckSubstitutionMap(processedTerm,CurrentSymbol)) {
+	  _arrayread_symbol[processedTerm] = CurrentSymbol;
+	}
+	// Check if it already has an abstract variable.
+	else if((it1 = _arrayread_symbol.find(processedTerm)) != _arrayread_symbol.end()) {
+	  CurrentSymbol = it1->second;
+	}
+	else {
+	  // Make up a new abstract variable.
+	  // FIXME: Make this into a method (there already may BE a method) and
+	  // get rid of the fixed-length buffer!
+	  //build symbolic name corresponding to array read. The symbolic
+	  //name has 2 components: stringname, and a count
+	  const char * b = arrName.GetName();
+	  std::string c(b);
+	  char d[32];
+	  sprintf(d,"%d",_symbol_count++);
+	  std::string ccc(d);
+	  c += "array_" + ccc;
+	  
+	  CurrentSymbol = CreateSymbol(c.c_str());
+	  CurrentSymbol.SetValueWidth(processedTerm.GetValueWidth());
+	  CurrentSymbol.SetIndexWidth(processedTerm.GetIndexWidth());
+	  _arrayread_symbol[processedTerm] = CurrentSymbol;	  
+	}
+	
+	//list of array-read indices corresponding to arrName, seen while
+	//traversing the AST tree. we need this list to construct the ITEs
+	// Dill: we hope to make this irrelevant.  Harmless for now.
+	ASTVec readIndices = _arrayname_readindices[arrName];
+	
+	//construct the ITE structure for this array-read
+	ASTNode ite = CurrentSymbol;
+	_introduced_symbols.insert(CurrentSymbol);
+	BVTypeCheck(ite);
+	
+	if(arrayread_refinement) {
+	  // ite is really a variable here; it is an ite in the
+	  // else-branch
+	  result = ite;
+	}
+	else {
+	  // Full Seshia transform if we're not doing read refinement.
+	  //do not loop if the current readIndex is a BVCONST
+	  // if(BVCONST == term[1].GetKind() && !SeenNonConstReadIndex && optimize) {
+	  // 	    result = ite; 
+	  // 	  }
+	  // 	  else {	  
+	    //else part: SET the SeenNonConstReadIndex var, and do the hard work
+	    //SeenNonConstReadIndex = true;
+	    ASTVec::reverse_iterator it2=readIndices.rbegin();
+	    ASTVec::reverse_iterator it2end=readIndices.rend();
+	    for(;it2!=it2end;it2++) {
+	      ASTNode cond = CreateSimplifiedEQ(readIndex,*it2);
+	      if(ASTFalse == cond)
+		continue;
+	      
+	      ASTNode arrRead = CreateTerm(READ,width,arrName,*it2);
+	      //Good idea to TypeCheck internally constructed nodes
+	      BVTypeCheck(arrRead);
+	      
+	      ASTNode arrayreadSymbol = _arrayread_symbol[arrRead];
+	      if(arrayreadSymbol.IsNull())
+		FatalError("TransformArray:symbolic variable for processedTerm, p," 
+			   "does not exist:p = ",arrRead);
+	      ite = CreateSimplifiedTermITE(cond,arrayreadSymbol,ite);
+	    }
+	    result = ite;
+	    //}
+	}
+	
+	_arrayname_readindices[arrName].push_back(readIndex);	
+	//save the ite corresponding to 'processedTerm'
+	_arrayread_ite[processedTerm] = result;
+	break;
+      } //end of READ over a SYMBOL
+      case WRITE:{	
+	/* The input to this case is: READ((WRITE A i val) j)
+	 *
+	 * The output of this case is: ITE( (= i j) val (READ A i))
+	 */
+	
+	/* 1. arrName or term[0] is infact a WRITE(A,i,val) expression
+	 *
+	 * 2. term[1] is the read-index j
+	 *
+	 * 3. arrName[0] is the new arrName i.e. A. A can be either a
+              SYMBOL or a nested WRITE. no other possibility
+	 *
+	 * 4. arrName[1] is the WRITE index i.e. i
+	 *
+	 * 5. arrName[2] is the WRITE value i.e. val (val can inturn
+	 *    be an array read)
+	 */
+	ASTNode readIndex = TransformTerm(term[1]);
+	ASTNode writeIndex = TransformTerm(arrName[1]);
+	ASTNode writeVal = TransformTerm(arrName[2]);
+	
+	if(!(SYMBOL == arrName[0].GetKind() || 
+	     WRITE == arrName[0].GetKind())) 
+	  FatalError("TransformArray: An array write is being attempted on a non-array:",term);
+	if(ARRAY_TYPE != arrName[0].GetType())
+	  FatalError("TransformArray: An array write is being attempted on a non-array:",term);
+	
+	ASTNode cond = CreateSimplifiedEQ(writeIndex,readIndex);
+	//TypeCheck internally created node
+	BVTypeCheck(cond);
+	ASTNode readTerm = CreateTerm(READ,width,arrName[0],readIndex);
+	//TypeCheck internally created node
+	BVTypeCheck(readTerm);
+	ASTNode readPushedIn = TransformArray(readTerm);
+	//TypeCheck internally created node
+	BVTypeCheck(readPushedIn);
+	//result = CreateTerm(ITE, arrName[0].GetValueWidth(),cond,writeVal,readPushedIn);
+	result = CreateSimplifiedTermITE(cond,writeVal,readPushedIn);
+
+	//Good idea to typecheck terms created inside the system
+	BVTypeCheck(result);
+	break;
+      } //end of READ over a WRITE
+      case ITE: {
+	/* READ((ITE cond thn els) j) 
+	 *
+	 * is transformed into
+	 *
+	 * (ITE cond (READ thn j) (READ els j))
+	 */
+	
+	//(ITE cond thn els)
+	ASTNode term0 = term[0];
+	//READINDEX j
+	ASTNode j = TransformTerm(term[1]);
+	
+	ASTNode cond = term0[0];
+	//first array 
+	ASTNode t01  = term0[1];
+	//second array
+	ASTNode t02  = term0[2];
+	
+	cond = TransformFormula(cond);
+	ASTNode thn = TransformTerm(t01);
+	ASTNode els = TransformTerm(t02);
+	
+	if(!(t01.GetValueWidth() == t02.GetValueWidth() &&
+	     t01.GetValueWidth() == thn.GetValueWidth() &&
+	     t01.GetValueWidth() == els.GetValueWidth()))
+	  FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n",term);
+
+	if(!(t01.GetIndexWidth() == t02.GetIndexWidth() &&
+	     t01.GetIndexWidth() == thn.GetIndexWidth() &&
+	     t01.GetIndexWidth() == els.GetIndexWidth()))
+	  FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n",term);
+
+	//(READ thn j)
+	ASTNode thnRead = CreateTerm(READ,width,thn,j);
+	BVTypeCheck(thnRead);
+	thnRead = TransformArray(thnRead);
+	
+	//(READ els j)
+	ASTNode elsRead = CreateTerm(READ,width,els,j);
+	BVTypeCheck(elsRead);
+	elsRead = TransformArray(elsRead);
+	
+	//(ITE cond (READ thn j) (READ els j))
+	result = CreateSimplifiedTermITE(cond,thnRead,elsRead);
+	BVTypeCheck(result);
+      break;
+      }
+      default:
+	FatalError("TransformArray: The READ is NOT over SYMBOL/WRITE/ITE",term);
+	break;
+      } 
+      break;
+    } //end of READ switch
+    default:
+      FatalError("TransformArray: input term is of wrong kind: ",ASTUndefined);
+      break;
+    }
+    
+    TransformMap[term] = result;
+    return result;
+  } //end of TransformArray()  
+} //end of namespace BEEV
diff --git a/stp/AST/asttest.cpp b/stp/AST/asttest.cpp
new file mode 100644
index 00000000..57f3d20c
--- /dev/null
+++ b/stp/AST/asttest.cpp
@@ -0,0 +1,29 @@
+#include "AST.h"
+
+using namespace BEEV;
+
+int main()
+{
+
+  BeevMgr * bm = new BeevMgr();
+  ASTNode s1 = bm->CreateSymbol("foo");
+  s1 = bm->CreateSymbol("foo1");
+  s1 = bm->CreateSymbol("foo2");
+  ASTNode s2 = bm->CreateSymbol("bar");
+  cout << "s1" <<  s1 << endl;
+  cout << "s2" <<  s2 << endl;
+
+  ASTNode b1 = bm->CreateBVConst(5,12);
+  ASTNode b2 = bm->CreateBVConst(6,36);
+  cout << "b1: " <<  b1 << endl;
+  cout << "b2: " <<  b2 << endl;
+
+  ASTNode a1 = bm->CreateNode(EQ, s1, s2);
+  ASTNode a2 = bm->CreateNode(AND, s1, s2);
+  a1 = bm->CreateNode(OR, s1, s2);
+  ASTNode a3 = bm->CreateNode(IMPLIES, a1, a2);
+  ASTNode a4 = bm->CreateNode(IMPLIES, s1, a2);
+  cout << "a3" <<  a3 << endl;
+  cout << "a4" <<  a4 << endl;
+  return 0;
+}
diff --git a/stp/AST/bbtest.cpp b/stp/AST/bbtest.cpp
new file mode 100644
index 00000000..83aa6a4e
--- /dev/null
+++ b/stp/AST/bbtest.cpp
@@ -0,0 +1,96 @@
+#include "AST.h"
+
+using namespace BEEV;
+
+int main()
+{
+  const int size = 32;
+
+  BeevMgr *bm = new BeevMgr();
+  ASTNode s1 = bm->CreateSymbol("x");
+  s1.SetValueWidth(size);
+  cout << "s1" <<  s1 << endl;
+  ASTNode s2 = bm->CreateSymbol("y");
+  s2.SetValueWidth(size);
+  cout << "s2" <<  s2 << endl;
+  ASTNode s3 = bm->CreateSymbol("z");
+  s3.SetValueWidth(size);
+  cout << "s3" <<  s3 << endl;
+
+  ASTNode c1 = bm->CreateBVConst(size,0);
+  cout << "c1" <<  c1 << endl;
+  ASTVec bbc1 = bm->BBTerm(c1);
+  cout << "bitblasted c1 " << endl;
+  LispPrintVec(cout, bbc1, 0);
+  cout << endl;
+  bm->AlreadyPrintedSet.clear();
+
+  ASTNode c2 = bm->CreateBVConst(size,1);
+  c2.SetValueWidth(size);
+  cout << "c2" <<  c2 << endl;
+  ASTVec bbc2 = bm->BBTerm(c2);
+  cout << "bitblasted c2 " << endl;
+  LispPrintVec(cout, bbc2, 0);
+  cout << endl;
+  bm->AlreadyPrintedSet.clear();
+
+  ASTNode c3 = bm->CreateBVConst(size, 0xFFFFFFFF);
+  c3.SetValueWidth(size);
+  cout << "c3" <<  c3 << endl;
+  ASTVec bbc3 = bm->BBTerm(c3);
+  cout << "bitblasted c3 " << endl;
+  LispPrintVec(cout, bbc3, 0);
+  cout << endl;
+  bm->AlreadyPrintedSet.clear();
+
+  ASTNode c4 = bm->CreateBVConst(size, 0xAAAAAAAA);
+  c4.SetValueWidth(size);
+  cout << "c4" <<  c4 << endl;
+  ASTVec bbc4 = bm->BBTerm(c4);
+  cout << "bitblasted c4 " << endl;
+  LispPrintVec(cout, bbc4, 0);
+  cout << endl;
+  bm->AlreadyPrintedSet.clear();
+
+//   ASTNode b1 = bm->CreateBVConst(12);
+//   ASTNode b2 = bm->CreateBVConst(36);
+//   cout << "b1: " <<  b1 << endl;
+//   cout << "b2: " <<  b2 << endl;
+
+  ASTNode a1 = bm->CreateNode(BVPLUS, s1, s2);
+  a1.SetValueWidth(size);
+
+  ASTVec& bba1 = bm->BBTerm(a1);
+  cout << "bitblasted a1 " << endl;
+  LispPrintVec(cout, bba1, 0);
+  cout << endl;
+  bm->AlreadyPrintedSet.clear();
+
+  ASTNode a2 = bm->CreateNode(BVPLUS, s1, s2, s3);
+  a1.SetValueWidth(2);
+
+  ASTVec& bba2 = bm->BBTerm(a2);
+  cout << "bitblasted a2 " << endl;
+  LispPrintVec(cout, bba2, 0);
+  cout << endl;
+  bm->AlreadyPrintedSet.clear();
+
+  ASTNode a3 = bm->CreateNode(BVXOR, s1, s2);
+  a3.SetValueWidth(2);
+
+  ASTVec& bba3 = bm->BBTerm(a3);
+  cout << "bitblasted a3 " << endl;
+  LispPrintVec(cout, bba3, 0);
+  cout << endl;
+  bm->AlreadyPrintedSet.clear();
+
+  ASTNode a4 = bm->CreateNode(EQ, s1, s2);
+  ASTNode bba4 = bm->BBForm(a4);
+  cout << "bitblasted a4 " << endl << bba4 << endl;
+
+  ASTNode a5 = bm->CreateNode(BVLE, s1, s2);
+  ASTNode bba5 = bm->BBForm(a5);
+  cout << "bitblasted a5 " << endl << bba5 << endl;
+
+  return 0;
+}
diff --git a/stp/AST/cnftest.cpp b/stp/AST/cnftest.cpp
new file mode 100644
index 00000000..7ce270c8
--- /dev/null
+++ b/stp/AST/cnftest.cpp
@@ -0,0 +1,47 @@
+// -*- c++ -*-
+
+// Test program for CNF conversion.
+
+#include "AST.h"
+
+using namespace BEEV;
+
+int main()
+{
+  const int size = 1;
+  
+  BeevMgr *bm = new BeevMgr();
+  ASTNode s1 = bm->CreateSymbol("x");
+  s1.SetValueWidth(size);
+  
+  cout << "s1" <<  s1 << endl;
+  ASTNode s2 = bm->CreateSymbol("y");
+  s2.SetValueWidth(size);
+
+  cout << "s2" <<  s2 << endl;
+  ASTNode s3 = bm->CreateSymbol("z");
+  s3.SetValueWidth(size);
+  
+  cout << "s3" <<  s3 << endl;
+
+  ASTNode bbs1 = bm->BBForm(s1);
+  cout << "bitblasted s1" << endl << bbs1 << endl;
+  bm->PrintClauseList(cout, bm->ToCNF(bbs1));
+
+  ASTNode a2 = bm->CreateNode(AND, s1, s2);
+  ASTNode bba2 = bm->BBForm(a2);
+  cout << "bitblasted a2" << endl << bba2 << endl;
+  bm->PrintClauseList(cout, bm->ToCNF(bba2));
+
+  ASTNode a3 = bm->CreateNode(OR, s1, s2);
+  ASTNode bba3 = bm->BBForm(a3);
+  cout << "bitblasted a3" << endl << bba3 << endl;
+  bm->PrintClauseList(cout, bm->ToCNF(bba3));
+
+  ASTNode a4 = bm->CreateNode(EQ, s1, s2);
+  ASTNode bba4 = bm->BBForm(a4);
+  cout << "bitblasted a4 " << endl << bba4 << endl;
+
+  bm->PrintClauseList(cout, bm->ToCNF(bba4));
+
+}
diff --git a/stp/AST/genkinds.pl b/stp/AST/genkinds.pl
new file mode 100755
index 00000000..7944832b
--- /dev/null
+++ b/stp/AST/genkinds.pl
@@ -0,0 +1,123 @@
+#!/usr/bin/perl -w
+
+#AUTHORS: Vijay Ganesh, David L. Dill BEGIN DATE: November, 2005
+#LICENSE: Please view LICENSE file in the home dir of this Program
+#given a file containing kind names, one per line produces .h and .cpp
+#files for the kinds.
+
+#globals
+@kindnames = ();
+$minkids = 0;
+$maxkids = 0;
+@cat_bits = ();
+@category_names = ();
+%cat_index = ();
+
+$now = localtime time;
+
+sub read_kind_defs {
+    open(KFILE, "< ASTKind.kinds") || die "Cannot open .kinds file: $!\n";
+    @kindlines = <KFILE>;
+    close(KFILE)
+}
+
+# create lists of things indexed by kinds.
+sub split_fields {
+    my $kind_cat_bits;
+    # matches anything with three whitespace-delimited alphanumeric fields,
+    # followed by rest of line.  Automatically ignores lines beginning with '#' and blank lines.
+    for (@kindlines) {
+	if (/Categories:\s+(.*)/) {
+	    @category_names = split(/\s+/, $1);
+	    $i = 0;
+	    for (@category_names) {
+		$cat_index{$_} = $i++;
+		# print "cat_index{$_} = $i\n";
+	    }
+	}
+	elsif (/^(\w+)\s+(\w+)\s+(\w+|-)\s+(.*)/) {
+	    push(@kindnames, $1);
+	    push(@minkids, $2);
+	    push(@maxkids, $3);
+	    @kind_cats = split(/\s+/, $4);
+	    # build a bit vector of categories.
+	    $kind_cat_bits = 0;
+	    for (@kind_cats) {
+		$kind_cat_bits |= (1 << int($cat_index{$_}));
+	    }
+	    push(@cat_bits, $kind_cat_bits); 
+	}
+    }
+}
+
+sub gen_h_file {
+    open(HFILE, "> ASTKind.h") || die "Cannot open .h file: $!\n";
+
+    print HFILE 
+	"// -*- c++ -*-\n",
+	"#ifndef TESTKINDS_H\n",
+	"#define TESTKINDS_H\n",
+	"// Generated automatically by genkinds.pl from ASTKind.kinds $now.\n",
+	"// Do not edit\n",
+	"namespace BEEV {\n  typedef enum {\n";
+
+    for (@kindnames) {
+	print HFILE "    $_,\n";
+    }
+
+    print HFILE 
+	"} Kind;\n\n",
+	"extern unsigned char _kind_categories[];\n\n";
+
+    # For category named "cat", generate functions "bool is_cat_kind(k);"
+
+
+    for (@category_names) {
+	my $catname = $_;
+	my $kind_cat_bit = (1 << int($cat_index{$catname}));
+	print HFILE "inline bool is_", $catname, "_kind(Kind k) { return (_kind_categories[k] & $kind_cat_bit); }\n\n"
+    }
+
+    print HFILE
+	"extern const char *_kind_names[];\n\n",
+	"/** Prints symbolic name of kind */\n",
+	"inline ostream& operator<<(ostream &os, const Kind &kind) { os << _kind_names[kind]; return os; }\n",
+	"\n\n",
+	"};  // end namespace\n",
+	"\n\n#endif\n";
+
+    close(HFILE);
+}
+
+# generate the .cpp file
+
+sub gen_cpp_file {
+    open(CPPFILE, "> ASTKind.cpp") || die "Cannot open .h file: $!\n";
+
+    print CPPFILE
+	"// Generated automatically by genkinds.h from ASTKind.kinds $now.\n",
+	"// Do not edit\n",
+	"namespace BEEV {\n",
+	"const char * _kind_names[] =  {\n";
+    for (@kindnames) {
+	print CPPFILE "   \"$_\",\n";
+    }
+    print CPPFILE "};\n\n";
+
+    # category bits
+    print CPPFILE
+	"unsigned char _kind_categories[] = {\n";
+    for (@cat_bits) {
+	print CPPFILE "   $_,\n";
+    }
+    print CPPFILE 
+	"};\n",
+	"\n};  // end namespace\n";
+
+    close(CPPFILE);
+}
+
+&read_kind_defs;
+&split_fields;
+&gen_h_file;
+&gen_cpp_file;
diff --git a/stp/INSTALL b/stp/INSTALL
new file mode 100644
index 00000000..12cee121
--- /dev/null
+++ b/stp/INSTALL
@@ -0,0 +1,10 @@
+1. To install STP perform the following steps on your Unix/GNU-Linux/MacOS X commandline:
+
+./configure --with-prefix=$HOME (or another installation directory)
+make clean
+make
+make install
+
+2. To test the system after installation:
+
+make regressall
\ No newline at end of file
diff --git a/stp/LICENSE b/stp/LICENSE
new file mode 100644
index 00000000..41029509
--- /dev/null
+++ b/stp/LICENSE
@@ -0,0 +1,17 @@
+/*****************************************************************************/
+/*  AUTHORS:    Vijay Ganesh, David L. Dill             DATE: Nov 2005       */
+/*****************************************************************************/
+/* Copyright (C) 2005 by the Board of Trustees of Leland Stanford            */
+/* Junior University.                                                        */
+/*                                                                           */
+/* License to use, copy, modify, sell and/or distribute this software        */
+/* and its documentation for any purpose is hereby granted without           */
+/* royalty, subject to the terms and conditions defined in the \ref          */
+/* LICENSE file provided with this distribution.  In particular:             */
+/*                                                                           */
+/* - The above copyright notice and this permission notice must appear       */
+/* in all copies of the software and related documentation.                  */
+/*                                                                           */
+/* - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,               */
+/* EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.                           */
+/*****************************************************************************/
diff --git a/stp/Makefile b/stp/Makefile
new file mode 100644
index 00000000..f66644a5
--- /dev/null
+++ b/stp/Makefile
@@ -0,0 +1,64 @@
+ # STP (Simple Theorem Prover) top level makefile
+ #
+ # To make in debug mode, type 'make "CLFAGS=-ggdb"
+ # To make in optimized mode, type 'make "CFLAGS=-O2" 
+
+include Makefile.common
+
+BINARIES=bin/stp
+LIBS=AST/libast.a sat/libsatsolver.a simplifier/libsimplifier.a bitvec/libconsteval.a constantbv/libconstantbv.a c_interface/libcinterface.a
+DIRS=AST sat simplifier bitvec c_interface constantbv parser
+
+# NB: the TAGS target is a hack to get around this recursive make nonsense
+# we want all the source and header files generated before we make tags
+.PHONY: all
+all: lib/libstp.a bin/stp include/stp/c_interface.h
+
+AST/libast.a:
+	@$(MAKE) -q -C `dirname $@` || $(MAKE) -C `dirname $@`
+sat/libsatsolver.a: AST/libast.a
+	@$(MAKE) -q -C `dirname $@` || $(MAKE) -C `dirname $@`
+simplifier/libsimplifier.a: AST/libast.a
+	@$(MAKE) -q -C `dirname $@` || $(MAKE) -C `dirname $@`
+bitvec/libconsteval.a: AST/libast.a
+	@$(MAKE) -q -C `dirname $@` || $(MAKE) -C `dirname $@`
+constantbv/libconstantbv.a: AST/libast.a
+	@$(MAKE) -q -C `dirname $@` || $(MAKE) -C `dirname $@`
+c_interface/libcinterface.a: AST/libast.a
+	@$(MAKE) -q -C `dirname $@` || $(MAKE) -C `dirname $@`
+parser/parser: $(LIBS)
+	@$(MAKE) -q -C `dirname $@` || $(MAKE) -C `dirname $@`
+
+lib/libstp.a: parser/parser $(LIBS)
+	@mkdir -p lib
+	rm -f $@
+	@for dir in $(DIRS); do \
+		$(AR) rc $@ $$dir/*.o; \
+	done
+	$(RANLIB) $@
+
+bin/stp: parser/parser $(LIBS)
+	@mkdir -p bin
+	@cp parser/parser $@
+
+include/stp/c_interface.h: $(LIBS)
+	@mkdir -p include/stp
+	@cp c_interface/c_interface.h $@
+
+.PHONY: clean
+clean:
+	rm -rf *~
+	rm -rf *.a
+	rm -rf lib/*.a
+	rm -rf bin/*~
+	rm -rf bin/stp
+	rm -rf *.log
+	rm -f TAGS
+	$(MAKE) clean -C AST
+	$(MAKE) clean -C sat
+	$(MAKE) clean -C simplifier
+	$(MAKE) clean -C bitvec
+	$(MAKE) clean -C parser
+	$(MAKE) clean -C c_interface
+	$(MAKE) clean -C constantbv
+
diff --git a/stp/Makefile.common.in b/stp/Makefile.common.in
new file mode 100644
index 00000000..a88e35ed
--- /dev/null
+++ b/stp/Makefile.common.in
@@ -0,0 +1,16 @@
+# -*- Makefile -*-
+
+CFLAGS := @CFLAGS@
+CXXFLAGS := @CXXFLAGS@ -O2
+LDFLAGS := @LDFLAGS@ -lstdc++
+
+# use the darmin test as a proxy for detecting Mac OS X
+ifneq ($(shell uname -s), Darwin)
+  CFLAGS += -static
+endif
+
+CXXFLAGS += -Wall -DEXT_HASH_MAP
+
+LEX := flex
+YACC := bison -d -y --debug -v
+RANLIB := ranlib
diff --git a/stp/README b/stp/README
new file mode 100644
index 00000000..da0f9b96
--- /dev/null
+++ b/stp/README
@@ -0,0 +1,26 @@
+/********************************************************************
+ * PROGRAM NAME: STP (Simple Theorem Prover)	
+ *		
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *	
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+
+Install
+-------
+See INSTALL file in the home dir of this program
+
+Authors
+-------
+Vijay Ganesh, Stanford University, Stanford, CA, USA
+David L. Dill, Stanford University, Stanford, CA, USA
+Tim King, Stanford University, Stanford, CA, USA
+
+Makefiles and configuration scripts
+------------------------------------
+Cristian Cadar, Stanford University, Stanford, CA, USA
+Paul Twohey, Stanford University, Stanford, CA, USA
+Sergey Berezin, ATG Synopsys, Mountain View, CA, USA
+Clark Barrett, New York University, New York, NY, USA
diff --git a/stp/bitvec/Makefile b/stp/bitvec/Makefile
new file mode 100644
index 00000000..eb6e1121
--- /dev/null
+++ b/stp/bitvec/Makefile
@@ -0,0 +1,11 @@
+include ../Makefile.common
+
+SRCS = consteval.cpp
+OBJS = $(SRCS:.cpp=.o)
+
+libconsteval.a: $(OBJS)
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+clean:	
+	rm -rf *.o *~ *.a .#*
diff --git a/stp/bitvec/consteval.cpp b/stp/bitvec/consteval.cpp
new file mode 100644
index 00000000..7cb8dfcb
--- /dev/null
+++ b/stp/bitvec/consteval.cpp
@@ -0,0 +1,1044 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include "../AST/ASTUtil.h"
+namespace BEEV {
+
+  //error printing
+  static void BVConstEvaluatorError(CONSTANTBV::ErrCode e, const ASTNode& t){
+    std::string ss("BVConstEvaluator:");
+    ss += (const char*)BitVector_Error(e);	
+    FatalError(ss.c_str(), t);
+  }
+
+#ifndef NATIVE_C_ARITH
+  ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
+    ASTNode OutputNode;
+    Kind k = t.GetKind();
+
+    if(CheckSolverMap(t,OutputNode))
+      return OutputNode;
+    OutputNode = t;
+
+    unsigned int inputwidth = t.GetValueWidth();
+    unsigned int outputwidth = inputwidth;
+    CBV output = NULL;
+
+    CBV tmp0 = NULL;
+    CBV tmp1 = NULL;
+
+    //saving some typing. BVPLUS does not use these variables. if the
+    //input BVPLUS has two nodes, then we want to avoid setting these
+    //variables.
+    if(1 == t.Degree() ){
+      tmp0 = BVConstEvaluator(t[0]).GetBVConst();
+    }else if(2 == t.Degree() && k != BVPLUS ) {
+      tmp0 = BVConstEvaluator(t[0]).GetBVConst();
+      tmp1 = BVConstEvaluator(t[1]).GetBVConst();
+    }
+
+    switch(k) {
+    case UNDEFINED:
+    case READ:
+    case WRITE:
+    case SYMBOL:
+      FatalError("BVConstEvaluator: term is not a constant-term",t);
+      break;
+    case BVCONST:
+      //FIXME Handle this special case better
+      OutputNode = t;
+      break;
+    case BVNEG:{
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      CONSTANTBV::Set_Complement(output,tmp0);
+      OutputNode = CreateBVConst(output,outputwidth);
+      break;
+    }
+    case BVSX: {
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      //unsigned * out0 = BVConstEvaluator(t[0]).GetBVConst();
+      unsigned t0_width = t[0].GetValueWidth();
+      if(inputwidth == t0_width) {
+        CONSTANTBV::BitVector_Copy(output, tmp0);
+        OutputNode = CreateBVConst(output, outputwidth);    
+      }
+      else {
+        bool topbit_sign = (CONSTANTBV::BitVector_Sign(tmp0) < 0 );
+
+        if(topbit_sign){
+          CONSTANTBV::BitVector_Fill(output);
+        }
+        CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width);
+        OutputNode = CreateBVConst(output, outputwidth);    
+      }
+      break;
+    }
+    case BVAND: {
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      CONSTANTBV::Set_Intersection(output,tmp0,tmp1);
+      OutputNode = CreateBVConst(output, outputwidth);
+      break;
+    }
+    case BVOR: {
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      CONSTANTBV::Set_Union(output,tmp0,tmp1);
+      OutputNode = CreateBVConst(output, outputwidth);
+      break;
+    }
+    case BVXOR: {
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      CONSTANTBV::Set_ExclusiveOr(output,tmp0,tmp1);
+      OutputNode = CreateBVConst(output, outputwidth);
+      break;
+    }
+    case BVSUB: {
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      bool carry = false;
+      CONSTANTBV::BitVector_sub(output,tmp0,tmp1,&carry);
+      OutputNode = CreateBVConst(output, outputwidth);    
+      break;
+    }
+    case BVUMINUS: {
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      CONSTANTBV::BitVector_Negate(output, tmp0);
+      OutputNode = CreateBVConst(output, outputwidth);    
+      break;
+    }
+    case BVEXTRACT: {
+      output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      tmp0 = BVConstEvaluator(t[0]).GetBVConst();
+      unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
+      unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
+      unsigned int len = hi-low+1;
+
+      CONSTANTBV::BitVector_Destroy(output);
+      output = CONSTANTBV::BitVector_Create(len, false);
+      CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, low, len);
+      outputwidth = len;
+      OutputNode = CreateBVConst(output, outputwidth);
+      break;
+    }
+    //FIXME Only 2 inputs?
+    case BVCONCAT: {
+       output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      unsigned t0_width = t[0].GetValueWidth();
+      unsigned t1_width = t[1].GetValueWidth();
+      CONSTANTBV::BitVector_Destroy(output);
+      
+      output = CONSTANTBV::BitVector_Concat(tmp0, tmp1);
+      outputwidth = t0_width + t1_width;
+      OutputNode = CreateBVConst(output, outputwidth);
+      
+      break;
+    }
+    case BVMULT: {
+       output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      CBV tmp = CONSTANTBV::BitVector_Create(2*inputwidth,true);
+      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(tmp,tmp0,tmp1);
+      
+      if(0 != e) {
+        BVConstEvaluatorError(e,t);
+      }
+      //FIXME WHAT IS MY OUTPUT???? THE SECOND HALF of tmp?
+      //CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, inputwidth, inputwidth);
+      CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, 0, inputwidth);
+      OutputNode = CreateBVConst(output, outputwidth);
+      CONSTANTBV::BitVector_Destroy(tmp);
+      break;
+    }
+    case BVPLUS: {
+       output = CONSTANTBV::BitVector_Create(inputwidth,true);
+      bool carry = false;
+      ASTVec c = t.GetChildren();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	CBV kk = BVConstEvaluator(*it).GetBVConst();
+	CONSTANTBV::BitVector_add(output,output,kk,&carry);
+	carry = false;
+	//CONSTANTBV::BitVector_Destroy(kk);
+      }
+      OutputNode = CreateBVConst(output, outputwidth);
+      break;
+    }
+    //FIXME ANOTHER SPECIAL CASE
+    case SBVDIV:
+    case SBVMOD:{
+      OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
+      break;
+    }
+    case BVDIV: 
+    case BVMOD: {
+      CBV quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
+      CBV remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
+      
+      // tmp0 is dividend, tmp1 is the divisor
+      //All parameters to BitVector_Div_Pos must be distinct unlike BitVector_Divide
+      //FIXME the contents of the second parameter to Div_Pos is destroyed
+      //As tmp0 is currently the same as the copy belonging to an ASTNode t[0]
+      //this must be copied.
+      tmp0 = CONSTANTBV::BitVector_Clone(tmp0);      
+      CONSTANTBV::ErrCode e= CONSTANTBV::BitVector_Div_Pos(quotient,tmp0,tmp1,remainder);
+      CONSTANTBV::BitVector_Destroy(tmp0);
+      
+      if(0 != e) {
+	//error printing
+	if(counterexample_checking_during_refinement) {
+          output = CONSTANTBV::BitVector_Create(inputwidth,true);
+	  OutputNode = CreateBVConst(output, outputwidth);
+	  bvdiv_exception_occured = true;
+          
+          //  CONSTANTBV::BitVector_Destroy(output);
+	  break;
+	}
+	else {
+	  BVConstEvaluatorError(e,t);
+	}
+      } //end of error printing
+
+      //FIXME Not very standard in the current scheme
+      if(BVDIV == k){
+        OutputNode = CreateBVConst(quotient, outputwidth);
+        CONSTANTBV::BitVector_Destroy(remainder);
+      }else{
+        OutputNode = CreateBVConst(remainder, outputwidth);
+        CONSTANTBV::BitVector_Destroy(quotient);
+      }
+
+      break;
+    }
+    case ITE:
+      if(ASTTrue == t[0])
+	OutputNode = BVConstEvaluator(t[1]);
+      else if(ASTFalse == t[0])
+	OutputNode = BVConstEvaluator(t[2]);
+      else
+	FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t);
+      break;
+    case EQ: 
+      if(CONSTANTBV::BitVector_equal(tmp0,tmp1))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case NEQ:
+      if(!CONSTANTBV::BitVector_equal(tmp0,tmp1))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVLT:
+      if(-1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVLE: {
+      int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1);
+      if(comp <= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVGT:
+      if(1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVGE: {
+      int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1);
+      if(comp >= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    } 
+    case BVSLT:
+      if(-1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVSLE: {
+      signed int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1);
+      if(comp <= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVSGT:
+      if(1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVSGE: {
+      int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1);
+      if(comp >= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    } 
+    default:
+      FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
+      break;
+    }
+/*
+    if(BVCONST != k){
+     cerr<<inputwidth<<endl;
+     cerr<<"------------------------"<<endl;
+     t.LispPrint(cerr);
+     cerr<<endl;
+     OutputNode.LispPrint(cerr);
+     cerr<<endl<<"------------------------"<<endl;
+    }
+*/
+    UpdateSolverMap(t,OutputNode);
+    //UpdateSimplifyMap(t,OutputNode,false);
+    return OutputNode;
+  }
+#else
+  //accepts 64 bit BVConst and sign extends it
+  static unsigned long long int SXBVConst64(const ASTNode& t) {
+    unsigned long long int c = t.GetBVConst();
+    unsigned int len = t.GetValueWidth();
+
+    unsigned long long int mask = 1;
+    mask = mask << len-1;
+
+    bool TopBit = (c & mask) ? true : false;
+    if(!TopBit) return c;
+    
+    unsigned long long int sign = 0xffffffffffffffffLL;
+    sign = sign << len-1;
+
+    return (c | sign);
+  }
+
+  //FIXME: Ideally I would like the ASTNodes to be able to operate on
+  //themselves (add, sub, concat, etc.) rather than doing a
+  //GetBVConst() and then do the operation externally. For now,
+  //this is the fastest path to completion.
+  ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
+    //cerr << "inside begin bcconstevaluator: " << t << endl;
+
+    ASTNode OutputNode;
+    if(CheckSolverMap(t,OutputNode))
+      return OutputNode;
+    OutputNode = ASTUndefined;
+
+    Kind k = t.GetKind();
+    unsigned long long int output = 0;
+    unsigned inputwidth = t.GetValueWidth();
+    ASTNode t0 = ASTUndefined;
+    ASTNode t1 = ASTUndefined;
+    if(2 == t.Degree()) {
+      t0 = BVConstEvaluator(t[0]);
+      t1 = BVConstEvaluator(t[1]);
+    }
+    switch(k) {
+    case READ:
+    case UNDEFINED:
+    case WRITE:
+    case SYMBOL:
+      cerr << t;
+      FatalError("BVConstEvaluator: term is not a constant-term",t);
+      break;
+    case BVCONST:
+      return t;
+      break;
+    case BVNEG:
+      //compute bitwise negation in C
+      output = ~(BVConstEvaluator(t[0]).GetBVConst());
+      break;
+    case BVSX:
+      output = SXBVConst64(BVConstEvaluator(t[0]));    
+      break;
+    case BVAND:
+      output = t0.GetBVConst() & t1.GetBVConst();
+      break;
+    case BVOR:
+      output = t0.GetBVConst() | t1.GetBVConst();
+      break;
+    case BVXOR:
+      output = t0.GetBVConst() ^ t1.GetBVConst();
+      break;
+    case BVSUB:
+      output = t0.GetBVConst() - t1.GetBVConst();
+      break;
+    case BVUMINUS:
+      output = ~(BVConstEvaluator(t[0]).GetBVConst()) + 1;
+      break;
+    case BVEXTRACT: {
+      unsigned long long int val = BVConstEvaluator(t[0]).GetBVConst();
+      unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
+      unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
+
+      if(!(0 <= hi <= 64))
+	FatalError("ConstantEvaluator: hi bit in BVEXTRACT is > 32bits",t);
+      if(!(0 <= low <= hi <= 64))
+	FatalError("ConstantEvaluator: low bit in BVEXTRACT is > 32bits or hi",t);
+
+      //64 bit mask.
+      unsigned long long int mask1 = 0xffffffffffffffffLL;
+      mask1 >>= 64-(hi+1);
+      
+      //extract val[hi:0]
+      val &= mask1;
+      //extract val[hi:low]
+      val >>= low;
+      output = val;
+      break;
+    }
+    case BVCONCAT: {
+      unsigned long long int q = BVConstEvaluator(t0).GetBVConst();
+      unsigned long long int r = BVConstEvaluator(t1).GetBVConst();
+
+      unsigned int qlen = t[0].GetValueWidth();
+      unsigned int rlen = t[1].GetValueWidth();
+      unsigned int slen = t.GetValueWidth();
+      if(!(0 <  qlen + rlen  <= 64))
+	FatalError("BVConstEvaluator:"
+		   "lengths of childnodes of BVCONCAT are > 64:",t);
+
+      //64 bit mask for q
+      unsigned long long int qmask = 0xffffffffffffffffLL;     
+      qmask >>= 64-qlen;
+      //zero the useless bits of q
+      q &= qmask;
+
+      //64 bit mask for r
+      unsigned long long int rmask = 0xffffffffffffffffLL;     
+      rmask >>= 64-rlen;
+      //zero the useless bits of r
+      r &= rmask;
+      
+      //concatenate
+      q <<= rlen;
+      q |= r;
+
+      //64 bit mask for output s
+      unsigned long long int smask = 0xffffffffffffffffLL;
+      smask >>= 64-slen;
+      
+      //currently q has the output
+      output = q;      
+      output &= smask;
+      break;
+    }
+    case BVMULT: {
+      output = t0.GetBVConst() * t1.GetBVConst();
+
+      //64 bit mask
+      unsigned long long int mask = 0xffffffffffffffffLL;
+      mask = mask >> (64 - inputwidth);
+      output &= mask;
+      break;
+    }
+    case BVPLUS: {
+      ASTVec c = t.GetChildren();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++)
+	output += BVConstEvaluator(*it).GetBVConst();
+
+      //64 bit mask
+      unsigned long long int mask = 0xffffffffffffffffLL;
+      mask = mask >> (64 -inputwidth);
+      output &= mask;
+      break;
+    }
+    case SBVDIV:
+    case SBVMOD: {
+      output = BVConstEvaluator(TranslateSignedDivMod(t)).GetBVConst();
+      break;
+    }
+    case BVDIV: {
+      if(0 == t1.GetBVConst()) {
+	//if denominator is 0 then 
+	//  (if refinement is ON then output is set to 0) 
+	//   (else produce a fatal error)
+	if(counterexample_checking_during_refinement) {
+	  output = 0;
+	  bvdiv_exception_occured = true;
+	  break;
+	}
+	else {
+	  FatalError("BVConstEvaluator: divide by zero not allowed:",t);
+	}
+      }
+
+      output = t0.GetBVConst() / t1.GetBVConst();
+      //64 bit mask
+      unsigned long long int mask = 0xffffffffffffffffLL;
+      mask = mask >> (64 - inputwidth);
+      output &= mask;
+      break;
+    }
+    case BVMOD: {
+      if(0 == t1.GetBVConst()) {
+	//if denominator is 0 then 
+	//  (if refinement is ON then output is set to 0) 
+	//   (else produce a fatal error)
+	if(counterexample_checking_during_refinement) {
+	  output = 0;
+	  bvdiv_exception_occured = true;
+	  break;
+	}
+	else {
+	  FatalError("BVConstEvaluator: divide by zero not allowed:",t);
+	}
+      }
+
+      output = t0.GetBVConst() % t1.GetBVConst();
+      //64 bit mask
+      unsigned long long int mask = 0xffffffffffffffffLL;
+      mask = mask >> (64 - inputwidth);
+      output &= mask;
+      break;
+    }
+    case ITE:
+      if(ASTTrue == t[0])
+	OutputNode = BVConstEvaluator(t[1]);
+      else if(ASTFalse == t[0])
+	OutputNode = BVConstEvaluator(t[2]);
+      else
+	FatalError("BVConstEvaluator:" 
+		   "ITE condiional must be either TRUE or FALSE:",t);
+      break;
+    case EQ:
+      if(t0.GetBVConst() == t1.GetBVConst())
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case NEQ:
+      if(t0.GetBVConst() != t1.GetBVConst())
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+      break;
+    case BVLT: {
+      unsigned long long n0 = t0.GetBVConst();
+      unsigned long long n1 = t1.GetBVConst();
+      if(n0 < n1)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVLE:
+      if(t0.GetBVConst() <= t1.GetBVConst())
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVGT:
+      if(t0.GetBVConst() > t1.GetBVConst())
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVGE:
+      if(t0.GetBVConst() >= t1.GetBVConst())
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVSLT: {
+      signed long long int n0 = SXBVConst64(t0);
+      signed long long int n1 = SXBVConst64(t1);
+      if(n0 < n1)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVSLE: {
+      signed long long int n0 = SXBVConst64(t0);
+      signed long long int n1 = SXBVConst64(t1);
+      if(n0 <= n1)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVSGT: {   
+      signed long long int n0 = SXBVConst64(t0);
+      signed long long int n1 = SXBVConst64(t1);
+      if(n0 > n1)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVSGE: {   
+      signed long long int n0 = SXBVConst64(t0);
+      signed long long int n1 = SXBVConst64(t1);
+      if(n0 >= n1)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    default:
+      FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
+      break;
+    }    
+   
+    if(ASTTrue  != OutputNode && ASTFalse != OutputNode)
+      OutputNode = CreateBVConst(inputwidth, output);
+    UpdateSolverMap(t,OutputNode);
+    //UpdateSimplifyMap(t,OutputNode,false);
+    return OutputNode;
+  } //End of BVConstEvaluator
+#endif
+//In the block below is the old string based version
+//It is included here as an easy reference while the current code is being worked on.
+
+/*
+  ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
+    ASTNode OutputNode;
+    Kind k = t.GetKind();
+
+    if(CheckSolverMap(t,OutputNode))
+      return OutputNode;
+    OutputNode = t;
+
+    unsigned int inputwidth = t.GetValueWidth();
+    unsigned * output = CONSTANTBV::BitVector_Create(inputwidth,true);
+    unsigned * One = CONSTANTBV::BitVector_Create(inputwidth,true);
+    CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(One, (unsigned char*)"1");
+    //error printing
+    if(0 != e) {
+      std::string ss("BVConstEvaluator:");
+      ss += (const char*)BitVector_Error(e);	
+      FatalError(ss.c_str(), t);
+    }
+
+    unsigned * Zero = CONSTANTBV::BitVector_Create(inputwidth,true);
+    unsigned int * iii = One;
+    unsigned int * jjj = Zero;
+
+    //saving some typing. BVPLUS does not use these variables. if the
+    //input BVPLUS has two nodes, then we want to avoid setting these
+    //variables.
+    if(2 == t.Degree() && k != BVPLUS && k != BVCONCAT) {
+      iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
+      jjj = ConvertToCONSTANTBV(BVConstEvaluator(t[1]).GetBVConst());
+    }
+
+    char * cccc;
+    switch(k) {
+    case UNDEFINED:
+    case READ:
+    case WRITE:
+    case SYMBOL:
+      FatalError("BVConstEvaluator: term is not a constant-term",t);
+      break;
+    case BVCONST:
+      OutputNode = t;
+      break;
+    case BVNEG:{
+      //AARON
+      if (iii != One) free(iii);
+      //AARON
+
+      iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());     
+      CONSTANTBV::Set_Complement(output,iii);
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+      OutputNode = CreateBVConst(cccc,2);
+      break;
+    }
+    case BVSX: {
+      unsigned * out0 = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
+      unsigned t0_width = t[0].GetValueWidth();
+      if(inputwidth == t0_width) {
+	cccc = (char *)CONSTANTBV::BitVector_to_Bin(out0);
+	OutputNode = CreateBVConst(cccc,2);
+
+	//AARON
+	free(cccc);
+	//AARON
+
+	CONSTANTBV::BitVector_Destroy(out0);     
+      }
+      else {
+	// FIXME: (Dill) I'm guessing that BitVector sign returns 1 if the
+	// number is positive, 0 if 0, and -1 if negative.  But I'm only
+	// guessing.
+	signed int topbit_sign = (CONSTANTBV::BitVector_Sign(out0) < 0);
+	//out1 is the sign-extension bits
+	unsigned * out1 =  CONSTANTBV::BitVector_Create(inputwidth-t0_width,true);      
+	if(topbit_sign)
+	  CONSTANTBV::BitVector_Fill(out1);
+
+	//AARON
+	CONSTANTBV::BitVector_Destroy(output);
+	//AARON
+
+	output = CONSTANTBV::BitVector_Concat(out1,out0);
+	cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+	OutputNode = CreateBVConst(cccc,2);
+
+	//AARON
+	free(cccc);
+	//AARON
+
+	CONSTANTBV::BitVector_Destroy(out0);
+	CONSTANTBV::BitVector_Destroy(out1);
+      }
+      break;
+    }
+    case BVAND: {
+      CONSTANTBV::Set_Intersection(output,iii,jjj);
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      //AARON
+      
+      break;
+    }
+    case BVOR: {
+      CONSTANTBV::Set_Union(output,iii,jjj);
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      //AARON
+
+      break;
+    }
+    case BVXOR: {
+      CONSTANTBV::Set_ExclusiveOr(output,iii,jjj);
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      //AARON
+
+      break;
+    }
+    case BVSUB: {
+      bool carry = false;
+      CONSTANTBV::BitVector_sub(output,iii,jjj,&carry);
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      //AARON
+
+      break;
+    }
+    case BVUMINUS: {
+      bool carry = false;
+
+      //AARON
+      if (iii != One) free(iii);
+      //AARON
+
+      iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
+      CONSTANTBV::Set_Complement(output,iii);
+      CONSTANTBV::BitVector_add(output,output,One,&carry);
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      //AARON
+
+      break;
+    }
+    case BVEXTRACT: {
+      string s(BVConstEvaluator(t[0]).GetBVConst());
+      unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
+      unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
+
+      //length of substr to chop
+      unsigned int len = hi-low+1;
+      //distance from MSB
+      hi = s.size()-1 - hi;      
+      string ss = s.substr(hi,len);
+      OutputNode = CreateBVConst(ss.c_str(),2);
+      break;
+    }
+    case BVCONCAT: {
+      string s(BVConstEvaluator(t[0]).GetBVConst());
+      string r(BVConstEvaluator(t[1]).GetBVConst());
+  
+      string q(s+r);
+      OutputNode = CreateBVConst(q.c_str(),2);
+      break;
+    }
+    case BVMULT: {
+      unsigned * output1 = CONSTANTBV::BitVector_Create(2*inputwidth,true);
+      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(output1,iii,jjj);
+      //error printing
+      if(0 != e) {
+	std::string ss("BVConstEvaluator:");
+	ss += (const char*)BitVector_Error(e);	
+	//destroy all the CONSTANTBV bitvectors
+	CONSTANTBV::BitVector_Destroy(iii);
+	CONSTANTBV::BitVector_Destroy(jjj);       
+	CONSTANTBV::BitVector_Destroy(One);
+	CONSTANTBV::BitVector_Destroy(Zero);
+	FatalError(ss.c_str(), t);
+      }
+
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output1);
+      std::string s(cccc);
+
+      //AARON
+      free(cccc);
+      //AARON
+
+      s = s.substr(inputwidth,inputwidth);
+      OutputNode = CreateBVConst(s.c_str(),2);
+      CONSTANTBV::BitVector_Destroy(output1);
+      break;
+    }
+    case BVPLUS: {
+      bool carry = false;
+      ASTVec c = t.GetChildren();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	unsigned int * kk = ConvertToCONSTANTBV(BVConstEvaluator(*it).GetBVConst());
+	CONSTANTBV::BitVector_add(output,output,kk,&carry);
+	carry = false;
+	CONSTANTBV::BitVector_Destroy(kk);
+      }
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      //AARON
+
+      break;
+    }
+    case SBVDIV:
+    case SBVMOD: {
+      OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
+      break;
+    }
+    case BVDIV: {      
+      unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
+      unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
+      // iii is dividend, jjj is the divisor
+      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
+
+      if(0 != e) {
+	//error printing
+	if(counterexample_checking_during_refinement) {
+	  OutputNode = CreateZeroConst(inputwidth);
+	  bvdiv_exception_occured = true;
+	  break;
+	}
+	else {
+	  std::string ss("BVConstEvaluator:");
+	  ss += (const char*)BitVector_Error(e);	
+	  //destroy all the CONSTANTBV bitvectors
+	  CONSTANTBV::BitVector_Destroy(iii);
+	  CONSTANTBV::BitVector_Destroy(jjj);       
+	  CONSTANTBV::BitVector_Destroy(One);
+	  CONSTANTBV::BitVector_Destroy(Zero);
+
+	  //AARON
+	  iii = jjj = One = Zero = NULL;
+	  //AARON
+
+	  FatalError(ss.c_str(), t);
+	}
+      } //end of error printing
+
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(quotient);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      CONSTANTBV::BitVector_Destroy(quotient);
+      CONSTANTBV::BitVector_Destroy(remainder);
+      //AARON
+
+      break;
+    }
+   case BVMOD: {
+      unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
+      unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
+      // iii is dividend, jjj is the divisor
+      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
+
+      if(0 != e) {
+	//error printing
+	if(counterexample_checking_during_refinement) {
+	  OutputNode = CreateZeroConst(inputwidth);
+	  bvdiv_exception_occured = true;
+	  break;
+	}
+	else {
+	  std::string ss("BVConstEvaluator:");
+	  ss += (const char*)BitVector_Error(e);
+	  //destroy all the CONSTANTBV bitvectors
+	  CONSTANTBV::BitVector_Destroy(iii);
+	  CONSTANTBV::BitVector_Destroy(jjj);       
+	  CONSTANTBV::BitVector_Destroy(One);
+	  CONSTANTBV::BitVector_Destroy(Zero);	
+
+	  //AARON
+	  iii = jjj = One = Zero = NULL;
+	  //AARON
+
+	  FatalError(ss.c_str(), t);
+	}
+      } //end of errory printing
+
+      cccc = (char *)CONSTANTBV::BitVector_to_Bin(remainder);
+      OutputNode = CreateBVConst(cccc,2);
+
+      //AARON
+      free(cccc);
+      CONSTANTBV::BitVector_Destroy(quotient);
+      CONSTANTBV::BitVector_Destroy(remainder);
+      //AARON
+
+      break;
+    }
+    case ITE:
+      if(ASTTrue == t[0])
+	OutputNode = BVConstEvaluator(t[1]);
+      else if(ASTFalse == t[0])
+	OutputNode = BVConstEvaluator(t[2]);
+      else
+	FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t);
+      break;
+    case EQ: 
+      if(CONSTANTBV::BitVector_equal(iii,jjj))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case NEQ:
+      if(!CONSTANTBV::BitVector_equal(iii,jjj))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVLT:
+      if(-1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVLE: {
+      int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
+      if(comp <= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVGT:
+      if(1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVGE: {
+      int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
+      if(comp >= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    } 
+    case BVSLT:
+      if(-1 == CONSTANTBV::BitVector_Compare(iii,jjj))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVSLE: {
+      signed int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
+      if(comp <= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    }
+    case BVSGT:
+      if(1 == CONSTANTBV::BitVector_Compare(iii,jjj))
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    case BVSGE: {
+      int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
+      if(comp >= 0)
+	OutputNode = ASTTrue;
+      else
+	OutputNode = ASTFalse;
+      break;
+    } 
+    default:
+      FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
+      break;
+    }
+
+
+
+    // //destroy all the CONSTANTBV bitvectors
+//     CONSTANTBV::BitVector_Destroy(iii);
+//     CONSTANTBV::BitVector_Destroy(jjj);
+//     CONSTANTBV::BitVector_Destroy(output);
+
+//     if(k == BVNEG || k == BVUMINUS)
+//       CONSTANTBV::BitVector_Destroy(One);
+//     else if(k == BVAND   || k == BVOR  || k == BVXOR   || k == BVSUB || 
+// 	    k == BVMULT  || k == EQ    || k == NEQ     || k == BVLT  ||
+// 	    k == BVLE    || k == BVGT  || k == BVGE    || k == BVSLT ||
+// 	    k == BVSLE   || k == BVSGT || k == BVSGE) {
+//       CONSTANTBV::BitVector_Destroy(One);
+//       CONSTANTBV::BitVector_Destroy(Zero);
+//     }    
+
+    //AARON
+    if (output != NULL) CONSTANTBV::BitVector_Destroy(output);
+    if (One != NULL) CONSTANTBV::BitVector_Destroy(One);
+    if (Zero != NULL) CONSTANTBV::BitVector_Destroy(Zero);
+    if (iii != NULL && iii != One) CONSTANTBV::BitVector_Destroy(iii);
+    if (jjj != NULL && jjj != Zero) CONSTANTBV::BitVector_Destroy(jjj);
+    //AARON
+   
+    UpdateSolverMap(t,OutputNode);
+    //UpdateSimplifyMap(t,OutputNode,false);
+    return OutputNode;
+  }
+
+
+  unsigned int * ConvertToCONSTANTBV(const char * s) {
+    unsigned int length = strlen(s);
+    unsigned char * ccc = (unsigned char *)s;
+    unsigned *  iii = CONSTANTBV::BitVector_Create(length,true);
+    CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,ccc);
+    //error printing
+    if(0 != e) {
+      cerr << "ConverToCONSTANTBV: wrong bin value: " << BitVector_Error(e);      
+      FatalError("");
+    }
+    
+    return iii;
+  }
+*/
+}; //end of namespace BEEV
diff --git a/stp/c_interface/Makefile b/stp/c_interface/Makefile
new file mode 100644
index 00000000..cf6b09d1
--- /dev/null
+++ b/stp/c_interface/Makefile
@@ -0,0 +1,13 @@
+include ../Makefile.common
+
+SRCS = c_interface.cpp
+OBJS = $(SRCS:.cpp=.o)
+
+libcinterface.a: $(OBJS)
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+clean:	
+	rm -rf *.o *~ *.a .#*
+
+c_interface.o: c_interface.h
diff --git a/stp/c_interface/c_interface.cpp b/stp/c_interface/c_interface.cpp
new file mode 100644
index 00000000..f4e53114
--- /dev/null
+++ b/stp/c_interface/c_interface.cpp
@@ -0,0 +1,1548 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+#include "c_interface.h"
+
+#include <cstdlib>
+#include <cassert>
+#include <ostream>
+#include <iostream>
+#include "fdstream.h"
+#include "../AST/AST.h"
+
+//These typedefs lower the effort of using the keyboard to type (too
+//many overloaded meanings of the word type)
+typedef BEEV::ASTNode  node;
+typedef BEEV::ASTNode* nodestar;
+typedef BEEV::BeevMgr* bmstar;
+typedef BEEV::ASTVec   nodelist;
+typedef BEEV::CompleteCounterExample* CompleteCEStar;
+BEEV::ASTVec *decls = NULL;
+//vector<BEEV::ASTNode *> created_exprs;
+bool cinterface_exprdelete_on = false;
+
+void vc_setFlags(char c) {
+  std::string helpstring = "Usage: stp [-option] [infile]\n\n";
+  helpstring +=  "-r  : switch refinement off (optimizations are ON by default)\n";
+  helpstring +=  "-w  : switch wordlevel solver off (optimizations are ON by default)\n";
+  helpstring +=  "-a  : switch optimizations off (optimizations are ON by default)\n";
+  helpstring +=  "-s  : print function statistics\n";
+  helpstring +=  "-v  : print nodes \n";
+  helpstring +=  "-c  : construct counterexample\n";
+  helpstring +=  "-d  : check counterexample\n";
+  helpstring +=  "-p  : print counterexample\n";
+  helpstring +=  "-h  : help\n";
+  
+  switch(c) {
+  case 'a' :
+    BEEV::optimize = false;
+    BEEV::wordlevel_solve = false;
+    break;
+  case 'b':
+    BEEV::print_STPinput_back = true;
+    break;
+  case 'c':
+    BEEV::construct_counterexample = true;
+    break;
+  case 'd':
+    BEEV::construct_counterexample = true;
+    BEEV::check_counterexample = true;
+    break;
+  case 'e':
+    BEEV::variable_activity_optimize = true;
+    break;
+  case 'f':
+    BEEV::smtlib_parser_enable = true;
+    break;
+  case 'h':
+    cout << helpstring;
+    BEEV::FatalError("");
+    break;
+  case 'l' :
+    BEEV::linear_search = true;
+    break;
+  case 'n':
+    BEEV::print_output = true;
+    break;
+  case 'p':
+    BEEV::print_counterexample = true;
+    break;
+  case 'q':
+    BEEV::print_arrayval_declaredorder = true;
+    break;
+  case 'r':
+    BEEV::arrayread_refinement = false;
+    break;
+  case 's' :
+    BEEV::stats = true;
+    break;
+  case 'u':
+    BEEV::arraywrite_refinement = true;
+    break;  
+  case 'v' :
+    BEEV::print_nodes = true;
+    break;
+  case 'w':
+    BEEV::wordlevel_solve = false;
+    break;
+  case 'x':
+    cinterface_exprdelete_on = true;
+    break;
+  case 'z':
+    BEEV::print_sat_varorder = true;
+    break;
+  default:
+    std::string s = "C_interface: vc_setFlags: Unrecognized commandline flag:\n";
+    s += helpstring;
+    BEEV::FatalError(s.c_str());
+    break;
+  }
+}
+
+//Create a validity Checker. This is the global BeevMgr
+VC vc_createValidityChecker(void) {
+  vc_setFlags('d');
+#ifdef NATIVE_C_ARITH
+#else
+  CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot(); 
+  if(0 != c) {
+    cout << CONSTANTBV::BitVector_Error(c) << endl;
+    return 0;
+  }
+#endif
+  bmstar bm = new BEEV::BeevMgr();
+  decls = new BEEV::ASTVec();
+  //created_exprs.clear();
+  return (VC)bm;
+}
+
+// Expr I/O
+void vc_printExpr(VC vc, Expr e) {
+  //do not print in lisp mode
+  //bmstar b = (bmstar)vc;
+  BEEV::ASTNode q = (*(nodestar)e);
+  //   b->Begin_RemoveWrites = true;
+  //   BEEV::ASTNode q = b->SimplifyFormula_TopLevel(*((nodestar)e),false);
+  //   b->Begin_RemoveWrites = false;    
+  q.PL_Print(cout);
+}
+
+void vc_printExprFile(VC vc, Expr e, int fd) {
+  fdostream os(fd);
+  ((nodestar)e)->PL_Print(os);
+  //os.flush();
+}
+
+static void vc_printVarDeclsToStream(VC vc, ostream &os) {
+  for(BEEV::ASTVec::iterator i = decls->begin(),iend=decls->end();i!=iend;i++) {
+    node a = *i;
+    switch(a.GetType()) {
+    case BEEV::BITVECTOR_TYPE:
+      a.PL_Print(os);
+      os << " : BITVECTOR(" << a.GetValueWidth() << ");" << endl;
+      break;
+    case BEEV::ARRAY_TYPE:
+      a.PL_Print(os);
+      os << " : ARRAY " << "BITVECTOR(" << a.GetIndexWidth() << ") OF ";
+      os << "BITVECTOR(" << a.GetValueWidth() << ");" << endl;
+      break;
+    case BEEV::BOOLEAN_TYPE:
+      a.PL_Print(os);
+      os << " : BOOLEAN;" << endl;
+      break;
+    default:
+      BEEV::FatalError("vc_printDeclsToStream: Unsupported type",a);
+      break;
+    }
+  }
+}
+
+void vc_printVarDecls(VC vc) {
+  vc_printVarDeclsToStream(vc, cout);
+}
+
+static void vc_printAssertsToStream(VC vc, ostream &os, int simplify_print) {
+  bmstar b = (bmstar)vc;
+  BEEV::ASTVec v = b->GetAsserts();
+  for(BEEV::ASTVec::iterator i=v.begin(),iend=v.end();i!=iend;i++) {
+    b->Begin_RemoveWrites = true;
+    BEEV::ASTNode q = (simplify_print == 1) ? b->SimplifyFormula_TopLevel(*i,false) : *i;
+    q = (simplify_print == 1) ? b->SimplifyFormula_TopLevel(q,false) : q;
+    b->Begin_RemoveWrites = false;
+    os << "ASSERT( ";
+    q.PL_Print(os);
+    os << ");" << endl;
+  }
+}
+
+void vc_printAsserts(VC vc, int simplify_print) {
+  vc_printAssertsToStream(vc, cout, simplify_print);
+}
+
+void vc_printQueryStateToBuffer(VC vc, Expr e, char **buf, unsigned long *len, int simplify_print){
+  assert(vc);
+  assert(e);
+  assert(buf);
+  assert(len);
+  bmstar b = (bmstar)vc;
+
+  // formate the state of the query
+  stringstream os;
+  vc_printVarDeclsToStream(vc, os);
+  os << "%----------------------------------------------------" << endl;
+  vc_printAssertsToStream(vc, os, simplify_print);
+  os << "%----------------------------------------------------" << endl;
+  os << "QUERY( ";
+  b->Begin_RemoveWrites = true;
+  BEEV::ASTNode q = (simplify_print == 1) ? b->SimplifyFormula_TopLevel(*((nodestar)e),false) : *(nodestar)e;
+  b->Begin_RemoveWrites = false;    
+  q.PL_Print(os);
+  os << " );" << endl;
+
+  // convert to a c buffer
+  string s = os.str();
+  const char *cstr = s.c_str();
+  unsigned long size = s.size() + 1; // number of chars + terminating null
+  *buf = (char *)malloc(size);
+  if (!(*buf)) {
+    fprintf(stderr, "malloc(%lu) failed.", size);
+    assert(*buf);
+  }
+  *len = size;
+  memcpy(*buf, cstr, size);
+}
+
+void vc_printCounterExampleToBuffer(VC vc, char **buf, unsigned long *len) {
+  assert(vc);
+  assert(buf);
+  assert(len);
+  bmstar b = (bmstar)vc;
+
+  // formate the state of the query
+  std::ostringstream os;
+  BEEV::print_counterexample = true;
+  os << "COUNTEREXAMPLE BEGIN: \n";
+  b->PrintCounterExample(true,os);
+  os << "COUNTEREXAMPLE END: \n";
+
+  // convert to a c buffer
+  string s = os.str();
+  const char *cstr = s.c_str();
+  unsigned long size = s.size() + 1; // number of chars + terminating null
+  *buf = (char *)malloc(size);
+  if (!(*buf)) {
+    fprintf(stderr, "malloc(%lu) failed.", size);
+    assert(*buf);
+  }
+  *len = size;
+  memcpy(*buf, cstr, size);
+}
+
+void vc_printExprToBuffer(VC vc, Expr e, char **buf, unsigned long * len) {
+  stringstream os;
+  //bmstar b = (bmstar)vc;
+  BEEV::ASTNode q = *((nodestar)e);
+  // b->Begin_RemoveWrites = true;
+  //   BEEV::ASTNode q = b->SimplifyFormula_TopLevel(*((nodestar)e),false);
+  //   b->Begin_RemoveWrites = false;    
+  q.PL_Print(os);
+  //((nodestar)e)->PL_Print(os);
+  string s = os.str();
+  const char * cstr = s.c_str();
+  unsigned long size = s.size() + 1; // number of chars + terminating null
+  *buf = (char *)malloc(size);
+  *len = size;
+  memcpy(*buf, cstr, size);
+}
+
+void vc_printQuery(VC vc){
+  ostream& os = std::cout;
+  bmstar b = (bmstar)vc;
+  os << "QUERY(";
+  //b->Begin_RemoveWrites = true;
+  //BEEV::ASTNode q = b->SimplifyFormula_TopLevel(b->GetQuery(),false);
+  BEEV::ASTNode q = b->GetQuery();
+  //b->Begin_RemoveWrites = false;    
+  q.PL_Print(os);
+  // b->GetQuery().PL_Print(os);
+  os << ");" << endl;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Array-related methods                                                   //
+/////////////////////////////////////////////////////////////////////////////
+//! Create an array type
+Type vc_arrayType(VC vc, Type typeIndex, Type typeData) {
+  bmstar b = (bmstar)vc;
+  nodestar ti = (nodestar)typeIndex;
+  nodestar td = (nodestar)typeData;
+
+  if(!(ti->GetKind() == BEEV::BITVECTOR && (*ti)[0].GetKind() == BEEV::BVCONST))
+    BEEV::FatalError("Tyring to build array whose indextype i is not a BITVECTOR, where i = ",*ti);
+  if(!(td->GetKind()  == BEEV::BITVECTOR && (*td)[0].GetKind() == BEEV::BVCONST))
+    BEEV::FatalError("Trying to build an array whose valuetype v is not a BITVECTOR. where a = ",*td);
+  nodestar output = new node(b->CreateNode(BEEV::ARRAY,(*ti)[0],(*td)[0]));
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return (Type)output;
+}
+
+//! Create an expression for the value of array at the given index
+Expr vc_readExpr(VC vc, Expr array, Expr index) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)array;
+  nodestar i = (nodestar)index;
+  
+  b->BVTypeCheck(*a);
+  b->BVTypeCheck(*i);
+  node o = b->CreateTerm(BEEV::READ,a->GetValueWidth(),*a,*i);
+  b->BVTypeCheck(o);
+
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+// //! Array update; equivalent to "array WITH [index] := newValue"
+Expr vc_writeExpr(VC vc, Expr array, Expr index, Expr newValue) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)array;
+  nodestar i = (nodestar)index;
+  nodestar n = (nodestar)newValue;
+
+  b->BVTypeCheck(*a);
+  b->BVTypeCheck(*i);
+  b->BVTypeCheck(*n);
+  node o = b->CreateTerm(BEEV::WRITE,a->GetValueWidth(),*a,*i,*n);
+  o.SetIndexWidth(a->GetIndexWidth());
+  b->BVTypeCheck(o);
+
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Context-related methods                                                 //
+/////////////////////////////////////////////////////////////////////////////
+//! Assert a new formula in the current context.  
+/*! The formula must have Boolean type. */
+void vc_assertFormula(VC vc, Expr e) {
+  nodestar a = (nodestar)e;
+  bmstar b = (bmstar)vc;
+
+  if(!BEEV::is_Form_kind(a->GetKind()))
+    BEEV::FatalError("Trying to assert a NON formula: ",*a);
+
+  b->BVTypeCheck(*a);
+  b->AddAssert(*a);
+}
+
+//! Check validity of e in the current context.
+/*!  If the result is true, then the resulting context is the same as
+ * the starting context.  If the result is false, then the resulting
+ * context is a context in which e is false.  e must have Boolean
+ * type. */
+int vc_query(VC vc, Expr e) {
+  nodestar a = (nodestar)e;
+  bmstar b = (bmstar)vc;
+
+ if(!BEEV::is_Form_kind(a->GetKind()))
+    BEEV::FatalError("CInterface: Trying to QUERY a NON formula: ",*a);
+
+  b->BVTypeCheck(*a);
+  b->AddQuery(*a);
+
+  const BEEV::ASTVec v = b->GetAsserts();
+  node o;
+  if(!v.empty()) {
+    if(v.size()==1)
+      return b->TopLevelSAT(v[0],*a);
+    else 
+      return b->TopLevelSAT(b->CreateNode(BEEV::AND,v),*a);
+  }
+  else
+    return b->TopLevelSAT(b->CreateNode(BEEV::TRUE),*a);
+}
+
+void vc_push(VC vc) {
+  bmstar b = (bmstar)vc;
+  b->ClearAllCaches();
+  b->Push();
+}
+
+void vc_pop(VC vc) {
+  bmstar b = (bmstar)vc;
+  b->Pop();
+}
+
+void vc_printCounterExample(VC vc) {
+  bmstar b = (bmstar)vc;
+  BEEV::print_counterexample = true;    
+  cout << "COUNTEREXAMPLE BEGIN: \n";
+  b->PrintCounterExample(true);
+  cout << "COUNTEREXAMPLE END: \n";
+}
+
+// //! Return the counterexample after a failed query.
+// /*! This method should only be called after a query which returns
+//  * false.  It will try to return the simplest possible set of
+//  * assertions which are sufficient to make the queried expression
+//  * false.  The caller is responsible for freeing the array when
+//  * finished with it.
+//  */
+
+Expr vc_getCounterExample(VC vc, Expr e) {
+  nodestar a = (nodestar)e;
+  bmstar b = (bmstar)vc;    
+
+  bool t = false;
+  if(b->CounterExampleSize())
+    t = true;
+  nodestar output = new node(b->GetCounterExample(t, *a));  
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+int vc_counterexample_size(VC vc) {
+  bmstar b = (bmstar)vc;
+  return b->CounterExampleSize();
+}
+
+WholeCounterExample vc_getWholeCounterExample(VC vc) {
+  bmstar b = (bmstar)vc;
+  CompleteCEStar c = 
+    new BEEV::CompleteCounterExample(b->GetCompleteCounterExample(), b);
+  return c;
+}
+
+Expr vc_getTermFromCounterExample(VC vc, Expr e, CompleteCEStar cc) {
+  //bmstar b = (bmstar)vc;
+  nodestar n = (nodestar)e;
+  CompleteCEStar c = (CompleteCEStar)cc;
+
+  nodestar output = new node(c->GetCounterExample(*n));
+  return output;
+}
+
+int vc_getBVLength(VC vc, Expr ex) {
+  nodestar e = (nodestar)ex;
+
+  if(BEEV::BITVECTOR_TYPE != e->GetType()) {
+    BEEV::FatalError("c_interface: vc_GetBVLength: Input expression must be a bit-vector");
+  }
+
+  return e->GetValueWidth();
+} // end of vc_getBVLength
+
+/////////////////////////////////////////////////////////////////////////////
+// Expr Creation methods                                                   //
+/////////////////////////////////////////////////////////////////////////////
+//! Create a variable with a given name and type 
+/*! The type cannot be a function type. */
+Expr vc_varExpr1(VC vc, char* name, 
+		int indexwidth, int valuewidth) {
+  bmstar b = (bmstar)vc;
+
+  node o = b->CreateSymbol(name);
+  o.SetIndexWidth(indexwidth);
+  o.SetValueWidth(valuewidth);
+  
+  nodestar output = new node(o);
+  ////if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  b->BVTypeCheck(*output);
+
+  //store the decls in a vector for printing purposes
+  decls->push_back(o);
+  return output;
+}
+
+Expr vc_varExpr(VC vc, char * name, Type type) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)type;
+
+  node o = b->CreateSymbol(name);
+  switch(a->GetKind()) {
+  case BEEV::BITVECTOR:
+    o.SetIndexWidth(0);
+    o.SetValueWidth(GetUnsignedConst((*a)[0]));
+    break;
+  case BEEV::ARRAY:
+    o.SetIndexWidth(GetUnsignedConst((*a)[0]));
+    o.SetValueWidth(GetUnsignedConst((*a)[1]));
+    break;
+  case BEEV::BOOLEAN:
+    o.SetIndexWidth(0);
+    o.SetValueWidth(0);
+    break;
+  default:
+    BEEV::FatalError("CInterface: vc_varExpr: Unsupported type",*a);
+    break;
+  }
+  nodestar output = new node(o);
+  ////if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  b->BVTypeCheck(*output);
+
+  //store the decls in a vector for printing purposes
+  decls->push_back(o);
+  return output;
+}
+
+//! Create an equality expression.  The two children must have the
+//same type.
+Expr vc_eqExpr(VC vc, Expr ccc0, Expr ccc1) {
+  bmstar b = (bmstar)vc;
+
+  nodestar a = (nodestar)ccc0;
+  nodestar aa = (nodestar)ccc1;
+  b->BVTypeCheck(*a);
+  b->BVTypeCheck(*aa);
+  node o = b->CreateNode(BEEV::EQ,*a,*aa);
+
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_boolType(VC vc) {
+  bmstar b = (bmstar)vc;
+
+  node o = b->CreateNode(BEEV::BOOLEAN);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// BOOLEAN EXPR Creation methods                                           //
+/////////////////////////////////////////////////////////////////////////////
+// The following functions create Boolean expressions.  The children
+// provided as arguments must be of type Boolean.
+Expr vc_trueExpr(VC vc) {
+  bmstar b = (bmstar)vc;
+  node c = b->CreateNode(BEEV::TRUE);
+  
+  nodestar d = new node(c);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(d);
+  return d;
+}
+
+Expr vc_falseExpr(VC vc) {
+  bmstar b = (bmstar)vc;
+  node c = b->CreateNode(BEEV::FALSE);
+  
+  nodestar d = new node(c);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(d);
+  return d;
+}
+
+Expr vc_notExpr(VC vc, Expr ccc) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+  
+  node o = b->CreateNode(BEEV::NOT,*a);
+  b->BVTypeCheck(o);
+
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_andExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+  
+  node o = b->CreateNode(BEEV::AND,*l,*r);
+  b->BVTypeCheck(o);
+
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_orExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  node o = b->CreateNode(BEEV::OR,*l,*r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_andExprN(VC vc, Expr* cc, int n) {
+  bmstar b = (bmstar)vc;
+  nodestar * c = (nodestar *)cc;
+  nodelist d;
+  
+  for(int i =0; i < n; i++)
+    d.push_back(*c[i]);
+  
+  node o = b->CreateNode(BEEV::AND,d);
+  b->BVTypeCheck(o);
+
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+
+Expr vc_orExprN(VC vc, Expr* cc, int n) {
+  bmstar b = (bmstar)vc;
+  nodestar * c = (nodestar *)cc;
+  nodelist d;
+  
+  for(int i =0; i < n; i++)
+    d.push_back(*c[i]);
+  
+  node o = b->CreateNode(BEEV::OR,d);
+  b->BVTypeCheck(o);
+
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_iteExpr(VC vc, Expr cond, Expr thenpart, Expr elsepart){
+  bmstar b = (bmstar)vc;
+  nodestar c = (nodestar)cond;
+  nodestar t = (nodestar)thenpart;
+  nodestar e = (nodestar)elsepart;
+  
+  b->BVTypeCheck(*c);
+  b->BVTypeCheck(*t);
+  b->BVTypeCheck(*e);
+  node o;
+  //if the user asks for a formula then produce a formula, else
+  //prodcue a term
+  if(BEEV::BOOLEAN_TYPE == t->GetType())
+    o = b->CreateNode(BEEV::ITE,*c,*t,*e);
+  else {
+    o = b->CreateTerm(BEEV::ITE,t->GetValueWidth(),*c,*t,*e);
+    o.SetIndexWidth(t->GetIndexWidth());
+  }
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_impliesExpr(VC vc, Expr antecedent, Expr consequent){
+  bmstar b = (bmstar)vc;
+  nodestar c = (nodestar)antecedent;
+  nodestar t = (nodestar)consequent;
+  
+  b->BVTypeCheck(*c);
+  b->BVTypeCheck(*t);
+  node o;
+
+  o = b->CreateNode(BEEV::IMPLIES,*c,*t);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_iffExpr(VC vc, Expr e0, Expr e1){
+  bmstar b = (bmstar)vc;
+  nodestar c = (nodestar)e0;
+  nodestar t = (nodestar)e1;
+  
+  b->BVTypeCheck(*c);
+  b->BVTypeCheck(*t);
+  node o;
+
+  o = b->CreateNode(BEEV::IFF,*c,*t);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_boolToBVExpr(VC vc, Expr form) {
+  bmstar b = (bmstar)vc;
+  nodestar c = (nodestar)form;
+  
+  b->BVTypeCheck(*c);
+  if(!is_Form_kind(c->GetKind()))
+    BEEV::FatalError("CInterface: vc_BoolToBVExpr: You have input a NON formula:",*c);
+  
+  node o;
+  node one = b->CreateOneConst(1); 
+  node zero = b->CreateZeroConst(1);  
+  o = b->CreateTerm(BEEV::ITE,1,*c,one,zero);
+
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// BITVECTOR EXPR Creation methods                                         //
+/////////////////////////////////////////////////////////////////////////////
+Type vc_bvType(VC vc, int num_bits) {
+  bmstar b = (bmstar)vc;
+  
+  if(!(0 < num_bits))
+    BEEV::FatalError("CInterface: number of bits in a bvtype must be a positive integer:", 
+		     b->CreateNode(BEEV::UNDEFINED));
+
+  node e = b->CreateBVConst(32, num_bits);
+  nodestar output = new node(b->CreateNode(BEEV::BITVECTOR,e));
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Type vc_bv32Type(VC vc) {
+  return vc_bvType(vc,32);
+}
+
+
+Expr vc_bvConstExprFromStr(VC vc, char* binary_repr) {
+  bmstar b = (bmstar)vc;
+
+  node n = b->CreateBVConst(binary_repr,2);
+  b->BVTypeCheck(n);
+  nodestar output = new node(n);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvConstExprFromInt(VC vc,
+			   int n_bits, 
+			   unsigned int value) {
+  bmstar b = (bmstar)vc;
+
+  unsigned long long int v = (unsigned long long int)value;
+  node n = b->CreateBVConst(n_bits, v);
+  b->BVTypeCheck(n);
+  nodestar output = new node(n);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvConstExprFromLL(VC vc,
+			  int n_bits, 
+			  unsigned long long value) {
+  bmstar b = (bmstar)vc;
+  
+  node n = b->CreateBVConst(n_bits, value);
+  b->BVTypeCheck(n);
+  nodestar output = new node(n);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvConcatExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o =
+    b->CreateTerm(BEEV::BVCONCAT,
+		  l->GetValueWidth()+ r->GetValueWidth(),*l,*r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvPlusExpr(VC vc, int n_bits, Expr left, Expr right){
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVPLUS,n_bits, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+
+Expr vc_bv32PlusExpr(VC vc, Expr left, Expr right) {
+  return vc_bvPlusExpr(vc, 32, left, right);
+}
+
+
+Expr vc_bvMinusExpr(VC vc, int n_bits, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVSUB,n_bits, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+
+Expr vc_bv32MinusExpr(VC vc, Expr left, Expr right) {
+  return vc_bvMinusExpr(vc, 32, left, right);
+}
+
+
+Expr vc_bvMultExpr(VC vc, int n_bits, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVMULT,n_bits, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvDivExpr(VC vc, int n_bits, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVDIV,n_bits, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvModExpr(VC vc, int n_bits, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVMOD,n_bits, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_sbvDivExpr(VC vc, int n_bits, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::SBVDIV,n_bits, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_sbvModExpr(VC vc, int n_bits, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::SBVMOD,n_bits, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bv32MultExpr(VC vc, Expr left, Expr right) {
+  return vc_bvMultExpr(vc, 32, left, right);
+}
+
+
+// unsigned comparators
+Expr vc_bvLtExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVLT, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvLeExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVLE, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvGtExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVGT, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvGeExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVGE, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+// signed comparators
+Expr vc_sbvLtExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVSLT, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_sbvLeExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVSLE, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_sbvGtExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVSGT, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_sbvGeExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateNode(BEEV::BVSGE, *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvUMinusExpr(VC vc, Expr ccc) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+  b->BVTypeCheck(*a);
+
+  node o = b->CreateTerm(BEEV::BVUMINUS, a->GetValueWidth(), *a);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+// bitwise operations: these are terms not formulas
+Expr vc_bvAndExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVAND, (*l).GetValueWidth(), *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvOrExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVOR, (*l).GetValueWidth(), *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvXorExpr(VC vc, Expr left, Expr right) {
+  bmstar b = (bmstar)vc;
+  nodestar l = (nodestar)left;
+  nodestar r = (nodestar)right;
+
+  b->BVTypeCheck(*l);
+  b->BVTypeCheck(*r);
+  node o = b->CreateTerm(BEEV::BVXOR, (*l).GetValueWidth(), *l, *r);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvNotExpr(VC vc, Expr ccc) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+
+  b->BVTypeCheck(*a);
+  node o = b->CreateTerm(BEEV::BVNEG, a->GetValueWidth(), *a);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvLeftShiftExpr(VC vc, int sh_amt, Expr ccc) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+  b->BVTypeCheck(*a);
+
+  //convert leftshift to bvconcat
+  if(0 != sh_amt) {
+    node len = b->CreateBVConst(sh_amt, 0);
+    node o = b->CreateTerm(BEEV::BVCONCAT, a->GetValueWidth() + sh_amt, *a, len);
+    b->BVTypeCheck(o);
+    nodestar output = new node(o);
+    //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+    return output;
+  }
+  else
+    return a;
+}
+
+Expr vc_bvRightShiftExpr(VC vc, int sh_amt, Expr ccc) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+  b->BVTypeCheck(*a);
+  
+  unsigned int w = a->GetValueWidth();  
+  //the amount by which you are rightshifting
+  //is less-than/equal-to the length of input
+  //bitvector  
+  if(0 < (unsigned)sh_amt && (unsigned)sh_amt <= w) {
+    node len = b->CreateBVConst(sh_amt, 0);
+    node hi = b->CreateBVConst(32,w-1);
+    node low = b->CreateBVConst(32,sh_amt);
+    node extract = b->CreateTerm(BEEV::BVEXTRACT,w-sh_amt,*a,hi,low);
+
+    node n = b->CreateTerm(BEEV::BVCONCAT, w,len, extract);
+    b->BVTypeCheck(n);
+    nodestar output = new node(n);
+    //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+    return output;
+  }
+  else if(sh_amt == 0)
+    return a;
+  else {
+    if(0== w)
+      BEEV::FatalError("CInterface: vc_bvRightShiftExpr: cannot have a bitvector of length 0:",*a);
+    nodestar output = new node(b->CreateBVConst(w,0));
+    //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+    return output;
+  }
+}
+
+/* Same as vc_bvLeftShift only that the answer in 32 bits long */
+Expr vc_bv32LeftShiftExpr(VC vc, int sh_amt, Expr child) {
+  return vc_bvExtract(vc, vc_bvLeftShiftExpr(vc, sh_amt, child), 31, 0);
+}
+
+/* Same as vc_bvRightShift only that the answer in 32 bits long */
+Expr vc_bv32RightShiftExpr(VC vc, int sh_amt, Expr child) {
+  return vc_bvExtract(vc, vc_bvRightShiftExpr(vc, sh_amt, child), 31, 0);
+}
+
+
+Expr vc_bvVar32LeftShiftExpr(VC vc, Expr sh_amt, Expr child) {
+  Expr ifpart;
+  Expr thenpart;
+  Expr elsepart = vc_trueExpr(vc);
+  Expr ite = vc_trueExpr(vc);
+
+  for(int count=32; count >= 0; count--){
+    if(count != 32) {
+      ifpart = vc_eqExpr(vc, sh_amt, 
+			 vc_bvConstExprFromInt(vc, 32, count));
+      thenpart = vc_bvExtract(vc,
+			      vc_bvLeftShiftExpr(vc, count, child),
+			      31, 0);
+
+      ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
+      elsepart = ite;
+    } 
+    else
+      elsepart = vc_bvConstExprFromInt(vc,32, 0);    
+  }  
+  return ite;  
+}
+
+Expr vc_bvVar32DivByPowOfTwoExpr(VC vc, Expr child, Expr rhs) {
+  Expr ifpart;
+  Expr thenpart;
+  Expr elsepart = vc_trueExpr(vc);
+  Expr ite = vc_trueExpr(vc);
+
+  for(int count=32; count >= 0; count--){
+    if(count != 32) {
+      ifpart = vc_eqExpr(vc, rhs, 
+			 vc_bvConstExprFromInt(vc, 32, 1 << count));      
+      thenpart = vc_bvRightShiftExpr(vc, count, child);      
+      ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
+      elsepart = ite;
+    } else {
+      elsepart = vc_bvConstExprFromInt(vc,32, 0);
+    }    
+  }  
+  return ite;  
+}
+
+Expr vc_bvVar32RightShiftExpr(VC vc, Expr sh_amt, Expr child) {
+  Expr ifpart;
+  Expr thenpart;
+  Expr elsepart = vc_trueExpr(vc);
+  Expr ite = vc_trueExpr(vc);
+
+  for(int count=32; count >= 0; count--){
+    if(count != 32) {
+      ifpart = vc_eqExpr(vc, sh_amt, 
+			 vc_bvConstExprFromInt(vc, 32, count));      
+      thenpart = vc_bvRightShiftExpr(vc, count, child);      
+      ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
+      elsepart = ite;
+    } else {
+      elsepart = vc_bvConstExprFromInt(vc,32, 0);
+    }    
+  }  
+  return ite;  
+}
+
+Expr vc_bvExtract(VC vc, Expr ccc, int hi_num, int low_num) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+  b->BVTypeCheck(*a);
+
+  node hi = b->CreateBVConst(32,hi_num);
+  node low = b->CreateBVConst(32,low_num);
+  node o = b->CreateTerm(BEEV::BVEXTRACT,hi_num-low_num+1,*a,hi,low);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+Expr vc_bvBoolExtract(VC vc, Expr ccc, int bit_num) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+  b->BVTypeCheck(*a);
+
+  node bit = b->CreateBVConst(32,bit_num);
+  //node o = b->CreateNode(BEEV::BVGETBIT,*a,bit);  
+  node zero = b->CreateBVConst(1,0);
+  node oo = b->CreateTerm(BEEV::BVEXTRACT,1,*a,bit,bit);
+  node o = b->CreateNode(BEEV::EQ,oo,zero);
+  b->BVTypeCheck(o);
+  nodestar output = new node(o);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output; 
+}
+
+Expr vc_bvSignExtend(VC vc, Expr ccc, int nbits) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)ccc;
+  
+  //width of the expr which is being sign extended. nbits is the
+  //resulting length of the signextended expr
+  b->BVTypeCheck(*a);
+  
+  unsigned exprlen = a->GetValueWidth();
+  unsigned outputlen = nbits;
+  node n;
+  if(exprlen >= outputlen) {
+    //extract
+    node hi = b->CreateBVConst(32,outputlen-1);
+    node low = b->CreateBVConst(32,0);
+    n = b->CreateTerm(BEEV::BVEXTRACT,nbits,*a,hi,low);
+    b->BVTypeCheck(n);
+  }
+  else {
+    //sign extend
+    BEEV::ASTNode width = b->CreateBVConst(32,nbits);
+    n = b->CreateTerm(BEEV::BVSX,nbits,*a, width);
+  }
+
+  b->BVTypeCheck(n);
+  nodestar output = new node(n);
+  //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+  return output;
+}
+
+//! Return an int from a constant bitvector expression
+int getBVInt(Expr e) {
+  //bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)e;
+
+  if(BEEV::BVCONST != a->GetKind())
+    BEEV::FatalError("CInterface: getBVInt: Attempting to extract int value from a NON-constant BITVECTOR: ",*a);
+  return (int)GetUnsignedConst(*a);
+}
+
+//! Return an unsigned int from a constant bitvector expression
+unsigned int getBVUnsigned(Expr e) {
+  //bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)e;
+
+  if(BEEV::BVCONST != a->GetKind())
+    BEEV::FatalError("getBVUnsigned: Attempting to extract int value from a NON-constant BITVECTOR: ",*a);
+  return (unsigned int)GetUnsignedConst(*a);
+}
+
+//! Return an unsigned long long int from a constant bitvector expression
+unsigned long long int getBVUnsignedLongLong(Expr e) {
+  //bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)e;
+
+  if(BEEV::BVCONST != a->GetKind())
+    BEEV::FatalError("getBVUnsigned: Attempting to extract int value from a NON-constant BITVECTOR: ",*a);
+#ifdef NATIVE_C_ARITH
+  return (unsigned long long int)a->GetBVConst();
+#else
+  unsigned* bv = a->GetBVConst();
+
+  char * str_bv  = (char *)CONSTANTBV::BitVector_to_Bin(bv);
+  unsigned long long int tmp = strtoull(str_bv,NULL,2);
+  CONSTANTBV::BitVector_Dispose((unsigned char *)str_bv);
+  return tmp;
+#endif
+}
+
+
+Expr vc_simplify(VC vc, Expr e) {
+  bmstar b = (bmstar)vc;
+  nodestar a = (nodestar)e;
+
+  if(BEEV::BOOLEAN_TYPE == a->GetType()) {
+    nodestar output = new node(b->SimplifyFormula_TopLevel(*a,false));
+    //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+    b->Begin_RemoveWrites = true;
+    output = new node(b->SimplifyFormula_TopLevel(*output,false));
+    b->Begin_RemoveWrites = false;
+    return output;    
+  }
+  else {
+    nodestar output = new node(b->SimplifyTerm(*a));
+    //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+    b->Begin_RemoveWrites = true;
+    output = new node(b->SimplifyTerm(*output));
+    b->Begin_RemoveWrites = false;
+    return output;
+  }
+}
+
+/* C pointer support: C interface to support C memory arrays in CVCL */
+Expr vc_bvCreateMemoryArray(VC vc, char * arrayName) {
+  Type bv8  = vc_bvType(vc,8);
+  Type bv32 = vc_bvType(vc,32);
+  
+  Type malloced_mem0 = vc_arrayType(vc,bv32,bv8);
+  return vc_varExpr(vc, arrayName, malloced_mem0);
+}
+
+Expr vc_bvReadMemoryArray(VC vc, 
+			  Expr array, 
+			  Expr byteIndex, int numOfBytes) {
+  if(!(numOfBytes > 0))
+    BEEV::FatalError("numOfBytes must be greater than 0");
+
+  if(numOfBytes == 1)
+    return vc_readExpr(vc,array,byteIndex);
+  else {
+    int count = 1;
+    Expr a = vc_readExpr(vc,array,byteIndex);
+    while(--numOfBytes > 0) {
+      Expr b = vc_readExpr(vc,array,
+			   /*vc_simplify(vc, */
+				       vc_bvPlusExpr(vc, 32, 
+						     byteIndex,
+						     vc_bvConstExprFromInt(vc,32,count)))/*)*/;
+      a = vc_bvConcatExpr(vc,b,a);
+      count++;
+    }
+    return a;
+  }    
+}
+
+Expr vc_bvWriteToMemoryArray(VC vc, 
+			     Expr array, Expr byteIndex, 
+			     Expr element, int numOfBytes) {
+  if(!(numOfBytes > 0))
+    BEEV::FatalError("numOfBytes must be greater than 0");
+	    
+  int newBitsPerElem = numOfBytes*8;
+  if(numOfBytes == 1)
+    return vc_writeExpr(vc, array, byteIndex, element);
+  else {
+    int count = 1;
+    int hi = newBitsPerElem - 1;
+    int low = newBitsPerElem - 8;
+    int low_elem = 0;
+    int hi_elem = low_elem + 7;
+    Expr c = vc_bvExtract(vc, element, hi_elem, low_elem);
+    Expr newarray = vc_writeExpr(vc, array, byteIndex, c);
+    while(--numOfBytes > 0) {
+      hi = low-1;
+      low = low-8;      
+
+      low_elem = low_elem + 8;
+      hi_elem = low_elem + 7;
+
+      c = vc_bvExtract(vc, element, hi_elem, low_elem);
+      newarray = 
+	vc_writeExpr(vc, newarray,
+		     vc_bvPlusExpr(vc, 32, byteIndex, vc_bvConstExprFromInt(vc,32,count)),
+		     c);
+      count++;
+    }
+    return newarray;
+  }    
+}
+
+Expr vc_bv32ConstExprFromInt(VC vc, unsigned int value){
+  return vc_bvConstExprFromInt(vc, 32, value);
+}
+
+
+#if 0
+static char *val_to_binary_str(unsigned nbits, unsigned long long val) {
+        char s[65];
+
+	assert(nbits < sizeof s);
+        strcpy(s, "");
+        while(nbits-- > 0) {
+                if((val >> nbits) & 1)
+                        strcat(s, "1");
+                else
+                        strcat(s, "0");
+        }
+        return strdup(s);
+}
+#endif
+
+char* exprString(Expr e){
+  stringstream ss;
+  ((nodestar)e)->PL_Print(ss,0);
+  string s = ss.str();
+  char *copy = strdup(s.c_str());
+  return copy;
+}
+
+char* typeString(Type t){
+  stringstream ss;
+  ((nodestar)t)->PL_Print(ss,0);
+
+  string s = ss.str();
+  char *copy = strdup(s.c_str());
+  return copy;
+}
+
+Expr getChild(Expr e, int i){
+  nodestar a = (nodestar)e;
+
+  BEEV::ASTVec c = a->GetChildren();
+  if(0 <=  (unsigned)i && (unsigned)i < c.size()) {
+    BEEV::ASTNode o = c[i];
+    nodestar output = new node(o);
+    //if(cinterface_exprdelete_on) created_exprs.push_back(output);
+    return output;
+  }
+  else 
+    BEEV::FatalError("getChild: Error accessing childNode in expression: ",*a);
+  return a;
+}
+
+void vc_registerErrorHandler(void (*error_hdlr)(const char* err_msg)) {
+  BEEV::vc_error_hdlr = error_hdlr;
+}
+
+
+int vc_getHashQueryStateToBuffer(VC vc, Expr query) {
+  assert(vc);
+  assert(query);
+  bmstar b = (bmstar)vc;
+  nodestar qry = (nodestar)query;
+  BEEV::ASTVec v = b->GetAsserts(); 
+  BEEV::ASTNode out = b->CreateNode(BEEV::AND,b->CreateNode(BEEV::NOT,*qry),v);
+  return out.Hash();
+}
+
+Type vc_getType(VC vc, Expr ex) {
+  nodestar e = (nodestar)ex;
+
+  switch(e->GetType()) {
+  case BEEV::BOOLEAN_TYPE:
+    return vc_boolType(vc);
+    break;      
+  case BEEV::BITVECTOR_TYPE:
+    return vc_bvType(vc,e->GetValueWidth());
+    break;
+  case BEEV::ARRAY_TYPE: {
+    Type typeindex = vc_bvType(vc,e->GetIndexWidth());
+    Type typedata = vc_bvType(vc,e->GetValueWidth());
+    return vc_arrayType(vc,typeindex,typedata);
+    break;
+  }
+  default:
+    BEEV::FatalError("c_interface: vc_GetType: expression with bad typing: please check your expression construction");
+    return vc_boolType(vc);
+    break;
+  }
+}// end of vc_gettype()
+
+//!if e is TRUE then return 1; if e is FALSE then return 0; otherwise
+//return -1
+int vc_isBool(Expr e) {
+  nodestar input = (nodestar)e;
+  if(BEEV::TRUE == input->GetKind()) {
+    return 1;
+  }
+
+  if(BEEV::FALSE == input->GetKind()) {
+    return 0;
+  }
+
+  return -1;
+}
+
+void vc_Destroy(VC vc) {
+  bmstar b = (bmstar)vc;
+  // for(std::vector<BEEV::ASTNode *>::iterator it=created_exprs.begin(),
+  // 	itend=created_exprs.end();it!=itend;it++) {
+  //     BEEV::ASTNode * aaa = *it;
+  //     delete aaa;
+  //   }
+  delete decls;
+  delete b;
+}
+
+void vc_DeleteExpr(Expr e) {
+  nodestar input = (nodestar)e;
+  //bmstar b = (bmstar)vc;
+  delete input;
+}
+
+exprkind_t getExprKind(Expr e) {
+  nodestar input = (nodestar)e;
+  return (exprkind_t)(input->GetKind());  
+}
+
+int getDegree (Expr e) {
+  nodestar input = (nodestar)e;
+  return input->Degree();
+}
+
+int getBVLength(Expr ex) {
+  nodestar e = (nodestar)ex;
+
+  if(BEEV::BITVECTOR_TYPE != e->GetType()) {
+    BEEV::FatalError("c_interface: vc_GetBVLength: Input expression must be a bit-vector");
+  }
+
+  return e->GetValueWidth();
+} 
+
+type_t getType (Expr ex) {
+  nodestar e = (nodestar)ex;
+    
+  return (type_t)(e->GetType());
+}
+
+int getVWidth (Expr ex) {
+  nodestar e = (nodestar)ex;
+
+  return e->GetValueWidth();
+}
+
+int getIWidth (Expr ex) {
+  nodestar e = (nodestar)ex;
+
+  return e->GetIndexWidth();
+}
+
+void vc_printCounterExampleFile(VC vc, int fd) {
+  fdostream os(fd);
+  bmstar b = (bmstar)vc;
+  BEEV::print_counterexample = true;    
+  os << "COUNTEREXAMPLE BEGIN: \n";
+  b->PrintCounterExample(true, os);
+  os << "COUNTEREXAMPLE END: \n";
+}
+
+const char* exprName(Expr e){
+    return ((nodestar)e)->GetName();
+}
+
+int getExprID (Expr ex) {
+    BEEV::ASTNode q = (*(nodestar)ex);
+
+    return q.GetNodeNum();
+}
diff --git a/stp/c_interface/c_interface.h b/stp/c_interface/c_interface.h
new file mode 100644
index 00000000..a2fa8cd7
--- /dev/null
+++ b/stp/c_interface/c_interface.h
@@ -0,0 +1,401 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * License to use, copy, modify, sell and/or distribute this software
+ * and its documentation for any purpose is hereby granted without
+ * royalty, subject to the terms and conditions defined in the \ref
+ * LICENSE file provided with this distribution.  In particular:
+ *
+ * - The above copyright notice and this permission notice must appear
+ * in all copies of the software and related documentation.
+ *
+ * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
+ * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
+ ********************************************************************/
+// -*- c++ -*-
+#ifndef _cvcl__include__c_interface_h_
+#define _cvcl__include__c_interface_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+#ifdef STP_STRONG_TYPING
+#else
+  //This gives absolutely no pointer typing at compile-time. Most C
+  //users prefer this over stronger typing. User is the king. A
+  //stronger typed interface is in the works.
+  typedef void* VC;
+  typedef void* Expr;
+  typedef void* Type;
+  typedef void* WholeCounterExample;
+#endif
+
+  // o  : optimizations
+  // c  : check counterexample
+  // p  : print counterexample
+  // h  : help
+  // s  : stats
+  // v  : print nodes
+  void vc_setFlags(char c);
+  
+  //! Flags can be NULL
+  VC vc_createValidityChecker(void);
+  
+  // Basic types
+  Type vc_boolType(VC vc);
+  
+  //! Create an array type
+  Type vc_arrayType(VC vc, Type typeIndex, Type typeData);
+
+  /////////////////////////////////////////////////////////////////////////////
+  // Expr manipulation methods                                               //
+  /////////////////////////////////////////////////////////////////////////////
+
+  //! Create a variable with a given name and type 
+  /*! The type cannot be a function type. The var name can contain
+    only variables, numerals and underscore. If you use any other
+    symbol, you will get a segfault. */  
+  Expr vc_varExpr(VC vc, char * name, Type type);
+
+  //The var name can contain only variables, numerals and
+  //underscore. If you use any other symbol, you will get a segfault.
+  Expr vc_varExpr1(VC vc, char* name, 
+		  int indexwidth, int valuewidth);
+
+  //! Get the expression and type associated with a name.
+  /*!  If there is no such Expr, a NULL Expr is returned. */
+  //Expr vc_lookupVar(VC vc, char* name, Type* type);
+  
+  //! Get the type of the Expr.
+  Type vc_getType(VC vc, Expr e);
+  
+  int vc_getBVLength(VC vc, Expr e);
+
+  //! Create an equality expression.  The two children must have the same type.
+  Expr vc_eqExpr(VC vc, Expr child0, Expr child1);
+  
+  // Boolean expressions
+  
+  // The following functions create Boolean expressions.  The children
+  // provided as arguments must be of type Boolean (except for the
+  // function vc_iteExpr(). In the case of vc_iteExpr() the
+  // conditional must always be Boolean, but the ifthenpart
+  // (resp. elsepart) can be bit-vector or Boolean type. But, the
+  // ifthenpart and elsepart must be both of the same type)
+  Expr vc_trueExpr(VC vc);
+  Expr vc_falseExpr(VC vc);
+  Expr vc_notExpr(VC vc, Expr child);
+  Expr vc_andExpr(VC vc, Expr left, Expr right);
+  Expr vc_andExprN(VC vc, Expr* children, int numOfChildNodes);
+  Expr vc_orExpr(VC vc, Expr left, Expr right);
+  Expr vc_orExprN(VC vc, Expr* children, int numOfChildNodes);
+  Expr vc_impliesExpr(VC vc, Expr hyp, Expr conc);
+  Expr vc_iffExpr(VC vc, Expr left, Expr right);
+  //The output type of vc_iteExpr can be Boolean (formula-level ite)
+  //or bit-vector (word-level ite)
+  Expr vc_iteExpr(VC vc, Expr conditional, Expr ifthenpart, Expr elsepart);
+  
+  //Boolean to single bit BV Expression
+  Expr vc_boolToBVExpr(VC vc, Expr form);
+
+  // Arrays
+  
+  //! Create an expression for the value of array at the given index
+  Expr vc_readExpr(VC vc, Expr array, Expr index);
+
+  //! Array update; equivalent to "array WITH [index] := newValue"
+  Expr vc_writeExpr(VC vc, Expr array, Expr index, Expr newValue);
+  
+  // Expr I/O
+  //! Expr vc_parseExpr(VC vc, char* s);
+
+  //! Prints 'e' to stdout.
+  void vc_printExpr(VC vc, Expr e);
+
+  //! Prints 'e' into an open file descriptor 'fd'
+  void vc_printExprFile(VC vc, Expr e, int fd);
+
+  //! Prints state of 'vc' into malloc'd buffer '*buf' and stores the 
+  //  length into '*len'.  It is the responsibility of the caller to 
+  //  free the buffer.
+  //void vc_printStateToBuffer(VC vc, char **buf, unsigned long *len);
+
+  //! Prints 'e' to malloc'd buffer '*buf'.  Sets '*len' to the length of 
+  //  the buffer. It is the responsibility of the caller to free the buffer.
+  void vc_printExprToBuffer(VC vc, Expr e, char **buf, unsigned long * len);
+
+  //! Prints counterexample to stdout.
+  void vc_printCounterExample(VC vc);
+
+  //! Prints variable declarations to stdout.
+  void vc_printVarDecls(VC vc);
+
+  //! Prints asserts to stdout. The flag simplify_print must be set to
+  //"1" if you wish simplification to occur dring printing. It must be
+  //set to "0" otherwise
+  void vc_printAsserts(VC vc, int simplify_print);
+
+  //! Prints the state of the query to malloc'd buffer '*buf' and
+  //stores ! the length of the buffer to '*len'.  It is the
+  //responsibility of the caller to free the buffer. The flag
+  //simplify_print must be set to "1" if you wish simplification to
+  //occur dring printing. It must be set to "0" otherwise
+  void vc_printQueryStateToBuffer(VC vc, Expr e, 
+				  char **buf, unsigned long *len, int simplify_print);
+
+  //! Similar to vc_printQueryStateToBuffer()
+  void vc_printCounterExampleToBuffer(VC vc, char **buf,unsigned long *len);
+
+  //! Prints query to stdout.
+  void vc_printQuery(VC vc);
+
+  /////////////////////////////////////////////////////////////////////////////
+  // Context-related methods                                                 //
+  /////////////////////////////////////////////////////////////////////////////
+  
+  //! Assert a new formula in the current context.  
+  /*! The formula must have Boolean type. */
+  void vc_assertFormula(VC vc, Expr e);
+  
+  //! Simplify e with respect to the current context
+  Expr vc_simplify(VC vc, Expr e);
+
+  //! Check validity of e in the current context. e must be a FORMULA
+  //
+  //if returned 0 then input is INVALID. 
+  //
+  //if returned 1 then input is VALID
+  //
+  //if returned 2 then ERROR
+  int vc_query(VC vc, Expr e);
+  
+  //! Return the counterexample after a failed query.
+  Expr vc_getCounterExample(VC vc, Expr e);
+
+  //! get size of counterexample, i.e. the number of variables/array
+  //locations in the counterexample.
+  int vc_counterexample_size(VC vc);
+  
+  //! Checkpoint the current context and increase the scope level
+  void vc_push(VC vc);
+  
+  //! Restore the current context to its state at the last checkpoint
+  void vc_pop(VC vc);
+  
+  //! Return an int from a constant bitvector expression
+  int getBVInt(Expr e);
+  //! Return an unsigned int from a constant bitvector expression
+  unsigned int getBVUnsigned(Expr e);
+  //! Return an unsigned long long int from a constant bitvector expressions
+  unsigned long long int getBVUnsignedLongLong(Expr e);
+  
+  /**************************/
+  /* BIT VECTOR OPERATIONS  */
+  /**************************/
+  Type vc_bvType(VC vc, int no_bits);
+  Type vc_bv32Type(VC vc);
+  
+  Expr vc_bvConstExprFromStr(VC vc, char* binary_repr);
+  Expr vc_bvConstExprFromInt(VC vc, int n_bits, unsigned int value);
+  Expr vc_bvConstExprFromLL(VC vc, int n_bits, unsigned long long value);
+  Expr vc_bv32ConstExprFromInt(VC vc, unsigned int value);
+  
+  Expr vc_bvConcatExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvPlusExpr(VC vc, int n_bits, Expr left, Expr right);
+  Expr vc_bv32PlusExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvMinusExpr(VC vc, int n_bits, Expr left, Expr right);
+  Expr vc_bv32MinusExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvMultExpr(VC vc, int n_bits, Expr left, Expr right);
+  Expr vc_bv32MultExpr(VC vc, Expr left, Expr right);
+  // left divided by right i.e. left/right
+  Expr vc_bvDivExpr(VC vc, int n_bits, Expr left, Expr right);
+  // left modulo right i.e. left%right
+  Expr vc_bvModExpr(VC vc, int n_bits, Expr left, Expr right);
+  // signed left divided by right i.e. left/right
+  Expr vc_sbvDivExpr(VC vc, int n_bits, Expr left, Expr right);
+  // signed left modulo right i.e. left%right
+  Expr vc_sbvModExpr(VC vc, int n_bits, Expr left, Expr right);
+  
+  Expr vc_bvLtExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvLeExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvGtExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvGeExpr(VC vc, Expr left, Expr right);
+  
+  Expr vc_sbvLtExpr(VC vc, Expr left, Expr right);
+  Expr vc_sbvLeExpr(VC vc, Expr left, Expr right);
+  Expr vc_sbvGtExpr(VC vc, Expr left, Expr right);
+  Expr vc_sbvGeExpr(VC vc, Expr left, Expr right);
+  
+  Expr vc_bvUMinusExpr(VC vc, Expr child);
+
+  // bitwise operations: these are terms not formulas  
+  Expr vc_bvAndExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvOrExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvXorExpr(VC vc, Expr left, Expr right);
+  Expr vc_bvNotExpr(VC vc, Expr child);
+  
+  Expr vc_bvLeftShiftExpr(VC vc, int sh_amt, Expr child);
+  Expr vc_bvRightShiftExpr(VC vc, int sh_amt, Expr child);
+  /* Same as vc_bvLeftShift only that the answer in 32 bits long */
+  Expr vc_bv32LeftShiftExpr(VC vc, int sh_amt, Expr child);
+  /* Same as vc_bvRightShift only that the answer in 32 bits long */
+  Expr vc_bv32RightShiftExpr(VC vc, int sh_amt, Expr child);
+  Expr vc_bvVar32LeftShiftExpr(VC vc, Expr sh_amt, Expr child);
+  Expr vc_bvVar32RightShiftExpr(VC vc, Expr sh_amt, Expr child);
+  Expr vc_bvVar32DivByPowOfTwoExpr(VC vc, Expr child, Expr rhs);
+
+  Expr vc_bvExtract(VC vc, Expr child, int high_bit_no, int low_bit_no);
+  
+  //accepts a bitvector and position, and returns a boolean
+  //corresponding to that position. More precisely, it return the
+  //equation (x[bit_no:bit_no] = 0)
+  //FIXME  = 1 ?
+  Expr vc_bvBoolExtract(VC vc, Expr x, int bit_no);  
+  Expr vc_bvSignExtend(VC vc, Expr child, int nbits);
+  
+  /*C pointer support:  C interface to support C memory arrays in CVCL */
+  Expr vc_bvCreateMemoryArray(VC vc, char * arrayName);
+  Expr vc_bvReadMemoryArray(VC vc, 
+			  Expr array, Expr byteIndex, int numOfBytes);
+  Expr vc_bvWriteToMemoryArray(VC vc, 
+			       Expr array, Expr  byteIndex, 
+			       Expr element, int numOfBytes);
+  Expr vc_bv32ConstExprFromInt(VC vc, unsigned int value);
+  
+  // return a string representation of the Expr e. The caller is responsible
+  // for deallocating the string with free()
+  char* exprString(Expr e);
+  
+  // return a string representation of the Type t. The caller is responsible
+  // for deallocating the string with free()
+  char* typeString(Type t);
+
+  Expr getChild(Expr e, int i);
+
+  //1.if input expr is TRUE then the function returns 1;
+  //
+  //2.if input expr is FALSE then function returns 0;
+  //
+  //3.otherwise the function returns -1
+  int vc_isBool(Expr e);
+
+  /* Register the given error handler to be called for each fatal error.*/
+  void vc_registerErrorHandler(void (*error_hdlr)(const char* err_msg));
+
+  int vc_getHashQueryStateToBuffer(VC vc, Expr query);
+
+  //destroys the STP instance, and removes all the created expressions
+  void vc_Destroy(VC vc);
+
+  //deletes the expression e
+  void vc_DeleteExpr(Expr e);
+
+  //Get the whole counterexample from the current context
+  WholeCounterExample vc_getWholeCounterExample(VC vc);
+
+  //Get the value of a term expression from the CounterExample
+  Expr vc_getTermFromCounterExample(VC vc, Expr e, WholeCounterExample c);
+
+  //Kinds of Expr
+  enum exprkind_t{
+      UNDEFINED,
+      SYMBOL,
+      BVCONST,
+      BVNEG,
+      BVCONCAT,
+      BVOR,
+      BVAND,
+      BVXOR,
+      BVNAND,
+      BVNOR,
+      BVXNOR,
+      BVEXTRACT,
+      BVLEFTSHIFT,
+      BVRIGHTSHIFT,
+      BVSRSHIFT,
+      BVVARSHIFT,
+      BVPLUS,
+      BVSUB,
+      BVUMINUS,
+      BVMULTINVERSE,
+      BVMULT,
+      BVDIV,
+      BVMOD,
+      SBVDIV,
+      SBVMOD,
+      BVSX,
+      BOOLVEC,
+      ITE,
+      BVGETBIT,
+      BVLT,
+      BVLE,
+      BVGT,
+      BVGE,
+      BVSLT,
+      BVSLE,
+      BVSGT,
+      BVSGE,
+      EQ,
+      NEQ,
+      FALSE,
+      TRUE,
+      NOT,
+      AND,
+      OR,
+      NAND,
+      NOR,
+      XOR,
+      IFF,
+      IMPLIES,
+      READ,
+      WRITE,
+      ARRAY,
+      BITVECTOR,
+      BOOLEAN
+  };
+
+  // type of expression
+  enum type_t {
+      BOOLEAN_TYPE = 0,
+      BITVECTOR_TYPE,
+      ARRAY_TYPE,
+      UNKNOWN_TYPE
+  };
+
+  // get the kind of the expression
+  exprkind_t getExprKind (Expr e);
+
+  // get the number of children nodes
+  int getDegree (Expr e);
+
+  // get the bv length
+  int getBVLength(Expr e);
+
+  // get expression type
+  type_t getType (Expr e);
+
+  // get value bit width
+  int getVWidth (Expr e);
+
+  // get index bit width
+  int getIWidth (Expr e);
+
+  // Prints counterexample to an open file descriptor 'fd'
+  void vc_printCounterExampleFile(VC vc, int fd);
+
+  // get name of expression. must be a variable.
+  const char* exprName(Expr e);
+  
+  // get the node ID of an Expr.
+  int getExprID (Expr ex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/stp/c_interface/fdstream.h b/stp/c_interface/fdstream.h
new file mode 100644
index 00000000..2cff613c
--- /dev/null
+++ b/stp/c_interface/fdstream.h
@@ -0,0 +1,186 @@
+/*! @brief The following code declares classes to read from and write to
+ * file descriptore or file handles.
+ *
+ * See
+ *      http://www.josuttis.com/cppcode
+ * for details and the latest version.
+ *
+ * - open:
+ *      - integrating BUFSIZ on some systems?
+ *      - optimized reading of multiple characters
+ *      - stream for reading AND writing
+ *      - i18n
+ *
+ * (C) Copyright Nicolai M. Josuttis 2001.
+ * Permission to copy, use, modify, sell and distribute this software
+ * is granted provided this copyright notice appears in all copies.
+ * This software is provided "as is" without express or implied
+ * warranty, and with no claim as to its suitability for any purpose.
+ *
+ * Version: Jul 28, 2002
+ * History:
+ *  Jul 28, 2002: bugfix memcpy() => memmove()
+ *                fdinbuf::underflow(): cast for return statements
+ *  Aug 05, 2001: first public version
+ */
+#ifndef BOOST_FDSTREAM_HPP
+#define BOOST_FDSTREAM_HPP
+
+#include <istream>
+#include <ostream>
+#include <streambuf>
+
+
+// for EOF:
+#include <cstdio>
+// for memmove():
+#include <cstring>
+
+
+// low-level read and write functions
+#ifdef _MSC_VER
+# include <io.h>
+#else
+# include <unistd.h>
+//extern "C" {
+//    int write (int fd, const char* buf, int num);
+//    int read (int fd, char* buf, int num);
+//}
+#endif
+
+
+// BEGIN namespace BOOST
+namespace std {
+
+
+/************************************************************
+ * fdostream
+ * - a stream that writes on a file descriptor
+ ************************************************************/
+
+
+class fdoutbuf : public std::streambuf {
+  protected:
+    int fd;    // file descriptor
+  public:
+    // constructor
+    fdoutbuf (int _fd) : fd(_fd) {
+    }
+  protected:
+    // write one character
+    virtual int_type overflow (int_type c) {
+        if (c != EOF) {
+            char z = c;
+            if (write (fd, &z, 1) != 1) {
+                return EOF;
+            }
+        }
+        return c;
+    }
+    // write multiple characters
+    virtual
+    std::streamsize xsputn (const char* s,
+                            std::streamsize num) {
+        return write(fd,s,num);
+    }
+};
+
+class fdostream : public std::ostream {
+  protected:
+    fdoutbuf buf;
+  public:
+    fdostream (int fd) : std::ostream(0), buf(fd) {
+        rdbuf(&buf);
+    }
+};
+
+
+/************************************************************
+ * fdistream
+ * - a stream that reads on a file descriptor
+ ************************************************************/
+
+class fdinbuf : public std::streambuf {
+  protected:
+    int fd;    // file descriptor
+  protected:
+    /* data buffer:
+     * - at most, pbSize characters in putback area plus
+     * - at most, bufSize characters in ordinary read buffer
+     */
+    static const int pbSize = 4;        // size of putback area
+    static const int bufSize = 1024;    // size of the data buffer
+    char buffer[bufSize+pbSize];        // data buffer
+
+  public:
+    /* constructor
+     * - initialize file descriptor
+     * - initialize empty data buffer
+     * - no putback area
+     * => force underflow()
+     */
+    fdinbuf (int _fd) : fd(_fd) {
+        setg (buffer+pbSize,     // beginning of putback area
+              buffer+pbSize,     // read position
+              buffer+pbSize);    // end position
+    }
+
+  protected:
+    // insert new characters into the buffer
+    virtual int_type underflow () {
+#ifndef _MSC_VER
+        using std::memmove;
+#endif
+
+        // is read position before end of buffer?
+        if (gptr() < egptr()) {
+            return traits_type::to_int_type(*gptr());
+        }
+
+        /* process size of putback area
+         * - use number of characters read
+         * - but at most size of putback area
+         */
+        int numPutback;
+        numPutback = gptr() - eback();
+        if (numPutback > pbSize) {
+            numPutback = pbSize;
+        }
+
+        /* copy up to pbSize characters previously read into
+         * the putback area
+         */
+        memmove (buffer+(pbSize-numPutback), gptr()-numPutback,
+                numPutback);
+
+        // read at most bufSize new characters
+        int num;
+        num = read (fd, buffer+pbSize, bufSize);
+        if (num <= 0) {
+            // ERROR or EOF
+            return EOF;
+        }
+
+        // reset buffer pointers
+        setg (buffer+(pbSize-numPutback),   // beginning of putback area
+              buffer+pbSize,                // read position
+              buffer+pbSize+num);           // end of buffer
+
+        // return next character
+        return traits_type::to_int_type(*gptr());
+    }
+};
+
+class fdistream : public std::istream {
+  protected:
+    fdinbuf buf;
+  public:
+    fdistream (int fd) : std::istream(0), buf(fd) {
+        rdbuf(&buf);
+    }
+};
+
+
+} // END namespace boost
+
+#endif /*BOOST_FDSTREAM_HPP*/
diff --git a/stp/constantbv/Makefile b/stp/constantbv/Makefile
new file mode 100644
index 00000000..cd94ad94
--- /dev/null
+++ b/stp/constantbv/Makefile
@@ -0,0 +1,13 @@
+include ../Makefile.common
+
+SRCS = constantbv.cpp
+OBJS = $(SRCS:.cpp=.o)
+
+libconstantbv.a: $(OBJS)
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+clean:	
+	rm -rf *.o *~ *.a .#*
+
+constantbv.o: constantbv.h
diff --git a/stp/constantbv/constantbv.cpp b/stp/constantbv/constantbv.cpp
new file mode 100644
index 00000000..65698981
--- /dev/null
+++ b/stp/constantbv/constantbv.cpp
@@ -0,0 +1,3571 @@
+/*****************************************************************************/
+/*  AUTHOR:                                                                  */
+/*****************************************************************************/
+/*                                                                           */
+/*    Steffen Beyer                                                          */
+/*    mailto:sb@engelschall.com                                              */
+/*    http://www.engelschall.com/u/sb/download/                              */
+/*                                                                           */
+/*****************************************************************************/
+/*  COPYRIGHT:                                                               */
+/*****************************************************************************/
+/*                                                                           */
+/*    Copyright (c) 1995 - 2004 by Steffen Beyer.                            */
+/*    All rights reserved.                                                   */
+/*                                                                           */
+/*****************************************************************************/
+/*  LICENSE:                                                                 */
+/*****************************************************************************/
+/*                                                                           */
+/*    This library is free software; you can redistribute it and/or          */
+/*    modify it under the terms of the GNU Library General Public            */
+/*    License as published by the Free Software Foundation; either           */
+/*    version 2 of the License, || (at your option) any later version.       */
+/*                                                                           */
+/*    This library is distributed in the hope that it will be useful,        */
+/*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
+/*    MERCHANTABILITY || FITNESS FOR A PARTICULAR PURPOSE. See the GNU       */
+/*    Library General Public License for more details.                       */
+/*                                                                           */
+/*    You should have received a copy of the GNU Library General Public      */
+/*    License along with this library; if not, write to the                  */
+/*    Free Software Foundation, Inc.,                                        */
+/*    59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                  */
+/*                                                                           */
+/*    || download a copy from ftp://ftp.gnu.org/pub/gnu/COPYING.LIB-2.0      */
+/*                                                                           */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/*  MODULE NAME:  constantbv.cpp                       MODULE TYPE:constantbv*/
+/*****************************************************************************/
+/*  MODULE IMPORTS:                                                          */
+/*****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>                                 /*  MODULE TYPE:  (sys)  */
+#include <limits.h>                                 /*  MODULE TYPE:  (sys)  */
+#include <string.h>                                 /*  MODULE TYPE:  (sys)  */
+#include <ctype.h>                                  /*  MODULE TYPE:  (sys)  */
+#include "constantbv.h"
+
+namespace CONSTANTBV {
+/*****************************************************************************/
+/*  MODULE IMPLEMENTATION:                                                   */
+/*****************************************************************************/
+    /**********************************************/
+    /* global implementation-intrinsic constants: */
+    /**********************************************/
+
+#define BIT_VECTOR_HIDDEN_WORDS 3
+
+    /*****************************************************************/
+    /* global machine-dependent constants (set by "BitVector_Boot"): */
+    /*****************************************************************/
+
+static unsigned int BITS;     /* = # of bits in machine word (must be power of 2)  */
+static unsigned int MODMASK;  /* = BITS - 1 (mask for calculating modulo BITS)     */
+static unsigned int LOGBITS;  /* = ld(BITS) (logarithmus dualis)                   */
+static unsigned int FACTOR;   /* = ld(BITS / 8) (ld of # of bytes)                 */
+
+static unsigned int LSB = 1;  /* = mask for least significant bit                  */
+static unsigned int MSB;      /* = mask for most significant bit                   */
+
+static unsigned int LONGBITS; /* = # of bits in unsigned long                      */
+
+static unsigned int LOG10;    /* = logarithm to base 10 of BITS - 1                */
+static unsigned int EXP10;    /* = largest possible power of 10 in signed int      */
+
+    /********************************************************************/
+    /* global bit mask table for fast access (set by "BitVector_Boot"): */
+    /********************************************************************/
+
+static unsigned int *  BITMASKTAB;
+
+    /*****************************/
+    /* global macro definitions: */
+    /*****************************/
+
+#define BIT_VECTOR_ZERO_WORDS(target,count) \
+    while (count-- > 0) *target++ = 0;
+
+#define BIT_VECTOR_FILL_WORDS(target,fill,count) \
+    while (count-- > 0) *target++ = fill;
+
+#define BIT_VECTOR_FLIP_WORDS(target,flip,count) \
+    while (count-- > 0) *target++ ^= flip;
+
+#define BIT_VECTOR_COPY_WORDS(target,source,count) \
+    while (count-- > 0) *target++ = *source++;
+
+#define BIT_VECTOR_BACK_WORDS(target,source,count) \
+    { target += count; source += count; while (count-- > 0) *--target = *--source; }
+
+#define BIT_VECTOR_CLR_BIT(address,index) \
+    *(address+(index>>LOGBITS)) &= ~ BITMASKTAB[index & MODMASK];
+
+#define BIT_VECTOR_SET_BIT(address,index) \
+    *(address+(index>>LOGBITS)) |= BITMASKTAB[index & MODMASK];
+
+#define BIT_VECTOR_TST_BIT(address,index) \
+    ((*(address+(index>>LOGBITS)) & BITMASKTAB[index & MODMASK]) != 0)
+
+#define BIT_VECTOR_FLP_BIT(address,index,mask) \
+    (mask = BITMASKTAB[index & MODMASK]), \
+    (((*(addr+(index>>LOGBITS)) ^= mask) & mask) != 0)
+
+#define BIT_VECTOR_DIGITIZE(type,value,digit) \
+    value = (type) ((digit = value) / 10); \
+    digit -= value * 10; \
+    digit += (type) '0';
+
+    /*********************************************************/
+    /* private low-level functions (potentially dangerous!): */
+    /*********************************************************/
+
+static unsigned int power10(unsigned int x) {
+    unsigned int y = 1;
+
+    while (x-- > 0) y *= 10;
+    return(y);
+}
+
+static void BIT_VECTOR_zro_words(unsigned int *  addr, unsigned int count) {
+    BIT_VECTOR_ZERO_WORDS(addr,count)
+}
+
+static void BIT_VECTOR_cpy_words(unsigned int *  target, 
+				 unsigned int *  source, unsigned int count) {
+    BIT_VECTOR_COPY_WORDS(target,source,count)
+}
+
+static void BIT_VECTOR_mov_words(unsigned int *  target, 
+				 unsigned int *  source, unsigned int count) {
+    if (target != source) {
+        if (target < source) BIT_VECTOR_COPY_WORDS(target,source,count)
+        else                 BIT_VECTOR_BACK_WORDS(target,source,count)
+    }
+}
+
+static void BIT_VECTOR_ins_words(unsigned int *  addr, 
+				 unsigned int total, unsigned int count, boolean clear) {
+    unsigned int length;
+
+    if ((total > 0) && (count > 0)) {
+        if (count > total) count = total;
+        length = total - count;
+        if (length > 0) BIT_VECTOR_mov_words(addr+count,addr,length);
+        if (clear)      BIT_VECTOR_zro_words(addr,count);
+    }
+}
+
+static void BIT_VECTOR_del_words(unsigned int *  addr, 
+				 unsigned int total, unsigned int count, boolean clear) {
+    unsigned int length;
+
+    if ((total > 0) && (count > 0)) {
+        if (count > total) count = total;
+        length = total - count;
+        if (length > 0) BIT_VECTOR_mov_words(addr,addr+count,length);
+        if (clear)      BIT_VECTOR_zro_words(addr+length,count);
+    }
+}
+
+static void BIT_VECTOR_reverse(unsigned char * string, unsigned int length) {
+    unsigned char * last;
+    unsigned char  temp;
+
+    if (length > 1) {
+        last = string + length - 1;
+        while (string < last) {
+            temp = *string;
+            *string = *last;
+            *last = temp;
+            string++;
+            last--;
+        }
+    }
+}
+
+static unsigned int BIT_VECTOR_int2str(unsigned char * string, unsigned int value) {
+    unsigned int  length;
+    unsigned int  digit;
+    unsigned char * work;
+
+    work = string;
+    if (value > 0) {
+        length = 0;
+        while (value > 0) {
+            BIT_VECTOR_DIGITIZE(unsigned int,value,digit)
+            *work++ = (unsigned char) digit;
+            length++;
+        }
+        BIT_VECTOR_reverse(string,length);
+    }
+    else {
+        length = 1;
+        *work++ = (unsigned char) '0';
+    }
+    return(length);
+}
+
+static unsigned int BIT_VECTOR_str2int(unsigned char * string, unsigned int *value) {
+    unsigned int  length;
+    unsigned int  digit;
+
+    *value = 0;
+    length = 0;
+    digit = (unsigned int) *string++;
+    /* separate because isdigit() is likely a macro! */
+    while (isdigit((int)digit) != 0) {
+        length++;
+        digit -= (unsigned int) '0';
+        if (*value) *value *= 10;
+        *value += digit;
+        digit = (unsigned int) *string++;
+    }
+    return(length);
+}
+
+    /********************************************/
+    /* routine to convert error code to string: */
+    /********************************************/
+
+unsigned char * BitVector_Error(ErrCode error) {
+    switch (error) {
+        case ErrCode_Ok:   return( (unsigned char *)     NULL     ); break;
+        case ErrCode_Type: return( (unsigned char *) ERRCODE_TYPE ); break;
+        case ErrCode_Bits: return( (unsigned char *) ERRCODE_BITS ); break;
+        case ErrCode_Word: return( (unsigned char *) ERRCODE_WORD ); break;
+        case ErrCode_Long: return( (unsigned char *) ERRCODE_LONG ); break;
+        case ErrCode_Powr: return( (unsigned char *) ERRCODE_POWR ); break;
+        case ErrCode_Loga: return( (unsigned char *) ERRCODE_LOGA ); break;
+        case ErrCode_Null: return( (unsigned char *) ERRCODE_NULL ); break;
+        case ErrCode_Indx: return( (unsigned char *) ERRCODE_INDX ); break;
+        case ErrCode_Ordr: return( (unsigned char *) ERRCODE_ORDR ); break;
+        case ErrCode_Size: return( (unsigned char *) ERRCODE_SIZE ); break;
+        case ErrCode_Pars: return( (unsigned char *) ERRCODE_PARS ); break;
+        case ErrCode_Ovfl: return( (unsigned char *) ERRCODE_OVFL ); break;
+        case ErrCode_Same: return( (unsigned char *) ERRCODE_SAME ); break;
+        case ErrCode_Expo: return( (unsigned char *) ERRCODE_EXPO ); break;
+        case ErrCode_Zero: return( (unsigned char *) ERRCODE_ZERO ); break;
+        default:           return( (unsigned char *) ERRCODE_OOPS ); break;
+    }
+}
+
+    /*****************************************/
+    /* automatic self-configuration routine: */
+    /*****************************************/
+
+    /*******************************************************/
+    /*                                                     */
+    /*   MUST be called once prior to any other function   */
+    /*   to initialize the machine dependent constants     */
+    /*   of this package! (But call only ONCE, or you      */
+    /*   will suffer memory leaks!)                        */
+    /*                                                     */
+    /*******************************************************/
+
+ErrCode BitVector_Boot(void) {
+    unsigned long longsample = 1L;
+    unsigned int sample = LSB;
+    unsigned int lsb;
+
+    if (sizeof(unsigned int) > sizeof(size_t)) return(ErrCode_Type);
+
+    BITS = 1;
+    while (sample <<= 1) BITS++;    /* determine # of bits in a machine word */
+
+    if (BITS != (sizeof(unsigned int) << 3)) return(ErrCode_Bits);
+
+    if (BITS < 16) return(ErrCode_Word);
+
+    LONGBITS = 1;
+    while (longsample <<= 1) LONGBITS++;  /* = # of bits in an unsigned long */
+
+    if (BITS > LONGBITS) return(ErrCode_Long);
+
+    LOGBITS = 0;
+    sample = BITS;
+    lsb = (sample & LSB);
+    while ((sample >>= 1) && (! lsb)) {
+        LOGBITS++;
+        lsb = (sample & LSB);
+    }
+
+    if (sample) return(ErrCode_Powr);      /* # of bits is not a power of 2! */
+
+    if (BITS != (LSB << LOGBITS)) return(ErrCode_Loga);
+
+    MODMASK = BITS - 1;
+    FACTOR = LOGBITS - 3;  /* ld(BITS / 8) = ld(BITS) - ld(8) = ld(BITS) - 3 */
+    MSB = (LSB << MODMASK);
+
+    BITMASKTAB = (unsigned int * ) malloc((size_t) (BITS << FACTOR));
+
+    if (BITMASKTAB == NULL) return(ErrCode_Null);
+
+    for ( sample = 0; sample < BITS; sample++ ) {
+        BITMASKTAB[sample] = (LSB << sample);
+    }
+
+    LOG10 = (unsigned int) (MODMASK * 0.30103); /* = (BITS - 1) * ( ln 2 / ln 10 ) */
+    EXP10 = power10(LOG10);
+
+    return(ErrCode_Ok);
+}
+
+unsigned int BitVector_Size(unsigned int bits) {          /* bit vector size (# of words)  */
+    unsigned int size;
+
+    size = bits >> LOGBITS;
+    if (bits & MODMASK) size++;
+    return(size);
+}
+
+unsigned int BitVector_Mask(unsigned int bits)           /* bit vector mask (unused bits) */
+{
+    unsigned int mask;
+
+    mask = bits & MODMASK;
+    if (mask) mask = (unsigned int) ~(~0L << mask); else mask = (unsigned int) ~0L;
+    return(mask);
+}
+
+unsigned char * BitVector_Version(void)
+{
+    return((unsigned char *)"6.4");
+}
+
+unsigned int BitVector_Word_Bits(void)
+{
+    return(BITS);
+}
+
+unsigned int BitVector_Long_Bits(void)
+{
+    return(LONGBITS);
+}
+
+/********************************************************************/
+/*                                                                  */
+/*  WARNING: Do not "free()" constant character strings, i.e.,      */
+/*           don't call "BitVector_Dispose()" for strings returned  */
+/*           by "BitVector_Error()" or "BitVector_Version()"!       */
+/*                                                                  */
+/*  ONLY call this function for strings allocated with "malloc()",  */
+/*  i.e., the strings returned by the functions "BitVector_to_*()"  */
+/*  and "BitVector_Block_Read()"!                                   */
+/*                                                                  */
+/********************************************************************/
+
+void BitVector_Dispose(unsigned char * string)                      /* free string   */
+{
+    if (string != NULL) free((void *) string);
+}
+
+void BitVector_Destroy(unsigned int *  addr)                        /* free bitvec   */
+{
+    if (addr != NULL)
+    {
+        addr -= BIT_VECTOR_HIDDEN_WORDS;
+        free((void *) addr);
+    }
+}
+
+void BitVector_Destroy_List(unsigned int *  *  list, unsigned int count)      /* free list     */
+{
+    unsigned int *  *  slot;
+
+    if (list != NULL)
+    {
+        slot = list;
+        while (count-- > 0)
+        {
+            BitVector_Destroy(*slot++);
+        }
+        free((void *) list);
+    }
+}
+
+unsigned int *  BitVector_Create(unsigned int bits, boolean clear)         /* malloc        */
+{
+    unsigned int  size;
+    unsigned int  mask;
+    unsigned int  bytes;
+    unsigned int *  addr;
+    unsigned int *  zero;
+
+    size = BitVector_Size(bits);
+    mask = BitVector_Mask(bits);
+    bytes = (size + BIT_VECTOR_HIDDEN_WORDS) << FACTOR;
+    addr = (unsigned int * ) malloc((size_t) bytes);
+    if (addr != NULL)
+    {
+        *addr++ = bits;
+        *addr++ = size;
+        *addr++ = mask;
+        if (clear)
+        {
+            zero = addr;
+            BIT_VECTOR_ZERO_WORDS(zero,size)
+        }
+    }
+    return(addr);
+}
+
+unsigned int *  *  BitVector_Create_List(unsigned int bits, boolean clear, unsigned int count)
+{
+    unsigned int *  *  list = NULL;
+    unsigned int *  *  slot;
+    unsigned int *  addr;
+    unsigned int   i;
+
+    if (count > 0)
+    {
+        list = (unsigned int *  * ) malloc(sizeof(unsigned int * ) * count);
+        if (list != NULL)
+        {
+            slot = list;
+            for ( i = 0; i < count; i++ )
+            {
+                addr = BitVector_Create(bits,clear);
+                if (addr == NULL)
+                {
+                    BitVector_Destroy_List(list,i);
+                    return(NULL);
+                }
+                *slot++ = addr;
+            }
+        }
+    }
+    return(list);
+}
+
+unsigned int *  BitVector_Resize(unsigned int *  oldaddr, unsigned int bits)       /* realloc       */
+{
+    unsigned int  bytes;
+    unsigned int  oldsize;
+    unsigned int  oldmask;
+    unsigned int  newsize;
+    unsigned int  newmask;
+    unsigned int *  newaddr;
+    unsigned int *  source;
+    unsigned int *  target;
+
+    oldsize = size_(oldaddr);
+    oldmask = mask_(oldaddr);
+    newsize = BitVector_Size(bits);
+    newmask = BitVector_Mask(bits);
+    if (oldsize > 0) *(oldaddr+oldsize-1) &= oldmask;
+    if (newsize <= oldsize)
+    {
+        newaddr = oldaddr;
+        bits_(newaddr) = bits;
+        size_(newaddr) = newsize;
+        mask_(newaddr) = newmask;
+        if (newsize > 0) *(newaddr+newsize-1) &= newmask;
+    }
+    else
+    {
+        bytes = (newsize + BIT_VECTOR_HIDDEN_WORDS) << FACTOR;
+        newaddr = (unsigned int * ) malloc((size_t) bytes);
+        if (newaddr != NULL)
+        {
+            *newaddr++ = bits;
+            *newaddr++ = newsize;
+            *newaddr++ = newmask;
+            target = newaddr;
+            source = oldaddr;
+            newsize -= oldsize;
+            BIT_VECTOR_COPY_WORDS(target,source,oldsize)
+            BIT_VECTOR_ZERO_WORDS(target,newsize)
+        }
+        BitVector_Destroy(oldaddr);
+    }
+    return(newaddr);
+}
+
+unsigned int *  BitVector_Shadow(unsigned int *  addr)     /* makes new, same size but empty */
+{
+    return( BitVector_Create(bits_(addr),true) );
+}
+
+unsigned int *  BitVector_Clone(unsigned int *  addr)               /* makes exact duplicate */
+{
+    unsigned int  bits;
+    unsigned int *  twin;
+
+    bits = bits_(addr);
+    twin = BitVector_Create(bits,false);
+    if ((twin != NULL) && (bits > 0))
+        BIT_VECTOR_cpy_words(twin,addr,size_(addr));
+    return(twin);
+}
+
+unsigned int *  BitVector_Concat(unsigned int *  X, unsigned int *  Y)      /* returns concatenation */
+{
+    /* BEWARE that X = most significant part, Y = least significant part! */
+
+    unsigned int  bitsX;
+    unsigned int  bitsY;
+    unsigned int  bitsZ;
+    unsigned int *  Z;
+
+    bitsX = bits_(X);
+    bitsY = bits_(Y);
+    bitsZ = bitsX + bitsY;
+    Z = BitVector_Create(bitsZ,false);
+    if ((Z != NULL) && (bitsZ > 0))
+    {
+        BIT_VECTOR_cpy_words(Z,Y,size_(Y));
+        BitVector_Interval_Copy(Z,X,bitsY,0,bitsX);
+        *(Z+size_(Z)-1) &= mask_(Z);
+    }
+    return(Z);
+}
+
+void BitVector_Copy(unsigned int *  X, unsigned int *  Y)                           /* X = Y */
+{
+    unsigned int  sizeX = size_(X);
+    unsigned int  sizeY = size_(Y);
+    unsigned int  maskX = mask_(X);
+    unsigned int  maskY = mask_(Y);
+    unsigned int  fill  = 0;
+    unsigned int *  lastX;
+    unsigned int *  lastY;
+
+    if ((X != Y) && (sizeX > 0))
+    {
+        lastX = X + sizeX - 1;
+        if (sizeY > 0)
+        {
+            lastY = Y + sizeY - 1;
+            if ( (*lastY & (maskY & ~ (maskY >> 1))) == 0 ) *lastY &= maskY;
+            else
+            {
+                fill = (unsigned int) ~0L;
+                *lastY |= ~ maskY;
+            }
+            while ((sizeX > 0) && (sizeY > 0))
+            {
+                *X++ = *Y++;
+                sizeX--;
+                sizeY--;
+            }
+            *lastY &= maskY;
+        }
+        while (sizeX-- > 0) *X++ = fill;
+        *lastX &= maskX;
+    }
+}
+
+void BitVector_Empty(unsigned int *  addr)                        /* X = {}  clr all */
+{
+    unsigned int size = size_(addr);
+
+    BIT_VECTOR_ZERO_WORDS(addr,size)
+}
+
+void BitVector_Fill(unsigned int *  addr)                         /* X = ~{} set all */
+{
+    unsigned int size = size_(addr);
+    unsigned int mask = mask_(addr);
+    unsigned int fill = (unsigned int) ~0L;
+
+    if (size > 0)
+    {
+        BIT_VECTOR_FILL_WORDS(addr,fill,size)
+        *(--addr) &= mask;
+    }
+}
+
+void BitVector_Flip(unsigned int *  addr)                         /* X = ~X flip all */
+{
+    unsigned int size = size_(addr);
+    unsigned int mask = mask_(addr);
+    unsigned int flip = (unsigned int) ~0L;
+
+    if (size > 0)
+    {
+        BIT_VECTOR_FLIP_WORDS(addr,flip,size)
+        *(--addr) &= mask;
+    }
+}
+
+void BitVector_Primes(unsigned int *  addr)
+{
+    unsigned int  bits = bits_(addr);
+    unsigned int  size = size_(addr);
+    unsigned int *  work;
+    unsigned int  temp;
+    unsigned int  i,j;
+
+    if (size > 0)
+    {
+        temp = 0xAAAA;
+        i = BITS >> 4;
+        while (--i > 0)
+        {
+            temp <<= 16;
+            temp |= 0xAAAA;
+        }
+        i = size;
+        work = addr;
+        *work++ = temp ^ 0x0006;
+        while (--i > 0) *work++ = temp;
+        for ( i = 3; (j = i * i) < bits; i += 2 )
+        {
+            for ( ; j < bits; j += i ) BIT_VECTOR_CLR_BIT(addr,j)
+        }
+        *(addr+size-1) &= mask_(addr);
+    }
+}
+
+void BitVector_Reverse(unsigned int *  X, unsigned int *  Y)
+{
+    unsigned int bits = bits_(X);
+    unsigned int mask;
+    unsigned int bit;
+    unsigned int value;
+
+    if (bits > 0)
+    {
+        if (X == Y) BitVector_Interval_Reverse(X,0,bits-1);
+        else if (bits == bits_(Y))
+        {
+/*          mask = mask_(Y);  */
+/*          mask &= ~ (mask >> 1);  */
+            mask = BITMASKTAB[(bits-1) & MODMASK];
+            Y += size_(Y) - 1;
+            value = 0;
+            bit = LSB;
+            while (bits-- > 0)
+            {
+                if ((*Y & mask) != 0)
+                {
+                    value |= bit;
+                }
+                if (! (mask >>= 1))
+                {
+                    Y--;
+                    mask = MSB;
+                }
+                if (! (bit <<= 1))
+                {
+                    *X++ = value;
+                    value = 0;
+                    bit = LSB;
+                }
+            }
+            if (bit > LSB) *X = value;
+        }
+    }
+}
+
+void BitVector_Interval_Empty(unsigned int *  addr, unsigned int lower, unsigned int upper)
+{                                                  /* X = X \ [lower..upper] */
+    unsigned int  bits = bits_(addr);
+    unsigned int  size = size_(addr);
+    unsigned int *  loaddr;
+    unsigned int *  hiaddr;
+    unsigned int  lobase;
+    unsigned int  hibase;
+    unsigned int  lomask;
+    unsigned int  himask;
+    unsigned int  diff;
+
+    if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
+    {
+        lobase = lower >> LOGBITS;
+        hibase = upper >> LOGBITS;
+        diff = hibase - lobase;
+        loaddr = addr + lobase;
+        hiaddr = addr + hibase;
+
+        lomask = (unsigned int)   (~0L << (lower & MODMASK));
+        himask = (unsigned int) ~((~0L << (upper & MODMASK)) << 1);
+
+        if (diff == 0)
+        {
+            *loaddr &= ~ (lomask & himask);
+        }
+        else
+        {
+            *loaddr++ &= ~ lomask;
+            while (--diff > 0)
+            {
+                *loaddr++ = 0;
+            }
+            *hiaddr &= ~ himask;
+        }
+    }
+}
+
+void BitVector_Interval_Fill(unsigned int *  addr, unsigned int lower, unsigned int upper)
+{                                                  /* X = X + [lower..upper] */
+    unsigned int  bits = bits_(addr);
+    unsigned int  size = size_(addr);
+    unsigned int  fill = (unsigned int) ~0L;
+    unsigned int *  loaddr;
+    unsigned int *  hiaddr;
+    unsigned int  lobase;
+    unsigned int  hibase;
+    unsigned int  lomask;
+    unsigned int  himask;
+    unsigned int  diff;
+
+    if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
+    {
+        lobase = lower >> LOGBITS;
+        hibase = upper >> LOGBITS;
+        diff = hibase - lobase;
+        loaddr = addr + lobase;
+        hiaddr = addr + hibase;
+
+        lomask = (unsigned int)   (~0L << (lower & MODMASK));
+        himask = (unsigned int) ~((~0L << (upper & MODMASK)) << 1);
+
+        if (diff == 0)
+        {
+            *loaddr |= (lomask & himask);
+        }
+        else
+        {
+            *loaddr++ |= lomask;
+            while (--diff > 0)
+            {
+                *loaddr++ = fill;
+            }
+            *hiaddr |= himask;
+        }
+        *(addr+size-1) &= mask_(addr);
+    }
+}
+
+void BitVector_Interval_Flip(unsigned int *  addr, unsigned int lower, unsigned int upper)
+{                                                  /* X = X ^ [lower..upper] */
+    unsigned int  bits = bits_(addr);
+    unsigned int  size = size_(addr);
+    unsigned int  flip = (unsigned int) ~0L;
+    unsigned int *  loaddr;
+    unsigned int *  hiaddr;
+    unsigned int  lobase;
+    unsigned int  hibase;
+    unsigned int  lomask;
+    unsigned int  himask;
+    unsigned int  diff;
+
+    if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
+    {
+        lobase = lower >> LOGBITS;
+        hibase = upper >> LOGBITS;
+        diff = hibase - lobase;
+        loaddr = addr + lobase;
+        hiaddr = addr + hibase;
+
+        lomask = (unsigned int)   (~0L << (lower & MODMASK));
+        himask = (unsigned int) ~((~0L << (upper & MODMASK)) << 1);
+
+        if (diff == 0)
+        {
+            *loaddr ^= (lomask & himask);
+        }
+        else
+        {
+            *loaddr++ ^= lomask;
+            while (--diff > 0)
+            {
+                *loaddr++ ^= flip;
+            }
+            *hiaddr ^= himask;
+        }
+        *(addr+size-1) &= mask_(addr);
+    }
+}
+
+void BitVector_Interval_Reverse(unsigned int *  addr, unsigned int lower, unsigned int upper)
+{
+    unsigned int  bits = bits_(addr);
+    unsigned int *  loaddr;
+    unsigned int *  hiaddr;
+    unsigned int  lomask;
+    unsigned int  himask;
+
+    if ((bits > 0) && (lower < bits) && (upper < bits) && (lower < upper))
+    {
+        loaddr = addr + (lower >> LOGBITS);
+        hiaddr = addr + (upper >> LOGBITS);
+        lomask = BITMASKTAB[lower & MODMASK];
+        himask = BITMASKTAB[upper & MODMASK];
+        for ( bits = upper - lower + 1; bits > 1; bits -= 2 )
+        {
+            if (((*loaddr & lomask) != 0) ^ ((*hiaddr & himask) != 0))
+            {
+                *loaddr ^= lomask;  /* swap bits only if they differ! */
+                *hiaddr ^= himask;
+            }
+            if (! (lomask <<= 1))
+            {
+                lomask = LSB;
+                loaddr++;
+            }
+            if (! (himask >>= 1))
+            {
+                himask = MSB;
+                hiaddr--;
+            }
+        }
+    }
+}
+
+boolean BitVector_interval_scan_inc(unsigned int *  addr, unsigned int start,
+                                    unsigned int * min, unsigned int * max)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int  offset;
+    unsigned int  bitmask;
+    unsigned int  value;
+    boolean empty;
+
+    if ((size == 0) || (start >= bits_(addr))) return(false);
+
+    *min = start;
+    *max = start;
+
+    offset = start >> LOGBITS;
+
+    *(addr+size-1) &= mask;
+
+    addr += offset;
+    size -= offset;
+
+    bitmask = BITMASKTAB[start & MODMASK];
+    mask = ~ (bitmask | (bitmask - 1));
+
+    value = *addr++;
+    if ((value & bitmask) == 0)
+    {
+        value &= mask;
+        if (value == 0)
+        {
+            offset++;
+            empty = true;
+            while (empty && (--size > 0))
+            {
+                if ((value = *addr++)) empty = false; else offset++;
+            }
+            if (empty) return(false);
+        }
+        start = offset << LOGBITS;
+        bitmask = LSB;
+        mask = value;
+        while (! (mask & LSB))
+        {
+            bitmask <<= 1;
+            mask >>= 1;
+            start++;
+        }
+        mask = ~ (bitmask | (bitmask - 1));
+        *min = start;
+        *max = start;
+    }
+    value = ~ value;
+    value &= mask;
+    if (value == 0)
+    {
+        offset++;
+        empty = true;
+        while (empty && (--size > 0))
+        {
+            if ((value = ~ *addr++)) empty = false; else offset++;
+        }
+        if (empty) value = LSB;
+    }
+    start = offset << LOGBITS;
+    while (! (value & LSB))
+    {
+        value >>= 1;
+        start++;
+    }
+    *max = --start;
+    return(true);
+}
+
+boolean BitVector_interval_scan_dec(unsigned int *  addr, unsigned int start,
+                                    unsigned int * min, unsigned int * max)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int offset;
+    unsigned int bitmask;
+    unsigned int value;
+    boolean empty;
+
+    if ((size == 0) || (start >= bits_(addr))) return(false);
+
+    *min = start;
+    *max = start;
+
+    offset = start >> LOGBITS;
+
+    if (offset >= size) return(false);
+
+    *(addr+size-1) &= mask;
+
+    addr += offset;
+    size = ++offset;
+
+    bitmask = BITMASKTAB[start & MODMASK];
+    mask = (bitmask - 1);
+
+    value = *addr--;
+    if ((value & bitmask) == 0)
+    {
+        value &= mask;
+        if (value == 0)
+        {
+            offset--;
+            empty = true;
+            while (empty && (--size > 0))
+            {
+                if ((value = *addr--)) empty = false; else offset--;
+            }
+            if (empty) return(false);
+        }
+        start = offset << LOGBITS;
+        bitmask = MSB;
+        mask = value;
+        while (! (mask & MSB))
+        {
+            bitmask >>= 1;
+            mask <<= 1;
+            start--;
+        }
+        mask = (bitmask - 1);
+        *max = --start;
+        *min = start;
+    }
+    value = ~ value;
+    value &= mask;
+    if (value == 0)
+    {
+        offset--;
+        empty = true;
+        while (empty && (--size > 0))
+        {
+            if ((value = ~ *addr--)) empty = false; else offset--;
+        }
+        if (empty) value = MSB;
+    }
+    start = offset << LOGBITS;
+    while (! (value & MSB))
+    {
+        value <<= 1;
+        start--;
+    }
+    *min = start;
+    return(true);
+}
+
+void BitVector_Interval_Copy(unsigned int *  X, unsigned int *  Y, unsigned int Xoffset,
+                             unsigned int Yoffset, unsigned int length)
+{
+    unsigned int  bitsX = bits_(X);
+    unsigned int  bitsY = bits_(Y);
+    unsigned int  source = 0;        /* silence compiler warning */
+    unsigned int  target = 0;        /* silence compiler warning */
+    unsigned int  s_lo_base;
+    unsigned int  s_hi_base;
+    unsigned int  s_lo_bit;
+    unsigned int  s_hi_bit;
+    unsigned int  s_base;
+    unsigned int  s_lower = 0;       /* silence compiler warning */
+    unsigned int  s_upper = 0;       /* silence compiler warning */
+    unsigned int  s_bits;
+    unsigned int  s_min;
+    unsigned int  s_max;
+    unsigned int  t_lo_base;
+    unsigned int  t_hi_base;
+    unsigned int  t_lo_bit;
+    unsigned int  t_hi_bit;
+    unsigned int  t_base;
+    unsigned int  t_lower = 0;       /* silence compiler warning */
+    unsigned int  t_upper = 0;       /* silence compiler warning */
+    unsigned int  t_bits;
+    unsigned int  t_min;
+    unsigned int  mask;
+    unsigned int  bits;
+    unsigned int  select;
+    boolean ascending;
+    boolean notfirst;
+    unsigned int *  Z = X;
+
+    if ((length > 0) && (Xoffset < bitsX) && (Yoffset < bitsY))
+    {
+        if ((Xoffset + length) > bitsX) length = bitsX - Xoffset;
+        if ((Yoffset + length) > bitsY) length = bitsY - Yoffset;
+
+        ascending = (Xoffset <= Yoffset);
+
+        s_lo_base = Yoffset >> LOGBITS;
+        s_lo_bit = Yoffset & MODMASK;
+        Yoffset += --length;
+        s_hi_base = Yoffset >> LOGBITS;
+        s_hi_bit = Yoffset & MODMASK;
+
+        t_lo_base = Xoffset >> LOGBITS;
+        t_lo_bit = Xoffset & MODMASK;
+        Xoffset += length;
+        t_hi_base = Xoffset >> LOGBITS;
+        t_hi_bit = Xoffset & MODMASK;
+
+        if (ascending)
+        {
+            s_base = s_lo_base;
+            t_base = t_lo_base;
+        }
+        else
+        {
+            s_base = s_hi_base;
+            t_base = t_hi_base;
+        }
+        s_bits = 0;
+        t_bits = 0;
+        Y += s_base;
+        X += t_base;
+        notfirst = false;
+        while (true)
+        {
+            if (t_bits == 0)
+            {
+                if (notfirst)
+                {
+                    *X = target;
+                    if (ascending)
+                    {
+                        if (t_base == t_hi_base) break;
+                        t_base++;
+                        X++;
+                    }
+                    else
+                    {
+                        if (t_base == t_lo_base) break;
+                        t_base--;
+                        X--;
+                    }
+                }
+                select = ((t_base == t_hi_base) << 1) | (t_base == t_lo_base);
+                switch (select)
+                {
+                    case 0:
+                        t_lower = 0;
+                        t_upper = BITS - 1;
+                        t_bits = BITS;
+                        target = 0;
+                        break;
+                    case 1:
+                        t_lower = t_lo_bit;
+                        t_upper = BITS - 1;
+                        t_bits = BITS - t_lo_bit;
+                        mask = (unsigned int) (~0L << t_lower);
+                        target = *X & ~ mask;
+                        break;
+                    case 2:
+                        t_lower = 0;
+                        t_upper = t_hi_bit;
+                        t_bits = t_hi_bit + 1;
+                        mask = (unsigned int) ((~0L << t_upper) << 1);
+                        target = *X & mask;
+                        break;
+                    case 3:
+                        t_lower = t_lo_bit;
+                        t_upper = t_hi_bit;
+                        t_bits = t_hi_bit - t_lo_bit + 1;
+                        mask = (unsigned int) (~0L << t_lower);
+                        mask &= (unsigned int) ~((~0L << t_upper) << 1);
+                        target = *X & ~ mask;
+                        break;
+                }
+            }
+            if (s_bits == 0)
+            {
+                if (notfirst)
+                {
+                    if (ascending)
+                    {
+                        if (s_base == s_hi_base) break;
+                        s_base++;
+                        Y++;
+                    }
+                    else
+                    {
+                        if (s_base == s_lo_base) break;
+                        s_base--;
+                        Y--;
+                    }
+                }
+                source = *Y;
+                select = ((s_base == s_hi_base) << 1) | (s_base == s_lo_base);
+                switch (select)
+                {
+                    case 0:
+                        s_lower = 0;
+                        s_upper = BITS - 1;
+                        s_bits = BITS;
+                        break;
+                    case 1:
+                        s_lower = s_lo_bit;
+                        s_upper = BITS - 1;
+                        s_bits = BITS - s_lo_bit;
+                        break;
+                    case 2:
+                        s_lower = 0;
+                        s_upper = s_hi_bit;
+                        s_bits = s_hi_bit + 1;
+                        break;
+                    case 3:
+                        s_lower = s_lo_bit;
+                        s_upper = s_hi_bit;
+                        s_bits = s_hi_bit - s_lo_bit + 1;
+                        break;
+                }
+            }
+            notfirst = true;
+            if (s_bits > t_bits)
+            {
+                bits = t_bits - 1;
+                if (ascending)
+                {
+                    s_min = s_lower;
+                    s_max = s_lower + bits;
+                }
+                else
+                {
+                    s_max = s_upper;
+                    s_min = s_upper - bits;
+                }
+                t_min = t_lower;
+            }
+            else
+            {
+                bits = s_bits - 1;
+                if (ascending) t_min = t_lower;
+                else           t_min = t_upper - bits;
+                s_min = s_lower;
+                s_max = s_upper;
+            }
+            bits++;
+            mask = (unsigned int) (~0L << s_min);
+            mask &= (unsigned int) ~((~0L << s_max) << 1);
+            if (s_min == t_min) target |= (source & mask);
+            else
+            {
+                if (s_min < t_min) target |= (source & mask) << (t_min-s_min);
+                else               target |= (source & mask) >> (s_min-t_min);
+            }
+            if (ascending)
+            {
+                s_lower += bits;
+                t_lower += bits;
+            }
+            else
+            {
+                s_upper -= bits;
+                t_upper -= bits;
+            }
+            s_bits -= bits;
+            t_bits -= bits;
+        }
+        *(Z+size_(Z)-1) &= mask_(Z);
+    }
+}
+
+
+unsigned int *  BitVector_Interval_Substitute(unsigned int *  X, unsigned int *  Y,
+                                      unsigned int Xoffset, unsigned int Xlength,
+                                      unsigned int Yoffset, unsigned int Ylength)
+{
+    unsigned int Xbits = bits_(X);
+    unsigned int Ybits = bits_(Y);
+    unsigned int limit;
+    unsigned int diff;
+
+    if ((Xoffset <= Xbits) && (Yoffset <= Ybits))
+    {
+        limit = Xoffset + Xlength;
+        if (limit > Xbits)
+        {
+            limit = Xbits;
+            Xlength = Xbits - Xoffset;
+        }
+        if ((Yoffset + Ylength) > Ybits)
+        {
+            Ylength = Ybits - Yoffset;
+        }
+        if (Xlength == Ylength)
+        {
+            if ((Ylength > 0) && ((X != Y) || (Xoffset != Yoffset)))
+            {
+                BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
+            }
+        }
+        else /* Xlength != Ylength */
+        {
+            if (Xlength > Ylength)
+            {
+                diff = Xlength - Ylength;
+                if (Ylength > 0) BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
+                if (limit < Xbits) BitVector_Delete(X,Xoffset+Ylength,diff,false);
+                if ((X = BitVector_Resize(X,Xbits-diff)) == NULL) return(NULL);
+            }
+            else /* Ylength > Xlength  ==>  Ylength > 0 */
+            {
+                diff = Ylength - Xlength;
+                if (X != Y)
+                {
+                    if ((X = BitVector_Resize(X,Xbits+diff)) == NULL) return(NULL);
+                    if (limit < Xbits) BitVector_Insert(X,limit,diff,false);
+                    BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
+                }
+                else /* in-place */
+                {
+                    if ((Y = X = BitVector_Resize(X,Xbits+diff)) == NULL) return(NULL);
+                    if (limit >= Xbits)
+                    {
+                        BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
+                    }
+                    else /* limit < Xbits */
+                    {
+                        BitVector_Insert(X,limit,diff,false);
+                        if ((Yoffset+Ylength) <= limit)
+                        {
+                            BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
+                        }
+                        else /* overlaps or lies above critical area */
+                        {
+                            if (limit <= Yoffset)
+                            {
+                                Yoffset += diff;
+                                BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
+                            }
+                            else /* Yoffset < limit */
+                            {
+                                Xlength = limit - Yoffset;
+                                BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Xlength);
+                                Yoffset = Xoffset + Ylength; /* = limit + diff */
+                                Xoffset += Xlength;
+                                Ylength -= Xlength;
+                                BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return(X);
+}
+
+boolean BitVector_is_empty(unsigned int *  addr)                    /* X == {} ?     */
+{
+    unsigned int  size = size_(addr);
+    boolean r = true;
+
+    if (size > 0)
+    {
+        *(addr+size-1) &= mask_(addr);
+        while (r && (size-- > 0)) r = ( *addr++ == 0 );
+    }
+    return(r);
+}
+
+boolean BitVector_is_full(unsigned int *  addr)                     /* X == ~{} ?    */
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    boolean r = false;
+    unsigned int *  last;
+
+    if (size > 0)
+    {
+        r = true;
+        last = addr + size - 1;
+        *last |= ~ mask;
+        while (r && (size-- > 0)) r = ( ~ *addr++ == 0 );
+        *last &= mask;
+    }
+    return(r);
+}
+
+boolean BitVector_equal(unsigned int *  X, unsigned int *  Y)               /* X == Y ?      */
+{
+    unsigned int  size = size_(X);
+    unsigned int  mask = mask_(X);
+    boolean r = false;
+
+    if (bits_(X) == bits_(Y))
+    {
+        r = true;
+        if (size > 0)
+        {
+            *(X+size-1) &= mask;
+            *(Y+size-1) &= mask;
+            while (r && (size-- > 0)) r = (*X++ == *Y++);
+        }
+    }
+    return(r);
+}
+
+/* X <,=,> Y ?     : unsigned     */
+signed int BitVector_Lexicompare(unsigned int *  X, unsigned int *  Y) {
+    unsigned int  bitsX = bits_(X);
+    unsigned int  bitsY = bits_(Y);
+    unsigned int  size  = size_(X);
+    boolean r = true;
+
+    if (bitsX == bitsY) {
+        if (size > 0) {
+            X += size;
+            Y += size;
+            while (r && (size-- > 0)) r = (*(--X) == *(--Y));
+        }
+        if (r) return((signed int) 0);
+        else {
+            if (*X < *Y) return((signed int) -1); else return((signed int) 1);
+        }
+    }
+    else {
+        if (bitsX < bitsY) return((signed int) -1); else return((signed int) 1);
+    }
+}
+
+signed int BitVector_Compare(unsigned int *  X, unsigned int *  Y)               /* X <,=,> Y ?   */
+{                                                           /*   signed      */
+    unsigned int  bitsX = bits_(X);
+    unsigned int  bitsY = bits_(Y);
+    unsigned int  size  = size_(X);
+    unsigned int  mask  = mask_(X);
+    unsigned int  sign;
+    boolean r = true;
+
+    if (bitsX == bitsY)
+    {
+        if (size > 0)
+        {
+            X += size;
+            Y += size;
+            mask &= ~ (mask >> 1);
+            if ((sign = (*(X-1) & mask)) != (*(Y-1) & mask))
+            {
+                if (sign) return((signed int) -1); else return((signed int) 1);
+            }
+            while (r && (size-- > 0)) r = (*(--X) == *(--Y));
+        }
+        if (r) return((signed int) 0);
+        else
+        {
+            if (*X < *Y) return((signed int) -1); else return((signed int) 1);
+        }
+    }
+    else
+    {
+        if (bitsX < bitsY) return((signed int) -1); else return((signed int) 1);
+    }
+}
+
+size_t BitVector_Hash(unsigned int * addr)
+{
+  unsigned int  bits = bits_(addr);
+  unsigned int  size = size_(addr);
+  unsigned int  value;
+  unsigned int  count;
+  unsigned int  digit;
+  unsigned int  length;
+    
+  size_t result = 0;
+
+  length = bits >> 2;
+  if (bits & 0x0003) length++;
+  if (size > 0)
+    {
+      *(addr+size-1) &= mask_(addr);
+      while ((size-- > 0) && (length > 0))
+        {
+          value = *addr++;
+          count = BITS >> 2;
+          while ((count-- > 0) && (length > 0))
+            {
+              digit = value & 0x000F;
+              if (digit > 9) digit += (unsigned int) 'A' - 10;
+              else           digit += (unsigned int) '0';
+              result = 5*result + digit; length--;
+              if ((count > 0) && (length > 0)) value >>= 4;
+            }
+        }
+    }
+  return result;
+}
+
+
+unsigned char * BitVector_to_Hex(unsigned int *  addr)
+{
+    unsigned int  bits = bits_(addr);
+    unsigned int  size = size_(addr);
+    unsigned int  value;
+    unsigned int  count;
+    unsigned int  digit;
+    unsigned int  length;
+    unsigned char * string;
+
+    length = bits >> 2;
+    if (bits & 0x0003) length++;
+    string = (unsigned char *) malloc((size_t) (length+1));
+    if (string == NULL) return(NULL);
+    string += length;
+    *string = (unsigned char) '\0';
+    if (size > 0)
+    {
+        *(addr+size-1) &= mask_(addr);
+        while ((size-- > 0) && (length > 0))
+        {
+            value = *addr++;
+            count = BITS >> 2;
+            while ((count-- > 0) && (length > 0))
+            {
+                digit = value & 0x000F;
+                if (digit > 9) digit += (unsigned int) 'A' - 10;
+                else           digit += (unsigned int) '0';
+                *(--string) = (unsigned char) digit; length--;
+                if ((count > 0) && (length > 0)) value >>= 4;
+            }
+        }
+    }
+    return(string);
+}
+
+ErrCode BitVector_from_Hex(unsigned int *  addr, unsigned char * string)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    boolean ok = true;
+    unsigned int  length;
+    unsigned int  value;
+    unsigned int  count;
+    int     digit;
+
+    if (size > 0)
+    {
+        length = strlen((char *) string);
+        string += length;
+        while (size-- > 0)
+        {
+            value = 0;
+            for ( count = 0; (ok && (length > 0) && (count < BITS)); count += 4 )
+            {
+                digit = (int) *(--string); length--;
+                /* separate because toupper() is likely a macro! */
+                digit = toupper(digit);
+                if ((ok = (isxdigit(digit) != 0)))
+                {
+		  if (digit >= (int) 'A') digit -= (int) 'A' - 10;
+		  else                    digit -= (int) '0';
+		  value |= (((unsigned int) digit) << count);
+                }
+            }
+            *addr++ = value;
+        }
+        *(--addr) &= mask;
+    }
+    if (ok) return(ErrCode_Ok);
+    else    return(ErrCode_Pars);
+}
+
+unsigned char * BitVector_to_Bin(unsigned int *  addr)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  value;
+    unsigned int  count;
+    unsigned int  digit;
+    unsigned int  length;
+    unsigned char * string;
+
+    length = bits_(addr);
+    string = (unsigned char *) malloc((size_t) (length+1));
+    if (string == NULL) return(NULL);
+    string += length;
+    *string = (unsigned char) '\0';
+    if (size > 0)
+    {
+        *(addr+size-1) &= mask_(addr);
+        while (size-- > 0)
+        {
+            value = *addr++;
+            count = BITS;
+            if (count > length) count = length;
+            while (count-- > 0)
+            {
+                digit = value & 0x0001;
+                digit += (unsigned int) '0';
+                *(--string) = (unsigned char) digit; length--;
+                if (count > 0) value >>= 1;
+            }
+        }
+    }
+    return(string);
+}
+
+ErrCode BitVector_from_Bin(unsigned int *  addr, unsigned char * string)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    boolean ok = true;
+    unsigned int  length;
+    unsigned int  value;
+    unsigned int  count;
+    int     digit;
+
+    if (size > 0)
+    {
+        length = strlen((char *) string);
+        string += length;
+        while (size-- > 0)
+        {
+            value = 0;
+            for ( count = 0; (ok && (length > 0) && (count < BITS)); count++ )
+            {
+                digit = (int) *(--string); length--;
+                switch (digit)
+                {
+                    case (int) '0':
+                        break;
+                    case (int) '1':
+                        value |= BITMASKTAB[count];
+                        break;
+                    default:
+                        ok = false;
+                        break;
+                }
+            }
+            *addr++ = value;
+        }
+        *(--addr) &= mask;
+    }
+    if (ok) return(ErrCode_Ok);
+    else    return(ErrCode_Pars);
+}
+
+unsigned char * BitVector_to_Dec(unsigned int *  addr)
+{
+    unsigned int  bits = bits_(addr);
+    unsigned int  length;
+    unsigned int  digits;
+    unsigned int  count;
+    unsigned int  q;
+    unsigned int  r;
+    boolean loop;
+    unsigned char * result;
+    unsigned char * string;
+    unsigned int *  quot;
+    unsigned int *  rest;
+    unsigned int *  temp;
+    unsigned int *  base;
+    signed int   sign;
+
+    length = (unsigned int) (bits / 3.3);        /* digits = bits * ln(2) / ln(10) */
+    length += 2; /* compensate for truncating & provide space for minus sign */
+    result = (unsigned char *) malloc((size_t) (length+1));    /* remember the '\0'! */
+    if (result == NULL) return(NULL);
+    string = result;
+    sign = BitVector_Sign(addr);
+    if ((bits < 4) || (sign == 0))
+    {
+        if (bits > 0) digits = *addr; else digits = (unsigned int) 0;
+        if (sign < 0) digits = ((unsigned int)(-((signed int)digits))) & mask_(addr);
+        *string++ = (unsigned char) digits + (unsigned char) '0';
+        digits = 1;
+    }
+    else
+    {
+        quot = BitVector_Create(bits,false);
+        if (quot == NULL)
+        {
+            BitVector_Dispose(result);
+            return(NULL);
+        }
+        rest = BitVector_Create(bits,false);
+        if (rest == NULL)
+        {
+            BitVector_Dispose(result);
+            BitVector_Destroy(quot);
+            return(NULL);
+        }
+        temp = BitVector_Create(bits,false);
+        if (temp == NULL)
+        {
+            BitVector_Dispose(result);
+            BitVector_Destroy(quot);
+            BitVector_Destroy(rest);
+            return(NULL);
+        }
+        base = BitVector_Create(bits,true);
+        if (base == NULL)
+        {
+            BitVector_Dispose(result);
+            BitVector_Destroy(quot);
+            BitVector_Destroy(rest);
+            BitVector_Destroy(temp);
+            return(NULL);
+        }
+        if (sign < 0) BitVector_Negate(quot,addr);
+        else           BitVector_Copy(quot,addr);
+        digits = 0;
+        *base = EXP10;
+        loop = (bits >= BITS);
+        do
+        {
+            if (loop)
+            {
+                BitVector_Copy(temp,quot);
+                if (BitVector_Div_Pos(quot,temp,base,rest))
+                {
+                    BitVector_Dispose(result); /* emergency exit */
+                    BitVector_Destroy(quot);
+                    BitVector_Destroy(rest);   /* should never occur */
+                    BitVector_Destroy(temp);   /* under normal operation */
+                    BitVector_Destroy(base);
+                    return(NULL);
+                }
+                loop = ! BitVector_is_empty(quot);
+                q = *rest;
+            }
+            else q = *quot;
+            count = LOG10;
+            while (((loop && (count-- > 0)) || ((! loop) && (q != 0))) &&
+                (digits < length))
+            {
+                if (q != 0)
+                {
+                    BIT_VECTOR_DIGITIZE(unsigned int,q,r)
+                }
+                else r = (unsigned int) '0';
+                *string++ = (unsigned char) r;
+                digits++;
+            }
+        }
+        while (loop && (digits < length));
+        BitVector_Destroy(quot);
+        BitVector_Destroy(rest);
+        BitVector_Destroy(temp);
+        BitVector_Destroy(base);
+    }
+    if ((sign < 0) && (digits < length))
+    {
+        *string++ = (unsigned char) '-';
+        digits++;
+    }
+    *string = (unsigned char) '\0';
+    BIT_VECTOR_reverse(result,digits);
+    return(result);
+}
+
+ErrCode BitVector_from_Dec(unsigned int *  addr, unsigned char * string)
+{
+    ErrCode error = ErrCode_Ok;
+    unsigned int  bits = bits_(addr);
+    unsigned int  mask = mask_(addr);
+    boolean init = (bits > BITS);
+    boolean minus;
+    boolean shift;
+    boolean carry;
+    unsigned int *  term;
+    unsigned int *  base;
+    unsigned int *  prod;
+    unsigned int *  rank;
+    unsigned int *  temp;
+    unsigned int  accu;
+    unsigned int  powr;
+    unsigned int  count;
+    unsigned int  length;
+    int     digit;
+
+    if (bits > 0)
+    {
+        length = strlen((char *) string);
+        if (length == 0) return(ErrCode_Pars);
+        digit = (int) *string;
+        if ((minus = (digit == (int) '-')) ||
+                     (digit == (int) '+'))
+        {
+            string++;
+            if (--length == 0) return(ErrCode_Pars);
+        }
+        string += length;
+        term = BitVector_Create(BITS,false);
+        if (term == NULL)
+        {
+            return(ErrCode_Null);
+        }
+        base = BitVector_Create(BITS,false);
+        if (base == NULL)
+        {
+            BitVector_Destroy(term);
+            return(ErrCode_Null);
+        }
+        prod = BitVector_Create(bits,init);
+        if (prod == NULL)
+        {
+            BitVector_Destroy(term);
+            BitVector_Destroy(base);
+            return(ErrCode_Null);
+        }
+        rank = BitVector_Create(bits,init);
+        if (rank == NULL)
+        {
+            BitVector_Destroy(term);
+            BitVector_Destroy(base);
+            BitVector_Destroy(prod);
+            return(ErrCode_Null);
+        }
+        temp = BitVector_Create(bits,false);
+        if (temp == NULL)
+        {
+            BitVector_Destroy(term);
+            BitVector_Destroy(base);
+            BitVector_Destroy(prod);
+            BitVector_Destroy(rank);
+            return(ErrCode_Null);
+        }
+        BitVector_Empty(addr);
+        *base = EXP10;
+        shift = false;
+        while ((! error) && (length > 0))
+        {
+            accu = 0;
+            powr = 1;
+            count = LOG10;
+            while ((! error) && (length > 0) && (count-- > 0))
+            {
+                digit = (int) *(--string); length--;
+                /* separate because isdigit() is likely a macro! */
+                if (isdigit(digit) != 0)
+                {
+                    accu += ((unsigned int) digit - (unsigned int) '0') * powr;
+                    powr *= 10;
+                }
+                else error = ErrCode_Pars;
+            }
+            if (! error)
+            {
+                if (shift)
+                {
+                    *term = accu;
+                    BitVector_Copy(temp,rank);
+                    error = BitVector_Mul_Pos(prod,temp,term,false);
+                }
+                else
+                {
+                    *prod = accu;
+                    if ((! init) && ((accu & ~ mask) != 0)) error = ErrCode_Ovfl;
+                }
+                if (! error)
+                {
+                    carry = false;
+                    BitVector_compute(addr,addr,prod,false,&carry);
+                    /* ignores sign change (= overflow) but ! */
+                    /* numbers too large (= carry) for resulting bit vector */
+                    if (carry) error = ErrCode_Ovfl;
+                    else
+                    {
+                        if (length > 0)
+                        {
+                            if (shift)
+                            {
+                                BitVector_Copy(temp,rank);
+                                error = BitVector_Mul_Pos(rank,temp,base,false);
+                            }
+                            else
+                            {
+                                *rank = *base;
+                                shift = true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        BitVector_Destroy(term);
+        BitVector_Destroy(base);
+        BitVector_Destroy(prod);
+        BitVector_Destroy(rank);
+        BitVector_Destroy(temp);
+        if (! error && minus)
+        {
+            BitVector_Negate(addr,addr);
+            if ((*(addr + size_(addr) - 1) & mask & ~ (mask >> 1)) == 0)
+                error = ErrCode_Ovfl;
+        }
+    }
+    return(error);
+}
+
+unsigned char * BitVector_to_Enum(unsigned int *  addr)
+{
+    unsigned int  bits = bits_(addr);
+    unsigned int  sample;
+    unsigned int  length;
+    unsigned int  digits;
+    unsigned int  factor;
+    unsigned int  power;
+    unsigned int  start;
+    unsigned int  min;
+    unsigned int  max;
+    unsigned char * string;
+    unsigned char * target;
+    boolean comma;
+
+    if (bits > 0)
+    {
+        sample = bits - 1;  /* greatest possible index */
+        length = 2;         /* account for index 0 && terminating '\0' */
+        digits = 1;         /* account for intervening dashes && commas */
+        factor = 1;
+        power = 10;
+        while (sample >= (power-1))
+        {
+            length += ++digits * factor * 6;  /* 9,90,900,9000,... (9*2/3 = 6) */
+            factor = power;
+            power *= 10;
+        }
+        if (sample > --factor)
+        {
+            sample -= factor;
+            factor = (unsigned int) ( sample / 3 );
+            factor = (factor << 1) + (sample - (factor * 3));
+            length += ++digits * factor;
+        }
+    }
+    else length = 1;
+    string = (unsigned char *) malloc((size_t) length);
+    if (string == NULL) return(NULL);
+    start = 0;
+    comma = false;
+    target = string;
+    while ((start < bits) && BitVector_interval_scan_inc(addr,start,&min,&max))
+    {
+        start = max + 2;
+        if (comma) *target++ = (unsigned char) ',';
+        if (min == max)
+        {
+            target += BIT_VECTOR_int2str(target,min);
+        }
+        else
+        {
+            if (min+1 == max)
+            {
+                target += BIT_VECTOR_int2str(target,min);
+                *target++ = (unsigned char) ',';
+                target += BIT_VECTOR_int2str(target,max);
+            }
+            else
+            {
+                target += BIT_VECTOR_int2str(target,min);
+                *target++ = (unsigned char) '-';
+                target += BIT_VECTOR_int2str(target,max);
+            }
+        }
+        comma = true;
+    }
+    *target = (unsigned char) '\0';
+    return(string);
+}
+
+ErrCode BitVector_from_Enum(unsigned int *  addr, unsigned char * string)
+{
+    ErrCode error = ErrCode_Ok;
+    unsigned int  bits = bits_(addr);
+    unsigned int  state = 1;
+    unsigned int  token;
+    unsigned int  index = 0;
+    unsigned int  start = 0;         /* silence compiler warning */
+
+    if (bits > 0)
+    {
+        BitVector_Empty(addr);
+        while ((! error) && (state != 0))
+        {
+            token = (unsigned int) *string;
+            /* separate because isdigit() is likely a macro! */
+            if (isdigit((int)token) != 0)
+            {
+                string += BIT_VECTOR_str2int(string,&index);
+                if (index < bits) token = (unsigned int) '0';
+                else error = ErrCode_Indx;
+            }
+            else string++;
+            if (! error)
+            switch (state)
+            {
+                case 1:
+                    switch (token)
+                    {
+                        case (unsigned int) '0':
+                            state = 2;
+                            break;
+                        case (unsigned int) '\0':
+                            state = 0;
+                            break;
+                        default:
+                            error = ErrCode_Pars;
+                            break;
+                    }
+                    break;
+                case 2:
+                    switch (token)
+                    {
+                        case (unsigned int) '-':
+                            start = index;
+                            state = 3;
+                            break;
+                        case (unsigned int) ',':
+                            BIT_VECTOR_SET_BIT(addr,index)
+                            state = 5;
+                            break;
+                        case (unsigned int) '\0':
+                            BIT_VECTOR_SET_BIT(addr,index)
+                            state = 0;
+                            break;
+                        default:
+                            error = ErrCode_Pars;
+                            break;
+                    }
+                    break;
+                case 3:
+                    switch (token)
+                    {
+                        case (unsigned int) '0':
+                            if (start < index)
+                                BitVector_Interval_Fill(addr,start,index);
+                            else if (start == index)
+                                BIT_VECTOR_SET_BIT(addr,index)
+                            else error = ErrCode_Ordr;
+                            state = 4;
+                            break;
+                        default:
+                            error = ErrCode_Pars;
+                            break;
+                    }
+                    break;
+                case 4:
+                    switch (token)
+                    {
+                        case (unsigned int) ',':
+                            state = 5;
+                            break;
+                        case (unsigned int) '\0':
+                            state = 0;
+                            break;
+                        default:
+                            error = ErrCode_Pars;
+                            break;
+                    }
+                    break;
+                case 5:
+                    switch (token)
+                    {
+                        case (unsigned int) '0':
+                            state = 2;
+                            break;
+                        default:
+                            error = ErrCode_Pars;
+                            break;
+                    }
+                    break;
+            }
+        }
+    }
+    return(error);
+}
+
+void BitVector_Bit_Off(unsigned int *  addr, unsigned int index)           /* X = X \ {x}   */
+{
+    if (index < bits_(addr)) BIT_VECTOR_CLR_BIT(addr,index)
+}
+
+void BitVector_Bit_On(unsigned int *  addr, unsigned int index)            /* X = X + {x}   */
+{
+    if (index < bits_(addr)) BIT_VECTOR_SET_BIT(addr,index)
+}
+
+boolean BitVector_bit_flip(unsigned int *  addr, unsigned int index)   /* X=(X+{x})\(X*{x}) */
+{
+    unsigned int mask;
+
+    if (index < bits_(addr)) return( BIT_VECTOR_FLP_BIT(addr,index,mask) );
+    else                     return( false );
+}
+
+boolean BitVector_bit_test(unsigned int *  addr, unsigned int index)       /* {x} in X ?    */
+{
+    if (index < bits_(addr)) return( BIT_VECTOR_TST_BIT(addr,index) );
+    else                     return( false );
+}
+
+void BitVector_Bit_Copy(unsigned int *  addr, unsigned int index, boolean bit)
+{
+    if (index < bits_(addr))
+    {
+        if (bit) BIT_VECTOR_SET_BIT(addr,index)
+        else     BIT_VECTOR_CLR_BIT(addr,index)
+    }
+}
+
+void BitVector_LSB(unsigned int *  addr, boolean bit)
+{
+    if (bits_(addr) > 0)
+    {
+        if (bit) *addr |= LSB;
+        else     *addr &= ~ LSB;
+    }
+}
+
+void BitVector_MSB(unsigned int *  addr, boolean bit)
+{
+    unsigned int size = size_(addr);
+    unsigned int mask = mask_(addr);
+
+    if (size-- > 0)
+    {
+        if (bit) *(addr+size) |= mask & ~ (mask >> 1);
+        else     *(addr+size) &= ~ mask | (mask >> 1);
+    }
+}
+
+boolean BitVector_lsb_(unsigned int *  addr)
+{
+    if (size_(addr) > 0) return( (*addr & LSB) != 0 );
+    else                 return( false );
+}
+
+boolean BitVector_msb_(unsigned int *  addr)
+{
+    unsigned int size = size_(addr);
+    unsigned int mask = mask_(addr);
+
+    if (size-- > 0)
+        return( (*(addr+size) & (mask & ~ (mask >> 1))) != 0 );
+    else
+        return( false );
+}
+
+boolean BitVector_rotate_left(unsigned int *  addr)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int  msb;
+    boolean carry_in;
+    boolean carry_out = false;
+
+    if (size > 0)
+    {
+        msb = mask & ~ (mask >> 1);
+        carry_in = ((*(addr+size-1) & msb) != 0);
+        while (size-- > 1)
+        {
+            carry_out = ((*addr & MSB) != 0);
+            *addr <<= 1;
+            if (carry_in) *addr |= LSB;
+            carry_in = carry_out;
+            addr++;
+        }
+        carry_out = ((*addr & msb) != 0);
+        *addr <<= 1;
+        if (carry_in) *addr |= LSB;
+        *addr &= mask;
+    }
+    return(carry_out);
+}
+
+boolean BitVector_rotate_right(unsigned int *  addr)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int  msb;
+    boolean carry_in;
+    boolean carry_out = false;
+
+    if (size > 0)
+    {
+        msb = mask & ~ (mask >> 1);
+        carry_in = ((*addr & LSB) != 0);
+        addr += size-1;
+        *addr &= mask;
+        carry_out = ((*addr & LSB) != 0);
+        *addr >>= 1;
+        if (carry_in) *addr |= msb;
+        carry_in = carry_out;
+        addr--;
+        size--;
+        while (size-- > 0)
+        {
+            carry_out = ((*addr & LSB) != 0);
+            *addr >>= 1;
+            if (carry_in) *addr |= MSB;
+            carry_in = carry_out;
+            addr--;
+        }
+    }
+    return(carry_out);
+}
+
+boolean BitVector_shift_left(unsigned int *  addr, boolean carry_in)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int  msb;
+    boolean carry_out = carry_in;
+
+    if (size > 0)
+    {
+        msb = mask & ~ (mask >> 1);
+        while (size-- > 1)
+        {
+            carry_out = ((*addr & MSB) != 0);
+            *addr <<= 1;
+            if (carry_in) *addr |= LSB;
+            carry_in = carry_out;
+            addr++;
+        }
+        carry_out = ((*addr & msb) != 0);
+        *addr <<= 1;
+        if (carry_in) *addr |= LSB;
+        *addr &= mask;
+    }
+    return(carry_out);
+}
+
+boolean BitVector_shift_right(unsigned int *  addr, boolean carry_in)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int  msb;
+    boolean carry_out = carry_in;
+
+    if (size > 0)
+    {
+        msb = mask & ~ (mask >> 1);
+        addr += size-1;
+        *addr &= mask;
+        carry_out = ((*addr & LSB) != 0);
+        *addr >>= 1;
+        if (carry_in) *addr |= msb;
+        carry_in = carry_out;
+        addr--;
+        size--;
+        while (size-- > 0)
+        {
+            carry_out = ((*addr & LSB) != 0);
+            *addr >>= 1;
+            if (carry_in) *addr |= MSB;
+            carry_in = carry_out;
+            addr--;
+        }
+    }
+    return(carry_out);
+}
+
+void BitVector_Move_Left(unsigned int *  addr, unsigned int bits)
+{
+    unsigned int count;
+    unsigned int words;
+
+    if (bits > 0)
+    {
+        count = bits & MODMASK;
+        words = bits >> LOGBITS;
+        if (bits >= bits_(addr)) BitVector_Empty(addr);
+        else
+        {
+            while (count-- > 0) BitVector_shift_left(addr,0);
+            BitVector_Word_Insert(addr,0,words,true);
+        }
+    }
+}
+
+void BitVector_Move_Right(unsigned int *  addr, unsigned int bits)
+{
+    unsigned int count;
+    unsigned int words;
+
+    if (bits > 0)
+    {
+        count = bits & MODMASK;
+        words = bits >> LOGBITS;
+        if (bits >= bits_(addr)) BitVector_Empty(addr);
+        else
+        {
+            while (count-- > 0) BitVector_shift_right(addr,0);
+            BitVector_Word_Delete(addr,0,words,true);
+        }
+    }
+}
+
+void BitVector_Insert(unsigned int *  addr, unsigned int offset, unsigned int count, boolean clear)
+{
+    unsigned int bits = bits_(addr);
+    unsigned int last;
+
+    if ((count > 0) && (offset < bits))
+    {
+        last = offset + count;
+        if (last < bits)
+        {
+            BitVector_Interval_Copy(addr,addr,last,offset,(bits-last));
+        }
+        else last = bits;
+        if (clear) BitVector_Interval_Empty(addr,offset,(last-1));
+    }
+}
+
+void BitVector_Delete(unsigned int *  addr, unsigned int offset, unsigned int count, boolean clear)
+{
+    unsigned int bits = bits_(addr);
+    unsigned int last;
+
+    if ((count > 0) && (offset < bits))
+    {
+        last = offset + count;
+        if (last < bits)
+        {
+            BitVector_Interval_Copy(addr,addr,offset,last,(bits-last));
+        }
+        else count = bits - offset;
+        if (clear) BitVector_Interval_Empty(addr,(bits-count),(bits-1));
+    }
+}
+
+boolean BitVector_increment(unsigned int *  addr)                   /* X++           */
+{
+    unsigned int  size  = size_(addr);
+    unsigned int  mask  = mask_(addr);
+    unsigned int *  last  = addr + size - 1;
+    boolean carry = true;
+
+    if (size > 0)
+    {
+        *last |= ~ mask;
+        while (carry && (size-- > 0))
+        {
+            carry = (++(*addr++) == 0);
+        }
+        *last &= mask;
+    }
+    return(carry);
+}
+
+boolean BitVector_decrement(unsigned int *  addr)                   /* X--           */
+{
+    unsigned int  size  = size_(addr);
+    unsigned int  mask  = mask_(addr);
+    unsigned int *  last  = addr + size - 1;
+    boolean carry = true;
+
+    if (size > 0)
+    {
+        *last &= mask;
+        while (carry && (size-- > 0))
+        {
+            carry = (*addr == 0);
+            --(*addr++);
+        }
+        *last &= mask;
+    }
+    return(carry);
+}
+
+boolean BitVector_compute(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean minus, boolean *carry)
+{
+    unsigned int size = size_(X);
+    unsigned int mask = mask_(X);
+    unsigned int vv = 0;
+    unsigned int cc;
+    unsigned int mm;
+    unsigned int yy;
+    unsigned int zz;
+    unsigned int lo;
+    unsigned int hi;
+
+    if (size > 0)
+    {
+        if (minus) cc = (*carry == 0);
+        else       cc = (*carry != 0);
+        /* deal with (size-1) least significant full words first: */
+        while (--size > 0)
+        {
+            yy = *Y++;
+            if (minus) zz = (unsigned int) ~ ( Z ? *Z++ : 0 );
+            else       zz = (unsigned int)     ( Z ? *Z++ : 0 );
+            lo = (yy & LSB) + (zz & LSB) + cc;
+            hi = (yy >> 1) + (zz >> 1) + (lo >> 1);
+            cc = ((hi & MSB) != 0);
+            *X++ = (hi << 1) | (lo & LSB);
+        }
+        /* deal with most significant word (may be used only partially): */
+        yy = *Y & mask;
+        if (minus) zz = (unsigned int) ~ ( Z ? *Z : 0 );
+        else       zz = (unsigned int)     ( Z ? *Z : 0 );
+        zz &= mask;
+        if (mask == LSB) /* special case, only one bit used */
+        {
+            vv = cc;
+            lo = yy + zz + cc;
+            cc = (lo >> 1);
+            vv ^= cc;
+            *X = lo & LSB;
+        }
+        else
+        {
+            if (~ mask) /* not all bits are used, but more than one */
+            {
+                mm = (mask >> 1);
+                vv = (yy & mm) + (zz & mm) + cc;
+                mm = mask & ~ mm;
+                lo = yy + zz + cc;
+                cc = (lo >> 1);
+                vv ^= cc;
+                vv &= mm;
+                cc &= mm;
+                *X = lo & mask;
+            }
+            else /* other special case, all bits are used */
+            {
+                mm = ~ MSB;
+                lo = (yy & mm) + (zz & mm) + cc;
+                vv = lo & MSB;
+                hi = ((yy & MSB) >> 1) + ((zz & MSB) >> 1) + (vv >> 1);
+                cc = hi & MSB;
+                vv ^= cc;
+                *X = (hi << 1) | (lo & mm);
+            }
+        }
+        if (minus) *carry = (cc == 0);
+        else       *carry = (cc != 0);
+    }
+    return(vv != 0);
+}
+
+boolean BitVector_add(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean *carry)
+{
+    return(BitVector_compute(X,Y,Z,false,carry));
+}
+
+boolean BitVector_sub(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean *carry)
+{
+    return(BitVector_compute(X,Y,Z,true,carry));
+}
+
+boolean BitVector_inc(unsigned int *  X, unsigned int *  Y)
+{
+    boolean carry = true;
+
+    return(BitVector_compute(X,Y,NULL,false,&carry));
+}
+
+boolean BitVector_dec(unsigned int *  X, unsigned int *  Y)
+{
+    boolean carry = true;
+
+    return(BitVector_compute(X,Y,NULL,true,&carry));
+}
+
+void BitVector_Negate(unsigned int *  X, unsigned int *  Y)
+{
+    unsigned int  size  = size_(X);
+    unsigned int  mask  = mask_(X);
+    boolean carry = true;
+
+    if (size > 0)
+    {
+        while (size-- > 0)
+        {
+            *X = ~ *Y++;
+            if (carry)
+            {
+                carry = (++(*X) == 0);
+            }
+            X++;
+        }
+        *(--X) &= mask;
+    }
+}
+
+void BitVector_Absolute(unsigned int *  X, unsigned int *  Y)
+{
+    unsigned int size = size_(Y);
+    unsigned int mask = mask_(Y);
+
+    if (size > 0)
+    {
+        if (*(Y+size-1) & (mask & ~ (mask >> 1))) BitVector_Negate(X,Y);
+        else                                             BitVector_Copy(X,Y);
+    }
+}
+
+// FIXME:  What the hell does the return value of this mean?
+// It returns 0, 1, or -1 under mysterious circumstances.
+signed int BitVector_Sign(unsigned int *  addr)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int *  last = addr + size - 1;
+    boolean r    = true;
+
+    if (size > 0)
+    {
+        *last &= mask;
+        while (r && (size-- > 0)) r = ( *addr++ == 0 );
+    }
+    if (r) return((signed int) 0);
+    else
+    {
+        if (*last & (mask & ~ (mask >> 1))) return((signed int) -1);
+        else                                      return((signed int)  1);
+    }
+}
+
+ErrCode BitVector_Mul_Pos(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean strict)
+{
+    unsigned int  mask;
+    unsigned int  limit;
+    unsigned int  count;
+    signed long  last;
+    unsigned int *  sign;
+    boolean carry;
+    boolean overflow;
+    boolean ok = true;
+
+    /*
+       Requirements:
+         -  X, Y && Z must be distinct
+         -  X && Y must have equal sizes (whereas Z may be any size!)
+         -  Z should always contain the SMALLER of the two factors Y && Z
+       Constraints:
+         -  The contents of Y (&& of X, of course) are destroyed
+            (only Z is preserved!)
+    */
+
+    if ((X == Y) || (X == Z) || (Y == Z)) return(ErrCode_Same);
+    if (bits_(X) != bits_(Y)) return(ErrCode_Size);
+    BitVector_Empty(X);
+    if (BitVector_is_empty(Y)) return(ErrCode_Ok); /* exit also taken if bits_(Y)==0 */
+    if ((last = Set_Max(Z)) < 0L) return(ErrCode_Ok);
+    limit = (unsigned int) last;
+    sign = Y + size_(Y) - 1;
+    mask = mask_(Y);
+    *sign &= mask;
+    mask &= ~ (mask >> 1);
+    for ( count = 0; (ok && (count <= limit)); count++ )
+    {
+        if ( BIT_VECTOR_TST_BIT(Z,count) )
+        {
+            carry = false;
+            overflow = BitVector_compute(X,X,Y,false,&carry);
+            if (strict) ok = ! (carry || overflow);
+            else        ok = !  carry;
+        }
+        if (ok && (count < limit))
+        {
+            carry = BitVector_shift_left(Y,0);
+            if (strict)
+            {
+                overflow = ((*sign & mask) != 0);
+                ok = ! (carry || overflow);
+            }
+            else ok = ! carry;
+        }
+    }
+    if (ok) return(ErrCode_Ok); else return(ErrCode_Ovfl);
+}
+
+ErrCode BitVector_Multiply(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
+{
+    ErrCode error = ErrCode_Ok;
+    unsigned int  bit_x = bits_(X);
+    unsigned int  bit_y = bits_(Y);
+    unsigned int  bit_z = bits_(Z);
+    unsigned int  size;
+    unsigned int  mask;
+    unsigned int  msb;
+    unsigned int *  ptr_y;
+    unsigned int *  ptr_z;
+    boolean sgn_x;
+    boolean sgn_y;
+    boolean sgn_z;
+    boolean zero;
+    unsigned int *  A;
+    unsigned int *  B;
+
+    /*
+       Requirements:
+         -  Y && Z must have equal sizes
+         -  X must have at least the same size as Y && Z but may be larger (!)
+       Features:
+         -  The contents of Y && Z are preserved
+         -  X may be identical with Y or Z (or both!)
+            (in-place multiplication is possible!)
+    */
+
+    if ((bit_y != bit_z) || (bit_x < bit_y)) return(ErrCode_Size);
+    if (BitVector_is_empty(Y) || BitVector_is_empty(Z))
+    {
+        BitVector_Empty(X);
+    }
+    else
+    {
+        A = BitVector_Create(bit_y,false);
+        if (A == NULL) return(ErrCode_Null);
+        B = BitVector_Create(bit_z,false);
+        if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
+        size  = size_(Y);
+        mask  = mask_(Y);
+        msb   = (mask & ~ (mask >> 1));
+        sgn_y = (((*(Y+size-1) &= mask) & msb) != 0);
+        sgn_z = (((*(Z+size-1) &= mask) & msb) != 0);
+        sgn_x = sgn_y ^ sgn_z;
+        if (sgn_y) BitVector_Negate(A,Y); else BitVector_Copy(A,Y);
+        if (sgn_z) BitVector_Negate(B,Z); else BitVector_Copy(B,Z);
+        ptr_y = A + size;
+        ptr_z = B + size;
+        zero = true;
+        while (zero && (size-- > 0))
+        {
+            zero &= (*(--ptr_y) == 0);
+            zero &= (*(--ptr_z) == 0);
+        }
+        if (*ptr_y > *ptr_z)
+        {
+            if (bit_x > bit_y)
+            {
+                A = BitVector_Resize(A,bit_x);
+                if (A == NULL) { BitVector_Destroy(B); return(ErrCode_Null); }
+            }
+            error = BitVector_Mul_Pos(X,A,B,true);
+        }
+        else
+        {
+            if (bit_x > bit_z)
+            {
+                B = BitVector_Resize(B,bit_x);
+                if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
+            }
+            error = BitVector_Mul_Pos(X,B,A,true);
+        }
+        if ((! error) && sgn_x) BitVector_Negate(X,X);
+        BitVector_Destroy(A);
+        BitVector_Destroy(B);
+    }
+    return(error);
+}
+
+ErrCode BitVector_Div_Pos(unsigned int *  Q, unsigned int *  X, unsigned int *  Y, unsigned int *  R)
+{
+    unsigned int  bits = bits_(Q);
+    unsigned int  mask;
+    unsigned int *  addr;
+    signed long  last;
+    boolean flag;
+    boolean copy = false; /* flags whether valid rest is in R (0) || X (1) */
+
+    /*
+       Requirements:
+         -  All bit vectors must have equal sizes
+         -  Q, X, Y && R must all be distinct bit vectors
+         -  Y must be non-zero (of course!)
+       Constraints:
+         -  The contents of X (&& Q && R, of course) are destroyed
+            (only Y is preserved!)
+    */
+
+    if ((bits != bits_(X)) || (bits != bits_(Y)) || (bits != bits_(R)))
+        return(ErrCode_Size);
+    if ((Q == X) || (Q == Y) || (Q == R) || (X == Y) || (X == R) || (Y == R))
+        return(ErrCode_Same);
+    if (BitVector_is_empty(Y))
+        return(ErrCode_Zero);
+
+    BitVector_Empty(R);
+    BitVector_Copy(Q,X);
+    if ((last = Set_Max(Q)) < 0L) return(ErrCode_Ok);
+    bits = (unsigned int) ++last;
+    while (bits-- > 0)
+    {
+        addr = Q + (bits >> LOGBITS);
+        mask = BITMASKTAB[bits & MODMASK];
+        flag = ((*addr & mask) != 0);
+        if (copy)
+        {
+            BitVector_shift_left(X,flag);
+            flag = false;
+            BitVector_compute(R,X,Y,true,&flag);
+        }
+        else
+        {
+            BitVector_shift_left(R,flag);
+            flag = false;
+            BitVector_compute(X,R,Y,true,&flag);
+        }
+        if (flag) *addr &= ~ mask;
+        else
+        {
+            *addr |= mask;
+            copy = ! copy;
+        }
+    }
+    if (copy) BitVector_Copy(R,X);
+    return(ErrCode_Ok);
+}
+
+ErrCode BitVector_Divide(unsigned int *  Q, unsigned int *  X, unsigned int *  Y, unsigned int *  R)
+{
+    ErrCode error = ErrCode_Ok;
+    unsigned int  bits = bits_(Q);
+    unsigned int  size = size_(Q);
+    unsigned int  mask = mask_(Q);
+    unsigned int  msb = (mask & ~ (mask >> 1));
+    boolean sgn_q;
+    boolean sgn_x;
+    boolean sgn_y;
+    unsigned int *  A;
+    unsigned int *  B;
+
+    /*
+       Requirements:
+         -  All bit vectors must have equal sizes
+         -  Q && R must be two distinct bit vectors
+         -  Y must be non-zero (of course!)
+       Features:
+         -  The contents of X && Y are preserved
+         -  Q may be identical with X || Y (or both)
+            (in-place division is possible!)
+         -  R may be identical with X || Y (or both)
+            (but not identical with Q!)
+    */
+
+    if ((bits != bits_(X)) || (bits != bits_(Y)) || (bits != bits_(R)))
+        return(ErrCode_Size);
+    if (Q == R)
+        return(ErrCode_Same);
+    if (BitVector_is_empty(Y))
+        return(ErrCode_Zero);
+
+    if (BitVector_is_empty(X))
+    {
+        BitVector_Empty(Q);
+        BitVector_Empty(R);
+    }
+    else
+    {
+        A = BitVector_Create(bits,false);
+        if (A == NULL) return(ErrCode_Null);
+        B = BitVector_Create(bits,false);
+        if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
+        size--;
+        sgn_x = (((*(X+size) &= mask) & msb) != 0);
+        sgn_y = (((*(Y+size) &= mask) & msb) != 0);
+        sgn_q = sgn_x ^ sgn_y;
+        if (sgn_x) BitVector_Negate(A,X); else BitVector_Copy(A,X);
+        if (sgn_y) BitVector_Negate(B,Y); else BitVector_Copy(B,Y);
+        if (! (error = BitVector_Div_Pos(Q,A,B,R)))
+        {
+            if (sgn_q) BitVector_Negate(Q,Q);
+            if (sgn_x) BitVector_Negate(R,R);
+        }
+        BitVector_Destroy(A);
+        BitVector_Destroy(B);
+    }
+    return(error);
+}
+
+ErrCode BitVector_GCD(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
+{
+    ErrCode error = ErrCode_Ok;
+    unsigned int  bits = bits_(X);
+    unsigned int  size = size_(X);
+    unsigned int  mask = mask_(X);
+    unsigned int  msb = (mask & ~ (mask >> 1));
+    boolean sgn_a;
+    boolean sgn_b;
+    boolean sgn_r;
+    unsigned int *  Q;
+    unsigned int *  R;
+    unsigned int *  A;
+    unsigned int *  B;
+    unsigned int *  T;
+
+    /*
+       Requirements:
+         -  All bit vectors must have equal sizes
+       Features:
+         -  The contents of Y && Z are preserved
+         -  X may be identical with Y || Z (or both)
+            (in-place is possible!)
+         -  GCD(0,z) == GCD(z,0) == z
+         -  negative values are h&&led correctly
+    */
+
+    if ((bits != bits_(Y)) || (bits != bits_(Z))) return(ErrCode_Size);
+    if (BitVector_is_empty(Y))
+    {
+        if (X != Z) BitVector_Copy(X,Z);
+        return(ErrCode_Ok);
+    }
+    if (BitVector_is_empty(Z))
+    {
+        if (X != Y) BitVector_Copy(X,Y);
+        return(ErrCode_Ok);
+    }
+    Q = BitVector_Create(bits,false);
+    if (Q == NULL)
+    {
+        return(ErrCode_Null);
+    }
+    R = BitVector_Create(bits,false);
+    if (R == NULL)
+    {
+        BitVector_Destroy(Q);
+        return(ErrCode_Null);
+    }
+    A = BitVector_Create(bits,false);
+    if (A == NULL)
+    {
+        BitVector_Destroy(Q);
+        BitVector_Destroy(R);
+        return(ErrCode_Null);
+    }
+    B = BitVector_Create(bits,false);
+    if (B == NULL)
+    {
+        BitVector_Destroy(Q);
+        BitVector_Destroy(R);
+        BitVector_Destroy(A);
+        return(ErrCode_Null);
+    }
+    size--;
+    sgn_a = (((*(Y+size) &= mask) & msb) != 0);
+    sgn_b = (((*(Z+size) &= mask) & msb) != 0);
+    if (sgn_a) BitVector_Negate(A,Y); else BitVector_Copy(A,Y);
+    if (sgn_b) BitVector_Negate(B,Z); else BitVector_Copy(B,Z);
+    while (! error)
+    {
+        if (! (error = BitVector_Div_Pos(Q,A,B,R)))
+        {
+            if (BitVector_is_empty(R)) break;
+            T = A; sgn_r = sgn_a;
+            A = B; sgn_a = sgn_b;
+            B = R; sgn_b = sgn_r;
+            R = T;
+        }
+    }
+    if (! error)
+    {
+        if (sgn_b) BitVector_Negate(X,B); else BitVector_Copy(X,B);
+    }
+    BitVector_Destroy(Q);
+    BitVector_Destroy(R);
+    BitVector_Destroy(A);
+    BitVector_Destroy(B);
+    return(error);
+}
+
+ErrCode BitVector_GCD2(unsigned int *  U, unsigned int *  V, unsigned int *  W, unsigned int *  X, unsigned int *  Y)
+{
+    ErrCode error = ErrCode_Ok;
+    unsigned int  bits = bits_(U);
+    unsigned int  size = size_(U);
+    unsigned int  mask = mask_(U);
+    unsigned int  msb = (mask & ~ (mask >> 1));
+    boolean minus;
+    boolean carry;
+    boolean sgn_q;
+    boolean sgn_r;
+    boolean sgn_a;
+    boolean sgn_b;
+    boolean sgn_x;
+    boolean sgn_y;
+    unsigned int *  *  L;
+    unsigned int *  Q;
+    unsigned int *  R;
+    unsigned int *  A;
+    unsigned int *  B;
+    unsigned int *  T;
+    unsigned int *  X1;
+    unsigned int *  X2;
+    unsigned int *  X3;
+    unsigned int *  Y1;
+    unsigned int *  Y2;
+    unsigned int *  Y3;
+    unsigned int *  Z;
+
+    /*
+       Requirements:
+         -  All bit vectors must have equal sizes
+         -  U, V, && W must all be distinct bit vectors
+       Features:
+         -  The contents of X && Y are preserved
+         -  U, V && W may be identical with X || Y (or both,
+            provided that U, V && W are mutually distinct)
+            (i.e., in-place is possible!)
+         -  GCD(0,z) == GCD(z,0) == z
+         -  negative values are h&&led correctly
+    */
+
+    if ((bits != bits_(V)) ||
+        (bits != bits_(W)) ||
+        (bits != bits_(X)) ||
+        (bits != bits_(Y)))
+    {
+        return(ErrCode_Size);
+    }
+    if ((U == V) || (U == W) || (V == W))
+    {
+        return(ErrCode_Same);
+    }
+    if (BitVector_is_empty(X))
+    {
+        if (U != Y) BitVector_Copy(U,Y);
+        BitVector_Empty(V);
+        BitVector_Empty(W);
+        *W = 1;
+        return(ErrCode_Ok);
+    }
+    if (BitVector_is_empty(Y))
+    {
+        if (U != X) BitVector_Copy(U,X);
+        BitVector_Empty(V);
+        BitVector_Empty(W);
+        *V = 1;
+        return(ErrCode_Ok);
+    }
+    if ((L = BitVector_Create_List(bits,false,11)) == NULL)
+    {
+        return(ErrCode_Null);
+    }
+    Q  = L[0];
+    R  = L[1];
+    A  = L[2];
+    B  = L[3];
+    X1 = L[4];
+    X2 = L[5];
+    X3 = L[6];
+    Y1 = L[7];
+    Y2 = L[8];
+    Y3 = L[9];
+    Z  = L[10];
+    size--;
+    sgn_a = (((*(X+size) &= mask) & msb) != 0);
+    sgn_b = (((*(Y+size) &= mask) & msb) != 0);
+    if (sgn_a) BitVector_Negate(A,X); else BitVector_Copy(A,X);
+    if (sgn_b) BitVector_Negate(B,Y); else BitVector_Copy(B,Y);
+    BitVector_Empty(X1);
+    BitVector_Empty(X2);
+    *X1 = 1;
+    BitVector_Empty(Y1);
+    BitVector_Empty(Y2);
+    *Y2 = 1;
+    sgn_x = false;
+    sgn_y = false;
+    while (! error)
+    {
+        if ((error = BitVector_Div_Pos(Q,A,B,R)))
+        {
+            break;
+        }
+        if (BitVector_is_empty(R))
+        {
+            break;
+        }
+        sgn_q = sgn_a ^ sgn_b;
+
+        if (sgn_x) BitVector_Negate(Z,X2); else BitVector_Copy(Z,X2);
+        if ((error = BitVector_Mul_Pos(X3,Z,Q,true)))
+        {
+            break;
+        }
+        minus = ! (sgn_x ^ sgn_q);
+        carry = 0;
+        if (BitVector_compute(X3,X1,X3,minus,&carry))
+        {
+            error = ErrCode_Ovfl;
+            break;
+        }
+        sgn_x = (((*(X3+size) &= mask) & msb) != 0);
+
+        if (sgn_y) BitVector_Negate(Z,Y2); else BitVector_Copy(Z,Y2);
+        if ((error = BitVector_Mul_Pos(Y3,Z,Q,true)))
+        {
+            break;
+        }
+        minus = ! (sgn_y ^ sgn_q);
+        carry = 0;
+        if (BitVector_compute(Y3,Y1,Y3,minus,&carry))
+        {
+            error = ErrCode_Ovfl;
+            break;
+        }
+        sgn_y = (((*(Y3+size) &= mask) & msb) != 0);
+
+        T = A; sgn_r = sgn_a;
+        A = B; sgn_a = sgn_b;
+        B = R; sgn_b = sgn_r;
+        R = T;
+
+        T = X1;
+        X1 = X2;
+        X2 = X3;
+        X3 = T;
+
+        T = Y1;
+        Y1 = Y2;
+        Y2 = Y3;
+        Y3 = T;
+    }
+    if (! error)
+    {
+        if (sgn_b) BitVector_Negate(U,B); else BitVector_Copy(U,B);
+        BitVector_Copy(V,X2);
+        BitVector_Copy(W,Y2);
+    }
+    BitVector_Destroy_List(L,11);
+    return(error);
+}
+
+ErrCode BitVector_Power(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
+{
+    ErrCode error = ErrCode_Ok;
+    unsigned int  bits  = bits_(X);
+    boolean first = true;
+    signed long  last;
+    unsigned int  limit;
+    unsigned int  count;
+    unsigned int *  T;
+
+    /*
+       Requirements:
+         -  X must have at least the same size as Y but may be larger (!)
+         -  X may not be identical with Z
+         -  Z must be positive
+       Features:
+         -  The contents of Y && Z are preserved
+    */
+
+    if (X == Z) return(ErrCode_Same);
+    if (bits < bits_(Y)) return(ErrCode_Size);
+    if (BitVector_msb_(Z)) return(ErrCode_Expo);
+    if ((last = Set_Max(Z)) < 0L)
+    {
+        if (bits < 2) return(ErrCode_Ovfl);
+        BitVector_Empty(X);
+        *X |= LSB;
+        return(ErrCode_Ok);                             /* anything ^ 0 == 1 */
+    }
+    if (BitVector_is_empty(Y))
+    {
+        if (X != Y) BitVector_Empty(X);
+        return(ErrCode_Ok);                    /* 0 ^ anything ! zero == 0 */
+    }
+    T = BitVector_Create(bits,false);
+    if (T == NULL) return(ErrCode_Null);
+    limit = (unsigned int) last;
+    for ( count = 0; ((!error) && (count <= limit)); count++ )
+    {
+        if ( BIT_VECTOR_TST_BIT(Z,count) )
+        {
+            if (first)
+            {
+                first = false;
+                if (count) {             BitVector_Copy(X,T); }
+                else       { if (X != Y) BitVector_Copy(X,Y); }
+            }
+            else error = BitVector_Multiply(X,T,X); /* order important because T > X */
+        }
+        if ((!error) && (count < limit))
+        {
+            if (count) error = BitVector_Multiply(T,T,T);
+            else       error = BitVector_Multiply(T,Y,Y);
+        }
+    }
+    BitVector_Destroy(T);
+    return(error);
+}
+
+void BitVector_Block_Store(unsigned int *  addr, unsigned char * buffer, unsigned int length)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int  value;
+    unsigned int  count;
+
+    /* provide translation for independence of endian-ness: */
+    if (size > 0)
+    {
+        while (size-- > 0)
+        {
+            value = 0;
+            for ( count = 0; (length > 0) && (count < BITS); count += 8 )
+            {
+                value |= (((unsigned int) *buffer++) << count); length--;
+            }
+            *addr++ = value;
+        }
+        *(--addr) &= mask;
+    }
+}
+
+unsigned char * BitVector_Block_Read(unsigned int *  addr, unsigned int * length)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  value;
+    unsigned int  count;
+    unsigned char * buffer;
+    unsigned char * target;
+
+    /* provide translation for independence of endian-ness: */
+    *length = size << FACTOR;
+    buffer = (unsigned char *) malloc((size_t) ((*length)+1));
+    if (buffer == NULL) return(NULL);
+    target = buffer;
+    if (size > 0)
+    {
+        *(addr+size-1) &= mask_(addr);
+        while (size-- > 0)
+        {
+            value = *addr++;
+            count = BITS >> 3;
+            while (count-- > 0)
+            {
+                *target++ = (unsigned char) (value & 0x00FF);
+                if (count > 0) value >>= 8;
+            }
+        }
+    }
+    *target = (unsigned char) '\0';
+    return(buffer);
+}
+
+void BitVector_Word_Store(unsigned int *  addr, unsigned int offset, unsigned int value)
+{
+    unsigned int size = size_(addr);
+
+    if (size > 0)
+    {
+        if (offset < size) *(addr+offset) = value;
+        *(addr+size-1) &= mask_(addr);
+    }
+}
+
+unsigned int BitVector_Word_Read(unsigned int *  addr, unsigned int offset)
+{
+    unsigned int size = size_(addr);
+
+    if (size > 0)
+    {
+        *(addr+size-1) &= mask_(addr);
+        if (offset < size) return( *(addr+offset) );
+    }
+    return( (unsigned int) 0 );
+}
+
+void BitVector_Word_Insert(unsigned int *  addr, unsigned int offset, unsigned int count,
+                           boolean clear)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int *  last = addr+size-1;
+
+    if (size > 0)
+    {
+        *last &= mask;
+        if (offset > size) offset = size;
+        BIT_VECTOR_ins_words(addr+offset,size-offset,count,clear);
+        *last &= mask;
+    }
+}
+
+void BitVector_Word_Delete(unsigned int *  addr, unsigned int offset, unsigned int count,
+                           boolean clear)
+{
+    unsigned int  size = size_(addr);
+    unsigned int  mask = mask_(addr);
+    unsigned int *  last = addr+size-1;
+
+    if (size > 0)
+    {
+        *last &= mask;
+        if (offset > size) offset = size;
+        BIT_VECTOR_del_words(addr+offset,size-offset,count,clear);
+        *last &= mask;
+    }
+}
+
+void BitVector_Chunk_Store(unsigned int *  addr, unsigned int chunksize, unsigned int offset,
+                           unsigned long value)
+{
+    unsigned int bits = bits_(addr);
+    unsigned int mask;
+    unsigned int temp;
+
+    if ((chunksize > 0) && (offset < bits))
+    {
+        if (chunksize > LONGBITS) chunksize = LONGBITS;
+        if ((offset + chunksize) > bits) chunksize = bits - offset;
+        addr += offset >> LOGBITS;
+        offset &= MODMASK;
+        while (chunksize > 0)
+        {
+            mask = (unsigned int) (~0L << offset);
+            bits = offset + chunksize;
+            if (bits < BITS)
+            {
+                mask &= (unsigned int) ~(~0L << bits);
+                bits = chunksize;
+            }
+            else bits = BITS - offset;
+            temp = (unsigned int) (value << offset);
+            temp &= mask;
+            *addr &= ~ mask;
+            *addr++ |= temp;
+            value >>= bits;
+            chunksize -= bits;
+            offset = 0;
+        }
+    }
+}
+
+unsigned long BitVector_Chunk_Read(unsigned int *  addr, unsigned int chunksize, unsigned int offset)
+{
+    unsigned int bits = bits_(addr);
+    unsigned int chunkbits = 0;
+    unsigned long value = 0L;
+    unsigned long temp;
+    unsigned int mask;
+
+    if ((chunksize > 0) && (offset < bits))
+    {
+        if (chunksize > LONGBITS) chunksize = LONGBITS;
+        if ((offset + chunksize) > bits) chunksize = bits - offset;
+        addr += offset >> LOGBITS;
+        offset &= MODMASK;
+        while (chunksize > 0)
+        {
+            bits = offset + chunksize;
+            if (bits < BITS)
+            {
+                mask = (unsigned int) ~(~0L << bits);
+                bits = chunksize;
+            }
+            else
+            {
+                mask = (unsigned int) ~0L;
+                bits = BITS - offset;
+            }
+            temp = (unsigned long) ((*addr++ & mask) >> offset);
+            value |= temp << chunkbits;
+            chunkbits += bits;
+            chunksize -= bits;
+            offset = 0;
+        }
+    }
+    return(value);
+}
+
+    /*******************/
+    /* set operations: */
+    /*******************/
+
+void Set_Union(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)             /* X = Y + Z     */
+{
+    unsigned int bits = bits_(X);
+    unsigned int size = size_(X);
+    unsigned int mask = mask_(X);
+
+    if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
+    {
+        while (size-- > 0) *X++ = *Y++ | *Z++;
+        *(--X) &= mask;
+    }
+}
+
+void Set_Intersection(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)      /* X = Y * Z     */
+{
+    unsigned int bits = bits_(X);
+    unsigned int size = size_(X);
+    unsigned int mask = mask_(X);
+
+    if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
+    {
+        while (size-- > 0) *X++ = *Y++ & *Z++;
+        *(--X) &= mask;
+    }
+}
+
+void Set_Difference(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)        /* X = Y \ Z     */
+{
+    unsigned int bits = bits_(X);
+    unsigned int size = size_(X);
+    unsigned int mask = mask_(X);
+
+    if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
+    {
+        while (size-- > 0) *X++ = *Y++ & ~ *Z++;
+        *(--X) &= mask;
+    }
+}
+
+void Set_ExclusiveOr(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)       /* X=(Y+Z)\(Y*Z) */
+{
+    unsigned int bits = bits_(X);
+    unsigned int size = size_(X);
+    unsigned int mask = mask_(X);
+
+    if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
+    {
+        while (size-- > 0) *X++ = *Y++ ^ *Z++;
+        *(--X) &= mask;
+    }
+}
+
+void Set_Complement(unsigned int *  X, unsigned int *  Y)                   /* X = ~Y        */
+{
+    unsigned int size = size_(X);
+    unsigned int mask = mask_(X);
+
+    if ((size > 0) && (bits_(X) == bits_(Y)))
+    {
+        while (size-- > 0) *X++ = ~ *Y++;
+        *(--X) &= mask;
+    }
+}
+
+    /******************/
+    /* set functions: */
+    /******************/
+
+boolean Set_subset(unsigned int *  X, unsigned int *  Y)                    /* X subset Y ?  */
+{
+    unsigned int size = size_(X);
+    boolean r = false;
+
+    if ((size > 0) && (bits_(X) == bits_(Y)))
+    {
+        r = true;
+        while (r && (size-- > 0)) r = ((*X++ & ~ *Y++) == 0);
+    }
+    return(r);
+}
+
+unsigned int Set_Norm(unsigned int *  addr)                                /* = | X |       */
+{
+    unsigned char * byte;
+    unsigned int  bytes;
+    unsigned int   n;
+
+    byte = (unsigned char *) addr;
+    bytes = size_(addr) << FACTOR;
+    n = 0;
+    while (bytes-- > 0)
+    {
+        n += BitVector_BYTENORM[*byte++];
+    }
+    return(n);
+}
+
+unsigned int Set_Norm2(unsigned int *  addr)                               /* = | X |       */
+{
+    unsigned int  size = size_(addr);
+    unsigned int  w0,w1;
+    unsigned int   n,k;
+
+    n = 0;
+    while (size-- > 0)
+    {
+        k = 0;
+        w1 = ~ (w0 = *addr++);
+        while (w0 && w1)
+        {
+            w0 &= w0 - 1;
+            w1 &= w1 - 1;
+            k++;
+        }
+        if (w0 == 0) n += k;
+        else         n += BITS - k;
+    }
+    return(n);
+}
+
+unsigned int Set_Norm3(unsigned int *  addr)                               /* = | X |       */
+{
+    unsigned int  size  = size_(addr);
+    unsigned int   count = 0;
+    unsigned int  c;
+
+    while (size-- > 0)
+    {
+        c = *addr++;
+        while (c)
+        {
+            c &= c - 1;
+            count++;
+        }
+    }
+    return(count);
+}
+
+signed long Set_Min(unsigned int *  addr)                                /* = min(X)      */
+{
+    boolean empty = true;
+    unsigned int  size  = size_(addr);
+    unsigned int  i     = 0;
+    unsigned int  c     = 0;         /* silence compiler warning */
+
+    while (empty && (size-- > 0))
+    {
+        if ((c = *addr++)) empty = false; else i++;
+    }
+    if (empty) return((signed long) LONG_MAX);                  /* plus infinity  */
+    i <<= LOGBITS;
+    while (! (c & LSB))
+    {
+        c >>= 1;
+        i++;
+    }
+    return((signed long) i);
+}
+
+signed long Set_Max(unsigned int *  addr)                                /* = max(X)      */
+{
+    boolean empty = true;
+    unsigned int  size  = size_(addr);
+    unsigned int  i     = size;
+    unsigned int  c     = 0;         /* silence compiler warning */
+
+    addr += size-1;
+    while (empty && (size-- > 0))
+    {
+        if ((c = *addr--)) empty = false; else i--;
+    }
+    if (empty) return((signed long) LONG_MIN);                  /* minus infinity */
+    i <<= LOGBITS;
+    while (! (c & MSB))
+    {
+        c <<= 1;
+        i--;
+    }
+    return((signed long) --i);
+}
+
+    /**********************************/
+    /* matrix-of-booleans operations: */
+    /**********************************/
+
+void Matrix_Multiplication(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
+                           unsigned int *  Y, unsigned int rowsY, unsigned int colsY,
+                           unsigned int *  Z, unsigned int rowsZ, unsigned int colsZ)
+{
+    unsigned int i;
+    unsigned int j;
+    unsigned int k;
+    unsigned int indxX;
+    unsigned int indxY;
+    unsigned int indxZ;
+    unsigned int termX;
+    unsigned int termY;
+    unsigned int sum;
+
+  if ((colsY == rowsZ) && (rowsX == rowsY) && (colsX == colsZ) &&
+      (bits_(X) == rowsX*colsX) &&
+      (bits_(Y) == rowsY*colsY) &&
+      (bits_(Z) == rowsZ*colsZ))
+  {
+    for ( i = 0; i < rowsY; i++ )
+    {
+        termX = i * colsX;
+        termY = i * colsY;
+        for ( j = 0; j < colsZ; j++ )
+        {
+            indxX = termX + j;
+            sum = 0;
+            for ( k = 0; k < colsY; k++ )
+            {
+                indxY = termY + k;
+                indxZ = k * colsZ + j;
+                if ( BIT_VECTOR_TST_BIT(Y,indxY) &
+                     BIT_VECTOR_TST_BIT(Z,indxZ) ) sum ^= 1;
+            }
+            if (sum) BIT_VECTOR_SET_BIT(X,indxX)
+            else     BIT_VECTOR_CLR_BIT(X,indxX)
+        }
+    }
+  }
+}
+
+void Matrix_Product(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
+                    unsigned int *  Y, unsigned int rowsY, unsigned int colsY,
+                    unsigned int *  Z, unsigned int rowsZ, unsigned int colsZ)
+{
+    unsigned int i;
+    unsigned int j;
+    unsigned int k;
+    unsigned int indxX;
+    unsigned int indxY;
+    unsigned int indxZ;
+    unsigned int termX;
+    unsigned int termY;
+    unsigned int sum;
+
+  if ((colsY == rowsZ) && (rowsX == rowsY) && (colsX == colsZ) &&
+      (bits_(X) == rowsX*colsX) &&
+      (bits_(Y) == rowsY*colsY) &&
+      (bits_(Z) == rowsZ*colsZ))
+  {
+    for ( i = 0; i < rowsY; i++ )
+    {
+        termX = i * colsX;
+        termY = i * colsY;
+        for ( j = 0; j < colsZ; j++ )
+        {
+            indxX = termX + j;
+            sum = 0;
+            for ( k = 0; k < colsY; k++ )
+            {
+                indxY = termY + k;
+                indxZ = k * colsZ + j;
+                if ( BIT_VECTOR_TST_BIT(Y,indxY) &
+                     BIT_VECTOR_TST_BIT(Z,indxZ) ) sum |= 1;
+            }
+            if (sum) BIT_VECTOR_SET_BIT(X,indxX)
+            else     BIT_VECTOR_CLR_BIT(X,indxX)
+        }
+    }
+  }
+}
+
+void Matrix_Closure(unsigned int *  addr, unsigned int rows, unsigned int cols)
+{
+    unsigned int i;
+    unsigned int j;
+    unsigned int k;
+    unsigned int ii;
+    unsigned int ij;
+    unsigned int ik;
+    unsigned int kj;
+    unsigned int termi;
+    unsigned int termk;
+
+  if ((rows == cols) && (bits_(addr) == rows*cols))
+  {
+    for ( i = 0; i < rows; i++ )
+    {
+        ii = i * cols + i;
+        BIT_VECTOR_SET_BIT(addr,ii)
+    }
+    for ( k = 0; k < rows; k++ )
+    {
+        termk = k * cols;
+        for ( i = 0; i < rows; i++ )
+        {
+            termi = i * cols;
+            ik = termi + k;
+            for ( j = 0; j < rows; j++ )
+            {
+                ij = termi + j;
+                kj = termk + j;
+                if ( BIT_VECTOR_TST_BIT(addr,ik) &
+                     BIT_VECTOR_TST_BIT(addr,kj) )
+                     BIT_VECTOR_SET_BIT(addr,ij)
+            }
+        }
+    }
+  }
+}
+
+void Matrix_Transpose(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
+                      unsigned int *  Y, unsigned int rowsY, unsigned int colsY)
+{
+    unsigned int  i;
+    unsigned int  j;
+    unsigned int  ii;
+    unsigned int  ij;
+    unsigned int  ji;
+    unsigned int  addii;
+    unsigned int  addij;
+    unsigned int  addji;
+    unsigned int  bitii;
+    unsigned int  bitij;
+    unsigned int  bitji;
+    unsigned int  termi;
+    unsigned int  termj;
+    boolean swap;
+
+  /* BEWARE that "in-place" is ONLY possible if the matrix is quadratic!! */
+
+  if ((rowsX == colsY) && (colsX == rowsY) &&
+      (bits_(X) == rowsX*colsX) &&
+      (bits_(Y) == rowsY*colsY))
+  {
+    if (rowsY == colsY) /* in-place is possible! */
+    {
+        for ( i = 0; i < rowsY; i++ )
+        {
+            termi = i * colsY;
+            for ( j = 0; j < i; j++ )
+            {
+                termj = j * colsX;
+                ij = termi + j;
+                ji = termj + i;
+                addij = ij >> LOGBITS;
+                addji = ji >> LOGBITS;
+                bitij = BITMASKTAB[ij & MODMASK];
+                bitji = BITMASKTAB[ji & MODMASK];
+                swap = ((*(Y+addij) & bitij) != 0);
+                if ((*(Y+addji) & bitji) != 0)
+                     *(X+addij) |=     bitij;
+                else
+                     *(X+addij) &= ~ bitij;
+                if (swap)
+                     *(X+addji) |=     bitji;
+                else
+                     *(X+addji) &= ~ bitji;
+            }
+            ii = termi + i;
+            addii = ii >> LOGBITS;
+            bitii = BITMASKTAB[ii & MODMASK];
+            if ((*(Y+addii) & bitii) != 0)
+                 *(X+addii) |=     bitii;
+            else
+                 *(X+addii) &= ~ bitii;
+        }
+    }
+    else /* rowsX != colsX, in-place is ~ possible! */
+    {
+        for ( i = 0; i < rowsY; i++ )
+        {
+            termi = i * colsY;
+            for ( j = 0; j < colsY; j++ )
+            {
+                termj = j * colsX;
+                ij = termi + j;
+                ji = termj + i;
+                addij = ij >> LOGBITS;
+                addji = ji >> LOGBITS;
+                bitij = BITMASKTAB[ij & MODMASK];
+                bitji = BITMASKTAB[ji & MODMASK];
+                if ((*(Y+addij) & bitij) != 0)
+                     *(X+addji) |=     bitji;
+                else
+                     *(X+addji) &= ~ bitji;
+            }
+        }
+    }
+  }
+}
+}; //end of namespace CONSTANTBV
diff --git a/stp/constantbv/constantbv.h b/stp/constantbv/constantbv.h
new file mode 100644
index 00000000..47e0c56f
--- /dev/null
+++ b/stp/constantbv/constantbv.h
@@ -0,0 +1,316 @@
+#ifndef MODULE_BIT_VECTOR
+#define MODULE_BIT_VECTOR
+/*****************************************************************************/
+/*  AUTHOR:                                                                  */
+/*****************************************************************************/
+/*                                                                           */
+/*    Steffen Beyer                                                          */
+/*    mailto:sb@engelschall.com                                              */
+/*    http://www.engelschall.com/u/sb/download/                              */
+/*                                                                           */
+/*****************************************************************************/
+/*  COPYRIGHT:                                                               */
+/*****************************************************************************/
+/*                                                                           */
+/*    Copyright (c) 1995 - 2004 by Steffen Beyer.                            */
+/*    All rights reserved.                                                   */
+/*                                                                           */
+/*****************************************************************************/
+/*  LICENSE:                                                                 */
+/*****************************************************************************/
+/*                                                                           */
+/*    This library is free software; you can redistribute it and/or          */
+/*    modify it under the terms of the GNU Library General Public            */
+/*    License as published by the Free Software Foundation; either           */
+/*    version 2 of the License, or (at your option) any later version.       */
+/*                                                                           */
+/*    This library is distributed in the hope that it will be useful,        */
+/*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
+/*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU       */
+/*    Library General Public License for more details.                       */
+/*                                                                           */
+/*    You should have received a copy of the GNU Library General Public      */
+/*    License along with this library; if not, write to the                  */
+/*    Free Software Foundation, Inc.,                                        */
+/*    59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                  */
+/*                                                                           */
+/*    or download a copy from ftp://ftp.gnu.org/pub/gnu/COPYING.LIB-2.0      */
+/*                                                                           */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/*  MODULE NAME:  BitVector.h                           MODULE TYPE:  (adt)  */
+/*****************************************************************************/
+/*  MODULE IMPORTS:                                                          */
+/*****************************************************************************/
+#include <stdlib.h>                                 /*  MODULE TYPE:  (sys)  */
+#include <limits.h>                                 /*  MODULE TYPE:  (sys)  */
+#include <string.h>                                 /*  MODULE TYPE:  (sys)  */
+#include <ctype.h>                                  /*  MODULE TYPE:  (sys)  */
+/*****************************************************************************/
+/*  MODULE INTERFACE:                                                        */
+/*****************************************************************************/
+
+namespace CONSTANTBV {
+
+#ifdef __cplusplus
+  extern "C" {
+    typedef bool boolean;
+#else
+    typedef enum { false = (0!=0), true = (0==0) } boolean;
+#endif
+
+    typedef enum {
+        ErrCode_Ok = 0,    /* everything went allright                       */	
+        ErrCode_Type,      /* types word and size_t have incompatible sizes  */
+        ErrCode_Bits,      /* bits of word and sizeof(word) are inconsistent */
+        ErrCode_Word,      /* size of word is less than 16 bits              */
+        ErrCode_Long,      /* size of word is greater than size of long      */
+        ErrCode_Powr,      /* number of bits of word is not a power of two   */
+        ErrCode_Loga,      /* error in calculation of logarithm              */	
+        ErrCode_Null,      /* unable to allocate memory                      */	
+        ErrCode_Indx,      /* index out of range                             */
+        ErrCode_Ordr,      /* minimum > maximum index                        */
+        ErrCode_Size,      /* bit vector size mismatch                       */
+        ErrCode_Pars,      /* input string syntax error                      */
+        ErrCode_Ovfl,      /* numeric overflow error                         */
+        ErrCode_Same,      /* operands must be distinct                      */
+        ErrCode_Expo,      /* exponent must be positive                      */
+        ErrCode_Zero       /* division by zero error                         */
+      } ErrCode;
+
+
+    /* ===> MISCELLANEOUS BASIC FUNCTIONS: <=== */
+    unsigned char * BitVector_Error(ErrCode error);     /* return string for err code */
+    ErrCode         BitVector_Boot (void);              /* 0 = ok, 1..7 = error */
+    unsigned int    BitVector_Size(unsigned int bits);  /* bit vector size (# of words)  */
+    unsigned int    BitVector_Mask(unsigned int bits);  /* bit vector mask (unused bits) */
+    
+    /* ===> CLASS METHODS: <=== */
+    unsigned char * BitVector_Version(void);           /* return version string */
+    unsigned int    BitVector_Word_Bits(void);         /* return # of bits in machine word */
+    unsigned int    BitVector_Long_Bits(void);         /* return # of bits in unsigned long */
+
+    /* ===> CONSTRUCTOR METHODS: <=== */
+    unsigned int *  BitVector_Create      (unsigned int bits, boolean clear);                /* malloc */
+    unsigned int ** BitVector_Create_List (unsigned int bits, boolean clear, unsigned int count);
+    unsigned int *  BitVector_Resize      (unsigned int * oldaddr, unsigned int bits);       /* realloc */
+    unsigned int *  BitVector_Shadow      (unsigned int * addr);                             /* make new same size but empty */
+    unsigned int *  BitVector_Clone       (unsigned int * addr);                             /* make exact duplicate */
+    unsigned int *  BitVector_Concat      (unsigned int * X, unsigned int * Y);              /* return concatenation */
+
+    /* ===> DESTRUCTOR METHODS: <=== */
+    void    BitVector_Dispose             (unsigned char * string);                     /* string */
+    void    BitVector_Destroy             (unsigned int * addr);                        /* bitvec */
+    void    BitVector_Destroy_List        (unsigned int * * list, unsigned int count);  /* list   */
+
+    /* ===> OBJECT METHODS: <=== */
+
+    /* ===> bit vector hash: */
+    size_t  BitVector_Hash                (unsigned int * X);
+
+    /* ===> bit vector copy function: */
+    void    BitVector_Copy                (unsigned int * X, unsigned int * Y);              /* X := Y   */
+
+    /* ===> bit vector initialization: */
+    void    BitVector_Empty               (unsigned int * addr);                      /* X = {}  */
+    void    BitVector_Fill                (unsigned int * addr);                      /* X = ~{} */
+    void    BitVector_Flip                (unsigned int * addr);                      /* X = ~X  */
+    void    BitVector_Primes              (unsigned int * addr);
+
+    /* ===> miscellaneous functions: */
+    void    BitVector_Reverse             (unsigned int * X, unsigned int * Y);
+    
+    /* ===> bit vector interval operations and functions: */
+    void    BitVector_Interval_Empty      (unsigned int * addr, unsigned int lower, unsigned int upper);
+    void    BitVector_Interval_Fill       (unsigned int * addr, unsigned int lower, unsigned int upper);
+    void    BitVector_Interval_Flip       (unsigned int * addr, unsigned int lower, unsigned int upper);
+    void    BitVector_Interval_Reverse    (unsigned int * addr, unsigned int lower, unsigned int upper);
+    
+    boolean BitVector_interval_scan_inc   (unsigned int * addr, unsigned int start,
+					   unsigned int * min, unsigned int * max);
+    boolean BitVector_interval_scan_dec   (unsigned int * addr, unsigned int start,
+					   unsigned int * min, unsigned int * max);
+    void    BitVector_Interval_Copy       (unsigned int * X, unsigned int * Y, 
+					   unsigned int Xoffset, unsigned int Yoffset, unsigned int length);
+    unsigned int * BitVector_Interval_Substitute(unsigned int * X, unsigned int * Y,
+						 unsigned int Xoffset, unsigned int Xlength,
+						 unsigned int Yoffset, unsigned int Ylength);
+
+    /* ===> bit vector test functions: */
+    boolean BitVector_is_empty            (unsigned int * addr);                         /* X == {} ?   */
+    boolean BitVector_is_full             (unsigned int * addr);                         /* X == ~{} ?  */
+    boolean BitVector_equal               (unsigned int * X, unsigned int * Y);          /* X == Y ?    */
+    signed int   BitVector_Lexicompare    (unsigned int * X, unsigned int * Y);          /* X <,=,> Y ? */
+    signed int   BitVector_Compare        (unsigned int * X, unsigned int * Y);          /* X <,=,> Y ? */
+    
+    /* ===> bit vector string conversion functions: */
+    unsigned char * BitVector_to_Hex      (unsigned int * addr);
+    ErrCode BitVector_from_Hex            (unsigned int * addr, unsigned char * string);
+    unsigned char * BitVector_to_Bin      (unsigned int * addr);
+    ErrCode BitVector_from_Bin            (unsigned int * addr, unsigned char * string);
+    unsigned char * BitVector_to_Dec      (unsigned int * addr);
+    ErrCode BitVector_from_Dec            (unsigned int * addr, unsigned char * string);
+    unsigned char * BitVector_to_Enum     (unsigned int * addr);
+    ErrCode BitVector_from_Enum           (unsigned int * addr, unsigned char * string);
+    
+    /* ===> bit vector bit operations, functions & tests: */
+    void    BitVector_Bit_Off             (unsigned int * addr, unsigned int index); /*  X = X \ {x}    */
+    void    BitVector_Bit_On              (unsigned int * addr, unsigned int index); /*  X = X + {x}    */
+    boolean BitVector_bit_flip            (unsigned int * addr, unsigned int index); /* (X+{x})\(X*{x}) */
+    boolean BitVector_bit_test            (unsigned int * addr, unsigned int index); /*  {x} in X ?     */
+    void    BitVector_Bit_Copy            (unsigned int * addr, unsigned int index, boolean bit);
+    
+    /* ===> bit vector bit shift & rotate functions: */
+    void    BitVector_LSB                 (unsigned int * addr, boolean bit);
+    void    BitVector_MSB                 (unsigned int * addr, boolean bit);
+    boolean BitVector_lsb_                (unsigned int * addr);
+    boolean BitVector_msb_                (unsigned int * addr);
+    boolean BitVector_rotate_left         (unsigned int * addr);
+    boolean BitVector_rotate_right        (unsigned int * addr);
+    boolean BitVector_shift_left          (unsigned int * addr, boolean carry_in);
+    boolean BitVector_shift_right         (unsigned int * addr, boolean carry_in);
+    void    BitVector_Move_Left           (unsigned int * addr, unsigned int bits);
+    void    BitVector_Move_Right          (unsigned int * addr, unsigned int bits);
+    
+    /* ===> bit vector insert/delete bits: */
+    void    BitVector_Insert              (unsigned int * addr, 
+					   unsigned int offset, unsigned int count, boolean clear);
+    void    BitVector_Delete              (unsigned int * addr, 
+					   unsigned int offset, unsigned int count, boolean clear);
+    
+    /* ===> bit vector arithmetic: */
+    boolean BitVector_increment           (unsigned int * addr);                        /*  X++  */
+    boolean BitVector_decrement           (unsigned int * addr);                        /*  X--  */
+    boolean BitVector_compute             (unsigned int * X, unsigned int * Y, 
+					   unsigned int * Z, boolean minus, boolean *carry);
+    boolean BitVector_add                 (unsigned int * X, 
+					   unsigned int * Y, unsigned int * Z, boolean *carry);
+    boolean BitVector_sub                 (unsigned int * X, 
+					   unsigned int * Y, unsigned int * Z, boolean *carry); /* X = Y-Z*/
+    boolean BitVector_inc                 (unsigned int * X, unsigned int * Y);
+    boolean BitVector_dec                 (unsigned int * X, unsigned int * Y);
+    
+    void    BitVector_Negate              (unsigned int * X, unsigned int * Y);
+    void    BitVector_Absolute            (unsigned int * X, unsigned int * Y);
+    signed int   BitVector_Sign           (unsigned int * addr);
+    ErrCode BitVector_Mul_Pos             (unsigned int * X, 
+					   unsigned int * Y, unsigned int * Z, boolean strict);
+    ErrCode BitVector_Multiply            (unsigned int * X, unsigned int * Y, unsigned int * Z);
+    ErrCode BitVector_Div_Pos             (unsigned int * Q, unsigned int * X, unsigned int * Y, unsigned int * R);
+    ErrCode BitVector_Divide              (unsigned int * Q, unsigned int * X, unsigned int * Y, unsigned int * R);
+    ErrCode BitVector_GCD                 (unsigned int * X, unsigned int * Y, unsigned int * Z);
+    ErrCode BitVector_GCD2                (unsigned int * U, unsigned int * V, unsigned int * W,      /*   O   */
+					   unsigned int * X, unsigned int * Y);     /*   I   */
+    ErrCode BitVector_Power               (unsigned int * X, unsigned int * Y, unsigned int * Z);
+    
+    /* ===> direct memory access functions: */
+    void    BitVector_Block_Store         (unsigned int * addr, 
+					   unsigned char * buffer, unsigned int length);
+    unsigned char * BitVector_Block_Read  (unsigned int * addr, unsigned int * length);
+    
+    /* ===> word array functions: */
+    void    BitVector_Word_Store          (unsigned int * addr, unsigned int offset, unsigned int value);
+    unsigned int   BitVector_Word_Read    (unsigned int * addr, unsigned int offset);
+    void    BitVector_Word_Insert         (unsigned int * addr, 
+					   unsigned int offset, unsigned int count, boolean clear);
+    void    BitVector_Word_Delete         (unsigned int * addr, 
+					   unsigned int offset, unsigned int count, boolean clear);
+    
+    /* ===> arbitrary size chunk functions: */
+    void    BitVector_Chunk_Store         (unsigned int * addr, unsigned int chunksize,
+					   unsigned int offset, unsigned long value);
+    unsigned long  BitVector_Chunk_Read   (unsigned int * addr, 
+					   unsigned int chunksize,unsigned int offset);
+    
+    /* ===> set operations: */
+    void    Set_Union                     (unsigned int * X, unsigned int * Y, unsigned int * Z); /* X = Y + Z */
+    void    Set_Intersection              (unsigned int * X, unsigned int * Y, unsigned int * Z); /* X = Y * Z */
+    void    Set_Difference                (unsigned int * X, unsigned int * Y, unsigned int * Z); /* X = Y \ Z */
+    void    Set_ExclusiveOr               (unsigned int * X, unsigned int * Y, unsigned int * Z); /*(Y+Z)\(Y*Z)*/
+    void    Set_Complement                (unsigned int * X, unsigned int * Y);                   /* X = ~Y    */
+    
+    /* ===> set functions: */
+    boolean        Set_subset             (unsigned int * X, unsigned int * Y);     /* X in Y ?  */
+    unsigned int   Set_Norm               (unsigned int * addr);                    /* = | X |   */
+    unsigned int   Set_Norm2              (unsigned int * addr);                    /* = | X |   */
+    unsigned int   Set_Norm3              (unsigned int * addr);                    /* = | X |   */
+    signed long    Set_Min                (unsigned int * addr);                    /* = min(X)  */
+    signed long    Set_Max                (unsigned int * addr);                    /* = max(X)  */
+    
+    /* ===> matrix-of-booleans operations: */
+    void    Matrix_Multiplication         (unsigned int * X, unsigned int rowsX, unsigned int colsX,
+					   unsigned int * Y, unsigned int rowsY, unsigned int colsY,
+					   unsigned int * Z, unsigned int rowsZ, unsigned int colsZ);
+    void    Matrix_Product                (unsigned int * X, unsigned int rowsX, unsigned int colsX,
+					   unsigned int * Y, unsigned int rowsY, unsigned int colsY,
+					   unsigned int * Z, unsigned int rowsZ, unsigned int colsZ);
+    void    Matrix_Closure                (unsigned int * addr, unsigned int rows, unsigned int cols);
+    void    Matrix_Transpose              (unsigned int * X, unsigned int rowsX, unsigned int colsX,
+					   unsigned int * Y, unsigned int rowsY, unsigned int colsY);
+    
+    /*****************************************************************************/
+    /*  MODULE RESOURCES:                                                        */
+    /*****************************************************************************/
+#define bits_(BitVector) *(BitVector-3)
+#define size_(BitVector) *(BitVector-2)
+#define mask_(BitVector) *(BitVector-1)
+    
+#define  ERRCODE_TYPE  "sizeof(word) > sizeof(size_t)"
+#define  ERRCODE_BITS  "bits(word) != sizeof(word)*8"
+#define  ERRCODE_WORD  "bits(word) < 16"
+#define  ERRCODE_LONG  "bits(word) > bits(long)"
+#define  ERRCODE_POWR  "bits(word) != 2^x"
+#define  ERRCODE_LOGA  "bits(word) != 2^ld(bits(word))"
+#define  ERRCODE_NULL  "unable to allocate memory"
+#define  ERRCODE_INDX  "index out of range"
+#define  ERRCODE_ORDR  "minimum > maximum index"
+#define  ERRCODE_SIZE  "bit vector size mismatch"
+#define  ERRCODE_PARS  "input string syntax error"
+#define  ERRCODE_OVFL  "numeric overflow error"
+#define  ERRCODE_SAME  "result vector(s) must be distinct"
+#define  ERRCODE_EXPO  "exponent must be positive"
+#define  ERRCODE_ZERO  "division by zero error"
+#define  ERRCODE_OOPS  "unexpected internal error - please contact author"
+        
+    const unsigned int BitVector_BYTENORM[256] = {
+      0x00, 0x01, 0x01, 0x02,  0x01, 0x02, 0x02, 0x03,
+      0x01, 0x02, 0x02, 0x03,  0x02, 0x03, 0x03, 0x04, /* 0x00 */
+      0x01, 0x02, 0x02, 0x03,  0x02, 0x03, 0x03, 0x04,
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05, /* 0x10 */
+      0x01, 0x02, 0x02, 0x03,  0x02, 0x03, 0x03, 0x04,
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05, /* 0x20 */
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05,
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06, /* 0x30 */
+      0x01, 0x02, 0x02, 0x03,  0x02, 0x03, 0x03, 0x04,
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05, /* 0x40 */
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05,
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06, /* 0x50 */
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05,
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06, /* 0x60 */
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06,
+      0x04, 0x05, 0x05, 0x06,  0x05, 0x06, 0x06, 0x07, /* 0x70 */
+      0x01, 0x02, 0x02, 0x03,  0x02, 0x03, 0x03, 0x04,
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05, /* 0x80 */
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05,
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06, /* 0x90 */
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05,
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06, /* 0xA0 */
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06,
+      0x04, 0x05, 0x05, 0x06,  0x05, 0x06, 0x06, 0x07, /* 0xB0 */
+      0x02, 0x03, 0x03, 0x04,  0x03, 0x04, 0x04, 0x05,
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06, /* 0xC0 */
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06,
+      0x04, 0x05, 0x05, 0x06,  0x05, 0x06, 0x06, 0x07, /* 0xD0 */
+      0x03, 0x04, 0x04, 0x05,  0x04, 0x05, 0x05, 0x06,
+      0x04, 0x05, 0x05, 0x06,  0x05, 0x06, 0x06, 0x07, /* 0xE0 */
+      0x04, 0x05, 0x05, 0x06,  0x05, 0x06, 0x06, 0x07,
+      0x05, 0x06, 0x06, 0x07,  0x06, 0x07, 0x07, 0x08  /* 0xF0 */
+    };
+#ifdef __cplusplus
+  };
+#endif
+}; //end of namespace CONSTANTBV
+#endif
+
diff --git a/stp/parser/Makefile b/stp/parser/Makefile
new file mode 100644
index 00000000..8211c825
--- /dev/null
+++ b/stp/parser/Makefile
@@ -0,0 +1,27 @@
+include ../Makefile.common
+
+SRCS = lexPL.cpp parsePL.cpp let-funcs.cpp main.cpp
+OBJS = $(SRCS:.cpp=.o)
+LIBS = -L../AST -last -L../sat -lsatsolver -L../simplifier -lsimplifier -L../bitvec -lconsteval -L../constantbv -lconstantbv
+
+all: parser 
+
+parser: lexPL.o parsePL.o let-funcs.o main.o 
+		$(CXX) $(CFLAGS) $(LDFLAGS) lexPL.o parsePL.o main.o let-funcs.o $(LIBS) -o parser
+
+main.o: parsePL_defs.h
+
+lexPL.cpp:	PL.lex parsePL_defs.h ../AST/AST.h
+		$(LEX) -o lexPL.cpp PL.lex
+
+parsePL_defs.h: y.tab.h
+		@cp y.tab.h parsePL_defs.h
+parsePL.cpp: y.tab.c
+		@cp y.tab.c parsePL.cpp
+
+y.tab.c y.tab.h:	PL.y
+		$(YACC) PL.y
+
+
+clean:	
+		rm -rf *.o parsePL_defs.h *~ lexPL.cpp parsePL.cpp *.output parser y.tab.* lex.yy.c .#*
diff --git a/stp/parser/PL.lex b/stp/parser/PL.lex
new file mode 100644
index 00000000..e9358a0e
--- /dev/null
+++ b/stp/parser/PL.lex
@@ -0,0 +1,128 @@
+%{
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+#include <iostream>
+#include "../AST/AST.h"
+#include "parsePL_defs.h"
+
+extern char *yytext;
+extern int yyerror (const char *msg);
+%}
+
+%option noyywrap
+%option nounput
+%option noreject
+%option noyymore
+%option yylineno
+%x	COMMENT
+%x	STRING_LITERAL
+LETTER	([a-zA-Z])
+HEX     ([0-9a-fA-F])
+BITS    ([0-1])
+DIGIT	([0-9])
+OPCHAR	(['?\_$])
+ANYTHING ({LETTER}|{DIGIT}|{OPCHAR})
+%%
+
+[()[\]{},.;:'!#?_=]  { return yytext[0];}
+
+[\n]             { /*Skip new line */ }
+[ \t\r\f]	 { /* skip whitespace */ }
+0b{BITS}+	 { yylval.node = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(yytext+2,  2)); return BVCONST_TOK;}
+0bin{BITS}+	 { yylval.node = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(yytext+4,  2)); return BVCONST_TOK;}
+0h{HEX}+         { yylval.node = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(yytext+2, 16)); return BVCONST_TOK;}
+0hex{HEX}+       { yylval.node = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(yytext+4, 16)); return BVCONST_TOK;}
+{DIGIT}+	 { yylval.uintval = strtoul(yytext, NULL, 10); return NUMERAL_TOK;}
+
+"%"		 { BEGIN COMMENT;}
+<COMMENT>"\n"	 { BEGIN INITIAL; /* return to normal mode */}
+<COMMENT>.	 { /* stay in comment mode */}
+
+"ARRAY"		 { return ARRAY_TOK; }
+"OF"		 { return OF_TOK; }
+"WITH"		 { return WITH_TOK; }
+"AND"		 { return AND_TOK;}
+"NAND"		 { return NAND_TOK;}
+"NOR"		 { return NOR_TOK;}
+"NOT"		 { return NOT_TOK; }
+"OR"		 { return OR_TOK; }
+"/="		 { return NEQ_TOK; }
+ ":="            { return ASSIGN_TOK;}
+"=>"		 { return IMPLIES_TOK; }
+"<=>"		 { return IFF_TOK; }
+"XOR"		 { return XOR_TOK; }
+"IF"		 { return IF_TOK; }
+"THEN"		 { return THEN_TOK; }
+"ELSE"		 { return ELSE_TOK; }
+"ELSIF"		 { return ELSIF_TOK; }
+"END"		 { return END_TOK; }
+"ENDIF"		 { return ENDIF_TOK; }
+"BV"             { return BV_TOK;}
+"BITVECTOR"      { return BV_TOK;}
+"BOOLEAN"        { return BOOLEAN_TOK;}
+"<<"             { return BVLEFTSHIFT_TOK;}
+">>"             { return BVRIGHTSHIFT_TOK;}
+"BVPLUS"         { return BVPLUS_TOK;}
+"BVSUB"          { return BVSUB_TOK;}
+"BVUMINUS"       { return BVUMINUS_TOK;}
+"BVMULT"         { return BVMULT_TOK;}
+"BVDIV"          { return BVDIV_TOK;}
+"BVMOD"          { return BVMOD_TOK;}
+"SBVDIV"         { return SBVDIV_TOK;}
+"SBVMOD"         { return SBVMOD_TOK;}
+"~"              { return BVNEG_TOK;}
+"&"              { return BVAND_TOK;}
+"|"              { return BVOR_TOK;}
+"BVXOR"          { return BVXOR_TOK;}
+"BVNAND"         { return BVNAND_TOK;}
+"BVNOR"          { return BVNOR_TOK;}
+"BVXNOR"         { return BVXNOR_TOK;}
+"@"              { return BVCONCAT_TOK;}
+"BVLT"           { return BVLT_TOK;}
+"BVGT"           { return BVGT_TOK;}
+"BVLE"           { return BVLE_TOK;}
+"BVGE"           { return BVGE_TOK;}
+"BVSLT"          { return BVSLT_TOK;}
+"BVSGT"          { return BVSGT_TOK;}
+"BVSLE"          { return BVSLE_TOK;}
+"BVSGE"          { return BVSGE_TOK;}
+"BVSX"           { return BVSX_TOK;} 
+"SBVLT"          { return BVSLT_TOK;}
+"SBVGT"          { return BVSGT_TOK;}
+"SBVLE"          { return BVSLE_TOK;}
+"SBVGE"          { return BVSGE_TOK;}
+"SX"             { return BVSX_TOK;} 
+"BOOLEXTRACT"    { return BOOLEXTRACT_TOK;}
+"BOOLBV"         { return BOOL_TO_BV_TOK;}
+"ASSERT"	 { return ASSERT_TOK; }
+"QUERY"	         { return QUERY_TOK; }
+"FALSE"          { return FALSELIT_TOK;}
+"TRUE"           { return TRUELIT_TOK;}
+"IN"             { return IN_TOK;}
+"LET"            { return LET_TOK;}
+"COUNTEREXAMPLE" { return COUNTEREXAMPLE_TOK;}
+"COUNTERMODEL"   { return COUNTEREXAMPLE_TOK;}
+ "PUSH"          { return PUSH_TOK;}
+ "POP"           { return POP_TOK;}
+
+(({LETTER})|(_)({ANYTHING}))({ANYTHING})*	{
+  BEEV::ASTNode nptr = BEEV::globalBeevMgr_for_parser->CreateSymbol(yytext); 
+
+  // Check valuesize to see if it's a prop var.  I don't like doing
+  // type determination in the lexer, but it's easier than rewriting
+  // the whole grammar to eliminate the term/formula distinction.  
+  yylval.node = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(nptr));
+  //yylval.node = new BEEV::ASTNode(nptr);
+  if ((yylval.node)->GetType() == BEEV::BOOLEAN_TYPE)
+    return FORMID_TOK;
+  else 
+    return TERMID_TOK;  
+}
+
+.                { yyerror("Illegal input character."); }
+%%
diff --git a/stp/parser/PL.y b/stp/parser/PL.y
new file mode 100644
index 00000000..aa58aa4c
--- /dev/null
+++ b/stp/parser/PL.y
@@ -0,0 +1,1006 @@
+%{
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+using namespace std; 
+
+  // Suppress the bogus warning suppression in bison (it generates
+  // compile error)
+#undef __GNUC_MINOR__
+
+  extern int yylex(void);
+  extern char* yytext;
+  extern int yylineno;
+  int yyerror(const char *s) {
+    cout << "syntax error: line " << yylineno << "\n" << s << endl;    
+    BEEV::FatalError("");
+    return 1;			/* Dill: don't know what it should return */
+  };
+
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYMAXDEPTH 10485760
+#define YYERROR_VERBOSE 1
+#define YY_EXIT_FAILURE -1
+%}
+
+%union {
+
+  unsigned int uintval;			/* for numerals in types. */
+  struct {
+    //stores the indexwidth and valuewidth
+    //indexwidth is 0 iff type is bitvector. positive iff type is
+    //array, and stores the width of the indexing bitvector
+    unsigned int indexwidth;
+    //width of the bitvector type
+    unsigned int valuewidth;
+  } indexvaluewidth;
+
+  //ASTNode,ASTVec
+  BEEV::ASTNode *node;
+  BEEV::ASTVec *vec;
+
+  //Hash_Map to hold Array Updates during parse A map from array index
+  //to array values. To support the WITH construct
+  BEEV::ASTNodeMap * Index_To_UpdateValue;
+};
+
+%start cmd
+
+%token	AND_TOK			"AND"
+%token	OR_TOK			"OR"
+%token	NOT_TOK			"NOT"
+%token	XOR_TOK			"XOR"
+%token	NAND_TOK		"NAND"
+%token	NOR_TOK			"NOR"
+%token	IMPLIES_TOK		"=>"
+%token	IFF_TOK			"<=>"
+
+%token	IF_TOK			"IF"
+%token	THEN_TOK		"THEN"
+%token	ELSE_TOK		"ELSE"
+%token	ELSIF_TOK		"ELSIF"
+%token	END_TOK			"END"
+%token	ENDIF_TOK		"ENDIF"
+%token	NEQ_TOK			"/="
+%token  ASSIGN_TOK              ":="
+
+%token  BV_TOK                  "BV"
+%token  BVLEFTSHIFT_TOK         "<<"
+%token  BVRIGHTSHIFT_TOK        ">>"
+%token  BVPLUS_TOK              "BVPLUS"
+%token  BVSUB_TOK               "BVSUB"
+%token  BVUMINUS_TOK            "BVUMINUS"
+%token  BVMULT_TOK              "BVMULT"
+
+%token  BVDIV_TOK               "BVDIV"
+%token  BVMOD_TOK               "BVMOD"
+%token  SBVDIV_TOK              "SBVDIV"
+%token  SBVMOD_TOK              "SBVMOD"
+
+
+%token  BVNEG_TOK               "~"
+%token  BVAND_TOK               "&"
+%token  BVOR_TOK                "|"
+%token  BVXOR_TOK               "BVXOR"
+%token  BVNAND_TOK              "BVNAND"
+%token  BVNOR_TOK               "BVNOR"
+%token  BVXNOR_TOK              "BVXNOR"
+%token  BVCONCAT_TOK            "@"
+
+%token  BVLT_TOK                "BVLT"
+%token  BVGT_TOK                "BVGT"
+%token  BVLE_TOK                "BVLE"
+%token  BVGE_TOK                "BVGE"
+
+%token  BVSLT_TOK               "BVSLT"
+%token  BVSGT_TOK               "BVSGT"
+%token  BVSLE_TOK               "BVSLE"
+%token  BVSGE_TOK               "BVSGE"
+%token  BOOL_TO_BV_TOK          "BOOLBV"
+%token  BVSX_TOK                "BVSX"
+%token  BOOLEXTRACT_TOK         "BOOLEXTRACT"
+%token  ASSERT_TOK              "ASSERT"
+%token  QUERY_TOK               "QUERY"
+
+%token  BOOLEAN_TOK             "BOOLEAN"
+%token  ARRAY_TOK               "ARRAY"
+%token  OF_TOK                  "OF"
+%token  WITH_TOK                "WITH"
+
+%token  TRUELIT_TOK             "TRUE"
+%token  FALSELIT_TOK            "FALSE"
+
+%token  IN_TOK                  "IN"
+%token  LET_TOK                 "LET"
+//%token  COUNTEREXAMPLE_TOK      "COUNTEREXAMPLE"
+%token  PUSH_TOK                "PUSH"
+%token  POP_TOK                 "POP"
+
+%left IN_TOK
+%left XOR_TOK
+%left IFF_TOK
+%right IMPLIES_TOK
+%left OR_TOK
+%left AND_TOK
+%left NAND_TOK
+%left NOR_TOK
+%left NOT_TOK
+%left BVCONCAT_TOK
+%left BVOR_TOK
+%left BVAND_TOK
+%left BVXOR_TOK
+%left BVNAND_TOK
+%left BVNOR_TOK
+%left BVXNOR_TOK
+%left BVNEG_TOK
+%left BVLEFTSHIFT_TOK BVRIGHTSHIFT_TOK
+%left WITH_TOK
+
+%nonassoc '=' NEQ_TOK ASSIGN_TOK
+%nonassoc BVLT_TOK BVLE_TOK BVGT_TOK BVGE_TOK
+%nonassoc BVUMINUS_TOK BVPLUS_TOK BVSUB_TOK BVSX_TOK
+%nonassoc '[' 
+%nonassoc '{' '.' '('
+%nonassoc BV_TOK
+
+%type <vec>  Exprs FORM_IDs reverseFORM_IDs
+%type <vec>  Asserts 
+%type <node> Expr Formula IfExpr ElseRestExpr IfForm ElseRestForm Assert Query ArrayUpdateExpr
+%type <Index_To_UpdateValue> Updates
+
+%type <indexvaluewidth>  BvType BoolType ArrayType Type 
+
+%token <node> BVCONST_TOK
+%token <node> TERMID_TOK FORMID_TOK COUNTEREXAMPLE_TOK
+%token <uintval> NUMERAL_TOK
+
+%%
+
+cmd             :      other_cmd
+                |      other_cmd counterexample
+                ; 
+
+counterexample  :      COUNTEREXAMPLE_TOK ';'
+                       {
+			 BEEV::print_counterexample = true;			 
+			 BEEV::globalBeevMgr_for_parser->PrintCounterExample(true);
+		       }                              
+                ;
+
+other_cmd       :      other_cmd1
+                |      Query 
+                       { 
+			 BEEV::globalBeevMgr_for_parser->TopLevelSAT(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE),*$1); 
+			 delete $1;
+		       }
+                |      VarDecls Query 
+                       { 
+			 BEEV::globalBeevMgr_for_parser->TopLevelSAT(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE),*$2); 
+			 delete $2;
+		       }
+                |      other_cmd1 Query
+                       {
+			 BEEV::ASTVec aaa = BEEV::globalBeevMgr_for_parser->GetAsserts();
+			 if(aaa.size() == 0)
+			   yyerror("Fatal Error: parsing:  GetAsserts() call: no assertions: ");
+			 if(aaa.size() == 1)
+			   BEEV::globalBeevMgr_for_parser->TopLevelSAT(aaa[0],*$2);
+			 else  		   
+			   BEEV::globalBeevMgr_for_parser->TopLevelSAT(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND,aaa),*$2);
+			 delete $2;
+		       }
+                ;
+
+other_cmd1      :     VarDecls Asserts
+                      {
+			delete $2;
+                      }                 
+                |     Asserts
+                      {
+			delete $1;
+		      }
+                |     other_cmd1 VarDecls Asserts
+                      {
+                        delete $3;
+                      }
+                ;
+
+/* push            :     PUSH_TOK */
+/*                       { */
+/* 			BEEV::globalBeevMgr_for_parser->Push(); */
+/*                       } */
+/*                 | */
+/*                 ; */
+
+/* pop             :     POP_TOK */
+/*                       { */
+/* 			BEEV::globalBeevMgr_for_parser->Pop(); */
+/*                       } */
+/*                 | */
+/*                 ; */
+
+Asserts         :      Assert 
+                       {
+			 $$ = new BEEV::ASTVec;
+			 $$->push_back(*$1);
+			 BEEV::globalBeevMgr_for_parser->AddAssert(*$1);
+			 delete $1;
+                       }
+                |      Asserts Assert
+                       {
+			 $1->push_back(*$2);
+			 BEEV::globalBeevMgr_for_parser->AddAssert(*$2);
+			 $$ = $1;
+			 delete $2;
+		       }
+                ;
+
+Assert          :      ASSERT_TOK Formula ';' { $$ = $2; }                
+                ;
+
+Query           :      QUERY_TOK Formula ';' { BEEV::globalBeevMgr_for_parser->AddQuery(*$2); $$ = $2;}
+                ; 
+
+
+/* Grammar for Variable Declaration */
+VarDecls	:      VarDecl ';'
+                       {
+                       }
+                |      VarDecls  VarDecl ';'
+                       {
+		       }
+		;
+
+VarDecl		:      FORM_IDs ':' Type 
+                       {
+			 for(BEEV::ASTVec::iterator i=$1->begin(),iend=$1->end();i!=iend;i++) {
+			   BEEV::_parser_symbol_table.insert(*i);
+			   i->SetIndexWidth($3.indexwidth);
+			   i->SetValueWidth($3.valuewidth);
+
+			   //FIXME: HACK_ATTACK. this vector was hacked into the code to
+			   //support a special request by Dawson' group. They want the
+			   //counterexample to be printed in the order of variables declared.
+			   BEEV::globalBeevMgr_for_parser->_special_print_set.push_back(*i);
+			 }
+			 delete $1;
+		       }
+                |      FORM_IDs ':' Type '=' Expr
+		       {
+			 //do type checking. if doesn't pass then abort
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			 if($3.indexwidth != $5->GetIndexWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 if($3.valuewidth != $5->GetValueWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 
+			 for(BEEV::ASTVec::iterator i=$1->begin(),iend=$1->end();i!=iend;i++) {			   
+			   //set the valuewidth of the identifier
+			   i->SetValueWidth($5->GetValueWidth());
+			   i->SetIndexWidth($5->GetIndexWidth());
+			   
+			   BEEV::globalBeevMgr_for_parser->LetExprMgr(*i,*$5);
+			   delete $5;
+			 }
+		       }
+                |      FORM_IDs ':' Type '=' Formula
+                       {
+			 //do type checking. if doesn't pass then abort
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			 if($3.indexwidth != $5->GetIndexWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 if($3.valuewidth != $5->GetValueWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 
+			 for(BEEV::ASTVec::iterator i=$1->begin(),iend=$1->end();i!=iend;i++) {			   
+			   //set the valuewidth of the identifier
+			   i->SetValueWidth($5->GetValueWidth());
+			   i->SetIndexWidth($5->GetIndexWidth());
+			   
+			   BEEV::globalBeevMgr_for_parser->LetExprMgr(*i,*$5);
+			   delete $5;
+			 }
+		       }                
+		;
+
+reverseFORM_IDs  :      FORMID_TOK
+                       {
+			 $$ = new BEEV::ASTVec;		        
+			 $$->push_back(*$1);
+			 delete $1;
+                       }
+                |      FORMID_TOK ',' reverseFORM_IDs
+                       {
+			 $3->push_back(*$1);
+			 $$ = $3;
+			 delete $1;
+                       }
+                ;
+
+FORM_IDs         :     reverseFORM_IDs
+                      {
+			$$ = new BEEV::ASTVec($1->rbegin(),$1->rend());
+			delete $1;
+                      }
+                ;
+
+/* Grammar for Types */
+Type		:      BvType { $$ = $1; }
+                |      BoolType { $$ = $1; }
+                |      ArrayType { $$ = $1; }
+		;		
+
+BvType          :      BV_TOK '(' NUMERAL_TOK ')' 
+                       {
+                         /*((indexwidth is 0) && (valuewidth>0)) iff type is BV*/
+			 $$.indexwidth = 0;
+			 unsigned int length = $3;
+			 if(length > 0) {
+			   $$.valuewidth = length;
+			 }
+			 else
+			  BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+		       }
+                ;
+BoolType        :      BOOLEAN_TOK
+                       {
+			 $$.indexwidth = 0;
+			 $$.valuewidth = 0;
+		       }
+                ;
+ArrayType       :      ARRAY_TOK BvType OF_TOK BvType
+                       {
+			 $$.indexwidth = $2.valuewidth;
+			 $$.valuewidth = $4.valuewidth;
+		       }
+                ;
+
+/*Grammar for ITEs which are a type of Term*/
+IfExpr	        :      IF_TOK Formula THEN_TOK Expr ElseRestExpr 
+                       {
+			 unsigned int width = $4->GetValueWidth();
+			 if (width != $5->GetValueWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");			 
+			 if($4->GetIndexWidth() != $5->GetIndexWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");
+
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$2);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$4);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE, width, *$2, *$4, *$5));
+			 $$->SetIndexWidth($5->GetIndexWidth());
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$$);
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		      }
+		;
+
+ElseRestExpr	:      ELSE_TOK Expr ENDIF_TOK  { $$ = $2; }
+                |      ELSIF_TOK Expr THEN_TOK Expr ElseRestExpr 
+                       {
+			 unsigned int width = $2->GetValueWidth();
+			 if (width != $4->GetValueWidth() || width != $5->GetValueWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");
+			 if ($2->GetIndexWidth() != $4->GetValueWidth() || $2->GetIndexWidth() != $5->GetValueWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");
+
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$2);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$4);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);			
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE, width, *$2, *$4, *$5));
+			 $$->SetIndexWidth($5->GetIndexWidth());
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$$);
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		       }
+		;
+
+/* Grammar for formulas */
+Formula		:     '(' Formula ')' { $$ = $2; }
+		|      FORMID_TOK {  $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); delete $1;}
+                |      BOOLEXTRACT_TOK '(' Expr ',' NUMERAL_TOK ')'
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if(0 > (unsigned)$5 || width <= (unsigned)$5)
+			   yyerror("Fatal Error: BOOLEXTRACT: trying to boolextract a bit which beyond range");
+			 
+			 BEEV::ASTNode hi  =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+			 BEEV::ASTNode low =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,1,*$3,hi,low));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 BEEV::ASTNode zero = BEEV::globalBeevMgr_for_parser->CreateBVConst(1,0);			 
+			 BEEV::ASTNode * out = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::EQ,*n,zero));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*out);
+
+			 $$ = out;
+			 delete $3;
+                       }
+                |      Expr '=' Expr 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::EQ, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Expr NEQ_TOK Expr 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NEQ, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       }
+		|      NOT_TOK Formula 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOT, *$2));
+			 delete $2;
+		       }
+		|      Formula OR_TOK Formula %prec OR_TOK 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::OR, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Formula NOR_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOR, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Formula AND_TOK Formula %prec AND_TOK 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       }
+		|      Formula NAND_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NAND, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       }
+		|      Formula IMPLIES_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IMPLIES, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       }
+		|      Formula IFF_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IFF, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Formula XOR_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::XOR, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+	        |      BVLT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVGT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVLE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVGE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSLT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSGT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSLE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSGE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+		|      IfForm
+		|      TRUELIT_TOK 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE)); 
+			 $$->SetIndexWidth(0); 
+			 $$->SetValueWidth(0);
+                       }
+		|      FALSELIT_TOK 
+                       { 
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::FALSE)); 
+			 $$->SetIndexWidth(0); 
+			 $$->SetValueWidth(0);
+		       }
+
+                |      LET_TOK LetDecls IN_TOK Formula
+                       {
+			 $$ = $4;
+			 //Cleanup the LetIDToExprMap
+			 BEEV::globalBeevMgr_for_parser->CleanupLetIDMap();
+		       }
+                ;
+
+/*Grammar for ITEs which are Formulas */
+IfForm	        :      IF_TOK Formula THEN_TOK Formula ElseRestForm 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::ITE, *$2, *$4, *$5));
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		      }
+		;
+
+ElseRestForm	:      ELSE_TOK Formula ENDIF_TOK  { $$ = $2; }
+                |      ELSIF_TOK Formula THEN_TOK Formula ElseRestForm 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::ITE, *$2, *$4, *$5));
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		       }
+		;
+
+/*Grammar for a list of expressions*/
+Exprs		:      Expr 
+                       {
+			 $$ = new BEEV::ASTVec;
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$1);
+			 $$->push_back(*$1);
+			 delete $1;
+		       }
+                |      Exprs ',' Expr 
+                       {
+			 $1->push_back(*$3);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+			 $$ = $1; 
+			 delete $3;
+		       }
+		;
+
+/* Grammar for Expr */
+Expr		:      TERMID_TOK { $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); delete $1;}
+                |      '(' Expr ')' { $$ = $2; }
+	        |      BVCONST_TOK { $$ = $1; }
+                |      BOOL_TO_BV_TOK '(' Formula ')'		
+                       {
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+			 BEEV::ASTNode one = BEEV::globalBeevMgr_for_parser->CreateBVConst(1,1);
+			 BEEV::ASTNode zero = BEEV::globalBeevMgr_for_parser->CreateBVConst(1,0);
+
+			 //return ITE(*$3, length(1), 0bin1, 0bin0)
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE,1,*$3,one,zero));
+			 delete $3;
+                       }
+		|      Expr '[' Expr ']' 
+                       {			 
+			 // valuewidth is same as array, indexwidth is 0.
+			 unsigned int width = $1->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $1;
+			 delete $3;
+		       }
+                |      Expr '(' Expr ')' //array read but in the form of a uninterpreted function application
+                       {
+			 // valuewidth is same as array, indexwidth is 0.
+			 unsigned int width = $1->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $1;
+			 delete $3;
+		       }
+	        |      Expr '[' NUMERAL_TOK ':' NUMERAL_TOK ']' 
+                       {
+			 int width = $3 - $5 + 1;
+			 if (width < 0)
+			   yyerror("Negative width in extract");
+			 
+			 if((unsigned)$3 >= $1->GetValueWidth() || (unsigned)$5 < 0)
+			   yyerror("Parsing: Wrong width in BVEXTRACT\n");			 
+
+			 BEEV::ASTNode hi  =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $3);
+			 BEEV::ASTNode low =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT, width, *$1,hi,low));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+		       }
+	        |      BVNEG_TOK Expr 
+                       {
+			 unsigned int width = $2->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNEG, width, *$2));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $2;
+		       }
+	        |      Expr BVAND_TOK Expr 
+                       {
+			 unsigned int width = $1->GetValueWidth();
+			 if (width != $3->GetValueWidth()) {
+			   yyerror("Width mismatch in AND");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVAND, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       }
+	        |      Expr BVOR_TOK Expr 
+                       {
+			 unsigned int width = $1->GetValueWidth();
+			 if (width != $3->GetValueWidth()) {
+			   yyerror("Width mismatch in OR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVOR, width, *$1, *$3)); 
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       }
+	        |      BVXOR_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in XOR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVXOR, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVNAND_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in NAND");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNAND, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $3;
+			 delete $5;
+		       }
+                |      BVNOR_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in NOR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNOR, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVXNOR_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in NOR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVXNOR, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $3;
+			 delete $5;
+		       }
+                |      BVSX_TOK '(' Expr ',' NUMERAL_TOK ')' 
+                       {
+			 //width of the expr which is being sign
+			 //extended. $5 is the resulting length of the
+			 //signextended expr
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+			 if($3->GetValueWidth() == $5) {
+			   $$ = $3;
+			 }
+			 else {
+			   BEEV::ASTNode width = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,$5);
+			   BEEV::ASTNode *n =  
+			     new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSX, $5,*$3,width));
+			   BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			   $$ = n;
+			   delete $3;
+			 }
+		       }
+	        |      Expr BVCONCAT_TOK Expr 
+                       {
+			 unsigned int width = $1->GetValueWidth() + $3->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 
+			 delete $1;
+			 delete $3;
+		       }
+                |      Expr BVLEFTSHIFT_TOK NUMERAL_TOK 
+                       {
+			 BEEV::ASTNode zero_bits = BEEV::globalBeevMgr_for_parser->CreateZeroConst($3);
+			 BEEV::ASTNode * n = 
+			   new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT,
+											$1->GetValueWidth() + $3, *$1, zero_bits));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+                       }
+                |      Expr BVRIGHTSHIFT_TOK NUMERAL_TOK 
+                       {
+			 BEEV::ASTNode len = BEEV::globalBeevMgr_for_parser->CreateZeroConst($3);
+			 unsigned int w = $1->GetValueWidth();
+
+			 //the amount by which you are rightshifting
+			 //is less-than/equal-to the length of input
+			 //bitvector
+			 if((unsigned)$3 < w) {
+			   BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w-1);
+			   BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,$3);
+			   BEEV::ASTNode extract = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-$3,*$1,hi,low);
+			   BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, w,len, extract));
+			   BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			   $$ = n;
+			 } 
+			 else
+			   $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateZeroConst(w));			 
+
+			 delete $1;
+                       }
+                |      BVPLUS_TOK '(' NUMERAL_TOK ',' Exprs ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVPLUS, $3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+                       }
+                |      BVSUB_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSUB, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+                       }
+                |      BVUMINUS_TOK '(' Expr ')' 
+                       {
+			 unsigned width = $3->GetValueWidth();
+			 BEEV::ASTNode * n =  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVUMINUS,width,*$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+                       }
+                |      BVMULT_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVMULT, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      BVDIV_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVDIV, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      BVMOD_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVMOD, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      SBVDIV_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::SBVDIV, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      SBVMOD_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::SBVMOD, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $5;
+			 delete $7;
+		       }        
+		|      IfExpr { $$ = $1; }
+                |      ArrayUpdateExpr
+                |      LET_TOK LetDecls IN_TOK Expr
+                       {
+			 $$ = $4;
+			 //Cleanup the LetIDToExprMap
+			 //BEEV::globalBeevMgr_for_parser->CleanupLetIDMap();
+		       }
+		;
+
+/*Grammar for Array Update Expr*/
+ArrayUpdateExpr : Expr WITH_TOK Updates
+                  {
+		    BEEV::ASTNode * result;
+		    unsigned int width = $1->GetValueWidth();
+
+		    BEEV::ASTNodeMap::iterator it = $3->begin();
+		    BEEV::ASTNodeMap::iterator itend = $3->end();
+		    result = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::WRITE,
+							      width,
+							      *$1,
+							      (*it).first,
+							      (*it).second));
+		    result->SetIndexWidth($1->GetIndexWidth());
+		    BEEV::globalBeevMgr_for_parser->BVTypeCheck(*result);
+		    for(it++;it!=itend;it++) {
+		      result = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::WRITE,
+								width,
+								*result,
+								(*it).first,
+								(*it).second));
+		      result->SetIndexWidth($1->GetIndexWidth());
+		      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*result);
+		    }
+		    BEEV::globalBeevMgr_for_parser->BVTypeCheck(*result);
+		    $$ = result;
+		    delete $3;
+                  }
+                ;
+
+Updates         : '[' Expr ']' ASSIGN_TOK Expr 
+                  {
+		    $$ = new BEEV::ASTNodeMap();
+		    (*$$)[*$2] = *$5;		    
+                  }
+                | Updates WITH_TOK '[' Expr ']' ASSIGN_TOK Expr 
+                  {		    
+		    (*$1)[*$4] = *$7;
+                  }
+                ;
+
+/*Grammar for LET Expr*/
+LetDecls	:	LetDecl 
+		|	LetDecls ',' LetDecl 
+		;
+
+LetDecl		:	FORMID_TOK '=' Expr 
+                        {
+			  //Expr must typecheck
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($3->GetValueWidth());
+			  $1->SetIndexWidth($3->GetIndexWidth());
+
+			  //populate the hashtable from LET-var -->
+			  //LET-exprs and then process them:
+			  //
+			  //1. ensure that LET variables do not clash
+			  //1. with declared variables.
+			  //
+			  //2. Ensure that LET variables are not
+			  //2. defined more than once
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$3);
+			  delete $1;
+			  delete $3;
+			}
+                |	FORMID_TOK ':' Type '=' Expr
+			{
+			  //do type checking. if doesn't pass then abort
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			  
+			  if($3.indexwidth != $5->GetIndexWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			  if($3.valuewidth != $5->GetValueWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($5->GetValueWidth());
+			  $1->SetIndexWidth($5->GetIndexWidth());
+
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$5);
+			  delete $1;
+			  delete $5;
+			}
+                |       FORMID_TOK '=' Formula
+                        {
+			  //Expr must typecheck
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($3->GetValueWidth());
+			  $1->SetIndexWidth($3->GetIndexWidth());
+
+			  //Do LET-expr management
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$3);
+			  delete $1;
+			  delete $3;
+			}
+                |	FORMID_TOK ':' Type '=' Formula
+			{
+			  //do type checking. if doesn't pass then abort
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+
+			  if($3.indexwidth != $5->GetIndexWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			  if($3.valuewidth != $5->GetValueWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($5->GetValueWidth());
+			  $1->SetIndexWidth($5->GetIndexWidth());
+
+			  //Do LET-expr management
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$5);
+			  delete $1;
+			  delete $5;
+			}                
+		;
+
+%%
diff --git a/stp/parser/let-funcs.cpp b/stp/parser/let-funcs.cpp
new file mode 100644
index 00000000..1de10492
--- /dev/null
+++ b/stp/parser/let-funcs.cpp
@@ -0,0 +1,85 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include <stdlib.h>
+
+namespace BEEV {
+  //external parser table for declared symbols. Only symbols which are
+  //declared are stored here.
+  ASTNodeSet _parser_symbol_table;
+
+  // FUNC: This function maintains a map between LET-var names and
+  // LET-expressions
+  //
+  //1. if the Let-var is already defined in the LET scope, then the
+  //1. function returns an error.
+  //
+  //2. if the Let-var is already declared variable in the input, then
+  //2. the function returns an error
+  //
+  //3. otherwise add the <var,letExpr> pair to the _letid_expr table.
+  void BeevMgr::LetExprMgr(const ASTNode& var, const ASTNode& letExpr) {
+    ASTNodeMap::iterator it;
+    if(((it = _letid_expr_map.find(var)) != _letid_expr_map.end()) && 
+       it->second != ASTUndefined) {      
+      FatalError("LetExprMgr:The LET-var v has already been defined in this LET scope: v =", var);
+    }
+
+    if(_parser_symbol_table.find(var) != _parser_symbol_table.end()) {
+      FatalError("LetExprMgr:This var is already declared. cannot redeclare as a letvar: v =", var);
+    }
+
+    _letid_expr_map[var] = letExpr;   
+  }
+
+  //this function looksup the "var to letexpr map" and returns the
+  //corresponding letexpr. if there is no letexpr, then it simply
+  //returns the var.
+  ASTNode BeevMgr::ResolveID(const ASTNode& v) {
+    if(v.GetKind() != SYMBOL) {
+      return v;
+    }
+
+    if(_parser_symbol_table.find(v) != _parser_symbol_table.end()) {
+      return v;
+    }
+
+    ASTNodeMap::iterator it;
+    if((it =_letid_expr_map.find(v)) != _letid_expr_map.end()) {
+      if(it->second == ASTUndefined) 
+	FatalError("Unresolved Identifier: ",v);
+      else
+	return it->second;
+    }
+
+    //this is to mark the let-var as undefined. the let var is defined
+    //only after the LetExprMgr has completed its work, and until then
+    //'v' is undefined. 
+    //
+    //declared variables also get stored in this map, but there value
+    //is ASTUndefined. This is really a hack. I don't know how to get
+    //rid of this hack.
+    _letid_expr_map[v] = ASTUndefined;
+    return v;    
+  }
+  
+  // This function simply cleans up the LetID -> LetExpr Map.   
+  void BeevMgr::CleanupLetIDMap(void) { 
+    ASTNodeMap::iterator it = _letid_expr_map.begin();
+    ASTNodeMap::iterator itend = _letid_expr_map.end();
+    for(;it!=itend;it++) {
+      if(it->second != ASTUndefined) {
+	it->first.SetValueWidth(0);
+	it->first.SetIndexWidth(0);
+      }
+    }
+    _letid_expr_map.clear();
+  }
+};
diff --git a/stp/parser/main.cpp b/stp/parser/main.cpp
new file mode 100644
index 00000000..ed251ed3
--- /dev/null
+++ b/stp/parser/main.cpp
@@ -0,0 +1,181 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <algorithm>
+#include <ctime>
+#include <unistd.h>
+#include <signal.h>
+//#include <zlib.h>
+#include <stdio.h>
+#include "../AST/AST.h"
+#include "parsePL_defs.h"
+#include "../sat/Solver.h"
+#include "../sat/SolverTypes.h"
+#include "../sat/VarOrder.h"
+
+#include <unistd.h>
+
+#ifdef EXT_HASH_MAP
+  using namespace __gnu_cxx;
+#endif
+
+/* GLOBAL FUNCTION: parser
+ */
+extern int yyparse();
+//extern int smtlibparse();
+
+/* GLOBAL VARS: Some global vars for the Main function.
+ *
+ */
+const char * prog = "stp";
+int linenum  = 1;
+const char * usage = "Usage: %s [-option] [infile]\n";
+std::string helpstring = "\n\n";
+
+// Amount of memory to ask for at beginning of main.
+static const intptr_t INITIAL_MEMORY_PREALLOCATION_SIZE = 4000000;
+
+// Used only in smtlib lexer/parser
+BEEV::ASTNode SingleBitOne;
+BEEV::ASTNode SingleBitZero;
+
+/******************************************************************************
+ * MAIN FUNCTION: 
+ *
+ * step 0. Parse the input into an ASTVec.
+ * step 1. Do BV Rewrites
+ * step 2. Bitblasts the ASTNode.
+ * step 3. Convert to CNF
+ * step 4. Convert to SAT
+ * step 5. Call SAT to determine if input is SAT or UNSAT
+ ******************************************************************************/
+int main(int argc, char ** argv) {
+  char * infile;
+  extern FILE *yyin;
+
+  // Grab some memory from the OS upfront to reduce system time when individual
+  // hash tables are being allocated
+
+  if (sbrk(INITIAL_MEMORY_PREALLOCATION_SIZE) == ((void *) -1)) {
+    // FIXME: figure out how to get and print the real error message.
+    BEEV::FatalError("Initial allocation of memory failed.");
+  }
+  
+  //populate the help string
+  helpstring +=  "-r  : switch refinement off (optimizations are ON by default)\n";
+  helpstring +=  "-w  : switch wordlevel solver off (optimizations are ON by default)\n";
+  helpstring +=  "-a  : switch optimizations off (optimizations are ON by default)\n";
+  helpstring +=  "-s  : print function statistics\n";
+  helpstring +=  "-v  : print nodes \n";
+  helpstring +=  "-c  : construct counterexample\n";
+  helpstring +=  "-d  : check counterexample\n";
+  helpstring +=  "-p  : print counterexample\n";
+  helpstring +=  "-x  : flatten nested XORs\n";
+  helpstring +=  "-h  : help\n";
+
+  for(int i=1; i < argc;i++) {
+    if(argv[i][0] == '-')
+      switch(argv[i][1]) {
+      case 'a' :
+	BEEV::optimize = false;
+	BEEV::wordlevel_solve = false;
+	break;
+      case 'b':
+	BEEV::print_STPinput_back = true;
+	break;
+      case 'c':
+	BEEV::construct_counterexample = true;
+	break;
+      case 'd':
+	BEEV::construct_counterexample = true;
+	BEEV::check_counterexample = true;
+	break;
+      case 'e':
+	BEEV::variable_activity_optimize = true;
+	break;
+      case 'f':
+	BEEV::smtlib_parser_enable = true;
+	break;
+      case 'h':
+	fprintf(stderr,usage,prog);
+	cout << helpstring;
+	//BEEV::FatalError("");
+	return -1;
+	break;
+      case 'l' :
+	BEEV::linear_search = true;
+	break;
+      case 'n':
+	BEEV::print_output = true;
+	break;
+      case 'p':
+	BEEV::print_counterexample = true;
+	break;
+      case 'q':
+	BEEV::print_arrayval_declaredorder = true;
+	break;
+      case 'r':
+	BEEV::arrayread_refinement = false;
+	break;
+      case 's' :
+	BEEV::stats = true;
+	break;
+      case 'u':
+	BEEV::arraywrite_refinement = false;
+	break;
+      case 'v' :
+	BEEV::print_nodes = true;
+	break;
+      case 'w':
+	BEEV::wordlevel_solve = false;
+	break;
+      case 'x':
+	BEEV::xor_flatten = true;
+	break;
+      case 'z':
+	BEEV::print_sat_varorder = true;
+	break;
+      default:
+	fprintf(stderr,usage,prog);
+	cout << helpstring;
+	//BEEV::FatalError("");
+	return -1;
+	break;
+      }
+    else {
+      infile = argv[i];
+      yyin = fopen(infile,"r");
+      if(yyin == NULL) {
+	fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
+	BEEV::FatalError("");
+      }
+    }
+  }
+
+#ifdef NATIVE_C_ARITH
+#else
+  CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot(); 
+  if(0 != c) {
+    cout << CONSTANTBV::BitVector_Error(c) << endl;
+    return 0;
+  }
+#endif           
+
+  //want to print the output always from the commandline. 
+  BEEV::print_output = true;
+  BEEV::globalBeevMgr_for_parser = new BEEV::BeevMgr();  
+
+  SingleBitOne = BEEV::globalBeevMgr_for_parser->CreateOneConst(1);
+  SingleBitZero = BEEV::globalBeevMgr_for_parser->CreateZeroConst(1);
+  //BEEV::smtlib_parser_enable = true;
+  yyparse();
+}//end of Main
diff --git a/stp/parser/smtlib.lex b/stp/parser/smtlib.lex
new file mode 100644
index 00000000..a03ae94e
--- /dev/null
+++ b/stp/parser/smtlib.lex
@@ -0,0 +1,232 @@
+%{
+  /********************************************************************
+   * AUTHORS: Vijay Ganesh, David L. Dill
+   *
+   * BEGIN DATE: July, 2006
+   *
+   * This file is modified version of the CVCL's smtlib.lex file. Please
+   * see CVCL license below
+   ********************************************************************/
+  
+  /********************************************************************
+   * \file smtlib.lex
+   * 
+   * Author: Sergey Berezin, Clark Barrett
+   * 
+   * Created: Apr 30 2005
+   *
+   * <hr>
+   * Copyright (C) 2004 by the Board of Trustees of Leland Stanford
+   * Junior University and by New York University. 
+   *
+   * License to use, copy, modify, sell and/or distribute this software
+   * and its documentation for any purpose is hereby granted without
+   * royalty, subject to the terms and conditions defined in the \ref
+   * LICENSE file provided with this distribution.  In particular:
+   *
+   * - The above copyright notice and this permission notice must appear
+   * in all copies of the software and related documentation.
+   *
+   * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
+   * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
+   * 
+   * <hr>
+   ********************************************************************/
+  // -*- c++ -*-
+#include <iostream>
+#include "../AST/AST.h"
+#include "parsePL_defs.h"
+  
+  extern char *yytext;
+  extern int yyerror (char *msg);
+  
+  // File-static (local to this file) variables and functions
+  static std::string _string_lit;
+  
+  static char escapeChar(char c) {
+    switch(c) {
+    case 'n': return '\n';
+    case 't': return '\t';
+    default: return c;
+    }
+  }      
+
+  extern BEEV::ASTNode SingleBitOne;
+  extern BEEV::ASTNode SingleBitZero;
+
+/* Changed for smtlib speedup */
+/* bv{DIGIT}+      { yylval.node = new BEEV::ASTNode(BEEV::_bm->CreateBVConst(yytext+2, 10)); return BVCONST_TOK;} */
+
+%}
+
+%option noyywrap
+%option nounput
+%option noreject
+%option noyymore
+%option yylineno
+
+%x	COMMENT
+%x	STRING_LITERAL
+%x      USER_VALUE
+
+LETTER	([a-zA-Z])
+DIGIT	([0-9])
+OPCHAR	(['\.\_]) 
+ANYTHING  ({LETTER}|{DIGIT}|{OPCHAR})
+
+%%
+[ \n\t\r\f]	{ /* sk'ip whitespace */ }
+{DIGIT}+	{ yylval.uintval = strtoul(yytext, NULL, 10); return NUMERAL_TOK; }
+
+
+bv{DIGIT}+	{ yylval.ullval = strtoull(yytext+2, NULL, 10); return BVCONST_TOK; }
+
+bit{DIGIT}+     {
+  		   char c = yytext[3];
+		   if (c == '1') {
+		     yylval.node = new BEEV::ASTNode(SingleBitOne);
+		   }
+		   else {
+		     yylval.node = new BEEV::ASTNode(SingleBitZero);
+		   }
+		   return BITCONST_TOK;
+		};
+
+
+";"		{ BEGIN COMMENT; }
+<COMMENT>"\n"	{ BEGIN INITIAL; /* return to normal mode */}
+<COMMENT>.	{ /* stay in comment mode */ }
+
+<INITIAL>"\""		{ BEGIN STRING_LITERAL;
+                          _string_lit.erase(_string_lit.begin(),
+                                            _string_lit.end()); }
+<STRING_LITERAL>"\\".	{ /* escape characters (like \n or \") */
+                          _string_lit.insert(_string_lit.end(),
+                                             escapeChar(yytext[1])); }
+<STRING_LITERAL>"\""	{ BEGIN INITIAL; /* return to normal mode */
+			  yylval.str = new std::string(_string_lit);
+                          return STRING_TOK; }
+<STRING_LITERAL>.	{ _string_lit.insert(_string_lit.end(),*yytext); }
+
+
+<INITIAL>"{"		{ BEGIN USER_VALUE;
+                          _string_lit.erase(_string_lit.begin(),
+                                            _string_lit.end()); }
+<USER_VALUE>"\\"[{}] { /* escape characters */
+                          _string_lit.insert(_string_lit.end(),yytext[1]); }
+
+<USER_VALUE>"}"	        { BEGIN INITIAL; /* return to normal mode */
+			  yylval.str = new std::string(_string_lit);
+                          return USER_VAL_TOK; }
+<USER_VALUE>"\n"        { _string_lit.insert(_string_lit.end(),'\n');}
+<USER_VALUE>.	        { _string_lit.insert(_string_lit.end(),*yytext); }
+
+"BitVec"        { return BITVEC_TOK;}
+"Array"         { return ARRAY_TOK;}
+"true"          { return TRUE_TOK; }
+"false"         { return FALSE_TOK; }
+"not"           { return NOT_TOK; }
+"implies"       { return IMPLIES_TOK; }
+"ite"           { return ITE_TOK;}
+"if_then_else"  { return IF_THEN_ELSE_TOK; }
+"and"           { return AND_TOK; }
+"or"            { return OR_TOK; }
+"xor"           { return XOR_TOK; }
+"iff"           { return IFF_TOK; }
+"let"           { return LET_TOK; }
+"flet"          { return FLET_TOK; }
+"notes"         { return NOTES_TOK; }
+"cvc_command"   { return CVC_COMMAND_TOK; }
+"sorts"         { return SORTS_TOK; }
+"funs"          { return FUNS_TOK; }
+"preds"         { return PREDS_TOK; }
+"extensions"    { return EXTENSIONS_TOK; }
+"definition"    { return DEFINITION_TOK; }
+"axioms"        { return AXIOMS_TOK; }
+"logic"         { return LOGIC_TOK; }
+"sat"           { return SAT_TOK; }
+"unsat"         { return UNSAT_TOK; }
+"unknown"       { return UNKNOWN_TOK; }
+"assumption"    { return ASSUMPTION_TOK; }
+"formula"       { return FORMULA_TOK; }
+"status"        { return STATUS_TOK; }
+"difficulty"    { return DIFFICULTY_TOK; }
+"benchmark"     { return BENCHMARK_TOK; }
+"source"        { return SOURCE_TOK;}
+"category"      { return CATEGORY_TOK;} 
+"extrasorts"    { return EXTRASORTS_TOK; }
+"extrafuns"     { return EXTRAFUNS_TOK; }
+"extrapreds"    { return EXTRAPREDS_TOK; }
+"language"      { return LANGUAGE_TOK; }
+"distinct"      { return DISTINCT_TOK; }
+"select"        { return SELECT_TOK; }
+"store"         { return STORE_TOK; }
+":"             { return COLON_TOK; }
+"\["            { return LBRACKET_TOK; }
+"\]"            { return RBRACKET_TOK; }
+"("             { return LPAREN_TOK; }
+")"             { return RPAREN_TOK; }
+"$"             { return DOLLAR_TOK; }
+"?"             { return QUESTION_TOK; }
+"="             {return EQ_TOK;}
+
+"nand"		{ return NAND_TOK;}
+"nor"		{ return NOR_TOK;}
+"/="		{ return NEQ_TOK; }
+ ":="           { return ASSIGN_TOK;}
+"shift_left0"   { return BVLEFTSHIFT_TOK;}
+"bvshl"         { return BVLEFTSHIFT_1_TOK;}
+"shift_right0"  { return BVRIGHTSHIFT_TOK;}
+"bvlshr"        { return BVRIGHTSHIFT_1_TOK;}
+"bvadd"         { return BVPLUS_TOK;}
+"bvsub"         { return BVSUB_TOK;}
+"bvnot"         { return BVNOT_TOK;}
+"bvmul"         { return BVMULT_TOK;}
+"bvdiv"         { return BVDIV_TOK;}
+"bvmod"         { return BVMOD_TOK;}
+"bvneg"         { return BVNEG_TOK;}
+"bvand"         { return BVAND_TOK;}
+"bvor"          { return BVOR_TOK;}
+"bvxor"         { return BVXOR_TOK;}
+"bvnand"        { return BVNAND_TOK;}
+"bvnor"         { return BVNOR_TOK;}
+"bvxnor"        { return BVXNOR_TOK;}
+"concat"        { return BVCONCAT_TOK;}
+"extract"       { return BVEXTRACT_TOK;}
+"bvlt"          { return BVLT_TOK;}
+"bvgt"          { return BVGT_TOK;}
+"bvleq"         { return BVLE_TOK;}
+"bvgeq"         { return BVGE_TOK;}
+"bvult"         { return BVLT_TOK;}
+"bvugt"         { return BVGT_TOK;}
+"bvuleq"        { return BVLE_TOK;}
+"bvugeq"        { return BVGE_TOK;}
+"bvule"         { return BVLE_TOK;}
+"bvuge"         { return BVGE_TOK;}
+
+"bvslt"         { return BVSLT_TOK;}
+"bvsgt"         { return BVSGT_TOK;}
+"bvsleq"        { return BVSLE_TOK;}
+"bvsgeq"        { return BVSGE_TOK;}
+"bvsle"         { return BVSLE_TOK;}
+"bvsge"         { return BVSGE_TOK;}
+
+"sign_extend"   { return BVSX_TOK;} 
+"boolextract"   { return BOOLEXTRACT_TOK;}
+"boolbv"        { return BOOL_TO_BV_TOK;}
+
+(({LETTER})|(_)({ANYTHING}))({ANYTHING})*	{
+  BEEV::ASTNode nptr = BEEV::globalBeevMgr_for_parser->CreateSymbol(yytext); 
+
+  // Check valuesize to see if it's a prop var.  I don't like doing
+  // type determination in the lexer, but it's easier than rewriting
+  // the whole grammar to eliminate the term/formula distinction.  
+  yylval.node = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(nptr));
+  //yylval.node = new BEEV::ASTNode(nptr);
+  if ((yylval.node)->GetType() == BEEV::BOOLEAN_TYPE)
+    return FORMID_TOK;
+  else 
+    return TERMID_TOK;  
+}
+. { yyerror("Illegal input character."); }
+%%
diff --git a/stp/parser/smtlib.y b/stp/parser/smtlib.y
new file mode 100644
index 00000000..0aa22dee
--- /dev/null
+++ b/stp/parser/smtlib.y
@@ -0,0 +1,1036 @@
+%{
+  /********************************************************************
+   * AUTHORS: Vijay Ganesh, David L. Dill
+   *
+   * BEGIN DATE: July, 2006
+   *
+   * This file is modified version of the CVCL's smtlib.y file. Please
+   * see CVCL license below
+   ********************************************************************/
+  
+  /********************************************************************
+   *
+   * \file smtlib.y
+   * 
+   * Author: Sergey Berezin, Clark Barrett
+   * 
+   * Created: Apr 30 2005
+   *
+   * <hr>
+   * Copyright (C) 2004 by the Board of Trustees of Leland Stanford
+   * Junior University and by New York University. 
+   *
+   * License to use, copy, modify, sell and/or distribute this software
+   * and its documentation for any purpose is hereby granted without
+   * royalty, subject to the terms and conditions defined in the \ref
+   * LICENSE file provided with this distribution.  In particular:
+   *
+   * - The above copyright notice and this permission notice must appear
+   * in all copies of the software and related documentation.
+   *
+   * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
+   * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
+   * 
+   * <hr>
+   ********************************************************************/
+  // -*- c++ -*-
+
+#include "../AST/AST.h"
+  using namespace std; 
+  
+  // Suppress the bogus warning suppression in bison (it generates
+  // compile error)
+#undef __GNUC_MINOR__
+  
+  extern char* yytext;
+  extern int yylineno;
+  
+  //int yylineno;
+
+  extern int yylex(void);
+
+  int yyerror(char *s) {
+    //yylineno = 0;
+    cout << "syntax error: line " << yylineno << "\n" << s << endl;
+    cout << "  token: " << yytext << endl;
+    BEEV::FatalError("");
+    return 1;
+  }
+
+  BEEV::ASTNode query;
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYMAXDEPTH 104857600
+#define YYERROR_VERBOSE 1
+#define YY_EXIT_FAILURE -1
+%}
+
+%union {  
+  // FIXME: Why is this not an UNSIGNED int?
+  int uintval;			/* for numerals in types. */
+
+  // for BV32 BVCONST 
+  unsigned long long ullval;
+
+  struct {
+    //stores the indexwidth and valuewidth
+    //indexwidth is 0 iff type is bitvector. positive iff type is
+    //array, and stores the width of the indexing bitvector
+    unsigned int indexwidth;
+    //width of the bitvector type
+    unsigned int valuewidth;
+  } indexvaluewidth;
+
+  //ASTNode,ASTVec
+  BEEV::ASTNode *node;
+  BEEV::ASTVec *vec;
+  std::string *str;
+};
+
+%start cmd
+
+%type <indexvaluewidth> sort_symb sort_symbs
+%type <node> status
+%type <vec> bench_attributes an_formulas
+
+%type <node> benchmark bench_name bench_attribute
+%type <node> an_term an_nonbvconst_term an_formula 
+
+%type <node> var fvar logic_name
+%type <str> user_value
+
+%token <uintval> NUMERAL_TOK
+%token <ullval> BVCONST_TOK
+%token <node> BITCONST_TOK
+%token <node> FORMID_TOK TERMID_TOK 
+%token <str> STRING_TOK
+%token <str> USER_VAL_TOK
+%token SOURCE_TOK
+%token CATEGORY_TOK
+%token DIFFICULTY_TOK
+%token BITVEC_TOK
+%token ARRAY_TOK
+%token SELECT_TOK
+%token STORE_TOK
+%token TRUE_TOK
+%token FALSE_TOK
+%token NOT_TOK
+%token IMPLIES_TOK
+%token ITE_TOK
+%token IF_THEN_ELSE_TOK
+%token AND_TOK
+%token OR_TOK
+%token XOR_TOK
+%token IFF_TOK
+%token EXISTS_TOK
+%token FORALL_TOK
+%token LET_TOK
+%token FLET_TOK
+%token NOTES_TOK
+%token CVC_COMMAND_TOK
+%token SORTS_TOK
+%token FUNS_TOK
+%token PREDS_TOK
+%token EXTENSIONS_TOK
+%token DEFINITION_TOK
+%token AXIOMS_TOK
+%token LOGIC_TOK
+%token COLON_TOK
+%token LBRACKET_TOK
+%token RBRACKET_TOK
+%token LPAREN_TOK
+%token RPAREN_TOK
+%token SAT_TOK
+%token UNSAT_TOK
+%token UNKNOWN_TOK
+%token ASSUMPTION_TOK
+%token FORMULA_TOK
+%token STATUS_TOK
+%token BENCHMARK_TOK
+%token EXTRASORTS_TOK
+%token EXTRAFUNS_TOK
+%token EXTRAPREDS_TOK
+%token LANGUAGE_TOK
+%token DOLLAR_TOK
+%token QUESTION_TOK
+%token DISTINCT_TOK
+%token SEMICOLON_TOK
+%token EOF_TOK
+%token EQ_TOK
+/*BV SPECIFIC TOKENS*/
+%token NAND_TOK
+%token NOR_TOK
+%token NEQ_TOK
+%token ASSIGN_TOK
+%token BV_TOK
+%token BOOLEAN_TOK
+%token BVLEFTSHIFT_TOK
+%token BVLEFTSHIFT_1_TOK
+%token BVRIGHTSHIFT_TOK
+%token BVRIGHTSHIFT_1_TOK
+%token BVPLUS_TOK
+%token BVSUB_TOK
+%token BVNOT_TOK //bvneg in CVCL
+%token BVMULT_TOK
+%token BVDIV_TOK
+%token BVMOD_TOK
+%token BVNEG_TOK //bvuminus in CVCL
+%token BVAND_TOK
+%token BVOR_TOK
+%token BVXOR_TOK
+%token BVNAND_TOK
+%token BVNOR_TOK
+%token BVXNOR_TOK
+%token BVCONCAT_TOK
+%token BVLT_TOK
+%token BVGT_TOK
+%token BVLE_TOK
+%token BVGE_TOK
+%token BVSLT_TOK
+%token BVSGT_TOK
+%token BVSLE_TOK
+%token BVSGE_TOK
+%token BVSX_TOK 
+%token BOOLEXTRACT_TOK
+%token BOOL_TO_BV_TOK
+%token BVEXTRACT_TOK
+
+%left LBRACKET_TOK RBRACKET_TOK
+
+%%
+
+cmd:
+    benchmark
+    {
+      if($1 != NULL) {
+	BEEV::globalBeevMgr_for_parser->TopLevelSAT(*$1,query);
+	delete $1;
+      }
+      YYACCEPT;
+    }
+;
+
+benchmark:
+    LPAREN_TOK BENCHMARK_TOK bench_name bench_attributes RPAREN_TOK
+    {
+      if($4 != NULL){
+	if($4->size() > 1) 
+	  $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND,*$4));
+	else
+	  $$ = new BEEV::ASTNode((*$4)[0]);	  
+	delete $4;
+      }
+      else {
+	$$ = NULL;
+      }
+    }
+/*   | EOF_TOK */
+/*     { */
+/*     } */
+;
+
+bench_name:
+    FORMID_TOK
+    {
+    }
+;
+
+bench_attributes:
+    bench_attribute
+    {
+      $$ = new BEEV::ASTVec;
+      if ($1 != NULL) {
+	$$->push_back(*$1);
+	BEEV::globalBeevMgr_for_parser->AddAssert(*$1);
+	delete $1;
+      }
+    }
+  | bench_attributes bench_attribute
+    {
+      if ($1 != NULL && $2 != NULL) {
+	$1->push_back(*$2);
+	BEEV::globalBeevMgr_for_parser->AddAssert(*$2);
+	$$ = $1;
+	delete $2;
+      }
+    }
+;
+
+bench_attribute:
+    COLON_TOK ASSUMPTION_TOK an_formula
+    {
+      //assumptions are like asserts
+      $$ = $3;
+    }
+  | COLON_TOK FORMULA_TOK an_formula
+    {
+      //the query
+      query = BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOT,*$3);
+      BEEV::globalBeevMgr_for_parser->AddQuery(query);
+      //dummy true
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE));
+      
+      
+    }
+  | COLON_TOK STATUS_TOK status
+    {
+      $$ = NULL;
+    }
+  | COLON_TOK LOGIC_TOK logic_name
+    {
+      if (!(0 == strcmp($3->GetName(),"QF_UFBV")  ||
+            0 == strcmp($3->GetName(),"QF_AUFBV"))) {
+	yyerror("Wrong input logic:");
+      }
+      $$ = NULL;
+    }
+  | COLON_TOK EXTRAFUNS_TOK LPAREN_TOK var_decls RPAREN_TOK
+    {
+      $$ = NULL;
+    }
+  | COLON_TOK EXTRAPREDS_TOK LPAREN_TOK var_decls RPAREN_TOK
+    {
+      $$ = NULL;
+    }
+  | annotation 
+    {
+      $$ = NULL;
+    }
+;
+
+logic_name:
+    FORMID_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      $$ = $1;
+    }
+  | FORMID_TOK
+    {
+      $$ = $1;
+    }
+;
+
+status:
+    SAT_TOK { $$ = NULL; }
+  | UNSAT_TOK { $$ = NULL; }
+  | UNKNOWN_TOK { $$ = NULL; }
+;
+
+
+/* annotations: */
+/*     annotation */
+/*     { */
+/*     } */
+/*   | annotations annotation */
+/*     { */
+/*     } */
+/*   ; */
+  
+annotation:
+    attribute 
+    {
+    }
+  | attribute user_value 
+    {
+    }
+;
+
+user_value:
+    USER_VAL_TOK
+    {
+      //cerr << "Printing user_value: " << *$1 << endl;
+    }
+;
+
+attribute:
+    COLON_TOK SOURCE_TOK
+    {
+    }
+   | COLON_TOK CATEGORY_TOK
+    {
+    }
+   | COLON_TOK DIFFICULTY_TOK 
+;
+
+sort_symbs:
+    sort_symb 
+    {
+      //a single sort symbol here means either a BitVec or a Boolean
+      $$.indexwidth = $1.indexwidth;
+      $$.valuewidth = $1.valuewidth;
+    }
+  | sort_symb sort_symb
+    {
+      //two sort symbols mean f: type --> type
+      $$.indexwidth = $1.valuewidth;
+      $$.valuewidth = $2.valuewidth;
+    }
+;
+
+var_decls:
+    var_decl
+    {
+    }
+//  | LPAREN_TOK var_decl RPAREN_TOK
+  |
+    var_decls var_decl
+    {
+    }
+;
+
+var_decl:
+    LPAREN_TOK FORMID_TOK sort_symbs RPAREN_TOK
+    {
+      BEEV::_parser_symbol_table.insert(*$2);
+      //Sort_symbs has the indexwidth/valuewidth. Set those fields in
+      //var
+      $2->SetIndexWidth($3.indexwidth);
+      $2->SetValueWidth($3.valuewidth);
+    }
+   | LPAREN_TOK FORMID_TOK RPAREN_TOK
+    {
+      BEEV::_parser_symbol_table.insert(*$2);
+      //Sort_symbs has the indexwidth/valuewidth. Set those fields in
+      //var
+      $2->SetIndexWidth(0);
+      $2->SetValueWidth(0);
+    }
+;
+
+an_formulas:
+    an_formula
+    {
+      $$ = new BEEV::ASTVec;
+      if ($1 != NULL) {
+	$$->push_back(*$1);
+	delete $1;
+      }
+    }
+  |
+    an_formulas an_formula
+    {
+      if ($1 != NULL && $2 != NULL) {
+	$1->push_back(*$2);
+	$$ = $1;
+	delete $2;
+      }
+    }
+;
+
+an_formula:   
+    TRUE_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE)); 
+      $$->SetIndexWidth(0); 
+      $$->SetValueWidth(0);
+    }
+  | FALSE_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::FALSE)); 
+      $$->SetIndexWidth(0); 
+      $$->SetValueWidth(0);
+    }
+  | fvar
+    {
+      $$ = $1;
+    }
+  | LPAREN_TOK EQ_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK EQ_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateSimplifiedEQ(*$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSLT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSLT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSLE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSLE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSGT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSGT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSGE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSGE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVLT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVLT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVLE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVLE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVGT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVGT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVGE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVGE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK an_formula RPAREN_TOK
+    {
+      $$ = $2;
+    }
+  | LPAREN_TOK NOT_TOK an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOT, *$3));
+      delete $3;
+    }
+  | LPAREN_TOK IMPLIES_TOK an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IMPLIES, *$3, *$4));
+      delete $3;
+      delete $4;
+    }
+  | LPAREN_TOK IF_THEN_ELSE_TOK an_formula an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::ITE, *$3, *$4, *$5));
+      delete $3;
+      delete $4;
+      delete $5;
+    }
+  | LPAREN_TOK AND_TOK an_formulas RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND, *$3));
+      delete $3;
+    }
+  | LPAREN_TOK OR_TOK an_formulas RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::OR, *$3));
+      delete $3;
+    }
+  | LPAREN_TOK XOR_TOK an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::XOR, *$3, *$4));
+      delete $3;
+      delete $4;
+    }
+  | LPAREN_TOK IFF_TOK an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IFF, *$3, *$4));
+      delete $3;
+      delete $4;
+    }
+  | letexpr_mgmt an_formula RPAREN_TOK
+  //| letexpr_mgmt an_formula annotations RPAREN_TOK
+    {
+      $$ = $2;
+      //Cleanup the LetIDToExprMap
+      BEEV::globalBeevMgr_for_parser->CleanupLetIDMap();			 
+    }
+;
+
+letexpr_mgmt: 
+    LPAREN_TOK LET_TOK LPAREN_TOK QUESTION_TOK FORMID_TOK an_term RPAREN_TOK
+    {
+     //Expr must typecheck
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$6);
+      
+      //set the valuewidth of the identifier
+      $5->SetValueWidth($6->GetValueWidth());
+      $5->SetIndexWidth($6->GetIndexWidth());
+      
+      //populate the hashtable from LET-var -->
+      //LET-exprs and then process them:
+      //
+      //1. ensure that LET variables do not clash
+      //1. with declared variables.
+      //
+      //2. Ensure that LET variables are not
+      //2. defined more than once
+      BEEV::globalBeevMgr_for_parser->LetExprMgr(*$5,*$6);
+      delete $5;
+      delete $6;      
+   }
+ | LPAREN_TOK FLET_TOK LPAREN_TOK DOLLAR_TOK FORMID_TOK an_formula RPAREN_TOK 
+   {
+     //Expr must typecheck
+     BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$6);
+     
+     //set the valuewidth of the identifier
+     $5->SetValueWidth($6->GetValueWidth());
+     $5->SetIndexWidth($6->GetIndexWidth());
+     
+     //Do LET-expr management
+     BEEV::globalBeevMgr_for_parser->LetExprMgr(*$5,*$6);
+     delete $5;
+     delete $6;     
+   }
+
+/* an_terms: */
+/*     an_term */
+/*     { */
+/*     } */
+/*   | an_terms an_term */
+/*     { */
+/*     } */
+/* ; */
+
+an_term:
+    BVCONST_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(64, $1));
+    }
+  | BVCONST_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst($3, $1));
+    }
+  | an_nonbvconst_term
+  ;
+
+an_nonbvconst_term: 
+    BITCONST_TOK { $$ = $1; }
+  | var
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1));
+      delete $1;
+    }
+  | LPAREN_TOK an_term RPAREN_TOK
+  //| LPAREN_TOK an_term annotations RPAREN_TOK
+    {
+      $$ = $2;
+      //$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->SimplifyTerm(*$2));
+      //delete $2;
+    }
+  | LPAREN_TOK TERMID_TOK an_term RPAREN_TOK
+    {
+      //ARRAY READ
+      // valuewidth is same as array, indexwidth is 0.
+      BEEV::ASTNode in = *$2;
+      BEEV::ASTNode m = *$3;
+      unsigned int width = in.GetValueWidth();
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, in, m));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  | SELECT_TOK an_term an_term
+    {
+      //ARRAY READ
+      // valuewidth is same as array, indexwidth is 0.
+      BEEV::ASTNode array = *$2;
+      BEEV::ASTNode index = *$3;
+      unsigned int width = array.GetValueWidth();
+      BEEV::ASTNode * n = 
+	new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, array, index));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  | STORE_TOK an_term an_term an_term
+    {
+      //ARRAY WRITE
+      unsigned int width = $4->GetValueWidth();
+      BEEV::ASTNode array = *$2;
+      BEEV::ASTNode index = *$3;
+      BEEV::ASTNode writeval = *$4;
+      BEEV::ASTNode write_term = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::WRITE,width,array,index,writeval);
+      write_term.SetIndexWidth($2->GetIndexWidth());
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(write_term);
+      BEEV::ASTNode * n = new BEEV::ASTNode(write_term);
+      $$ = n;
+      delete $2;
+      delete $3;
+      delete $4;
+    }
+/*   | BVEXTRACT_TOK LBRACKET_TOK NUMERAL_TOK COLON_TOK NUMERAL_TOK RBRACKET_TOK BVCONST_TOK */
+/*     { */
+/*       // This special case is when we have an extract on top of a constant bv, which happens */
+/*       // almost all the time in the smt syntax. */
+
+/*       // $3 is high, $5 is low.  They are ints (why not unsigned? See uintval) */
+/*       int hi  =  $3; */
+/*       int low =  $5; */
+/*       int width = hi - low + 1; */
+
+/*       if (width < 0) */
+/* 	yyerror("Negative width in extract"); */
+
+/*       unsigned long long int val = $7; */
+
+/*       // cut and past from BV32 const evaluator */
+
+/*       unsigned long long int mask1 = 0xffffffffffffffffLL; */
+
+/*       mask1 >>= 64-(hi+1); */
+      
+/*       //extract val[hi:0] */
+/*       val &= mask1; */
+/*       //extract val[hi:low] */
+/*       val >>= low; */
+
+/*       // val is the desired BV32. */
+/*       BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(width, val)); */
+/*       $$ = n; */
+/*     } */
+  | BVEXTRACT_TOK LBRACKET_TOK NUMERAL_TOK COLON_TOK NUMERAL_TOK RBRACKET_TOK an_term
+    {
+      int width = $3 - $5 + 1;
+      if (width < 0)
+	yyerror("Negative width in extract");
+      
+      if((unsigned)$3 >= $7->GetValueWidth() || (unsigned)$5 < 0)
+	yyerror("Parsing: Wrong width in BVEXTRACT\n");			 
+      
+      BEEV::ASTNode hi  =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $3);
+      BEEV::ASTNode low =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+      BEEV::ASTNode output = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT, width, *$7,hi,low);
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->SimplifyTerm(output));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $7;
+    }
+  |  ITE_TOK an_formula an_term an_term 
+    {
+      unsigned int width = $3->GetValueWidth();
+      if (width != $4->GetValueWidth()) {
+	cerr << *$3;
+	cerr << *$4;
+	yyerror("Width mismatch in IF-THEN-ELSE");
+      }			 
+      if($3->GetIndexWidth() != $4->GetIndexWidth())
+	yyerror("Width mismatch in IF-THEN-ELSE");
+      
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$2);
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$4);
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateSimplifiedTermITE(*$2, *$3, *$4));
+      //$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE,width,*$2, *$3, *$4));
+      $$->SetIndexWidth($4->GetIndexWidth());
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$$);
+      delete $2;
+      delete $3;
+      delete $4;
+    }
+  |  BVCONCAT_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth() + $3->GetValueWidth();
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      
+      delete $2;
+      delete $3;
+    }
+  |  BVNOT_TOK an_term
+    {
+      //this is the BVNEG (term) in the CVCL language
+      unsigned int width = $2->GetValueWidth();
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNEG, width, *$2));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+    }
+  |  BVNEG_TOK an_term
+    {
+      //this is the BVUMINUS term in CVCL langauge
+      unsigned width = $2->GetValueWidth();
+      BEEV::ASTNode * n =  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVUMINUS,width,*$2));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+    }
+  |  BVAND_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in AND");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVAND, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVOR_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in OR");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVOR, width, *$2, *$3)); 
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVXOR_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in XOR");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVXOR, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVSUB_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVSUB");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSUB, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVPLUS_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVPLUS");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVPLUS, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+
+    }
+  |  BVMULT_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVMULT");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVMULT, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVNAND_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVNAND");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNAND, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVNOR_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVNOR");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNOR, width, *$2, *$3)); 
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVLEFTSHIFT_TOK an_term NUMERAL_TOK 
+    {
+      unsigned int w = $2->GetValueWidth();
+      if((unsigned)$3 < w) {
+	BEEV::ASTNode trailing_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst($3, 0);
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32, w-$3-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,0);
+	BEEV::ASTNode m = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-$3,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT,w,m,trailing_zeros));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      delete $2;
+    }
+   |  BVLEFTSHIFT_1_TOK an_term an_term 
+    {
+      unsigned int w = $2->GetValueWidth();
+      unsigned int shift_amt = GetUnsignedConst(*$3);
+      if((unsigned)shift_amt < w) {
+	BEEV::ASTNode trailing_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst(shift_amt, 0);
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32, w-shift_amt-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,0);
+	BEEV::ASTNode m = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-shift_amt,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT,w,m,trailing_zeros));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else {
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      }
+      delete $2;
+      //delete $3;
+    }
+  |  BVRIGHTSHIFT_TOK an_term NUMERAL_TOK 
+    {
+      BEEV::ASTNode leading_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst($3, 0);
+      unsigned int w = $2->GetValueWidth();
+      
+      //the amount by which you are rightshifting
+      //is less-than/equal-to the length of input
+      //bitvector
+      if((unsigned)$3 < w) {
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,$3);
+	BEEV::ASTNode extract = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-$3,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, w,leading_zeros, extract));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else {
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      }
+      delete $2;
+    }
+   |  BVRIGHTSHIFT_1_TOK an_term an_term 
+    {
+      unsigned int shift_amt = GetUnsignedConst(*$3);
+      BEEV::ASTNode leading_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst(shift_amt, 0);
+      unsigned int w = $2->GetValueWidth();
+      
+      //the amount by which you are rightshifting
+      //is less-than/equal-to the length of input
+      //bitvector
+      if((unsigned)shift_amt < w) {
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,shift_amt);
+	BEEV::ASTNode extract = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-shift_amt,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, w,leading_zeros, extract));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else {
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      }
+      delete $2;
+    }
+  |  BVSX_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK an_term 
+    {
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+      unsigned w = $5->GetValueWidth() + $3;
+      BEEV::ASTNode width = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w);
+      BEEV::ASTNode *n =  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSX,w,*$5,width));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $5;
+    }
+;
+  
+sort_symb:
+    BITVEC_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      // Just return BV width.  If sort is BOOL, width is 0.
+      // Otherwise, BITVEC[w] returns w. 
+      //
+      //((indexwidth is 0) && (valuewidth>0)) iff type is BV
+      $$.indexwidth = 0;
+      unsigned int length = $3;
+      if(length > 0) {
+	$$.valuewidth = length;
+      }
+      else {
+	BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+      }
+    }
+   | ARRAY_TOK LBRACKET_TOK NUMERAL_TOK COLON_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      unsigned int index_len = $3;
+      unsigned int value_len = $5;
+      if(index_len > 0) {
+	$$.indexwidth = $3;
+      }
+      else {
+	BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+      }
+
+      if(value_len > 0) {
+	$$.valuewidth = $5;
+      }
+      else {
+	BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+      }
+    }
+;
+
+var:
+    FORMID_TOK 
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); 
+      delete $1;      
+    }
+   | TERMID_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1));
+      delete $1;
+    }
+   | QUESTION_TOK TERMID_TOK
+    {
+      $$ = $2;
+    }
+;
+
+fvar:
+    DOLLAR_TOK FORMID_TOK
+    {
+      $$ = $2; 
+    }
+  | FORMID_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); 
+      delete $1;      
+    }   
+;
+%%
diff --git a/stp/sat/Global.h b/stp/sat/Global.h
new file mode 100644
index 00000000..a428975c
--- /dev/null
+++ b/stp/sat/Global.h
@@ -0,0 +1,255 @@
+/****************************************************************************************[Global.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Global_h
+#define Global_h
+
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <new>
+
+// PKT: needs to be outside namespace MINISAT or mac os x compilation breaks
+#ifdef _MSC_VER
+#else
+#include <unistd.h>
+#endif
+
+namespace MINISAT {
+//=================================================================================================
+// Basic Types & Minor Things:
+
+// DWD: This is needed on darwin.
+typedef unsigned int uint;
+
+#ifdef _MSC_VER
+
+typedef INT64              int64;
+typedef UINT64             uint64;
+typedef INT_PTR            intp;
+typedef UINT_PTR           uintp;
+#define I64_fmt "I64d"
+#else
+
+typedef long long          int64;
+typedef unsigned long long uint64;
+typedef __PTRDIFF_TYPE__   intp;
+typedef unsigned __PTRDIFF_TYPE__ uintp;
+#define I64_fmt "lld"
+#endif
+
+template<class T> static inline T min(T x, T y) { return (x < y) ? x : y; }
+template<class T> static inline T max(T x, T y) { return (x > y) ? x : y; }
+
+template <bool> struct STATIC_ASSERTION_FAILURE;
+template <> struct STATIC_ASSERTION_FAILURE<true>{};
+#define TEMPLATE_FAIL STATIC_ASSERTION_FAILURE<false>()
+
+
+//=================================================================================================
+// 'malloc()'-style memory allocation -- never returns NULL; aborts instead:
+
+
+template<class T> static inline T* xmalloc(size_t size) {
+    T*   tmp = (T*)malloc(size * sizeof(T));
+    assert(size == 0 || tmp != NULL);
+    return tmp; }
+
+template<class T> static inline T* xrealloc(T* ptr, size_t size) {
+    T*   tmp = (T*)realloc((void*)ptr, size * sizeof(T));
+    assert(size == 0 || tmp != NULL);
+    return tmp; }
+
+template<class T> static inline void xfree(T *ptr) {
+    if (ptr != NULL) free((void*)ptr); }
+
+
+//=================================================================================================
+// Random numbers:
+
+
+// Returns a random float 0 <= x < 1. Seed must never be 0.
+static inline double drand(double& seed) {
+    seed *= 1389796;
+    int q = (int)(seed / 2147483647);
+    seed -= (double)q * 2147483647;
+    return seed / 2147483647; }
+
+// Returns a random integer 0 <= x < size. Seed must never be 0.
+static inline int irand(double& seed, int size) {
+    return (int)(drand(seed) * size); }
+
+
+//=================================================================================================
+// 'vec' -- automatically resizable arrays (via 'push()' method):
+
+
+// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
+
+template<class T>
+class vec {
+    T*  data;
+    int sz;
+    int cap;
+
+    void     init(int size, const T& pad);
+    void     grow(int min_cap);
+
+public:
+    // Types:
+    typedef int Key;
+    typedef T   Datum;
+
+    // Constructors:
+    vec(void)                   : data(NULL) , sz(0)   , cap(0)    { }
+    vec(int size)               : data(NULL) , sz(0)   , cap(0)    { growTo(size); }
+    vec(int size, const T& pad) : data(NULL) , sz(0)   , cap(0)    { growTo(size, pad); }
+    vec(T* array, int size)     : data(array), sz(size), cap(size) { }      // (takes ownership of array -- will be deallocated with 'xfree()')
+   ~vec(void)                                                      { clear(true); }
+
+    // Ownership of underlying array:
+    T*       release  (void)           { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; }
+    operator T*       (void)           { return data; }     // (unsafe but convenient)
+    operator const T* (void) const     { return data; }
+
+    // Size operations:
+    int      size   (void) const       { return sz; }
+    void     shrink (int nelems)       { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
+    void     pop    (void)             { sz--, data[sz].~T(); }
+    void     growTo (int size);
+    void     growTo (int size, const T& pad);
+    void     clear  (bool dealloc = false);
+    void     capacity (int size) { grow(size); }
+
+    // Stack interface:
+    void     push  (void)              { if (sz == cap) grow(sz+1); new (&data[sz]) T()    ; sz++; }
+    void     push  (const T& elem)     { if (sz == cap) grow(sz+1); new (&data[sz]) T(elem); sz++; }
+    const T& last  (void) const        { return data[sz-1]; }
+    T&       last  (void)              { return data[sz-1]; }
+
+    // Vector interface:
+    const T& operator [] (int index) const  { return data[index]; }
+    T&       operator [] (int index)        { return data[index]; }
+
+    // Don't allow copying (error prone):
+    vec<T>&  operator = (vec<T>& other) { TEMPLATE_FAIL; }
+             vec        (vec<T>& other) { TEMPLATE_FAIL; }
+
+    // Duplicatation (preferred instead):
+    void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (&copy[i]) T(data[i]); }
+    void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
+};
+
+template<class T>
+void vec<T>::grow(int min_cap) {
+    if (min_cap <= cap) return;
+    if (cap == 0) cap = (min_cap >= 2) ? min_cap : 2;
+    else          do cap = (cap*3+1) >> 1; while (cap < min_cap);
+    data = xrealloc(data, cap); }
+
+template<class T>
+void vec<T>::growTo(int size, const T& pad) {
+    if (sz >= size) return;
+    grow(size);
+    for (int i = sz; i < size; i++) new (&data[i]) T(pad);
+    sz = size; }
+
+template<class T>
+void vec<T>::growTo(int size) {
+    if (sz >= size) return;
+    grow(size);
+    for (int i = sz; i < size; i++) new (&data[i]) T();
+    sz = size; }
+
+template<class T>
+void vec<T>::clear(bool dealloc) {
+    if (data != NULL){
+        for (int i = 0; i < sz; i++) data[i].~T();
+        sz = 0;
+        if (dealloc) xfree(data), data = NULL, cap = 0; } }
+
+
+//=================================================================================================
+// Useful functions on vectors
+
+
+template<class V, class T>
+void remove(V& ts, const T& t)
+{
+    int j = 0;
+    for (; j < ts.size() && ts[j] != t; j++);
+    assert(j < ts.size());
+    for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
+    ts.pop();
+}
+
+
+template<class V, class T>
+bool find(V& ts, const T& t)
+{
+    int j = 0;
+    for (; j < ts.size() && ts[j] != t; j++);
+    return j < ts.size();
+}
+
+//=================================================================================================
+// Lifted booleans:
+
+
+class lbool {
+    int     value;
+    explicit lbool(int v) : value(v) { }
+
+public:
+    lbool()       : value(0) { }
+    lbool(bool x) : value((int)x*2-1) { }
+    int toInt(void) const { return value; }
+
+    bool  operator == (const lbool& other) const { return value == other.value; }
+    bool  operator != (const lbool& other) const { return value != other.value; }
+    lbool operator ~  (void)               const { return lbool(-value); }
+
+    friend int   toInt  (lbool l);
+    friend lbool toLbool(int   v);
+};
+inline int   toInt  (lbool l) { return l.toInt(); }
+inline lbool toLbool(int   v) { return lbool(v);  }
+
+const lbool l_True  = toLbool( 1);
+const lbool l_False = toLbool(-1);
+const lbool l_Undef = toLbool( 0);
+
+
+//=================================================================================================
+// Relation operators -- extend definitions from '==' and '<'
+
+
+#ifndef __SGI_STL_INTERNAL_RELOPS   // (be aware of SGI's STL implementation...)
+#define __SGI_STL_INTERNAL_RELOPS
+template <class T> static inline bool operator != (const T& x, const T& y) { return !(x == y); }
+template <class T> static inline bool operator >  (const T& x, const T& y) { return y < x;     }
+template <class T> static inline bool operator <= (const T& x, const T& y) { return !(y < x);  }
+template <class T> static inline bool operator >= (const T& x, const T& y) { return !(x < y);  }
+#endif
+
+
+//=================================================================================================
+};
+#endif
diff --git a/stp/sat/Heap.h b/stp/sat/Heap.h
new file mode 100644
index 00000000..acfa1c1e
--- /dev/null
+++ b/stp/sat/Heap.h
@@ -0,0 +1,151 @@
+/******************************************************************************************[Heap.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Heap_h
+#define Heap_h
+
+#include "../AST/ASTUtil.h"
+namespace MINISAT {
+
+//=================================================================================================
+
+
+static inline int left  (int i) { return i+i; }
+static inline int right (int i) { return i+i + 1; }
+static inline int parent(int i) { return i >> 1; }
+
+template<class C>
+class Heap {
+  public:
+    C        comp;
+    vec<int> heap;     // heap of ints
+    vec<int> indices;  // int -> index in heap
+
+    inline void percolateUp(int i)
+    {
+        int x = heap[i];
+        while (parent(i) != 0 && comp(x,heap[parent(i)])){
+            heap[i]          = heap[parent(i)];
+            indices[heap[i]] = i;
+            i                = parent(i);
+        }
+        heap   [i] = x;
+        indices[x] = i;
+    }
+
+    inline void percolateDown(int i)
+    {
+        int x = heap[i];
+        while (left(i) < heap.size()){
+            int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i);
+            if (!comp(heap[child],x)) break;
+            heap[i]          = heap[child];
+            indices[heap[i]] = i;
+            i                = child;
+        }
+        heap   [i] = x;
+        indices[x] = i;
+    }
+
+    bool ok(int n) const { 
+        return n >= 0 && n < (int)indices.size(); }
+
+  public:
+    Heap(C c) : comp(c) { heap.push(-1); }
+
+    void setBounds (int size)    { assert(size >= 0); indices.growTo(size,0); }
+    void increase  (int n)       { assert(ok(n)); assert(inHeap(n)); percolateUp(indices[n]); }
+    bool inHeap    (int n) const { assert(ok(n)); return indices[n] != 0; }
+    int  size      ()      const { return heap.size()-1; }
+    bool empty     ()      const { return size() == 0; }
+
+
+    void insert(int n) {
+        assert(!inHeap(n));
+        assert(ok(n));
+        indices[n] = heap.size();
+        heap.push(n);
+        percolateUp(indices[n]); 
+    }
+
+
+  int  getmin() {
+    //printing heap
+    if(BEEV::print_sat_varorder) {
+      // fprintf(stderr, "Vijay: heap before getmin: ");
+      //       for (uint i = 1; i < (uint)heap.size(); i++)
+      // 	fprintf(stderr, "%d ", heap[i]);
+      //       fprintf(stderr, "\n");
+    }
+    
+    int r            = heap[1];
+    heap[1]          = heap.last();
+    indices[heap[1]] = 1;
+    indices[r]       = 0;
+    heap.pop();
+    if (heap.size() > 1)
+      percolateDown(1);
+    return r; 
+  }
+
+    // fool proof variant of insert/increase
+    void update    (int n)    {
+        //fprintf(stderr, "update heap: ");
+        //for (uint i = 1; i < (uint)heap.size(); i++)
+        //    fprintf(stderr, "%d ", heap[i]);
+        //fprintf(stderr, "\n");
+        setBounds(n+1);
+        if (!inHeap(n))
+            insert(n);
+        else {
+            percolateUp(indices[n]);
+            percolateDown(indices[n]);
+        }
+    }
+
+
+    bool heapProperty() {
+        return heapProperty(1); }
+
+
+    bool heapProperty(int i) {
+        return i >= heap.size()
+            || ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); }
+
+    template <class F> void filter(const F& filt) {
+        int i,j;
+        for (i = j = 1; i < heap.size(); i++)
+            if (filt(heap[i])){
+                heap[j]          = heap[i];
+                indices[heap[i]] = j++;
+            }else
+                indices[heap[i]] = 0;
+
+        heap.shrink(i - j);
+        for (int i = heap.size() / 2; i >= 1; i--)
+            percolateDown(i);
+
+        assert(heapProperty());
+    }
+
+};
+
+//=================================================================================================
+};
+#endif
diff --git a/stp/sat/LICENSE b/stp/sat/LICENSE
new file mode 100644
index 00000000..590930bc
--- /dev/null
+++ b/stp/sat/LICENSE
@@ -0,0 +1,20 @@
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/stp/sat/Makefile b/stp/sat/Makefile
new file mode 100644
index 00000000..8298e05a
--- /dev/null
+++ b/stp/sat/Makefile
@@ -0,0 +1,16 @@
+include ../Makefile.common
+
+SRCS = Solver.C Simplifier.C
+OBJS = $(SRCS:.C=.o)
+
+libsatsolver.a: $(OBJS)
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+Solver.o: Solver.C Solver.h Sort.h SolverTypes.h VarOrder.h Global.h Heap.h
+Simplifier.o: Simplifier.C Solver.h Sort.h SolverTypes.h VarOrder.h Global.h Heap.h
+
+clean:
+	rm -rf *.o *~  *.a  depend.mak .#*
+depend:
+	makedepend -- $(CFLAGS) -- $(SRCS)
diff --git a/stp/sat/Simplifier.C b/stp/sat/Simplifier.C
new file mode 100644
index 00000000..1c192e20
--- /dev/null
+++ b/stp/sat/Simplifier.C
@@ -0,0 +1,542 @@
+/************************************************************************************[Simplifier.C]
+MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#include "Solver.h"
+
+namespace MINISAT {
+
+static const int grow = 0;
+
+//#define WEAKEN
+//#define MATING
+//#define ASSYMM
+
+bool Solver::assymmetricBranching(Clause& c)
+{
+    assert(decisionLevel() == 0);
+
+    //fprintf(stderr, "assymmetric branching on clause: "); printClause(c); fprintf(stderr, "\n");
+    if (satisfied(c)){
+        //fprintf(stderr, "subsumed.\n");
+        return true; }
+
+    int      old;
+    vec<Lit> copy; for (int i = 0; i < c.size(); i++) copy.push(c[i]);
+
+    do {
+        assert(copy.size() == c.size());
+
+        old = copy.size();
+
+        //fprintf(stderr, "checking that clause is normalized\n");
+        //for (int i = 0; i < copy.size(); i++)
+        //    assert(value(copy[i]) == l_Undef);
+
+        for (int i = 0; i < copy.size(); i++){
+            trail_lim.push(trail.size());
+            //fprintf(stderr, " -- trying to delete literal "); printLit(copy[i]); 
+            for (int j = 0; j < copy.size(); j++)
+                if (j != i)
+                    check(enqueue(~copy[j]));
+
+            if (propagate() != NULL){
+                //fprintf(stderr, " succeeded\n");
+                cancelUntil(0);
+                Lit l = copy[i];
+                assert(find(copy, l));
+                remove(copy, l);
+                if (!strengthen(c, l))
+                    return false;
+                i--;
+
+                if (c.size() == 1)
+                    return propagate() == NULL;
+                else
+                    assert(qhead == trail.size());
+            }
+            else
+                //fprintf(stderr, " failed\n");
+
+            cancelUntil(0);
+        }
+
+        //} while (false);
+    } while (copy.size() < old);
+
+    return true;
+}
+
+// Returns FALSE if clause is always satisfied ('out_clause' should not be used). 
+//bool Solver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
+bool Solver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
+{  
+    stats.merges++;
+
+    bool  ps_smallest = _ps.size() < _qs.size();
+    const Clause& ps =  ps_smallest ? _qs : _ps;
+    const Clause& qs =  ps_smallest ? _ps : _qs;
+
+    for (int i = 0; i < qs.size(); i++){
+        if (var(qs[i]) != v){
+            for (int j = 0; j < ps.size(); j++)
+                if (var(ps[j]) == var(qs[i])) {
+                    if (ps[j] == ~qs[i])
+                        return false;
+                    else
+                        goto next;
+                }
+            out_clause.push(qs[i]);
+        }
+        next:;
+    }
+
+    for (int i = 0; i < ps.size(); i++)
+        if (var(ps[i]) != v)
+            out_clause.push(ps[i]);
+
+    return true;
+}
+
+
+void Solver::gather(vec<Clause*>& clauses)
+{
+    //fprintf(stderr, "Gathering clauses for backwards subsumption\n");
+    int ntouched = 0;
+    assert(touched.size() == occurs.size());
+    clauses.clear();
+    for (int i = 0; i < touched.size(); i++)
+        if (touched[i]){
+            const vec<Clause*>& cs = getOccurs(i);
+            ntouched++;
+            for (int j = 0; j < cs.size(); j++)
+                if (cs[j]->mark() == 0){
+                    clauses.push(cs[j]);
+                    cs[j]->mark(2);
+                }
+            touched[i] = 0;
+        }
+
+    //fprintf(stderr, "Touched variables %d of %d yields %d clauses to check\n", ntouched, touched.size(), clauses.size());
+    for (int i = 0; i < clauses.size(); i++)
+        clauses[i]->mark(0);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  subsumes : (_c : ClauseId) (c : Clause&) (_d : ClauseId) (d : Clause&)  ->  bool
+|
+|  Description:
+|     Checks if c subsumes d, and at the same time, if c can be used to simplify d by subsumption
+|     resolution.
+|    
+|  Input:
+|     Indices into the 'clauses' vector _c, _d, and references to the corresponding clauses c, d.
+|
+|  Result:
+|     lit_Error  - No subsumption or simplification
+|     lit_Undef  - Clause c subsumes d
+|     l          - The literal l can be deleted from d
+|________________________________________________________________________________________________@*/
+inline Lit Solver::subsumes(const Clause& c, const Clause& d)
+{
+    stats.subsumption_checks++;
+    if (d.size() < c.size() || (c.abstraction() & ~d.abstraction()) != 0)
+        return lit_Error;
+
+    Lit ret = lit_Undef;
+
+    for (int i = 0; i < c.size(); i++) {
+        // search for c[i] or ~c[i]
+        for (int j = 0; j < d.size(); j++)
+            if (c[i] == d[j])
+                goto ok;
+            else if (ret == lit_Undef && c[i] == ~d[j]){
+                ret = c[i];
+                goto ok;
+            }
+
+        // did not find it
+        stats.subsumption_misses++;
+        return lit_Error;
+    ok:;
+    }
+
+    return ret;
+}
+
+
+// Backward subsumption + backward subsumption resolution
+bool Solver::backwardSubsumptionCheck()
+{
+    while (subsumption_queue.size() > 0 || qhead < trail.size()){
+
+        // if propagation queue is non empty, take the first literal and
+        // create a dummy unit clause
+        if (qhead < trail.size()){
+            Lit l = trail[qhead++];
+            (*bwdsub_tmpunit)[0] = l;
+            assert(bwdsub_tmpunit->mark() == 0);
+            subsumption_queue.push(bwdsub_tmpunit);
+        }
+        Clause&  c = *subsumption_queue.last(); subsumption_queue.pop();
+
+        if (c.mark())
+            continue;
+
+        if (c.size() == 1 && !enqueue(c[0]))
+            return false; 
+
+        // (1) find best variable to scan
+        Var best = var(c[0]);
+        for (int i = 1; i < c.size(); i++)
+            if (occurs[var(c[i])].size() < occurs[best].size())
+                best = var(c[i]);
+
+        // (2) search all candidates
+        const vec<Clause*>& cs = getOccurs(best);
+
+        for (int j = 0; j < cs.size(); j++)
+            if (cs[j] != &c){
+                if (cs[j]->mark())
+                    continue;
+                if (c.mark())
+                    break;
+
+                //fprintf(stderr, "backward candidate "); printClause(*cs[j]); fprintf(stderr, "\n"); 
+                Lit l = subsumes(c, *cs[j]);
+                if (l == lit_Undef){
+                    //fprintf(stderr, "clause backwards subsumed\n");
+                    //fprintf(stderr, " >> clause %d: ", cs[j]->mark()); printClause(*cs[j]); fprintf(stderr, "\n");
+                    //fprintf(stderr, " >> clause %d: ", c.mark()); printClause(c); fprintf(stderr, "\n");
+                    removeClause(*cs[j], false);
+                }else if (l != lit_Error){
+                    //fprintf(stderr, "backwards subsumption resolution\n");
+                    //fprintf(stderr, " >> clause %d: ", cs[j]->mark()); printClause(*cs[j]); fprintf(stderr, "\n");
+                    //fprintf(stderr, " >> clause %d: ", c.mark()); printClause(c); fprintf(stderr, "\n");
+
+                    assert(cs[j]->size() > 1);
+                    assert(find(*cs[j], ~l));
+
+                    subsumption_queue.push(cs[j]);
+                    if (!strengthen(*cs[j], ~l))
+                        return false;
+
+                    // did current candidate get deleted from cs? then check candidate at index j again
+                    if (var(l) == best)
+                        j--;
+                }
+            }
+    }
+
+    return true;
+}
+
+
+bool Solver::eliminateVar(Var v, bool fail)
+{
+    assert(hasVarProp(v, p_frozen));
+
+    vec<Clause*>  pos, neg;
+    const vec<Clause*>& cls = getOccurs(v);
+
+    if (value(v) != l_Undef || cls.size() == 0)
+        return true;
+
+    //fprintf(stderr, "trying to eliminate var %d\n", v+1);
+    for (int i = 0; i < cls.size(); i++){
+        //fprintf(stderr, "clause: "); printClause(*cls[i]); fprintf(stderr, "\n");
+        if (find(*cls[i], Lit(v)))
+            pos.push(cls[i]);
+        else{
+            assert(find(*cls[i], ~Lit(v)));
+            neg.push(cls[i]);
+        }
+    }
+
+#ifdef WEAKEN
+    vec<int> posc(pos.size(), 0);
+    vec<int> negc(neg.size(), 0);
+#endif
+    // check if number of clauses decreases
+    int      cnt = 0;
+    vec<Lit> resolvent;
+    for (int i = 0; i < pos.size(); i++)
+        for (int j = 0; j < neg.size(); j++){
+            resolvent.clear();
+            if (merge(*pos[i], *neg[j], v, resolvent)){
+                cnt++;
+#ifdef WEAKEN
+                posc[i]++;
+                negc[j]++;
+#endif
+            }
+#ifndef WEAKEN
+            if (cnt > cls.size() + grow)
+                return true;
+#else
+#ifdef MATING
+            if (cnt > cls.size() + grow)
+                if (posc[i] > 0)
+                    break;
+#endif
+#endif
+            assert(pos.size() <= n_occ[toInt(Lit(v))]);
+            assert(neg.size() <= n_occ[toInt(~Lit(v))]);
+        }
+
+#ifdef WEAKEN
+#ifdef MATING
+    for (int i = 0; i < neg.size(); i++)
+        if (negc[i] == 0)
+            for (int j = 0; j < pos.size(); j++){
+                resolvent.clear();
+                if (merge(*neg[i], *pos[j], v, resolvent)){
+                    negc[i]++;
+                    break;
+                }
+            }
+#endif
+    for (int i = 0; i < pos.size(); i++)
+        if (posc[i] == 0)
+            removeClause(*pos[i], false);
+
+    for (int i = 0; i < neg.size(); i++)
+        if (negc[i] == 0)
+            removeClause(*neg[i], false);
+
+    if (cnt > cls.size() + grow)
+        return true;
+#endif    
+    //if (pos.size() != n_occ[toInt(Lit(v))])
+    //    fprintf(stderr, "pos.size() = %d, n_occ[toInt(Lit(v))] = %d\n", pos.size(), n_occ[toInt(Lit(v))]);
+    assert(pos.size() == n_occ[toInt(Lit(v))]);
+    //if (neg.size() != n_occ[toInt(~Lit(v))])
+    //    fprintf(stderr, "neg.size() = %d, n_occ[toInt(Lit(v))] = %d\n", neg.size(), n_occ[toInt(Lit(v))]);
+    assert(neg.size() == n_occ[toInt(~Lit(v))]);
+    assert(cnt <= cls.size() + grow);
+    setVarProp(v, p_decisionvar, false);
+
+    // produce clauses in cross product
+    int top = clauses.size();
+    for (int i = 0; i < pos.size(); i++)
+        for (int j = 0; j < neg.size(); j++){
+            resolvent.clear();
+#ifdef WEAKEN
+            if (pos[i]->mark() == 1)
+                break;
+            if (neg[j]->mark() == 1)
+                continue;
+#endif
+
+            if (merge(*pos[i], *neg[j], v, resolvent)){
+                int i, j;
+                for (i = j = 0; i < resolvent.size(); i++)
+                    if (value(resolvent[i]) == l_True)
+                        goto next;
+                    else if (value(resolvent[i]) == l_Undef)
+                        resolvent[j++] = resolvent[i];
+                resolvent.shrink(i - j);
+
+                if (resolvent.size() == 1){
+                    if (!enqueue(resolvent[0]))
+                        return false;
+                }else{
+                    int apa = clauses.size();
+                    check(newClause(resolvent, false, true));
+                    assert(apa + 1 == clauses.size());
+                }
+            }
+            next:;
+        }
+
+    if (fail){
+        fprintf(stderr, "eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
+        fprintf(stderr, "previous clauses:\n");
+        for (int i = 0; i < cls.size(); i++){
+            printClause(*cls[i]);
+            fprintf(stderr, "\n");
+        }
+        
+        fprintf(stderr, "new clauses:\n");
+        for (int i = top; i < clauses.size(); i++){
+            printClause(*clauses[i]);
+            fprintf(stderr, "\n");
+        }
+
+        assert(0); }
+
+    //fprintf(stderr, "eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
+    //fprintf(stderr, "previous clauses:\n");
+    //for (int i = 0; i < cls.size(); i++){
+    //    printClause(*cls[i]);
+    //    fprintf(stderr, "\n");
+    //}
+    //
+    //fprintf(stderr, "new clauses:\n");
+    //for (int i = top; i < clauses.size(); i++){
+    //    printClause(*clauses[i]);
+    //    fprintf(stderr, "\n");
+    //}
+
+    // delete + store old clauses
+    eliminated_var.push(v);
+    eliminated_lim.push(eliminated.size());
+    for (int i = 0; i < cls.size(); i++){
+        eliminated.push(Clause_new(*cls[i]));
+
+#ifdef WEAKEN
+        if (cls[i]->mark() == 0)
+#endif
+            removeClause(*cls[i], false); 
+
+    }
+
+    assert(subsumption_queue.size() == 0);
+    for (int i = top; i < clauses.size(); i++)
+#ifdef ASSYMM
+        if (clauses[i]->mark() == 0)
+            if (!assymmetricBranching(*clauses[i]))
+                return false;
+            else
+                subsumption_queue.push(clauses[i]);
+#else
+        if (clauses[i]->mark() == 0)
+            subsumption_queue.push(clauses[i]);
+#endif
+
+    return backwardSubsumptionCheck();
+}
+
+
+void Solver::extendModel()
+{
+    assert(eliminated_var.size() == eliminated_lim.size());
+    for (int i = eliminated_var.size()-1; i >= 0; i--){
+        Var v = eliminated_var[i];
+        Lit l = lit_Undef;
+
+        //fprintf(stderr, "extending var %d\n", v+1);
+
+        for (int j = eliminated_lim[i]; j < (i+1 >= eliminated_lim.size() ? eliminated.size() : eliminated_lim[i+1]); j++){
+            assert(j < eliminated.size());
+            Clause& c = *eliminated[j];
+
+            //fprintf(stderr, "checking clause: "); printClause(c); fprintf(stderr, "\n");
+
+            for (int k = 0; k < c.size(); k++)
+                if (var(c[k]) == v)
+                    l = c[k];
+                else if (value(c[k]) != l_False)
+                    goto next;
+
+            assert(l != lit_Undef);
+            //fprintf(stderr, "Fixing var %d to %d\n", v+1, !sign(l));
+
+            assigns[v] = toInt(lbool(!sign(l)));
+            break;
+
+        next:;
+        }
+
+        if (value(v) == l_Undef)
+            assigns[v] = toInt(l_True);
+    }
+}
+
+
+bool Solver::eliminate()
+{
+    assert(subsumption);
+
+    int cnt = 0;
+    //fprintf(stderr, "eliminating variables\n");
+
+#ifdef INVARIANTS
+    // check that all clauses are simplified
+    fprintf(stderr, "Checking that all clauses are normalized prior to variable elimination\n");
+    for (int i = 0; i < clauses.size(); i++)
+        if (clauses[i]->mark() == 0){
+            Clause& c = *clauses[i];
+            for (int j = 0; j < c.size(); j++)
+                assert(value(c[j]) == l_Undef);
+        }
+    fprintf(stderr, "done.\n");
+#endif
+
+    for (;;){
+        gather(subsumption_queue);
+
+        if (subsumption_queue.size() == 0 && heap.size() == 0)
+            break;
+
+        //fprintf(stderr, "backwards subsumption: %10d\n", subsumption_queue.size());
+        if (!backwardSubsumptionCheck())
+            return false;
+
+        //fprintf(stderr, "variable elimination:  %10d\n", heap.size());
+        cnt = 0;
+        for (;;){
+            assert(!heap.empty() || heap.size() == 0);
+            if (heap.empty())
+                break;
+
+            Var elim = heap.getmin();
+
+            assert(hasVarProp(elim, p_frozen));
+
+            //for (int i = 1; i < heap.heap.size(); i++)
+            //    assert(heap.comp(elim, heap.heap[i]) || !heap.comp(elim, heap.heap[i]));
+
+            //if (cnt++ % 100 == 0)
+            //    fprintf(stderr, "left %10d\r", heap.size());
+            
+            if (!eliminateVar(elim))
+                return false;
+        }
+    }
+#ifdef INVARIANTS
+    // check that no more subsumption is possible
+    fprintf(stderr, "Checking that no more subsumption is possible\n");
+    cnt = 0;
+    for (int i = 0; i < clauses.size(); i++){
+        if (cnt++ % 1000 == 0)
+            fprintf(stderr, "left %10d\r", clauses.size() - i);
+        for (int j = 0; j < i; j++)
+            assert(clauses[i]->mark() ||
+                   clauses[j]->mark() ||
+                   subsumes(*clauses[i], *clauses[j]) == lit_Error);
+    }
+    fprintf(stderr, "done.\n");
+
+    // check that no more elimination is possible
+    fprintf(stderr, "Checking that no more elimination is possible\n");
+    for (int i = 0; i < nVars(); i++){
+        if (hasVarProp(i, p_frozen))
+            eliminateVar(i, true);
+    }
+    fprintf(stderr, "done.\n");
+
+#endif
+
+    assert(qhead == trail.size());
+
+    return true;
+}
+};
diff --git a/stp/sat/Solver.C b/stp/sat/Solver.C
new file mode 100644
index 00000000..0fcb6149
--- /dev/null
+++ b/stp/sat/Solver.C
@@ -0,0 +1,811 @@
+/****************************************************************************************[Solver.C]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#include "Solver.h"
+#include "Sort.h"
+#include <cmath>
+
+namespace MINISAT {
+//=================================================================================================
+// Operations on clauses:
+
+
+/*_________________________________________________________________________________________________
+|
+|  newClause : (ps : const vec<Lit>&) (learnt : bool)  ->  [void]
+|  
+|  Description:
+|    Allocate and add a new clause to the SAT solvers clause database. 
+|  
+|  Input:
+|    ps     - The new clause as a vector of literals.
+|    learnt - Is the clause a learnt clause? For learnt clauses, 'ps[0]' is assumed to be the
+|             asserting literal. An appropriate 'enqueue()' operation will be performed on this
+|             literal. One of the watches will always be on this literal, the other will be set to
+|             the literal with the highest decision level.
+|  
+|  Effect:
+|    Activity heuristics are updated.
+|________________________________________________________________________________________________@*/
+bool Solver::newClause(const vec<Lit>& ps_, bool learnt, bool normalized)
+{
+    vec<Lit>    qs;
+    if (!learnt && !normalized){
+        assert(decisionLevel() == 0);
+        ps_.copyTo(qs);             // Make a copy of the input vector.
+
+        // Remove duplicates:
+        sortUnique(qs);
+
+        // Check if clause is satisfied:
+        for (int i = 0; i < qs.size()-1; i++){
+            if (qs[i] == ~qs[i+1])
+                return true; }
+        for (int i = 0; i < qs.size(); i++){
+            if (value(qs[i]) == l_True)
+                return true; }
+
+        // Remove false literals:
+        int     i, j;
+        for (i = j = 0; i < qs.size(); i++)
+            if (value(qs[i]) != l_False)
+                qs[j++] = qs[i];
+        qs.shrink(i - j);
+    }
+    const vec<Lit>& ps = learnt || normalized ? ps_ : qs;     // 'ps' is now the (possibly) reduced vector of literals.
+
+    if (ps.size() == 0)
+        return false;
+    else if (ps.size() == 1){
+        assert(decisionLevel() == 0);
+        return enqueue(ps[0]);
+    }else{
+        // Allocate clause:
+        Clause* c   = Clause_new(ps, learnt);
+
+        if (learnt){
+            // Put the second watch on the first literal with highest decision level:
+            // (requires that this method is called at the level where the clause is asserting!)
+            int i;
+            for (i = 1; i < ps.size() && position(trailpos[var(ps[i])]) < trail_lim.last(); i++)
+                ;
+            (*c)[1] = ps[i];
+            (*c)[i] = ps[1];
+
+            // Bump, enqueue, store clause:
+            claBumpActivity(*c);        // (newly learnt clauses should be considered active)
+            check(enqueue((*c)[0], c));
+            learnts.push(c);
+            stats.learnts_literals += c->size();
+        }else{
+            // Store clause:
+            clauses.push(c);
+            stats.clauses_literals += c->size();
+
+            if (subsumption){
+                c->calcAbstraction();
+                for (int i = 0; i < c->size(); i++){
+                    assert(!find(occurs[var((*c)[i])], c));
+                    occurs[var((*c)[i])].push(c);
+                    n_occ[toInt((*c)[i])]++;
+                    touched[var((*c)[i])] = 1;
+
+                    if (heap.inHeap(var((*c)[i])))
+		      updateHeap(var((*c)[i]));
+                }
+            }
+
+        }
+        // Watch clause:
+        watches[toInt(~(*c)[0])].push(c);
+        watches[toInt(~(*c)[1])].push(c);
+    }
+
+    return true;
+}
+
+
+// Disposes a clauses and removes it from watcher lists. NOTE!
+// Low-level; does NOT change the 'clauses' and 'learnts' vector.
+//
+void Solver::removeClause(Clause& c, bool dealloc)
+{
+    //fprintf(stderr, "delete %d: ", _c); printClause(c); fprintf(stderr, "\n");
+    assert(c.mark() == 0);
+
+    if (c.size() > 1){
+        assert(find(watches[toInt(~c[0])], &c));
+        assert(find(watches[toInt(~c[1])], &c));
+        remove(watches[toInt(~c[0])], &c);
+        remove(watches[toInt(~c[1])], &c); }
+
+    if (c.learnt()) stats.learnts_literals -= c.size();
+    else            stats.clauses_literals -= c.size();
+
+    if (subsumption && !c.learnt()){
+        for (int i = 0; i < c.size(); i++){
+            if (dealloc){
+                assert(find(occurs[var(c[i])], &c));
+                remove(occurs[var(c[i])], &c); 
+            }
+            n_occ[toInt(c[i])]--;
+            updateHeap(var(c[i]));
+        }
+    }
+
+    if (dealloc)
+        xfree(&c);
+    else
+        c.mark(1);
+}
+
+
+bool Solver::satisfied(Clause& c) const
+{
+    for (int i = 0; i < c.size(); i++)
+        if (value(c[i]) == l_True)
+            return true;
+    return false; }
+
+
+bool Solver::strengthen(Clause& c, Lit l)
+{
+    assert(decisionLevel() == 0);
+    assert(c.size() > 1);
+    assert(c.mark() == 0);
+
+    assert(toInt(~c[0]) < watches.size());
+    assert(toInt(~c[1]) < watches.size());
+    
+    assert(find(watches[toInt(~c[0])], &c));
+    assert(find(watches[toInt(~c[1])], &c));
+    assert(find(c,l));
+
+    if (c.learnt()) stats.learnts_literals -= 1;
+    else            stats.clauses_literals -= 1;
+
+    if (c[0] == l || c[1] == l){
+        assert(find(watches[toInt(~l)], &c));
+        remove(c,l);
+        remove(watches[toInt(~l)], &c);
+        if (c.size() > 1){
+            assert(!find(watches[toInt(~c[1])], &c));
+            watches[toInt(~c[1])].push(&c); }
+        else {
+            assert(find(watches[toInt(~c[0])], &c));
+            remove(watches[toInt(~c[0])], &c);
+            removeClause(c, false);
+        }
+    }
+    else
+        remove(c,l);
+        
+    assert(c.size() == 1 || find(watches[toInt(~c[0])], &c));
+    assert(c.size() == 1 || find(watches[toInt(~c[1])], &c));
+
+    if (subsumption){
+        assert(find(occurs[var(l)], &c));
+        remove(occurs[var(l)], &c);
+        assert(!find(occurs[var(l)], &c));
+
+        c.calcAbstraction();
+
+        n_occ[toInt(l)]--;
+        updateHeap(var(l));
+    }
+
+    return c.size() == 1 ? enqueue(c[0]) : true;
+}
+
+
+//=================================================================================================
+// Minor methods:
+
+
+// Creates a new SAT variable in the solver. If 'decision_var' is cleared, variable will not be
+// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
+//
+Var Solver::newVar(bool polarity, bool dvar) {
+    int     index;
+    index = nVars();
+    watches     .push();          // (list for positive literal)
+    watches     .push();          // (list for negative literal)
+    reason      .push(NULL);
+    assigns     .push(toInt(l_Undef));
+    trailpos    .push(TrailPos(0,0));
+    activity    .push(0);
+    order       .newVar(polarity,dvar);
+    seen        .push(0);
+    touched     .push(0);
+    if (subsumption){
+        occurs  .push();
+        n_occ   .push(0);
+        n_occ   .push(0);
+        heap    .setBounds(index+1);
+    }
+    return index; }
+
+
+// Returns FALSE if immediate conflict.
+bool Solver::assume(Lit p) {
+    trail_lim.push(trail.size());
+    return enqueue(p); }
+
+
+// Revert to the state at given level.
+void Solver::cancelUntil(int level) {
+    if (decisionLevel() > level){
+        for (int c = trail.size()-1; c >= trail_lim[level]; c--){
+            Var     x  = var(trail[c]);
+            assigns[x] = toInt(l_Undef);
+            reason [x] = NULL; 
+            order.undo(x); }
+        qhead = trail_lim[level];
+        trail.shrink(trail.size() - trail_lim[level]);
+        trail_lim.shrink(trail_lim.size() - level);
+    }
+}
+
+
+//=================================================================================================
+// Major methods:
+
+
+/*_________________________________________________________________________________________________
+|
+|  analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&)  ->  [void]
+|  
+|  Description:
+|    Analyze conflict and produce a reason clause.
+|  
+|    Pre-conditions:
+|      * 'out_learnt' is assumed to be cleared.
+|      * Current decision level must be greater than root level.
+|  
+|    Post-conditions:
+|      * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
+|  
+|  Effect:
+|    Will undo part of the trail, upto but not beyond the assumption of the current decision level.
+|________________________________________________________________________________________________@*/
+void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel)
+{
+    int            pathC = 0;
+    int            btpos = -1;
+    Lit            p     = lit_Undef;
+
+    // Generate conflict clause:
+    //
+    out_learnt.push();      // (leave room for the asserting literal)
+    int index = trail.size()-1;
+    do{
+        assert(confl != NULL);          // (otherwise should be UIP)
+        Clause& c = *confl;
+
+        if (c.learnt())
+            claBumpActivity(c);
+
+        for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
+            Lit q = c[j];
+            if (!seen[var(q)] && position(trailpos[var(q)]) >= trail_lim[0]){
+	      varBumpActivity(q);
+                seen[var(q)] = 1;
+                if (position(trailpos[var(q)]) >= trail_lim.last())
+                    pathC++;
+                else{
+                    out_learnt.push(q);
+                    btpos = max(btpos, position(trailpos[var(q)]));
+                }
+            }
+        }
+
+        // Select next clause to look at:
+        while (!seen[var(trail[index--])]);
+        p     = trail[index+1];
+        confl = reason[var(p)];
+        seen[var(p)] = 0;
+        pathC--;
+
+    }while (pathC > 0);
+    out_learnt[0] = ~p;
+
+    // Find correct backtrack level
+    for (out_btlevel = trail_lim.size()-1; out_btlevel > 0 && trail_lim[out_btlevel-1] > btpos; out_btlevel--)
+        ;
+
+    int     i, j;
+    if (expensive_ccmin){
+        // Simplify conflict clause (a lot):
+        //
+        uint    min_level = 0;
+        for (i = 1; i < out_learnt.size(); i++)
+            min_level |= abstractLevel(trailpos[var(out_learnt[i])]);     // (maintain an abstraction of levels involved in conflict)
+
+        out_learnt.copyTo(analyze_toclear);
+        for (i = j = 1; i < out_learnt.size(); i++)
+            if (reason[var(out_learnt[i])] == NULL || !analyze_removable(out_learnt[i], min_level))
+                out_learnt[j++] = out_learnt[i];
+    }else{
+        // Simplify conflict clause (a little):
+        //
+        out_learnt.copyTo(analyze_toclear);
+        for (i = j = 1; i < out_learnt.size(); i++){
+            Clause& c = *reason[var(out_learnt[i])];
+            for (int k = 1; k < c.size(); k++)
+                if (!seen[var(c[k])] && position(trailpos[var(c[k])]) >= trail_lim[0]){
+                    out_learnt[j++] = out_learnt[i];
+                    break; }
+        }
+    }
+
+    stats.max_literals += out_learnt.size();
+    out_learnt.shrink(i - j);
+    stats.tot_literals += out_learnt.size();
+
+    for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)
+}
+
+
+// Check if 'p' can be removed. 'min_level' is used to abort early if visiting literals at a level that cannot be removed.
+//
+bool Solver::analyze_removable(Lit p, uint min_level)
+{
+    analyze_stack.clear(); analyze_stack.push(p);
+    int top = analyze_toclear.size();
+    while (analyze_stack.size() > 0){
+        assert(reason[var(analyze_stack.last())] != NULL);
+        Clause& c = *reason[var(analyze_stack.last())]; analyze_stack.pop();
+
+        for (int i = 1; i < c.size(); i++){
+            Lit      p   = c[i];
+            TrailPos tp = trailpos[var(p)];
+            if (!seen[var(p)] && position(tp) >= trail_lim[0]){
+                if (reason[var(p)] != NULL && (abstractLevel(tp) & min_level) != 0){
+                    seen[var(p)] = 1;
+                    analyze_stack.push(p);
+                    analyze_toclear.push(p);
+                }else{
+                    for (int j = top; j < analyze_toclear.size(); j++)
+                        seen[var(analyze_toclear[j])] = 0;
+                    analyze_toclear.shrink(analyze_toclear.size() - top);
+                    return false;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  analyzeFinal : (p : Lit) ->  [void]
+|  
+|  Description:
+|    Specialized analysis procedure to express the final conflict in terms of assumptions.
+|    Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
+|    stores the result in 'out_conflict'.
+|________________________________________________________________________________________________@*/
+void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
+{
+    out_conflict.clear();
+    out_conflict.push(p);
+
+    if (decisionLevel() == 0)
+        return;
+
+    seen[var(p)] = 1;
+
+    int start = position(trailpos[var(p)]);
+    for (int i = start; i >= trail_lim[0]; i--){
+        Var     x = var(trail[i]);
+        if (seen[x]){
+            if (reason[x] == NULL){
+                assert(position(trailpos[x]) >= trail_lim[0]);
+                out_conflict.push(~trail[i]);
+            }else{
+                Clause& c = *reason[x];
+                for (int j = 1; j < c.size(); j++)
+                    if (position(trailpos[var(c[j])]) >= trail_lim[0])
+                        seen[var(c[j])] = 1;
+            }
+            seen[x] = 0;
+        }
+    }
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  enqueue : (p : Lit) (from : Clause*)  ->  [bool]
+|  
+|  Description:
+|    Puts a new fact on the propagation queue as well as immediately updating the variable's value.
+|    Should a conflict arise, FALSE is returned.
+|  
+|  Input:
+|    p    - The fact to enqueue
+|    from - [Optional] Fact propagated from this (currently) unit clause. Stored in 'reason[]'.
+|           Default value is NULL (no reason).
+|  
+|  Output:
+|    TRUE if fact was enqueued without conflict, FALSE otherwise.
+|________________________________________________________________________________________________@*/
+bool Solver::enqueue(Lit p, Clause* from)
+{
+
+    if (value(p) != l_Undef)
+        return value(p) != l_False;
+    else{
+        assigns [var(p)] = toInt(lbool(!sign(p)));
+        trailpos[var(p)] = TrailPos(trail.size(),decisionLevel());
+        reason  [var(p)] = from;
+        trail.push(p);
+        return true;
+    }
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  propagate : [void]  ->  [Clause*]
+|  
+|  Description:
+|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
+|    otherwise NULL.
+|  
+|    Post-conditions:
+|      * the propagation queue is empty, even if there was a conflict.
+|________________________________________________________________________________________________@*/
+Clause* Solver::propagate()
+{
+    if (decisionLevel() == 0 && subsumption)
+        return backwardSubsumptionCheck() ? NULL : propagate_tmpempty;
+
+    Clause* confl = NULL;
+    //fprintf(stderr, "propagate, qhead = %d, qtail = %d\n", qhead, qtail);
+    while (qhead < trail.size()){
+        stats.propagations++;
+        simpDB_props--;
+
+        Lit            p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
+        vec<Clause*>&  ws  = watches[toInt(p)];
+        Clause         **i, **j, **end;
+
+        for (i = j = (Clause**)ws, end = i + ws.size();  i != end;){
+            Clause& c = **i++;
+            
+            // Make sure the false literal is data[1]:
+            Lit false_lit = ~p;
+            if (c[0] == false_lit)
+                c[0] = c[1], c[1] = false_lit;
+
+            assert(c[1] == false_lit);
+
+            // If 0th watch is true, then clause is already satisfied.
+            Lit first = c[0];
+            if (value(first) == l_True){
+                *j++ = &c;
+            }else{
+                // Look for new watch:
+                for (int k = 2; k < c.size(); k++)
+                    if (value(c[k]) != l_False){
+                        c[1] = c[k]; c[k] = false_lit;
+                        watches[toInt(~c[1])].push(&c);
+                        goto FoundWatch; }
+
+                // Did not find watch -- clause is unit under assignment:
+                *j++ = &c;
+                if (!enqueue(first, &c)){
+                    confl = &c;
+                    qhead = trail.size();
+                    // Copy the remaining watches:
+                    while (i < end)
+                        *j++ = *i++;
+                }
+            FoundWatch:;
+            }
+        }
+        ws.shrink(i - j);
+    }
+
+    return confl;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  reduceDB : ()  ->  [void]
+|  
+|  Description:
+|    Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
+|    clauses are clauses that are reason to some assignment. Binary clauses are never removed.
+|________________________________________________________________________________________________@*/
+struct reduceDB_lt { bool operator () (Clause* x, Clause* y) { return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity()); } };
+void Solver::reduceDB()
+{
+    int     i, j;
+    double  extra_lim = cla_inc / learnts.size();    // Remove any clause below this activity
+
+    sort(learnts, reduceDB_lt());
+    for (i = j = 0; i < learnts.size() / 2; i++){
+        if (learnts[i]->size() > 2 && !locked(*learnts[i]))
+            removeClause(*learnts[i]);
+        else
+            learnts[j++] = learnts[i];
+    }
+    for (; i < learnts.size(); i++){
+        if (learnts[i]->size() > 2 && !locked(*learnts[i]) && learnts[i]->activity() < extra_lim)
+            removeClause(*learnts[i]);
+        else
+            learnts[j++] = learnts[i];
+    }
+    learnts.shrink(i - j);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  simplifyDB : [void]  ->  [bool]
+|  
+|  Description:
+|    Simplify the clause database according to the current top-level assigment. Currently, the only
+|    thing done here is the removal of satisfied clauses, but more things can be put here.
+|________________________________________________________________________________________________@*/
+bool Solver::simplifyDB(bool expensive)
+{
+    assert(decisionLevel() == 0);
+    if (!ok || propagate() != NULL)
+        return ok = false;
+
+    if (nAssigns() == simpDB_assigns || 
+        (!subsumption && simpDB_props > 0)) // (nothing has changed or preformed a simplification too recently)
+        return true;
+
+    if (subsumption){
+        if (expensive && !eliminate())
+            return ok = false;
+
+        // Move this cleanup code to its own method ?
+        int      i , j;
+        vec<Var> dirty;
+        for (i = 0; i < clauses.size(); i++)
+            if (clauses[i]->mark() == 1){
+                Clause& c = *clauses[i];
+                for (int k = 0; k < c.size(); k++)
+                    if (!seen[var(c[k])]){
+                        seen[var(c[k])] = 1;
+                        dirty.push(var(c[k]));
+                    }
+            }
+        
+        for (i = 0; i < dirty.size(); i++){
+            cleanOcc(dirty[i]);
+            seen[dirty[i]] = 0;
+        }
+
+        for (i = j = 0; i < clauses.size(); i++)
+            if (clauses[i]->mark() == 1)
+                xfree(clauses[i]);
+            else
+                clauses[j++] = clauses[i];
+        clauses.shrink(i - j);
+    }
+
+    // Remove satisfied clauses:
+    for (int type = 0; type < (subsumption ? 1 : 2); type++){  // (only scan learnt clauses if subsumption is on)
+        vec<Clause*>& cs = type ? learnts : clauses;
+        int     j  = 0;
+        for (int i = 0; i < cs.size(); i++){
+            assert(cs[i]->mark() == 0);
+            if (satisfied(*cs[i]))
+                removeClause(*cs[i]);
+            else
+                cs[j++] = cs[i];
+        }
+        cs.shrink(cs.size()-j);
+    }
+    order.cleanup();
+
+    simpDB_assigns = nAssigns();
+    simpDB_props   = stats.clauses_literals + stats.learnts_literals;   // (shouldn't depend on 'stats' really, but it will do for now)
+
+    return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&)  ->  [lbool]
+|  
+|  Description:
+|    Search for a model the specified number of conflicts, keeping the number of learnt clauses
+|    below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to
+|    indicate infinity.
+|  
+|  Output:
+|    'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
+|    all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
+|    if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
+|________________________________________________________________________________________________@*/
+lbool Solver::search(int nof_conflicts, int nof_learnts)
+{
+    assert(ok);
+    int         backtrack_level;
+    int         conflictC = 0;
+    vec<Lit>    learnt_clause;
+
+    stats.starts++;
+    var_decay = 1 / params.var_decay;
+    cla_decay = 1 / params.clause_decay;
+
+    for (;;){
+        Clause* confl = propagate();
+        if (confl != NULL){
+            // CONFLICT
+            stats.conflicts++; conflictC++;
+            if (decisionLevel() == 0) return l_False;
+
+            learnt_clause.clear();
+            analyze(confl, learnt_clause, backtrack_level);
+            cancelUntil(backtrack_level);
+            newClause(learnt_clause, true);
+            varDecayActivity();
+            claDecayActivity();
+
+        }else{
+            // NO CONFLICT
+
+            if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
+                // Reached bound on number of conflicts:
+                progress_estimate = progressEstimate();
+                cancelUntil(0);
+                return l_Undef; }
+
+            // Simplify the set of problem clauses:
+            if (decisionLevel() == 0 && !simplifyDB())
+                return l_False;
+
+            if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts)
+                // Reduce the set of learnt clauses:
+                reduceDB();
+
+            Lit next = lit_Undef;
+
+            if (decisionLevel() < assumptions.size()){
+                // Perform user provided assumption:
+                next = assumptions[decisionLevel()]; 
+                if (value(next) == l_False){
+                    analyzeFinal(~next, conflict);
+                    return l_False; }
+            }else{
+                // New variable decision:
+                stats.decisions++;
+                next = order.select(params.random_var_freq, decisionLevel());		
+	    }
+            if (next == lit_Undef)
+                // Model found:
+                return l_True;
+
+            check(assume(next));
+        }
+    }
+}
+
+
+// Return search-space coverage. Not extremely reliable.
+//
+double Solver::progressEstimate()
+{
+    double  progress = 0;
+    double  F = 1.0 / nVars();
+
+    for (int i = 0; i <= decisionLevel(); i++){
+        int beg = i == 0 ? 0 : trail_lim[i - 1];
+        int end = i == decisionLevel() ? trail.size() : trail_lim[i];
+        progress += pow(F, i) * (end - beg);
+    }
+
+    return progress / nVars();
+}
+
+
+// Divide all variable activities by 1e100.
+//
+void Solver::varRescaleActivity()
+{
+    for (int i = 0; i < nVars(); i++)
+        activity[i] *= 1e-100;
+    var_inc *= 1e-100;
+}
+
+
+// Divide all constraint activities by 1e100.
+//
+void Solver::claRescaleActivity()
+{
+    for (int i = 0; i < learnts.size(); i++)
+        learnts[i]->activity() *= 1e-20;
+    cla_inc *= 1e-20;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  solve : (assumps : const vec<Lit>&)  ->  [bool]
+|  
+|  Description:
+|    Top-level solve.
+|________________________________________________________________________________________________@*/
+bool Solver::solve(const vec<Lit>& assumps)
+{
+    model.clear();
+    conflict.clear();
+
+    if (!simplifyDB(true)) return false;
+
+
+    double  nof_conflicts = params.restart_first;
+    double  nof_learnts   = nClauses() * params.learntsize_factor;
+    lbool   status        = l_Undef;
+    assumps.copyTo(assumptions);
+
+    if (verbosity >= 1){
+        reportf("==================================[MINISAT]====================================\n");
+        reportf("| Conflicts |          ORIGINAL         |          LEARNT          | Progress |\n");
+        reportf("|           |    Vars  Clauses Literals |    Limit  Clauses Lit/Cl |          |\n");
+        reportf("===============================================================================\n");
+    }
+
+    // Search:
+    while (status == l_Undef){
+        if (verbosity >= 1)
+            //reportf("| %9d | %7d %8d | %7d %7d %8d %7.1f | %6.3f %% |\n", (int)stats.conflicts, nClauses(), (int)stats.clauses_literals, (int)nof_learnts, nLearnts(), (int)stats.learnts_literals, (double)stats.learnts_literals/nLearnts(), progress_estimate*100);
+            reportf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", (int)stats.conflicts, order.size(), nClauses(), (int)stats.clauses_literals, (int)nof_learnts, nLearnts(), (double)stats.learnts_literals/nLearnts(), progress_estimate*100);
+        status = search((int)nof_conflicts, (int)nof_learnts);
+        nof_conflicts *= params.restart_inc;
+        nof_learnts   *= params.learntsize_inc;
+    }
+
+    if (verbosity >= 1)
+        reportf("==============================================================================\n");
+
+    if (status == l_True){
+        // Copy model:
+        extendModel();
+#if 1
+        //fprintf(stderr, "Verifying model.\n");
+        for (int i = 0; i < clauses.size(); i++)
+            assert(satisfied(*clauses[i]));
+        for (int i = 0; i < eliminated.size(); i++)
+            assert(satisfied(*eliminated[i]));
+#endif
+        model.growTo(nVars());
+        for (int i = 0; i < nVars(); i++) model[i] = value(i);
+    }else{
+        assert(status == l_False);
+        if (conflict.size() == 0)
+            ok = false;
+    }
+
+    cancelUntil(0);
+    return status == l_True;
+}
+};//end of MINISAT namespace
diff --git a/stp/sat/Solver.h b/stp/sat/Solver.h
new file mode 100644
index 00000000..829194cc
--- /dev/null
+++ b/stp/sat/Solver.h
@@ -0,0 +1,359 @@
+/****************************************************************************************[Solver.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Solver_h
+#define Solver_h
+
+#include "SolverTypes.h"
+#include "VarOrder.h"
+
+namespace MINISAT {
+// Redfine if you want output to go somewhere else:
+#define reportf(format, args...) ( printf(format , ## args), fflush(stdout) )
+
+
+//=================================================================================================
+// Solver -- the main class:
+struct SolverStats {
+    int64   starts, decisions, propagations, conflicts;
+    int64   clauses_literals, learnts_literals, max_literals, tot_literals;
+    int64   subsumption_checks, subsumption_misses, merges;
+    SolverStats() : 
+        starts(0), decisions(0), propagations(0), conflicts(0)
+      , clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) 
+      , subsumption_checks(0), subsumption_misses(0), merges(0)
+    { }
+};
+
+
+struct SearchParams {
+    double  var_decay, clause_decay, random_var_freq;
+    double  restart_inc, learntsize_inc, learntsize_factor;
+    int     restart_first;
+    
+    SearchParams(double v = 0.95, double c = 0.999, double r = 0.02,
+                 double ri = 1.5, double li = 1.1, double lf = (double)1/(double)3,
+                 int rf = 100) : 
+        var_decay(v), clause_decay(c), random_var_freq(r),
+        restart_inc(ri), learntsize_inc(li), learntsize_factor(lf),
+        restart_first(rf) { }
+};
+
+  struct ElimLt {
+    const vec<int>& n_occ;
+    
+    ElimLt(const vec<int>& no) : n_occ(no) {}
+    int  cost      (Var x)        const { return n_occ[toInt(Lit(x))] * n_occ[toInt(~Lit(x))]; }
+    bool operator()(Var x, Var y) const { return cost(x) < cost(y); } 
+  };
+
+class Solver {
+protected:
+    // Solver state:    
+    bool                ok;               // If FALSE,the constraints are already unsatisfiable. 
+                                          // No part of solver state may be used!
+    vec<Clause*>        clauses;          // List of problem clauses.
+    vec<Clause*>        learnts;          // List of learnt clauses.
+    int                 n_bin_clauses;    // Keep track of number of binary clauses "inlined" into the watcher lists (we do this primarily to get identical behavior to the version without the binary clauses trick).
+    double              cla_inc;          // Amount to bump next clause with.
+    double              cla_decay;        // INVERSE decay factor for clause activity: stores 1/decay.
+
+    vec<double>         activity;         // A heuristic measurement of the activity of a variable.
+    double              var_inc;          // Amount to bump next variable with.
+    double              var_decay;        // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
+    VarOrder            order;            // Keeps track of the decision variable order.
+    vec<char>           properties;       // TODO: describe!!!
+
+    vec<vec<Clause*> >  watches;          // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
+    vec<char>           assigns;          // The current assignments (lbool:s stored as char:s).
+    vec<Lit>            trail;            // Assignment stack; stores all assigments made in the order they were made.
+    vec<int>            trail_lim;        // Separator indices for different decision levels in 'trail'.
+    vec<Clause*>        reason;           // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
+    vec<TrailPos>       trailpos;         // 'trailpos[var]' contains the position in the trail at wich the assigment was made.
+    int                 qhead;            // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
+    int                 simpDB_assigns;   // Number of top-level assignments since last execution of 'simplifyDB()'.
+    int64               simpDB_props;     // Remaining number of propagations that must be made before next execution of 'simplifyDB()'.
+    vec<Lit>            assumptions;      // Current set of assumptions provided to solve by the user.
+
+    bool                subsumption;
+    vec<char>           touched;
+    vec<vec<Clause*> >  occurs;
+    vec<int>            n_occ;
+    Heap<ElimLt>        heap;
+    vec<Clause*>        subsumption_queue;
+
+    vec<Clause*>        eliminated;
+    vec<int>            eliminated_lim;
+    vec<Var>            eliminated_var;
+
+    // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
+    // used, exept 'seen' wich is used in several places.
+    //
+    vec<char>           seen;
+    vec<Lit>            analyze_stack;
+    vec<Lit>            analyze_toclear;
+    Clause*             propagate_tmpempty;
+    Clause*             propagate_tmpbin;
+    Clause*             analyze_tmpbin;
+    Clause*             bwdsub_tmpunit;
+
+    vec<Lit>            addBinary_tmp;
+    vec<Lit>            addTernary_tmp;
+
+    // Main internal methods:
+    //
+    bool        assume           (Lit p);
+    void        cancelUntil      (int level);
+    void        record           (const vec<Lit>& clause);
+
+    void        analyze          (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
+    bool        analyze_removable(Lit p, uint min_level);                                 // (helper method for 'analyze()')
+    void        analyzeFinal     (Lit p, vec<Lit>& out_conflict);
+    bool        enqueue          (Lit fact, Clause* from = NULL);
+    Clause*     propagate        ();
+    void        reduceDB         ();
+    Lit         pickBranchLit    ();
+    lbool       search           (int nof_conflicts, int nof_learnts);
+    double      progressEstimate ();
+
+    // Variable properties:
+    void        setVarProp (Var v, uint prop, bool b) { order.setVarProp(v, prop, b); }
+    bool        hasVarProp (Var v, uint prop) const   { return order.hasVarProp(v, prop); }
+    void        updateHeap (Var v) { 
+        if (hasVarProp(v, p_frozen))
+            heap.update(v); }
+
+    // Simplification methods:
+    //
+    void cleanOcc (Var v) {
+        assert(subsumption);
+        vec<Clause*>& occ = occurs[v];
+        int i, j;
+        for (i = j = 0; i < occ.size(); i++)
+            if (occ[i]->mark() != 1)
+                occ[j++] = occ[i];
+        occ.shrink(i - j); 
+    }
+
+    vec<Clause*>& getOccurs                (Var x) { cleanOcc(x); return occurs[x]; }
+    void          gather                   (vec<Clause*>& clauses);
+    Lit           subsumes                 (const Clause& c, const Clause& d);
+    bool          assymmetricBranching     (Clause& c);
+    bool          merge                    (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
+    
+    bool          backwardSubsumptionCheck ();
+    bool          eliminateVar             (Var v, bool fail = false);
+    bool          eliminate                ();
+    void          extendModel              ();
+
+    // Activity:
+    //
+    void     varBumpActivity(Lit p) {
+        if (var_decay < 0) return;     // (negative decay means static variable order -- don't bump)
+        if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity();
+        order.update(var(p)); }
+    void     varDecayActivity  () { if (var_decay >= 0) var_inc *= var_decay; }
+    void     varRescaleActivity();
+    void     claDecayActivity  () { cla_inc *= cla_decay; }
+    void     claRescaleActivity();
+
+    // Operations on clauses:
+    //
+    bool     newClause(const vec<Lit>& ps, bool learnt = false, bool normalized = false);
+    void     claBumpActivity (Clause& c) { if ( (c.activity() += cla_inc) > 1e20 ) claRescaleActivity(); }
+    bool     locked          (const Clause& c) const { return reason[var(c[0])] == &c; }
+    bool     satisfied       (Clause& c) const;
+    bool     strengthen      (Clause& c, Lit l);
+    void     removeClause    (Clause& c, bool dealloc = true);
+
+    int      decisionLevel() const { return trail_lim.size(); }
+
+public:
+    Solver() : ok               (true)
+             , n_bin_clauses    (0)
+             , cla_inc          (1)
+             , cla_decay        (1)
+             , var_inc          (1)
+             , var_decay        (1)
+             , order            (assigns, activity)
+             , qhead            (0)
+             , simpDB_assigns   (-1)
+             , simpDB_props     (0)
+             , subsumption      (true)
+             , heap             (n_occ)
+             , params           ()
+             , expensive_ccmin  (true)
+             , verbosity        (0)
+             , progress_estimate(0)
+             {
+                vec<Lit> dummy(2,lit_Undef);
+                propagate_tmpbin   = Clause_new(dummy);
+                analyze_tmpbin     = Clause_new(dummy);
+                dummy.pop();
+                bwdsub_tmpunit     = Clause_new(dummy);
+                dummy.pop();
+                propagate_tmpempty = Clause_new(dummy);
+                addBinary_tmp .growTo(2);
+                addTernary_tmp.growTo(3);
+             }
+
+   ~Solver() {
+       xfree(propagate_tmpbin);
+       xfree(analyze_tmpbin);
+       xfree(bwdsub_tmpunit);
+       xfree(propagate_tmpempty);
+       for (int i = 0; i < eliminated.size(); i++) xfree(eliminated[i]);
+       for (int i = 0; i < learnts.size();    i++) xfree(learnts[i]);
+       for (int i = 0; i < clauses.size();    i++) xfree(clauses[i]); }
+
+    // Helpers: (semi-internal)
+    //
+    lbool   value(Var x) const { return toLbool(assigns[x]); }
+    lbool   value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); }
+
+    int     nAssigns()   { return trail.size(); }
+    int     nClauses()   { return clauses.size(); }
+    int     nLearnts()   { return learnts.size(); }
+    int     nConflicts() { return (int)stats.conflicts; }
+
+    // Statistics: (read-only member variable)
+    //
+    SolverStats     stats;
+
+    // Mode of operation:
+    //
+    SearchParams    params;             // Restart frequency etc.
+    bool            expensive_ccmin;    // Controls conflict clause minimization. TRUE by default.
+    int             verbosity;          // Verbosity level. 0=silent, 1=some progress report, 2=everything
+
+    // Problem specification:
+    //
+    Var     newVar    (bool polarity = true, bool dvar = true);
+    int     nVars     ()                    { return assigns.size(); }
+    bool    addUnit   (Lit p)               { return ok && (ok = enqueue(p)); }
+    bool    addBinary (Lit p, Lit q)        { addBinary_tmp [0] = p; addBinary_tmp [1] = q; return addClause(addBinary_tmp); }
+    bool    addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; return addClause(addTernary_tmp); }
+    bool    addClause (const vec<Lit>& ps)  { if (ok && !newClause(ps)) ok = false; return ok; }
+
+    // Variable mode:
+    // 
+    void    freezeVar    (Var v) { setVarProp(v, p_frozen, true); updateHeap(v); }
+
+    // Solving:
+    //
+    bool    okay         () { return ok; }       // FALSE means solver is in a conflicting state
+    bool    simplifyDB   (bool expensive = true);
+    bool    solve        (const vec<Lit>& assumps);
+    bool    solve        () { vec<Lit> tmp; return solve(tmp); }
+    void    turnOffSubsumption() {
+        subsumption = false;
+        occurs.clear(true);
+        n_occ.clear(true);
+    }
+
+    double      progress_estimate;  // Set by 'search()'.
+    vec<lbool>  model;              // If problem is satisfiable, this vector contains the model (if any).
+    vec<Lit>    conflict;           // If problem is unsatisfiable (possibly under assumptions), this vector represent the conflict clause expressed in the assumptions.
+
+  double  returnActivity(int i) { return activity[i];}
+  void    updateInitialActivity(int i, double act) {activity[i] = act; order.heap.update(i);}
+};
+
+
+//=================================================================================================
+// Debug:
+
+
+#define L_LIT    "%sx%d"
+#define L_lit(p) sign(p)?"~":"", var(p)
+
+// Just like 'assert()' but expression will be evaluated in the release version as well.
+inline void check(bool expr) { assert(expr); }
+
+static void printLit(Lit l)
+{
+    fprintf(stderr, "%s%d", sign(l) ? "-" : "", var(l)+1);
+}
+
+template<class C>
+static void printClause(const C& c)
+{
+    for (int i = 0; i < c.size(); i++){
+        printLit(c[i]);
+        fprintf(stderr, " ");
+    }
+}
+
+//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#ifdef _MSC_VER
+
+#include <ctime>
+
+static inline double cpuTime(void) {
+    return (double)clock() / CLOCKS_PER_SEC; }
+
+static inline int64 memUsed() {
+    return 0; }
+
+//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#else
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+static inline double cpuTime(void) {
+    struct rusage ru;
+    getrusage(RUSAGE_SELF, &ru);
+    return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
+
+#if defined(__linux__) || defined(__CYGWIN__)
+static inline int memReadStat(int field)
+{
+    char    name[256];
+    pid_t pid = getpid();
+    sprintf(name, "/proc/%d/statm", pid);
+    FILE*   in = fopen(name, "rb");
+    if (in == NULL) return 0;
+    int     value;
+    for (; field >= 0; field--) {
+      int res = fscanf(in, "%d", &value);
+      (void) res;
+    }
+    fclose(in);
+    return value;
+}
+
+static inline int64 memUsed() { return (int64)memReadStat(0) * (int64)getpagesize(); }
+#else
+// use this by default. Mac OS X (Darwin) does not define an os type
+//defined(__FreeBSD__)
+
+static inline int64 memUsed(void) {
+    struct rusage ru;
+    getrusage(RUSAGE_SELF, &ru);
+    return ru.ru_maxrss*1024; }
+
+#endif
+
+//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#endif
+
+//=================================================================================================
+};
+#endif
diff --git a/stp/sat/SolverTypes.h b/stp/sat/SolverTypes.h
new file mode 100644
index 00000000..2b98b8ca
--- /dev/null
+++ b/stp/sat/SolverTypes.h
@@ -0,0 +1,127 @@
+/***********************************************************************************[SolverTypes.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+
+#ifndef SolverTypes_h
+#define SolverTypes_h
+
+#include "Global.h"
+
+namespace MINISAT {
+
+//=================================================================================================
+// Variables, literals, clause IDs:
+
+
+// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
+// so that they can be used as array indices.
+
+typedef int Var;
+#define var_Undef (-1)
+
+
+struct Lit {
+    int     x;
+
+    Lit() : x(2*var_Undef)                                              { }   // (lit_Undef)
+    explicit Lit(Var var, bool sign = false) : x((var+var) + (int)sign) { }
+};
+
+// Don't use these for constructing/deconstructing literals. Use the normal constructors instead.
+inline  int  toInt       (Lit p)           { return p.x; }                   // A "toInt" method that guarantees small, positive integers suitable for array indexing.
+inline  Lit  toLit       (int i)           { Lit p; p.x = i; return p; }     // Inverse of 'toInt()'
+
+inline  Lit  operator   ~(Lit p)           { Lit q; q.x = p.x ^ 1; return q; }
+inline  bool sign        (Lit p)           { return p.x & 1; }
+inline  int  var         (Lit p)           { return p.x >> 1; }
+inline  Lit  unsign      (Lit p)           { Lit q; q.x = p.x & ~1; return q; }
+inline  Lit  id          (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; }
+
+inline  bool operator == (Lit p, Lit q)    { return toInt(p) == toInt(q); }
+inline  bool operator != (Lit p, Lit q)    { return toInt(p) != toInt(q); }
+inline  bool operator <  (Lit p, Lit q)    { return toInt(p)  < toInt(q); }  // '<' guarantees that p, ~p are adjacent in the ordering.
+
+
+const Lit lit_Undef(var_Undef, false);  // }- Useful special constants.
+const Lit lit_Error(var_Undef, true );  // }
+
+
+//=================================================================================================
+// Clause -- a simple class for representing a clause:
+
+class Clause {
+    uint    size_etc;
+    union { float act; uint abst; } apa;
+    Lit     data[0];
+public:
+    // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
+    template<class V>
+    Clause(const V& ps, bool learnt) {
+        size_etc = (ps.size() << 3) | (uint)learnt;
+        for (int i = 0; i < ps.size(); i++) data[i] = ps[i];
+        if (learnt) apa.act = 0; else apa.abst = 0; }
+
+    // -- use this function instead:
+    template<class V>
+    friend Clause* Clause_new(const V& ps, bool learnt = false) {
+        assert(sizeof(Lit)      == sizeof(uint));
+        assert(sizeof(float)    == sizeof(uint));
+        void*   mem = xmalloc<char>(sizeof(Clause) + sizeof(uint)*(ps.size()));
+        return new (mem) Clause(ps, learnt); }
+
+    int       size        ()      const { return size_etc >> 3; }
+    void      shrink      (int i)       { assert(i <= size()); size_etc = (((size_etc >> 3) - i) << 3) | (size_etc & 7); }
+    void      pop         ()            { shrink(1); }
+    bool      learnt      ()      const { return size_etc & 1; }
+    uint      mark        ()      const { return (size_etc >> 1) & 3; }
+    void      mark        (uint m)      { size_etc = (size_etc & ~6) | ((m & 3) << 1); }
+    Lit       operator [] (int i) const { return data[i]; }
+    Lit&      operator [] (int i)       { return data[i]; }
+
+    float&    activity    ()       { return apa.act; }
+
+    uint      abstraction () const { return apa.abst; }
+
+    void calcAbstraction() {
+        uint abstraction = 0;
+        for (int i = 0; i < size(); i++)
+            abstraction |= 1 << (var(data[i]) & 31);
+        apa.abst = abstraction;  }
+};
+
+
+//=================================================================================================
+// TrailPos -- Stores an index into the trail as well as an approximation of a level. This data
+// is recorded for each assigment. (Replaces the old level information)
+
+
+class TrailPos {
+    int tp;
+ public:
+    explicit TrailPos(int index, int level) : tp( (index << 5) + (level & 31) ) { }
+
+    friend int abstractLevel(const TrailPos& p) { return 1 << (p.tp & 31); }
+    friend int position     (const TrailPos& p) { return p.tp >> 5; }
+
+    bool operator ==  (TrailPos other) const { return tp == other.tp; }
+    bool operator <   (TrailPos other) const { return tp <  other.tp; }
+};
+
+};
+#endif
diff --git a/stp/sat/Sort.h b/stp/sat/Sort.h
new file mode 100644
index 00000000..a7011edb
--- /dev/null
+++ b/stp/sat/Sort.h
@@ -0,0 +1,133 @@
+/******************************************************************************************[Sort.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Sort_h
+#define Sort_h
+
+
+namespace MINISAT {
+//=================================================================================================
+
+
+template<class T>
+struct LessThan_default {
+    bool operator () (T x, T y) { return x < y; }
+};
+
+
+//=================================================================================================
+
+
+template <class T, class LessThan>
+void selectionSort(T* array, int size, LessThan lt)
+{
+    int     i, j, best_i;
+    T       tmp;
+
+    for (i = 0; i < size-1; i++){
+        best_i = i;
+        for (j = i+1; j < size; j++){
+            if (lt(array[j], array[best_i]))
+                best_i = j;
+        }
+        tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
+    }
+}
+template <class T> static inline void selectionSort(T* array, int size) {
+    selectionSort(array, size, LessThan_default<T>()); }
+
+
+template <class T, class LessThan>
+void sort(T* array, int size, LessThan lt, double& seed)
+{
+    if (size <= 15)
+        selectionSort(array, size, lt);
+
+    else{
+        T           pivot = array[irand(seed, size)];
+        T           tmp;
+        int         i = -1;
+        int         j = size;
+
+        for(;;){
+            do i++; while(lt(array[i], pivot));
+            do j--; while(lt(pivot, array[j]));
+
+            if (i >= j) break;
+
+            tmp = array[i]; array[i] = array[j]; array[j] = tmp;
+        }
+
+        sort(array    , i     , lt, seed);
+        sort(&array[i], size-i, lt, seed);
+    }
+}
+template <class T, class LessThan> void sort(T* array, int size, LessThan lt) {
+    double  seed = 91648253; sort(array, size, lt, seed); }
+template <class T> static inline void sort(T* array, int size) {
+    sort(array, size, LessThan_default<T>()); }
+
+
+template <class T, class LessThan>
+void sortUnique(T* array, int& size, LessThan lt)
+{
+    int         i, j;
+    T           last;
+
+    if (size == 0) return;
+
+    sort(array, size, lt);
+
+    i    = 1;
+    last = array[0];
+    for (j = 1; j < size; j++){
+        if (lt(last, array[j])){
+            last = array[i] = array[j];
+            i++; }
+    }
+
+    size = i;
+}
+template <class T> static inline void sortUnique(T* array, int& size) {
+    sortUnique(array, size, LessThan_default<T>()); }
+
+
+//=================================================================================================
+// For 'vec's:
+
+
+template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
+    sort((T*)v, v.size(), lt); }
+template <class T> void sort(vec<T>& v) {
+    sort(v, LessThan_default<T>()); }
+
+
+template <class T, class LessThan> void sortUnique(vec<T>& v, LessThan lt) {
+    int     size = v.size();
+    T*      data = v.release();
+    sortUnique(data, size, lt);
+    v.~vec<T>();
+    new (&v) vec<T>(data, size); }
+template <class T> void sortUnique(vec<T>& v) {
+    sortUnique(v, LessThan_default<T>()); }
+
+
+//=================================================================================================
+};
+#endif
diff --git a/stp/sat/VarOrder.h b/stp/sat/VarOrder.h
new file mode 100644
index 00000000..6ad1bfb1
--- /dev/null
+++ b/stp/sat/VarOrder.h
@@ -0,0 +1,146 @@
+/**************************************************************************************[VarOrder.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef VarOrder_h
+#define VarOrder_h
+
+#include "SolverTypes.h"
+#include "Solver.h"
+#include "Heap.h"
+#include "../AST/ASTUtil.h"
+
+namespace MINISAT {
+  //=================================================================================================
+
+  struct VarOrder_lt {
+    const vec<double>&  activity;
+    bool operator () (Var x, Var y) { return activity[x] > activity[y]; }
+    VarOrder_lt(const vec<double>&  act) : activity(act) { }
+  };
+  
+
+  enum { p_decisionvar = 0, p_polarity = 1, p_frozen = 2, p_dontcare = 3 };
+  
+  
+  class VarOrder {
+    const vec<char>&    assigns;     // var->val. Pointer to external assignment table.
+    const vec<double>&  activity;    // var->act. Pointer to external activity table.
+    vec<char>           properties;
+    //Heap<VarOrder_lt>   heap;
+    //double              random_seed; // For the internal random number generator
+    
+    friend class VarFilter;
+  public:
+    //FIXME: Vijay: delete after experiments
+    Heap<VarOrder_lt>   heap;
+    double              random_seed; // For the internal random number generator
+    //FIXME ENDS HERE
+
+    VarOrder(const vec<char>& ass, const vec<double>& act) :
+      assigns(ass), activity(act), heap(VarOrder_lt(act)), random_seed(2007)
+      //assigns(ass), activity(act), heap(VarOrder_lt(act))
+    { }
+    
+    int  size       ()                         { return heap.size(); }
+    void setVarProp (Var v, uint prop, bool b) { properties[v] = (properties[v] & ~(1 << prop)) | (b << prop); }
+    bool hasVarProp (Var v, uint prop) const   { return properties[v] & (1 << prop); }
+    inline void cleanup    ();
+    
+    inline void newVar(bool polarity, bool dvar);
+    inline void update(Var x);                  // Called when variable increased in activity.
+    inline void undo(Var x);                    // Called when variable is unassigned and may be selected again.
+    //Selects a new, unassigned variable (or 'var_Undef' if none exists).
+    inline Lit  select(double random_freq =.0, int decision_level = 0); 
+  };
+  
+  
+  struct VarFilter {
+    const VarOrder& o;
+    VarFilter(const VarOrder& _o) : o(_o) {}
+    bool operator()(Var v) const { return toLbool(o.assigns[v]) == l_Undef  && o.hasVarProp(v, p_decisionvar); }
+    //bool operator()(Var v) const { return toLbool(o.assigns[v]) == l_Undef; }
+  };
+  
+  void VarOrder::cleanup()
+  {
+    VarFilter f(*this);
+    heap.filter(f);
+  }
+  
+  void VarOrder::newVar(bool polarity, bool dvar)
+  {
+    Var v = assigns.size()-1;
+    heap.setBounds(v+1);
+    properties.push(0);
+    setVarProp(v, p_decisionvar, dvar);
+    setVarProp(v, p_polarity, polarity);
+    undo(v);
+  }
+  
+  
+  void VarOrder::update(Var x)
+  {
+    if (heap.inHeap(x))
+      heap.increase(x);
+  }
+  
+  
+  void VarOrder::undo(Var x)
+  {
+    if (!heap.inHeap(x) && hasVarProp(x, p_decisionvar))
+      heap.insert(x);
+  }
+  
+  
+  Lit VarOrder::select(double random_var_freq, int decision_level)
+  {
+    Var next = var_Undef;
+    
+    if (drand(random_seed) < random_var_freq && !heap.empty())
+      next = irand(random_seed,assigns.size());
+
+    // Activity based decision:
+    while (next == var_Undef || toLbool(assigns[next]) != l_Undef || !hasVarProp(next, p_decisionvar))
+      if (heap.empty()){
+	next = var_Undef;
+	break;
+      }else
+	next = heap.getmin();
+    
+    //printing
+    if(BEEV::print_sat_varorder) {
+      if (next != var_Undef) {
+	BEEV::Convert_MINISATVar_To_ASTNode_Print(next,
+						  decision_level,
+						  hasVarProp(next, p_polarity));
+	// fprintf(stderr,"var = %d, prop = %d, decision = %d, polarity = %d, frozen = %d\n", 
+	// 		next+1, properties[next], hasVarProp(next, p_decisionvar), 
+	// 		hasVarProp(next, p_polarity), hasVarProp(next, p_frozen));
+      }
+      else
+	fprintf(stderr, "var = undef\n");
+    }
+    
+    return next == var_Undef ? lit_Undef : Lit(next, hasVarProp(next, p_polarity));
+  }
+  
+  
+  //=================================================================================================
+};
+#endif
diff --git a/stp/simplifier/Makefile b/stp/simplifier/Makefile
new file mode 100644
index 00000000..aba07e1b
--- /dev/null
+++ b/stp/simplifier/Makefile
@@ -0,0 +1,11 @@
+include ../Makefile.common
+
+SRCS = simplifier.cpp bvsolver.cpp
+OBJS = $(SRCS:.cpp=.o)
+
+libsimplifier.a: $(OBJS)
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+clean:	
+	rm -rf *.o *~ *.a .#*
diff --git a/stp/simplifier/bvsolver.cpp b/stp/simplifier/bvsolver.cpp
new file mode 100644
index 00000000..1c08f30b
--- /dev/null
+++ b/stp/simplifier/bvsolver.cpp
@@ -0,0 +1,714 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include "../AST/ASTUtil.h"
+#include "bvsolver.h"
+
+  //This file contains the implementation of member functions of
+  //bvsolver class, which represents the bitvector arithmetic linear
+  //solver. Please also refer the STP's CAV 2007 paper for the
+  //complete description of the linear solver algorithm
+  //
+  //The bitvector solver is a partial solver, i.e. it does not solve
+  //for all variables in the system of equations. it is
+  //best-effort. it relies on the SAT solver to be complete.
+  //
+  //The BVSolver assumes that the input equations are normalized, and
+  //have liketerms combined etc.
+  //
+  //0. Traverse top-down over the input DAG, looking for a conjunction
+  //0. of equations. if you find one, then for each equation in the
+  //0. conjunction, do the following steps.
+  //
+  //1. check for Linearity of the input equation
+  //
+  //2. Solve for a "chosen" variable. The variable should occur
+  //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
+  //2. paper for actual solving procedure
+  //
+  //4. Outside the solver, Substitute and Re-normalize the input DAG 
+namespace BEEV {  
+  //check the solver map for 'key'. If key is present, then return the
+  //value by reference in the argument 'output'
+  bool BVSolver::CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = FormulasAlreadySolvedMap.find(key)) != FormulasAlreadySolvedMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  } //CheckAlreadySolvedMap()
+
+  void BVSolver::UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value) {
+    FormulasAlreadySolvedMap[key] = value;
+  } //end of UpdateAlreadySolvedMap()
+
+  //FIXME This is doing way more arithmetic than it needs to.
+  //accepts an even number "in", and splits it into an odd number and
+  //a power of 2. i.e " in = b.(2^k) ". returns the odd number, and
+  //the power of two by reference
+  ASTNode BVSolver::SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, 
+						unsigned int& number_shifts) {
+    if(BVCONST != in.GetKind() || _bm->BVConstIsOdd(in)) {
+      FatalError("BVSolver:SplitNum_Odd_PowerOf2: input must be a BVCONST and even\n",in);
+    }
+    
+    unsigned int len = in.GetValueWidth();
+    ASTNode zero = _bm->CreateZeroConst(len);
+    ASTNode two = _bm->CreateTwoConst(len);
+    ASTNode div_by_2 = in;
+    ASTNode mod_by_2 = 
+      _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two)); 
+    while(mod_by_2 == zero) {
+      div_by_2 = 
+	_bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,div_by_2,two));
+      number_shifts++;
+      mod_by_2 = 
+	_bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two));
+    }
+    return div_by_2;
+  } //end of SplitEven_into_Oddnum_PowerOf2()
+
+  //Checks if there are any ARRAYREADS in the term, after the
+  //alreadyseenmap is cleared, i.e. traversing a new term altogether
+  bool BVSolver::CheckForArrayReads_TopLevel(const ASTNode& term) {
+    TermsAlreadySeenMap.clear();
+    return CheckForArrayReads(term);
+  }
+  
+  //Checks if there are any ARRAYREADS in the term
+  bool BVSolver::CheckForArrayReads(const ASTNode& term) {
+    ASTNode a = term;
+    ASTNodeMap::iterator it;    
+    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
+      //if the term has been seen, then simply return true, else
+      //return false
+      if(ASTTrue == (it->second)) {
+	return true;
+      }
+      else {
+	return false;
+      }
+    }
+
+    switch(term.GetKind()) {
+    case READ:
+      //an array read has been seen. Make an entry in the map and
+      //return true
+      TermsAlreadySeenMap[term] = ASTTrue;
+      return true;
+    default: {
+      ASTVec c = term.GetChildren();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	if(CheckForArrayReads(*it)) {
+	  return true;
+	}
+      }
+      break;
+    }
+    }
+
+    //If control is here, then it means that no arrayread was seen for
+    //the input 'term'. Make an entry in the map with the term as key
+    //and FALSE as value.
+    TermsAlreadySeenMap[term] = ASTFalse;
+    return false;
+  } //end of CheckForArrayReads()
+  
+  //check the solver map for 'key'. If key is present, then return the
+  //value by reference in the argument 'output'
+  bool BeevMgr::CheckSolverMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = SolverMap.find(key)) != SolverMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  } //end of CheckSolverMap()
+
+  bool BeevMgr::CheckSolverMap(const ASTNode& key) {
+    if(SolverMap.find(key) != SolverMap.end())	
+      return true;
+    else
+      return false;
+  } //end of CheckSolverMap()
+  
+  //update solvermap with (key,value) pair
+  bool BeevMgr::UpdateSolverMap(const ASTNode& key, const ASTNode& value) {
+    ASTNode var = (BVEXTRACT == key.GetKind()) ? key[0] : key;
+    if(!CheckSolverMap(var) && key != value) {
+      SolverMap[key] = value;
+      return true;
+    }  
+    return false;
+  } //end of UpdateSolverMap()
+
+  //collects the vars in the term 'lhs' into the multiset Vars
+  void BVSolver::VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& Vars) {
+    TermsAlreadySeenMap.clear();
+    VarsInTheTerm(lhs,Vars);
+  }
+
+  //collects the vars in the term 'lhs' into the multiset Vars
+  void BVSolver::VarsInTheTerm(const ASTNode& term, ASTNodeMultiSet& Vars) {
+    ASTNode a = term;
+    ASTNodeMap::iterator it;    
+    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
+      //if the term has been seen, then simply return
+      return;
+    }
+
+    switch(term.GetKind()) {
+    case BVCONST:
+      return;
+    case SYMBOL:
+      //cerr << "debugging: symbol added: " << term << endl;
+      Vars.insert(term);
+      break;
+    case READ:
+      //skip the arrayname, provided the arrayname is a SYMBOL
+      if(SYMBOL == term[0].GetKind()) {
+	VarsInTheTerm(term[1],Vars);
+      }
+      else {
+	VarsInTheTerm(term[0],Vars);
+	VarsInTheTerm(term[1],Vars);
+      }
+      break;
+    default: {
+      ASTVec c = term.GetChildren();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	  VarsInTheTerm(*it,Vars);	  
+      }
+      break;
+    }
+    }
+
+    //ensures that you don't double count. if you have seen the term
+    //once, then memoize
+    TermsAlreadySeenMap[term] = ASTTrue;
+    return;
+  } //end of VarsInTheTerm()  
+
+  bool BVSolver::DoNotSolveThis(const ASTNode& var) {
+    if(DoNotSolve_TheseVars.find(var) != DoNotSolve_TheseVars.end()) {
+      return true;
+    }
+    return false;
+  }
+
+  //chooses a variable in the lhs and returns the chosen variable
+  ASTNode BVSolver::ChooseMonom(const ASTNode& eq, ASTNode& modifiedlhs) {
+    if(!(EQ == eq.GetKind() && BVPLUS == eq[0].GetKind())) {
+      FatalError("ChooseMonom: input must be a EQ",eq);
+    }
+
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    ASTNode zero = _bm->CreateZeroConst(32);
+
+    //collect all the vars in the lhs and rhs
+    ASTNodeMultiSet Vars;
+    VarsInTheTerm_TopLevel(lhs,Vars);
+
+    //handle BVPLUS case
+    ASTVec c = lhs.GetChildren();
+    ASTVec o;    
+    ASTNode outmonom = _bm->CreateNode(UNDEFINED);
+    bool chosen_symbol = false;
+    bool chosen_odd = false;
+
+    //choose variables with no coeffs
+    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+      ASTNode monom = *it;
+      if(SYMBOL == monom.GetKind() &&
+	 Vars.count(monom) == 1    &&	 
+	 !_bm->VarSeenInTerm(monom,rhs) &&
+	 !DoNotSolveThis(monom)   &&
+	 !chosen_symbol) {
+	outmonom = monom;
+	chosen_symbol = true;
+      }
+      else if(BVUMINUS == monom.GetKind()  &&
+	      SYMBOL == monom[0].GetKind() &&
+	      Vars.count(monom[0]) == 1    &&
+	      !DoNotSolveThis(monom[0])   &&
+	      !_bm->VarSeenInTerm(monom[0],rhs) &&
+	      !chosen_symbol) {
+	//cerr << "Chosen Monom: " << monom << endl;
+	outmonom = monom;
+	chosen_symbol = true;
+      }
+      else {
+	o.push_back(monom);
+      }
+    }
+
+    //try to choose only odd coeffed variables first
+    if(!chosen_symbol) {
+      o.clear();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode monom = *it;
+	ASTNode var = (BVMULT == monom.GetKind()) ? monom[1] : _bm->CreateNode(UNDEFINED);
+
+	if(BVMULT == monom.GetKind()     && 
+	   BVCONST == monom[0].GetKind() &&
+	   _bm->BVConstIsOdd(monom[0])   &&
+	   ((SYMBOL == var.GetKind()  && 
+	     Vars.count(var) == 1) 
+	    || 
+	    (BVEXTRACT == var.GetKind()  && 
+	     SYMBOL == var[0].GetKind()  && 
+	     BVCONST == var[1].GetKind() && 
+	     zero == var[2] && 
+	     !_bm->VarSeenInTerm(var[0],rhs) &&
+	     !DoNotSolveThis(var[0]))	    
+	    ) &&
+	   !DoNotSolveThis(var)     &&
+	   !_bm->VarSeenInTerm(var,rhs)  &&
+	   !chosen_odd) {
+	  //monom[0] is odd.
+	  outmonom = monom;
+	  chosen_odd = true;
+	}
+	else {
+	o.push_back(monom);
+	}
+      }
+    }
+
+    modifiedlhs = (o.size() > 1) ? _bm->CreateTerm(BVPLUS,lhs.GetValueWidth(),o) : o[0];
+    return outmonom;
+  } //end of choosemonom()
+
+  //solver function which solves for variables with odd coefficient
+  ASTNode BVSolver::BVSolve_Odd(const ASTNode& input) {
+    ASTNode eq = input;
+    //cerr << "Input to BVSolve_Odd()" << eq << endl;
+    if(!(wordlevel_solve && EQ == eq.GetKind())) {
+      return input;
+    }
+
+    ASTNode output = input;
+    if(CheckAlreadySolvedMap(input,output)) {
+      return output;
+    }
+
+    //get the lhs and the rhs, and case-split on the lhs kind
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    if(BVPLUS == lhs.GetKind()) {
+      ASTNode chosen_monom = _bm->CreateNode(UNDEFINED);
+      ASTNode leftover_lhs;
+
+      //choose monom makes sure that it gets only those vars that
+      //occur exactly once in lhs and rhs put together
+      chosen_monom = ChooseMonom(eq, leftover_lhs);
+      if(chosen_monom == _bm->CreateNode(UNDEFINED)) {
+	//no monomial was chosen
+	return eq;
+      }
+      
+      //if control is here then it means that a monom was chosen
+      //
+      //construct:  rhs - (lhs without the chosen monom)
+      unsigned int len = lhs.GetValueWidth();
+      leftover_lhs = _bm->SimplifyTerm_TopLevel(_bm->CreateTerm(BVUMINUS,len,leftover_lhs));      
+      ASTNode newrhs = _bm->SimplifyTerm(_bm->CreateTerm(BVPLUS,len,rhs,leftover_lhs));
+      lhs = chosen_monom;
+      rhs = newrhs;
+    } //end of if(BVPLUS ...)
+
+    if(BVUMINUS == lhs.GetKind()) {
+      //equation is of the form (-lhs0) = rhs
+      ASTNode lhs0 = lhs[0];
+      rhs = _bm->SimplifyTerm(_bm->CreateTerm(BVUMINUS,rhs.GetValueWidth(),rhs));
+      lhs = lhs0;      
+    }
+
+    switch(lhs.GetKind()) {
+    case SYMBOL: {     
+      //input is of the form x = rhs first make sure that the lhs
+      //symbol does not occur on the rhs or that it has not been
+      //solved for
+      if(_bm->VarSeenInTerm(lhs,rhs)) {
+	//found the lhs in the rhs. Abort!
+	DoNotSolve_TheseVars.insert(lhs);
+	return eq;
+      }
+      
+      //rhs should not have arrayreads in it. it complicates matters
+      //during transformation
+      // if(CheckForArrayReads_TopLevel(rhs)) {
+      //       	return eq;
+      //       }
+
+      DoNotSolve_TheseVars.insert(lhs);
+      if(!_bm->UpdateSolverMap(lhs,rhs)) {
+	return eq;
+      }
+
+      output = ASTTrue;
+      break;
+    }
+    case BVEXTRACT: {
+      ASTNode zero = _bm->CreateZeroConst(32);
+      
+      if(!(SYMBOL == lhs[0].GetKind()  && 
+      	   BVCONST == lhs[1].GetKind() && 
+      	   zero == lhs[2] && 
+      	   !_bm->VarSeenInTerm(lhs[0],rhs) &&
+      	   !DoNotSolveThis(lhs[0]))) {
+      	return eq;
+      }
+      
+      if(_bm->VarSeenInTerm(lhs[0],rhs)) {
+      	DoNotSolve_TheseVars.insert(lhs[0]);
+      	return eq;
+      }
+      
+      DoNotSolve_TheseVars.insert(lhs[0]);
+      if(!_bm->UpdateSolverMap(lhs,rhs)) {
+      	return eq;
+      }
+
+      //if the extract of x[i:0] = t is entered into the solvermap,
+      //then also add another entry for x = x1@t
+      ASTNode var = lhs[0];
+      ASTNode newvar = NewVar(var.GetValueWidth() - lhs.GetValueWidth());
+      newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,rhs);
+      _bm->UpdateSolverMap(var,newvar);      
+      output = ASTTrue;
+      break;
+    }
+    case BVMULT: {
+      //the input is of the form a*x = t. If 'a' is odd, then compute
+      //its multiplicative inverse a^-1, multiply 't' with it, and
+      //update the solver map
+      if(BVCONST != lhs[0].GetKind()) {
+	return eq;
+      }
+      
+      if(!(SYMBOL == lhs[1].GetKind() ||
+	   (BVEXTRACT == lhs[1].GetKind() &&
+	   SYMBOL == lhs[1][0].GetKind()))) {
+	return eq;
+      }
+
+      bool ChosenVar_Is_Extract = (BVEXTRACT == lhs[1].GetKind()) ? true : false;
+
+      //if coeff is even, then we know that all the coeffs in the eqn
+      //are even. Simply return the eqn
+      if(!_bm->BVConstIsOdd(lhs[0])) {
+	return eq;
+      }
+
+      ASTNode a = _bm->MultiplicativeInverse(lhs[0]);
+      ASTNode chosenvar = (BVEXTRACT == lhs[1].GetKind()) ? lhs[1][0] : lhs[1];
+      ASTNode chosenvar_value = 
+	_bm->SimplifyTerm(_bm->CreateTerm(BVMULT,rhs.GetValueWidth(),a,rhs));
+      
+      //if chosenvar is seen in chosenvar_value then abort
+      if(_bm->VarSeenInTerm(chosenvar,chosenvar_value)) {
+	//abort solving
+	DoNotSolve_TheseVars.insert(lhs);
+	return eq;
+      }
+
+      //rhs should not have arrayreads in it. it complicates matters
+      //during transformation
+      // if(CheckForArrayReads_TopLevel(chosenvar_value)) {
+      //       	return eq;
+      //       }
+            
+      //found a variable to solve
+      DoNotSolve_TheseVars.insert(chosenvar);
+      chosenvar = lhs[1];
+      if(!_bm->UpdateSolverMap(chosenvar,chosenvar_value)) {
+	return eq;
+      }
+
+      if(ChosenVar_Is_Extract) {
+	ASTNode var = lhs[1][0];
+	ASTNode newvar = NewVar(var.GetValueWidth() - lhs[1].GetValueWidth());
+	newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,chosenvar_value);
+	_bm->UpdateSolverMap(var,newvar);
+      }
+      output = ASTTrue;
+      break;
+    }    
+    default:
+      output = eq;
+      break;
+    }
+    
+    UpdateAlreadySolvedMap(input,output);
+    return output;
+  } //end of BVSolve_Odd()
+
+  //Create a new variable of ValueWidth 'n'
+  ASTNode BVSolver::NewVar(unsigned int n) {
+    std:: string c("v");
+    char d[32];
+    sprintf(d,"%d",_symbol_count++);
+    std::string ccc(d);
+    c += "_solver_" + ccc;
+    
+    ASTNode CurrentSymbol = _bm->CreateSymbol(c.c_str());
+    CurrentSymbol.SetValueWidth(n);
+    CurrentSymbol.SetIndexWidth(0);
+    return CurrentSymbol;
+  } //end of NewVar()
+
+  //The toplevel bvsolver(). Checks if the formula has already been
+  //solved. If not, the solver() is invoked. If yes, then simply drop
+  //the formula
+  ASTNode BVSolver::TopLevelBVSolve(const ASTNode& input) {
+    if(!wordlevel_solve) {
+      return input;
+    }
+    
+    Kind k = input.GetKind();
+    if(!(EQ == k || AND == k)) {
+      return input;
+    }
+
+    ASTNode output = input;
+    if(CheckAlreadySolvedMap(input,output)) {
+      //output is TRUE. The formula is thus dropped
+      return output;
+    }
+    ASTVec o;
+    ASTVec c;
+    if(EQ == k) 
+      c.push_back(input);
+    else 
+      c = input.GetChildren();
+    ASTVec eveneqns;
+    ASTNode solved = ASTFalse;
+    for(ASTVec::iterator it = c.begin(), itend = c.end();it != itend;it++) { 
+      //_bm->ASTNodeStats("Printing before calling simplifyformula inside the solver:", *it);
+      ASTNode aaa = (ASTTrue == solved && EQ == it->GetKind()) ? _bm->SimplifyFormula(*it,false) : *it;
+      //ASTNode aaa = *it;
+      //_bm->ASTNodeStats("Printing after calling simplifyformula inside the solver:", aaa);
+      aaa = BVSolve_Odd(aaa);
+      //_bm->ASTNodeStats("Printing after oddsolver:", aaa);
+      bool even = false;
+      aaa = CheckEvenEqn(aaa, even);
+      if(even) {
+	eveneqns.push_back(aaa);
+      }
+      else {
+	if(ASTTrue != aaa) {
+	  o.push_back(aaa);
+	}
+      }
+      solved = aaa;
+    }
+
+    ASTNode evens;
+    if(eveneqns.size() > 0) {
+      //if there is a system of even equations then solve them
+      evens = (eveneqns.size() > 1) ? _bm->CreateNode(AND,eveneqns) : eveneqns[0];
+      //evens = _bm->SimplifyFormula(evens,false);
+      evens = BVSolve_Even(evens);
+      _bm->ASTNodeStats("Printing after evensolver:", evens);
+    }
+    else {
+      evens = ASTTrue;
+    }
+    output = (o.size() > 0) ? ((o.size() > 1) ? _bm->CreateNode(AND,o) : o[0]) : ASTTrue;
+    output = _bm->CreateNode(AND,output,evens);
+
+    UpdateAlreadySolvedMap(input,output);
+    return output;
+  } //end of TopLevelBVSolve()
+
+  ASTNode BVSolver::CheckEvenEqn(const ASTNode& input, bool& evenflag) {
+    ASTNode eq = input;
+    //cerr << "Input to BVSolve_Odd()" << eq << endl;
+    if(!(wordlevel_solve && EQ == eq.GetKind())) {
+      evenflag = false;
+      return eq;
+    }
+
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+    //lhs must be a BVPLUS, and rhs must be a BVCONST
+    if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
+      evenflag = false;
+      return eq;
+    }
+    
+    ASTVec lhs_c = lhs.GetChildren();
+    ASTNode savetheconst = rhs;
+    for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
+      ASTNode aaa = *it;
+      Kind itk = aaa.GetKind();
+
+      if(BVCONST == itk){
+	//check later if the constant is even or not
+	savetheconst = aaa;
+	continue;
+      }
+      
+      if(!(BVMULT == itk &&
+	   BVCONST == aaa[0].GetKind() &&
+	   SYMBOL == aaa[1].GetKind() &&
+	   !_bm->BVConstIsOdd(aaa[0]))) {
+	//If the monomials of the lhs are NOT of the form 'a*x' where
+	//'a' is even, then return the false
+	evenflag = false;
+	return eq;
+      }  
+    }//end of for loop
+
+    //if control is here then it means that all coeffs are even. the
+    //only remaining thing is to check if the constant is even or not
+    if(_bm->BVConstIsOdd(savetheconst)) {
+      //the constant turned out to be odd. we have UNSAT eqn
+      evenflag = false;
+      return ASTFalse;
+    }
+    
+    //all is clear. the eqn in even, through and through
+    evenflag = true;
+    return eq;
+  } //end of CheckEvenEqn
+
+  //solve an eqn whose monomials have only even coefficients
+  ASTNode BVSolver::BVSolve_Even(const ASTNode& input) {
+    if(!wordlevel_solve) {
+      return input;
+    }
+
+    if(!(EQ == input.GetKind() || AND == input.GetKind())) {
+      return input;
+    }
+
+    ASTNode output;
+    if(CheckAlreadySolvedMap(input,output)) {
+      return output;
+    }
+
+    ASTVec input_c;
+    if(EQ == input.GetKind()) {
+      input_c.push_back(input);
+    }
+    else {
+      input_c = input.GetChildren();
+    }
+
+    //power_of_2 holds the exponent of 2 in the coeff
+    unsigned int power_of_2 = 0;
+    //we need this additional variable to find the lowest power of 2
+    unsigned int power_of_2_lowest = 0xffffffff;
+    //the monom which has the least power of 2 in the coeff
+    ASTNode monom_with_best_coeff;
+    for(ASTVec::iterator jt=input_c.begin(),jtend=input_c.end();jt!=jtend;jt++) {
+      ASTNode eq = *jt;
+      ASTNode lhs = eq[0];
+      ASTNode rhs = eq[1];
+      ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+      //lhs must be a BVPLUS, and rhs must be a BVCONST
+      if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
+	return input;
+      }
+    
+      ASTVec lhs_c = lhs.GetChildren();
+      ASTNode odd;
+      for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
+	ASTNode aaa = *it;
+	Kind itk = aaa.GetKind();
+	if(!(BVCONST == itk &&
+	     !_bm->BVConstIsOdd(aaa)) &&
+	   !(BVMULT == itk &&
+	     BVCONST == aaa[0].GetKind() &&
+	     SYMBOL == aaa[1].GetKind() &&
+	     !_bm->BVConstIsOdd(aaa[0]))) {
+	  //If the monomials of the lhs are NOT of the form 'a*x' or 'a'
+	  //where 'a' is even, then return the eqn
+	  return input;
+	}
+	
+	//we are gauranteed that if control is here then the monomial is
+	//of the form 'a*x' or 'a', where 'a' is even
+	ASTNode coeff = (BVCONST == itk) ? aaa : aaa[0];
+	odd = SplitEven_into_Oddnum_PowerOf2(coeff,power_of_2);
+	if(power_of_2  < power_of_2_lowest) {
+	  power_of_2_lowest = power_of_2;
+	  monom_with_best_coeff = aaa;
+	}
+	power_of_2 = 0;
+      }//end of inner for loop
+    } //end of outer for loop    
+
+    //get the exponent
+    power_of_2 = power_of_2_lowest;
+    
+    //if control is here, we are gauranteed that we have chosen a
+    //monomial with fewest powers of 2
+    ASTVec formula_out;
+    for(ASTVec::iterator jt=input_c.begin(),jtend=input_c.end();jt!=jtend;jt++) {
+      ASTNode eq = *jt;      
+      ASTNode lhs = eq[0];
+      ASTNode rhs = eq[1];
+      ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+      //lhs must be a BVPLUS, and rhs must be a BVCONST
+      if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
+	return input;
+      }
+      
+      unsigned len = lhs.GetValueWidth();
+      ASTNode hi = _bm->CreateBVConst(32,len-1);
+      ASTNode low = _bm->CreateBVConst(32,len - power_of_2);
+      ASTNode low_minus_one = _bm->CreateBVConst(32,len - power_of_2 - 1);
+      ASTNode low_zero = _bm->CreateZeroConst(32);
+      unsigned newlen = len - power_of_2;
+      ASTNode two_const = _bm->CreateTwoConst(len);
+
+      unsigned count = power_of_2;
+      ASTNode two = two_const;
+      while(--count) {
+	two = _bm->BVConstEvaluator(_bm->CreateTerm(BVMULT,len,two_const,two));
+      }
+      ASTVec lhs_c = lhs.GetChildren();
+      ASTVec lhs_out;
+      for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
+	ASTNode aaa = *it;
+	Kind itk = aaa.GetKind();
+	if(BVCONST == itk) {
+	  aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,aaa,two));
+	  aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT,newlen,aaa,low_minus_one,low_zero));
+	}
+	else {
+	  //it must be of the form a*x
+	  ASTNode coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,aaa[0],two));
+	  coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT,newlen,coeff,low_minus_one,low_zero));
+	  ASTNode upper_x, lower_x;
+	  //upper_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, power_of_2, aaa[1], hi, low));
+	  lower_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, newlen,aaa[1],low_minus_one,low_zero));
+	  aaa = _bm->CreateTerm(BVMULT,newlen,coeff,lower_x);
+	}
+	lhs_out.push_back(aaa);
+      }//end of inner forloop()
+      rhs = _bm->CreateZeroConst(newlen);
+      lhs = _bm->CreateTerm(BVPLUS,newlen,lhs_out);     
+      formula_out.push_back(_bm->CreateSimplifiedEQ(lhs,rhs));
+    } //end of outer forloop()
+
+    output = 
+      (formula_out.size() > 0) ? (formula_out.size() > 1) ? _bm->CreateNode(AND,formula_out) : formula_out[0] : ASTTrue;
+
+    UpdateAlreadySolvedMap(input,output);
+    return output;
+  } //end of BVSolve_Even()
+};//end of namespace BEEV
diff --git a/stp/simplifier/bvsolver.h b/stp/simplifier/bvsolver.h
new file mode 100644
index 00000000..a8981b12
--- /dev/null
+++ b/stp/simplifier/bvsolver.h
@@ -0,0 +1,134 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include "../AST/ASTUtil.h"
+namespace BEEV {
+
+  //This class represents the bitvector arithmetic linear solver.
+  //
+  //The bitvector solver is a partial solver, i.e. it does not solve
+  //for all variables in the system of equations. it is
+  //best-effort. it relies on the SAT solver to be complete.
+  //
+  //The BVSolver assumes that the input equations are normalized, and
+  //have liketerms combined etc.
+  //
+  //0. Traverse top-down over the input DAG, looking for a conjunction
+  //0. of equations. if you find one, then for each equation in the
+  //0. conjunction, do the following steps.
+  //
+  //1. check for Linearity of the input equation
+  //
+  //2. Solve for a "chosen" variable. The variable should occur
+  //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
+  //2. paper for actual solving procedure
+  //
+  //4. Outside the solver, Substitute and Re-normalize the input DAG 
+  class BVSolver {
+    //Ptr to toplevel manager that manages bit-vector expressions
+    //(i.e. construct various kinds of expressions), and also has
+    //member functions that simplify bit-vector expressions
+    BeevMgr * _bm;
+    ASTNode ASTTrue, ASTFalse;
+
+    //Those formulas which have already been solved. If the same
+    //formula occurs twice then do not solve the second occurence, and
+    //instead drop it
+    ASTNodeMap FormulasAlreadySolvedMap;
+
+    //this map is useful while traversing terms and uniquely
+    //identifying variables in the those terms. Prevents double
+    //counting.
+    ASTNodeMap TermsAlreadySeenMap;
+    ASTNodeMap TermsAlreadySeenMap_ForArrays;
+
+    //count is used in the creation of new variables
+    unsigned int _symbol_count;
+
+    //solved variables list: If a variable has been solved for then do
+    //not solve for it again
+    ASTNodeSet DoNotSolve_TheseVars;
+
+    //checks if var has been solved for or not. if yes, then return
+    //true else return false
+    bool DoNotSolveThis(const ASTNode& var);
+
+    //traverses a term, and creates a multiset of all variables in the
+    //term. Does memoization to avoid double counting.
+    void VarsInTheTerm(const ASTNode& lhs, ASTNodeMultiSet& v);
+    void VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& v);
+
+    //choose a suitable var from the term
+    ASTNode ChooseMonom(const ASTNode& eq, ASTNode& modifiedterm);
+    //accepts an equation and solves for a variable or a monom in it
+    ASTNode BVSolve_Odd(const ASTNode& eq);
+
+    //solves equations of the form a*x=t where 'a' is even. Has a
+    //return value, unlike the normal BVSolve()
+    ASTNode BVSolve_Even(const ASTNode& eq);
+    ASTNode CheckEvenEqn(const ASTNode& input, bool& evenflag);
+
+    //Checks for arrayreads in a term. if yes then returns true, else
+    //return false
+    bool CheckForArrayReads(const ASTNode& term);
+    bool CheckForArrayReads_TopLevel(const ASTNode& term);
+
+    //Creates new variables used in solving
+    ASTNode NewVar(unsigned int n);
+
+    //this function return true if the var occurs in term, else the
+    //function returns false
+    bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
+    
+    //takes an even number "in" as input, and returns an odd number
+    //(return value) and a power of 2 (as number_shifts by reference),
+    //such that in = (odd_number * power_of_2).
+    //
+    //Refer STP's CAV 2007 (or Clark Barrett's 1998 paper on
+    //bit-vector arithmetic published in DAC 1998) paper for precise
+    //understanding of the algorithm
+    ASTNode SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, unsigned int& number_shifts);
+
+    //Once a formula has been solved, then update the alreadysolvedmap
+    //with the formula, and the solved value. The solved value can be
+    //described using the following example: Suppose input to the
+    //solver is
+    //
+    // input key: x = 2 AND y = x + t
+    //
+    // output value: y = 2 + t
+    void UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value);
+
+    //This function checks if the key (formula) has already been
+    //solved for.
+    //
+    //If yes it returns TRUE and fills the "output" with the
+    //solved-value (call by reference argument),
+    //
+    //else returns FALSE
+    bool CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output);
+  public:
+    //constructor
+    BVSolver(BeevMgr * bm) : _bm(bm), _symbol_count(0) {
+      ASTTrue = _bm->CreateNode(TRUE);
+      ASTFalse = _bm->CreateNode(FALSE);
+    };
+
+    //Destructor
+    ~BVSolver() {
+      TermsAlreadySeenMap.clear();
+      DoNotSolve_TheseVars.clear();
+    }
+
+    //Top Level Solver: Goes over the input DAG, identifies the
+    //equation to be solved, solves them,
+    ASTNode TopLevelBVSolve(const ASTNode& a);
+  }; //end of class bvsolver
+};//end of namespace BEEV
diff --git a/stp/simplifier/simplifier.cpp b/stp/simplifier/simplifier.cpp
new file mode 100644
index 00000000..2a627398
--- /dev/null
+++ b/stp/simplifier/simplifier.cpp
@@ -0,0 +1,2495 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include "../AST/ASTUtil.h"
+namespace BEEV {
+  
+  bool BeevMgr::CheckSimplifyMap(const ASTNode& key, 
+				 ASTNode& output, bool pushNeg) {
+    ASTNodeMap::iterator it, itend;
+    it = pushNeg ? SimplifyNegMap.find(key) : SimplifyMap.find(key);
+    itend = pushNeg ? SimplifyNegMap.end() : SimplifyMap.end();
+    
+    if(it != itend) {
+      output = it->second;
+      CountersAndStats("Successful_CheckSimplifyMap");
+      return true;
+    }
+
+    if(pushNeg && (it = SimplifyMap.find(key)) != SimplifyMap.end()) {
+      output = 
+	(ASTFalse == it->second) ? 
+	ASTTrue : 
+	(ASTTrue == it->second) ? ASTFalse : CreateNode(NOT, it->second);
+      CountersAndStats("2nd_Successful_CheckSimplifyMap");
+      return true;
+    }
+
+    return false;
+  }
+  
+  void BeevMgr::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg) {
+    if(pushNeg) 
+      SimplifyNegMap[key] = value;
+    else
+      SimplifyMap[key] = value;
+  }
+
+  bool BeevMgr::CheckSubstitutionMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = SolverMap.find(key)) != SolverMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  }
+  
+  bool BeevMgr::CheckSubstitutionMap(const ASTNode& key) {
+    if(SolverMap.find(key) != SolverMap.end())	
+      return true;
+    else
+      return false;
+  }
+  
+  bool BeevMgr::UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1) {
+    int i = TermOrder(e0,e1);
+    if(0 == i)
+      return false;
+
+    //e0 is of the form READ(Arr,const), and e1 is const, or
+    //e0 is of the form var, and e1 is const    
+    if(1 == i && !CheckSubstitutionMap(e0)) {
+      SolverMap[e0] = e1;
+      return true;
+    }
+    
+    //e1 is of the form READ(Arr,const), and e0 is const, or
+    //e1 is of the form var, and e0 is const
+    if (-1 == i && !CheckSubstitutionMap(e1)) { 
+      SolverMap[e1] = e0;
+      return true;
+    }
+
+    return false;
+  }
+
+  bool BeevMgr::CheckMultInverseMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = MultInverseMap.find(key)) != MultInverseMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  }
+
+  void BeevMgr::UpdateMultInverseMap(const ASTNode& key, const ASTNode& value) {
+      MultInverseMap[key] = value;
+  }
+
+
+  bool BeevMgr::CheckAlwaysTrueFormMap(const ASTNode& key) {
+    ASTNodeSet::iterator it = AlwaysTrueFormMap.find(key);
+    ASTNodeSet::iterator itend = AlwaysTrueFormMap.end();
+    
+    if(it != itend) {
+      //cerr << "found:" << *it << endl;
+      CountersAndStats("Successful_CheckAlwaysTrueFormMap");
+      return true;
+    }
+    
+    return false;
+  }
+  
+  void BeevMgr::UpdateAlwaysTrueFormMap(const ASTNode& key) {
+    AlwaysTrueFormMap.insert(key);
+  }
+
+  //if a is READ(Arr,const) or SYMBOL, and b is BVCONST then return 1
+  //if b is READ(Arr,const) or SYMBOL, and a is BVCONST then return -1
+  //
+  //else return 0 by default
+   int BeevMgr::TermOrder(const ASTNode& a, const ASTNode& b) {
+    Kind k1 = a.GetKind();
+    Kind k2 = b.GetKind();
+
+    //a is of the form READ(Arr,const), and b is const, or
+    //a is of the form var, and b is const
+    if((k1 == READ 
+	&& 
+	a[0].GetKind() == SYMBOL && 
+	a[1].GetKind() == BVCONST
+	)
+       && 
+       (k2 == BVCONST)
+       )
+      return 1;
+
+    if(k1 == SYMBOL) 
+      return 1;
+
+    //b is of the form READ(Arr,const), and a is const, or
+    //b is of the form var, and a is const
+    if((k1  == BVCONST)
+       &&
+       ((k2 == READ
+	 && 
+	 b[0].GetKind() == SYMBOL &&
+	 b[1].GetKind() == BVCONST
+	 ) 
+	 ||
+	k2 == SYMBOL
+	))
+      return -1;
+    return 0;
+  }
+
+  //This function records all the const-indices seen so far for each
+  //array. It populates the map '_arrayname_readindices' whose key is
+  //the arrayname, and vlaue is a vector of read-indices.
+  //
+  //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
+  //and index is a BVCONST.  
+  //
+  //Since these arrayreads are being nuked and recorded in the
+  //substitutionmap, we have to also record the fact that each
+  //arrayread (e0 is of the form READ(Arr,const) here is represented
+  //by a BVCONST (e1). This is necessary for later Leibnitz Axiom
+  //generation
+  void BeevMgr::FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1) {
+    int i = TermOrder(e0,e1);
+    if(0 == i) return;
+
+    if(1 == i && e0.GetKind() != SYMBOL && !CheckSubstitutionMap(e0)) {
+      _arrayname_readindices[e0[0]].push_back(e0[1]);
+      //e0 is the array read : READ(A,i) and e1 is a bvconst
+      _arrayread_symbol[e0] = e1;
+      return;
+    }
+    if(-1 == i && e1.GetKind() != SYMBOL &&  !CheckSubstitutionMap(e1)) {
+      _arrayname_readindices[e1[0]].push_back(e1[1]);
+      //e0 is the array read : READ(A,i) and e1 is a bvconst
+      _arrayread_symbol[e1] = e0;
+      return;
+    }
+  }
+
+  ASTNode BeevMgr::SimplifyFormula_NoRemoveWrites(const ASTNode& b, bool pushNeg) {
+    Begin_RemoveWrites = false;
+    ASTNode out = SimplifyFormula(b,pushNeg);
+    return out;
+  }
+
+  ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg) {
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    ASTNode out = SimplifyFormula(b,pushNeg);
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    return out;
+  }
+
+  ASTNode BeevMgr::SimplifyFormula(const ASTNode& b, bool pushNeg){
+    if(!optimize)
+      return b;
+
+    Kind kind = b.GetKind();
+    if(BOOLEAN_TYPE != b.GetType()) {
+      FatalError(" SimplifyFormula: You have input a nonformula kind: ",ASTUndefined,kind);
+    }
+    
+    ASTNode a = b;
+    ASTVec ca = a.GetChildren();
+    if(!(IMPLIES == kind || 
+	 ITE == kind ||
+	 isAtomic(kind))) {
+      SortByExprNum(ca);
+      a = CreateNode(kind,ca);
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    switch(kind){
+    case AND:
+    case OR:
+      output = SimplifyAndOrFormula(a,pushNeg);
+      break;
+    case NOT:
+      output = SimplifyNotFormula(a,pushNeg);
+      break;
+    case XOR:
+      output = SimplifyXorFormula(a,pushNeg);
+      break;
+    case NAND:
+      output = SimplifyNandFormula(a,pushNeg);
+      break;
+    case NOR:
+      output = SimplifyNorFormula(a,pushNeg);
+      break;
+    case IFF:
+      output = SimplifyIffFormula(a,pushNeg);
+      break;
+    case IMPLIES:
+      output = SimplifyImpliesFormula(a,pushNeg);
+      break;
+    case ITE:
+      output = SimplifyIteFormula(a,pushNeg);
+      break;
+    default:
+      //kind can be EQ,NEQ,BVLT,BVLE,... or a propositional variable
+      output = SimplifyAtomicFormula(a,pushNeg);
+      //output = pushNeg ? CreateNode(NOT,a) : a;
+      break;
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output, pushNeg);
+    return output;
+  }
+    
+  ASTNode BeevMgr::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg) {    
+    if(!optimize) {
+      return a;
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg)) {
+      return output;
+    }
+
+    ASTNode left,right;
+    if(a.Degree() == 2) {
+      //cerr << "Input to simplifyterm: left: " << a[0] << endl;
+      left = SimplifyTerm(a[0]);
+      //cerr << "Output of simplifyterm:left: " << left << endl;
+      //cerr << "Input to simplifyterm: right: " << a[1] << endl;
+      right = SimplifyTerm(a[1]);
+      //cerr << "Output of simplifyterm:left: " << right << endl;
+    }
+
+    Kind kind = a.GetKind();
+    switch(kind) {
+    case TRUE:
+      output = pushNeg ? ASTFalse : ASTTrue;
+      break;
+    case FALSE:
+      output = pushNeg ? ASTTrue : ASTFalse;
+      break;
+    case SYMBOL:
+      if(!CheckSolverMap(a,output)) {
+	output = a;
+      }
+      output = pushNeg ? CreateNode(NOT,output) : output;           
+      break;
+    case BVGETBIT: {
+      ASTNode term = SimplifyTerm(a[0]);
+      ASTNode thebit = a[1];
+      ASTNode zero = CreateZeroConst(1);
+      ASTNode one = CreateOneConst(1);
+      ASTNode getthebit = SimplifyTerm(CreateTerm(BVEXTRACT,1,term,thebit,thebit));
+      if(getthebit == zero)
+	output = pushNeg ? ASTTrue : ASTFalse;
+      else if(getthebit == one)
+	output = pushNeg ? ASTFalse : ASTTrue;
+      else {
+	output = CreateNode(BVGETBIT,term,thebit);
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      }
+      break;
+    }
+    case EQ:{
+      output = CreateSimplifiedEQ(left,right);
+      output = LhsMinusRhs(output);
+      output = ITEOpt_InEqs(output);
+      if(output == ASTTrue)
+	output = pushNeg ? ASTFalse : ASTTrue;
+      else if (output == ASTFalse)
+	output = pushNeg ? ASTTrue : ASTFalse;
+      else
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      break;  
+    } 
+    case NEQ: {
+      output = CreateSimplifiedEQ(left,right);
+      output = LhsMinusRhs(output);
+      if(output == ASTTrue)
+      	output = pushNeg ? ASTTrue : ASTFalse;
+      else if (output == ASTFalse)
+      	output = pushNeg ? ASTFalse : ASTTrue;
+      else
+	output = pushNeg ? output : CreateNode(NOT,output);
+      break;
+    }
+    case BVLT:
+    case BVLE:
+    case BVGT:
+    case BVGE:
+    case BVSLT:
+    case BVSLE:
+    case BVSGT:
+    case BVSGE: {
+      //output = CreateNode(kind,left,right);
+      //output = pushNeg ? CreateNode(NOT,output) : output;      
+      output = CreateSimplifiedINEQ(kind,left,right,pushNeg);
+      break;
+    }
+    default:
+      FatalError("SimplifyAtomicFormula: NO atomic formula of the kind: ",ASTUndefined,kind);
+      break;      
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  } //end of SimplifyAtomicFormula()
+
+  ASTNode BeevMgr::CreateSimplifiedINEQ(Kind k, 
+					const ASTNode& left, 
+					const ASTNode& right, 
+					bool pushNeg) {
+    ASTNode output;
+    if(BVCONST == left.GetKind() && BVCONST == right.GetKind()) {
+      output = BVConstEvaluator(CreateNode(k,left,right));
+      output = pushNeg ? (ASTFalse == output) ? ASTTrue : ASTFalse : output;
+      return output;
+    }
+
+    unsigned len = left.GetValueWidth();
+    ASTNode zero = CreateZeroConst(len);
+    ASTNode one = CreateOneConst(len);
+    ASTNode max = CreateMaxConst(len);
+    switch(k){
+    case BVLT:
+      if(right == zero) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else if(one == right) {
+	output = CreateSimplifiedEQ(left,zero);
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      }
+      else {
+	output = pushNeg ? CreateNode(BVLE,right,left) : CreateNode(BVLT,left,right);
+      }
+      break;
+    case BVLE:
+      if(left == zero) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(max == right) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(zero == right) {
+	output = CreateSimplifiedEQ(left,zero);
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      }
+      else {
+	output = pushNeg ? CreateNode(BVLT,right,left) : CreateNode(BVLE,left,right);
+      }
+      break;
+    case BVGT:
+      if(left == zero) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else {
+      output = pushNeg ? CreateNode(BVLE,left,right) : CreateNode(BVLT,right,left);
+      }
+      break;
+    case BVGE:
+      if(right == zero) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else {
+      output = pushNeg ? CreateNode(BVLT,left,right) : CreateNode(BVLE,right,left);
+      }
+      break;
+    case BVSLT:
+    case BVSLE:
+    case BVSGE:
+    case BVSGT: {
+      output = CreateNode(k,left,right);
+      output = pushNeg ? CreateNode(NOT,output) : output;
+    }
+      break;
+    default:
+      FatalError("Wrong Kind");
+      break;
+    }
+
+    return output;
+  }
+
+  //takes care of some simple ITE Optimizations in the context of equations
+  ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in) {
+    CountersAndStats("ITEOpts_InEqs");
+
+    if(!(EQ == in.GetKind() && optimize)) {
+      return in;
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(in,output,false)) {
+      return output;
+    }
+
+    ASTNode in1 = in[0];
+    ASTNode in2 = in[1];
+    Kind k1 = in1.GetKind();
+    Kind k2 = in2.GetKind();
+    if(in1 == in2) {
+      //terms are syntactically the same
+      output = ASTTrue;    
+    }
+    else if(BVCONST == k1 && BVCONST == k2) {
+      //here the terms are definitely not syntactically equal but may
+      //be semantically equal.
+      output = ASTFalse;
+    }
+    else if(ITE == k1 && 
+	    BVCONST == in1[1].GetKind() && 
+	    BVCONST == in1[2].GetKind() && BVCONST == k2) {
+      //if one side is a BVCONST and the other side is an ITE over
+      //BVCONST then we can do the following optimization:
+      //
+      // c = ITE(cond,c,d) <=> cond
+      //
+      // similarly ITE(cond,c,d) = c <=> cond
+      //
+      // c = ITE(cond,d,c) <=> NOT(cond) 
+      //
+      //similarly ITE(cond,d,c) = d <=> NOT(cond)
+      ASTNode cond = in1[0];
+      if(in1[1] == in2) {
+	//ITE(cond, c, d) = c <=> cond
+	output = cond;
+      }
+      else if(in1[2] == in2) {
+	cond = SimplifyFormula(cond,true);
+	output = cond;
+      }
+      else {
+	//last resort is to CreateNode
+	output = CreateNode(EQ,in1,in2);   
+      }    
+    }    
+    else if(ITE == k2 && 
+	    BVCONST == in2[1].GetKind() && 
+	    BVCONST == in2[2].GetKind() && BVCONST == k1) {
+      ASTNode cond = in2[0];
+      if(in2[1] == in1) {
+	//ITE(cond, c, d) = c <=> cond
+	output = cond;
+      }
+      else if(in2[2] == in1) {
+	cond = SimplifyFormula(cond,true);
+	output = cond;
+      }
+      else {
+	//last resort is to CreateNode
+	output = CreateNode(EQ,in1,in2);   
+      }    
+    }
+    else {
+      //last resort is to CreateNode
+      output = CreateNode(EQ,in1,in2);   
+    }
+    
+    UpdateSimplifyMap(in,output,false);
+    return output;
+ } //End of ITEOpts_InEqs()
+
+  //Tries to simplify the input to TRUE/FALSE. if it fails, then
+  //return the constructed equality
+  ASTNode BeevMgr::CreateSimplifiedEQ(const ASTNode& in1, const ASTNode& in2) {
+    CountersAndStats("CreateSimplifiedEQ");        
+    Kind k1 = in1.GetKind();
+    Kind k2 = in2.GetKind();
+
+    if(!optimize) {
+      return CreateNode(EQ,in1,in2);
+    }
+    
+    if(in1 == in2)
+      //terms are syntactically the same
+      return ASTTrue;    
+    
+    //here the terms are definitely not syntactically equal but may be
+    //semantically equal.    
+    if(BVCONST == k1 && BVCONST == k2)
+      return ASTFalse;
+    
+    //last resort is to CreateNode
+    return CreateNode(EQ,in1,in2);
+  }
+  
+  //accepts cond == t1, then part is t2, and else part is t3
+  ASTNode BeevMgr::CreateSimplifiedTermITE(const ASTNode& in0, 
+					   const ASTNode& in1, const ASTNode& in2) {
+    ASTNode t0 = in0;
+    ASTNode t1 = in1;
+    ASTNode t2 = in2;
+    CountersAndStats("CreateSimplifiedITE");
+    if(!optimize) {
+      if(t1.GetValueWidth() != t2.GetValueWidth()) {
+	cerr << "t2 is : = " << t2;
+	FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
+      }
+      if(t1.GetIndexWidth() != t2.GetIndexWidth()) {
+	cerr << "t2 is : = " << t2;
+	FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
+      }
+      return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
+    }
+
+    if(t0 == ASTTrue)
+      return t1;
+    if (t0 == ASTFalse)
+      return t2;    
+    if(t1 == t2)
+      return t1;    
+    if(CheckAlwaysTrueFormMap(t0)) {
+	return t1;
+    }     
+    if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) || 
+       (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
+      return t2;
+    }
+    
+    return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
+  }
+
+  ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    //cerr << "input:\n" << a << endl;
+
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    ASTVec c, outvec;
+    c = a.GetChildren();
+    ASTNode flat = FlattenOneLevel(a);
+    c = flat.GetChildren();
+    SortByExprNum(c);
+
+    Kind k = a.GetKind();
+    bool isAnd = (k == AND) ? true : false;
+
+    ASTNode annihilator = isAnd ? 
+      (pushNeg ? ASTTrue : ASTFalse): 
+      (pushNeg ? ASTFalse : ASTTrue);
+
+    ASTNode identity = isAnd ? 
+      (pushNeg ? ASTFalse : ASTTrue): 
+      (pushNeg ? ASTTrue : ASTFalse);
+
+    //do the work
+    ASTVec::const_iterator next_it;
+    for(ASTVec::const_iterator i=c.begin(),iend=c.end();i!=iend;i++) {
+      ASTNode aaa = *i;
+      next_it = i+1;
+      bool nextexists = (next_it < iend);
+      
+      aaa = SimplifyFormula(aaa,pushNeg);
+      if(annihilator == aaa) {
+	//memoize
+	UpdateSimplifyMap(*i,annihilator,pushNeg);
+	UpdateSimplifyMap(a, annihilator,pushNeg);
+	//cerr << "annihilator1: output:\n" << annihilator << endl;
+	return annihilator;
+      }
+      ASTNode bbb = ASTFalse;
+      if(nextexists) {
+      	bbb = SimplifyFormula(*next_it,pushNeg);
+      }      
+      if(nextexists &&  bbb == aaa) {
+      	//skip the duplicate aaa. *next_it will be included
+      }
+      else if(nextexists && 
+      	      ((bbb.GetKind() == NOT && bbb[0] == aaa))) {
+      	//memoize
+      	UpdateSimplifyMap(a, annihilator,pushNeg);
+      	//cerr << "annihilator2: output:\n" << annihilator << endl;
+      	return annihilator;
+      }
+      else if(identity == aaa) {
+	// //drop identites
+      }
+      else if((!isAnd && !pushNeg) ||
+	      (isAnd && pushNeg)) { 
+	outvec.push_back(aaa);	
+      }
+      else if((isAnd && !pushNeg) ||
+	      (!isAnd && pushNeg)) {
+	outvec.push_back(aaa);	
+      }
+      else {
+	outvec.push_back(aaa);
+      }
+    }
+
+    switch(outvec.size()) {
+    case 0: {
+      //only identities were dropped 
+      output = identity;
+      break;
+    }
+    case 1: {
+      output = SimplifyFormula(outvec[0],false);
+      break;
+    }
+    default: {
+      output = (isAnd) ? 
+	(pushNeg ? CreateNode(OR,outvec) : CreateNode(AND,outvec)): 
+	(pushNeg ? CreateNode(AND,outvec) : CreateNode(OR,outvec));
+      //output = FlattenOneLevel(output);
+      break;
+    }
+    }
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    //cerr << "output:\n" << output << endl;
+    return output;
+  } //end of SimplifyAndOrFormula
+
+
+  ASTNode BeevMgr::SimplifyNotFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if(!(a.Degree() == 1 && NOT == a.GetKind())) 
+      FatalError("SimplifyNotFormula: input vector with more than 1 node",ASTUndefined);
+
+    //if pushNeg is set then there is NOT on top
+    unsigned int NotCount = pushNeg ? 1 : 0;
+    ASTNode o = a;
+    //count the number of NOTs in 'a'
+    while(NOT == o.GetKind()) {
+      o = o[0];
+      NotCount++;
+    }
+
+    //pushnegation if there are odd number of NOTs
+    bool pn = (NotCount % 2 == 0) ? false : true;
+
+    if(CheckAlwaysTrueFormMap(o)) {
+      output = pn ? ASTFalse : ASTTrue;
+      return output;
+    }
+
+    if(CheckSimplifyMap(o,output,pn)) {
+      return output;
+    }
+
+    if (ASTTrue == o) {
+      output = pn ? ASTFalse : ASTTrue;
+    }
+    else if (ASTFalse == o) {
+      output = pn ? ASTTrue : ASTFalse;
+    }
+    else {
+      output = SimplifyFormula(o,pn);
+    }
+    //memoize
+    UpdateSimplifyMap(o,output,pn);
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if (a.GetChildren().size() > 2) {
+      FatalError("Simplify got an XOR with more than two children.");
+    }
+
+    ASTNode a0 = SimplifyFormula(a[0],false);
+    ASTNode a1 = SimplifyFormula(a[1],false);        
+    output = pushNeg ? CreateNode(IFF,a0,a1) : CreateNode(XOR,a0,a1);
+    
+    if(XOR == output.GetKind()) {
+      a0 = output[0];
+      a1 = output[1];
+      if(a0 == a1)
+	output = ASTFalse;
+      else if((a0 == ASTTrue  && a1 == ASTFalse) ||
+	      (a0 == ASTFalse && a1 == ASTTrue))
+	output = ASTTrue;
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyNandFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output,a0,a1;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    //the two NOTs cancel out
+    if(pushNeg) {
+      a0 = SimplifyFormula(a[0],false);
+      a1 = SimplifyFormula(a[1],false);
+      output = CreateNode(AND,a0,a1);
+    }
+    else {
+      //push the NOT implicit in the NAND
+      a0 = SimplifyFormula(a[0],true);
+      a1 = SimplifyFormula(a[1],true);
+      output = CreateNode(OR,a0,a1);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output,a0,a1;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    //the two NOTs cancel out
+    if(pushNeg) {
+      a0 = SimplifyFormula(a[0],false);
+      a1 = SimplifyFormula(a[1],false);
+      output = CreateNode(OR,a0,a1);
+    }
+    else {
+      //push the NOT implicit in the NAND
+      a0 = SimplifyFormula(a[0],true);
+      a1 = SimplifyFormula(a[1],true);
+      output = CreateNode(AND,a0,a1);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if(!(a.Degree()==2 && IMPLIES==a.GetKind()))
+      FatalError("SimplifyImpliesFormula: vector with wrong num of nodes",ASTUndefined);
+    
+    ASTNode c0,c1;
+    if(pushNeg) {
+      c0 = SimplifyFormula(a[0],false);
+      c1 = SimplifyFormula(a[1],true);
+      output = CreateNode(AND,c0,c1);
+    }
+    else {
+      c0 = SimplifyFormula(a[0],false);
+      c1 = SimplifyFormula(a[1],false);
+      if(ASTFalse == c0) {
+	output = ASTTrue;
+      }
+      else if (ASTTrue == c0) {
+	output = c1;
+      }
+      else if (c0 == c1) {
+	output = ASTTrue;
+      }
+      else if(CheckAlwaysTrueFormMap(c0)) {
+	// c0 AND (~c0 OR c1) <==> c1
+	//
+	//applying modus ponens
+	output = c1;
+      }
+      else if(CheckAlwaysTrueFormMap(c1)	||
+	      CheckAlwaysTrueFormMap(CreateNode(NOT,c0)) ||
+	      (NOT == c0.GetKind() && CheckAlwaysTrueFormMap(c0[0]))) {
+	//(~c0 AND (~c0 OR c1)) <==> TRUE
+	//
+	//(c0 AND ~c0->c1) <==> TRUE
+	output = ASTTrue;
+      }
+      else if (CheckAlwaysTrueFormMap(CreateNode(NOT,c1)) ||
+	       (NOT == c1.GetKind() && CheckAlwaysTrueFormMap(c1[0]))) {
+	//(~c1 AND c0->c1) <==> (~c1 AND ~c1->~c0) <==> ~c0
+	//(c1 AND c0->~c1) <==> (c1 AND c1->~c0) <==> ~c0
+	output = CreateNode(NOT,c0);
+      }
+      else {
+	if(NOT == c0.GetKind()) {
+	  output = CreateNode(OR,c0[0],c1);
+	}
+	else {
+	  output = CreateNode(OR,CreateNode(NOT,c0),c1);
+	}
+      }
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyIffFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if(!(a.Degree()==2 && IFF==a.GetKind()))
+      FatalError("SimplifyIffFormula: vector with wrong num of nodes",ASTUndefined);
+    
+    ASTNode c0 = a[0];
+    ASTNode c1 = SimplifyFormula(a[1],false);
+
+    if(pushNeg)
+      c0 = SimplifyFormula(c0,true);
+    else 
+      c0 = SimplifyFormula(c0,false);
+
+    if(ASTTrue == c0) {
+      output = c1;
+    }
+    else if (ASTFalse == c0) {
+      output = SimplifyFormula(c1,true);
+    }
+    else if (ASTTrue == c1) {
+      output = c0;
+    }
+    else if (ASTFalse == c1) {
+      output = SimplifyFormula(c0,true);
+    }
+    else if (c0 == c1) {
+      output = ASTTrue;
+    }
+    else if((NOT == c0.GetKind() && c0[0] == c1) ||
+	    (NOT == c1.GetKind() && c0 == c1[0])) {
+      output = ASTFalse;
+    }
+    else if(CheckAlwaysTrueFormMap(c0)) {
+      output = c1;
+    }
+    else if(CheckAlwaysTrueFormMap(c1)) {
+      output = c0;
+    }
+    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c0))) {
+      output = CreateNode(NOT,c1);
+    }
+    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c1))) {
+      output = CreateNode(NOT,c0);
+    }
+    else {
+      output = CreateNode(IFF,c0,c1);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyIteFormula(const ASTNode& b, bool pushNeg) {
+    if(!optimize)
+      return b;
+
+    ASTNode output;
+    if(CheckSimplifyMap(b,output,pushNeg))
+      return output;
+
+    if(!(b.Degree() == 3 && ITE == b.GetKind()))
+      FatalError("SimplifyIteFormula: vector with wrong num of nodes",ASTUndefined);    
+    
+    ASTNode a = b;
+    ASTNode t0 = SimplifyFormula(a[0],false);
+    ASTNode t1,t2;
+    if(pushNeg) {
+      t1 = SimplifyFormula(a[1],true);
+      t2 = SimplifyFormula(a[2],true);
+    }
+    else {
+      t1 = SimplifyFormula(a[1],false);
+      t2 = SimplifyFormula(a[2],false);
+    }
+    
+    if(ASTTrue == t0) {
+      output = t1;
+    }
+    else if (ASTFalse == t0) {
+      output = t2;
+    }
+    else if (t1 == t2) {
+      output = t1;
+    }
+    else if(ASTTrue == t1 && ASTFalse == t2) {
+      output = t0;
+    }
+    else if(ASTFalse == t1 && ASTTrue == t2) {
+      output = SimplifyFormula(t0,true);
+    }
+    else if(ASTTrue == t1) {
+      output = CreateNode(OR,t0,t2);
+    }
+    else if(ASTFalse == t1) {
+      output = CreateNode(AND,CreateNode(NOT,t0),t2);
+    }
+    else if(ASTTrue == t2) {
+      output = CreateNode(OR,CreateNode(NOT,t0),t1);
+    }
+    else if(ASTFalse == t2) {
+      output = CreateNode(AND,t0,t1);
+    }
+    else if(CheckAlwaysTrueFormMap(t0)) {
+      output = t1;
+    }
+    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) ||
+    	    (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
+      output = t2;
+    }
+    else {
+      output = CreateNode(ITE,t0,t1,t2);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;    
+  }
+
+  //one level deep flattening
+  ASTNode BeevMgr::FlattenOneLevel(const ASTNode& a) {
+    Kind k = a.GetKind();
+    if(!(BVPLUS == k || 
+	 AND == k || OR == k
+	 //|| BVAND == k 
+	 //|| BVOR == k
+	 )
+       ) {
+      return a;
+    }
+    
+    ASTNode output;
+    // if(CheckSimplifyMap(a,output,false)) {
+    //       //check memo table
+    //       //cerr << "output of SimplifyTerm Cache: " << output << endl;
+    //       return output;
+    //     }
+
+    ASTVec c = a.GetChildren();
+    ASTVec o;
+    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+      ASTNode aaa = *it;
+      if(k == aaa.GetKind()) {
+	ASTVec ac = aaa.GetChildren();
+	o.insert(o.end(),ac.begin(),ac.end());
+      }
+      else
+	o.push_back(aaa);      
+    } 
+    
+    if(is_Form_kind(k))
+      output = CreateNode(k,o);
+    else
+      output = CreateTerm(k,a.GetValueWidth(),o);
+
+    //UpdateSimplifyMap(a,output,false);
+    return output;
+    //memoize
+  } //end of flattenonelevel()
+
+  ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) {
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    ASTNode out = SimplifyTerm(b);
+    SimplifyNegMap.clear();
+    SimplifyMap.clear();
+    return out;
+  }
+
+  //This function simplifies terms based on their kind
+  ASTNode BeevMgr::SimplifyTerm(const ASTNode& inputterm) {
+    //cout << "SimplifyTerm: input: " << a << endl;
+    if(!optimize) {
+      return inputterm;
+    }
+
+    BVTypeCheck(inputterm);
+    ASTNode output;
+    if(wordlevel_solve && CheckSolverMap(inputterm,output)) {
+      //cout << "SimplifyTerm: output: " << output << endl;
+      return SimplifyTerm(output);     
+    }
+
+    if(CheckSimplifyMap(inputterm,output,false)) {
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+
+    Kind k = inputterm.GetKind();    
+    if(!is_Term_kind(k)) {
+      FatalError("SimplifyTerm: You have input a Non-term",ASTUndefined);
+    }
+
+    unsigned int inputValueWidth = inputterm.GetValueWidth();
+    switch(k) {
+    case BVCONST:
+      output = inputterm;
+      break;
+    case SYMBOL:
+      if(CheckSolverMap(inputterm,output)) {
+	return SimplifyTerm(output);
+      }
+      output = inputterm;
+      break;
+    case BVMULT:
+    case BVPLUS:{
+      if(BVMULT == k && 2 != inputterm.Degree()) {
+	FatalError("SimplifyTerm: We assume that BVMULT is binary",inputterm);
+      }
+      
+      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+      SortByExprNum(c);
+      ASTVec constkids, nonconstkids;
+
+      //go through the childnodes, and separate constant and
+      //nonconstant nodes. combine the constant nodes using the
+      //constevaluator. if the resultant constant is zero and k ==
+      //BVPLUS, then ignore it (similarily for 1 and BVMULT).  else,
+      //add the computed constant to the nonconst vector, flatten,
+      //sort, and create BVPLUS/BVMULT and return
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	if(BVCONST == aaa.GetKind()) {
+	  constkids.push_back(aaa);
+	}
+	else {
+	  nonconstkids.push_back(aaa);
+	}
+      }
+      
+      ASTNode one = CreateOneConst(inputValueWidth);
+      ASTNode max = CreateMaxConst(inputValueWidth);
+      ASTNode zero = CreateZeroConst(inputValueWidth);
+
+      //initialize constoutput to zero, in case there are no elements
+      //in constkids
+      ASTNode constoutput = (k == BVPLUS) ? zero : one;
+
+      if(1 == constkids.size()) {
+	//only one element in constkids
+	constoutput = constkids[0];
+      } 
+      else if (1 < constkids.size()) {
+	//many elements in constkids. simplify it
+	constoutput = CreateTerm(k,inputterm.GetValueWidth(),constkids);
+	constoutput = BVConstEvaluator(constoutput);
+      }
+
+      if(BVMULT == k && zero == constoutput) {
+	output = zero;
+      }
+      else if(BVMULT == k && 
+	      1 == nonconstkids.size() && 
+	      constoutput == max) {
+	//useful special case opt: when input is BVMULT(max_const,t),
+	//then output = BVUMINUS(t). this is easier on the bitblaster
+	output = CreateTerm(BVUMINUS,inputValueWidth,nonconstkids);
+      }
+      else {
+	if(0 < nonconstkids.size()) {
+	  //nonconstkids is not empty. First, combine const and
+	  //nonconstkids
+	  if(BVPLUS == k && constoutput != zero) {
+	    nonconstkids.push_back(constoutput);
+	  }
+	  else if(BVMULT == k && constoutput != one) {
+	    nonconstkids.push_back(constoutput);
+	  }
+
+	  if(1 == nonconstkids.size()) {
+	    //exactly one element in nonconstkids. output is exactly
+	    //nonconstkids[0]
+	    output = nonconstkids[0];
+	  }
+	  else {
+	    //more than 1 element in nonconstkids. create BVPLUS term
+	    SortByExprNum(nonconstkids);
+	    output = CreateTerm(k,inputValueWidth,nonconstkids);
+	    output = FlattenOneLevel(output);
+	    output = DistributeMultOverPlus(output,true);
+	    output = CombineLikeTerms(output);
+ 	  }
+	}
+	else {
+	  //nonconstkids was empty, all childnodes were constant, hence
+	  //constoutput is the output.
+	  output = constoutput;
+	}
+      }
+      if(BVMULT == output.GetKind() 
+	 || BVPLUS == output.GetKind()
+	 ) {
+	ASTVec d = output.GetChildren();
+	SortByExprNum(d);
+      	output = CreateTerm(output.GetKind(),output.GetValueWidth(),d);
+      }
+      break;
+    }
+    case BVSUB: {
+      ASTVec c = inputterm.GetChildren();
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      ASTNode a1 = SimplifyTerm(inputterm[1]);
+      unsigned int l = inputValueWidth;
+      if(a0 == a1)
+	output = CreateZeroConst(l);
+      else {
+	//covert x-y into x+(-y) and simplify. this transformation
+	//triggers more simplifications
+	a1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a1));
+	output = SimplifyTerm(CreateTerm(BVPLUS,l,a0,a1));
+      }
+      break;
+    }
+    case BVUMINUS: {
+      //important to treat BVUMINUS as a special case, because it
+      //helps in arithmetic transformations. e.g.  x + BVUMINUS(x) is
+      //actually 0. One way to reveal this fact is to strip bvuminus
+      //out, and replace with something else so that combineliketerms
+      //can catch this fact.
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      Kind k1 = a0.GetKind();
+      unsigned int l = a0.GetValueWidth();
+      ASTNode one = CreateOneConst(l);
+      switch(k1) {
+      case BVUMINUS:
+	output = a0[0];
+	break;
+      case BVCONST: {
+	output = BVConstEvaluator(CreateTerm(BVUMINUS,l,a0));
+	break;
+      }
+      case BVNEG: {
+	output = SimplifyTerm(CreateTerm(BVPLUS,l,a0[0],one));
+	break;
+      }
+      case BVMULT: {
+	if(BVUMINUS == a0[0].GetKind()) {
+	  output = CreateTerm(BVMULT,l,a0[0][0],a0[1]);
+	}
+	else if(BVUMINUS == a0[1].GetKind()) {
+	  output = CreateTerm(BVMULT,l,a0[0],a0[1][0]);
+	}
+	else {
+	  ASTNode a00 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[0]));	
+	  output = CreateTerm(BVMULT,l,a00,a0[1]);
+	}
+	break;
+      }
+      case BVPLUS: {
+	//push BVUMINUS over all the monomials of BVPLUS. Simplify
+	//along the way
+	//
+	//BVUMINUS(a1x1 + a2x2 + ...) <=> BVPLUS(BVUMINUS(a1x1) +
+	//BVUMINUS(a2x2) + ...
+	ASTVec c = a0.GetChildren();
+	ASTVec o;
+	for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	  //Simplify(BVUMINUS(a1x1))
+	  ASTNode aaa = SimplifyTerm(CreateTerm(BVUMINUS,l,*it));
+	  o.push_back(aaa);
+	}
+	//simplify the bvplus
+	output = SimplifyTerm(CreateTerm(BVPLUS,l,o));	
+	break;
+      }
+      case BVSUB: {
+	//BVUMINUS(BVSUB(x,y)) <=> BVSUB(y,x)
+	output = SimplifyTerm(CreateTerm(BVSUB,l,a0[1],a0[0]));
+	break;
+      }
+      case ITE: {
+	//BVUMINUS(ITE(c,t1,t2)) <==> ITE(c,BVUMINUS(t1),BVUMINUS(t2))
+	ASTNode c = a0[0];
+	ASTNode t1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[1]));
+	ASTNode t2 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[2]));
+	output = CreateSimplifiedTermITE(c,t1,t2);
+	break;
+      }
+      default: {
+	output = CreateTerm(BVUMINUS,l,a0);
+	break;
+      }
+      }
+      break;
+    }
+    case BVEXTRACT:{
+      //it is important to take care of wordlevel transformation in
+      //BVEXTRACT. it exposes oppurtunities for later simplification
+      //and solving (variable elimination)
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      Kind k1 = a0.GetKind();
+      unsigned int a_len = inputValueWidth;
+      
+      //indices for BVEXTRACT
+      ASTNode i = inputterm[1];
+      ASTNode j = inputterm[2];
+      ASTNode zero = CreateBVConst(32,0);
+      //recall that the indices of BVEXTRACT are always 32 bits
+      //long. therefore doing a GetBVUnsigned is ok.
+      unsigned int i_val = GetUnsignedConst(i);
+      unsigned int j_val = GetUnsignedConst(j);
+
+      // a0[i:0] and len(a0)=i+1, then return a0
+      if(0 == j_val && a_len == a0.GetValueWidth())
+	return a0;
+
+      switch(k1) {
+      case BVCONST: {
+	//extract the constant
+	output = BVConstEvaluator(CreateTerm(BVEXTRACT,a_len,a0,i,j));
+	break;
+      }
+      case BVCONCAT:{
+	//assumes concatenation is binary
+	//
+	//input is of the form a0[i:j]
+	//
+	//a0 is the conatentation t@u, and a0[0] is t, and a0[1] is u
+	ASTNode t = a0[0];
+	ASTNode u = a0[1];
+	unsigned int len_a0 = a0.GetValueWidth();
+	unsigned int len_u = u.GetValueWidth();
+
+	if(len_u > i_val) {
+	  //Apply the following rule:
+	  // (t@u)[i:j] <==> u[i:j], if len(u) > i
+	  //
+	  output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
+	}
+	else if(len_a0 > i_val && j_val >= len_u) {
+	  //Apply the rule:
+	  // (t@u)[i:j] <==> t[i-len_u:j-len_u], if len(t@u) > i >= j >= len(u)
+	  i = CreateBVConst(32, i_val - len_u);
+	  j = CreateBVConst(32, j_val - len_u);
+	  output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
+	}
+	else {
+	  //Apply the rule:
+	  // (t@u)[i:j] <==> t[i-len_u:0] @ u[len_u-1:j]
+	  i = CreateBVConst(32,i_val-len_u);
+	  ASTNode m = CreateBVConst(32, len_u-1);
+	  t = SimplifyTerm(CreateTerm(BVEXTRACT,i_val-len_u+1,t,i,zero));
+	  u = SimplifyTerm(CreateTerm(BVEXTRACT,len_u-j_val,u,m,j));
+	  output = CreateTerm(BVCONCAT,a_len,t,u);
+	}
+	break;
+      }
+      case BVPLUS:
+      case BVMULT: {	
+	// (BVMULT(n,t,u))[i:j] <==> BVMULT(i+1,t[i:0],u[i:0])[i:j]
+	//similar rule for BVPLUS
+	ASTVec c = a0.GetChildren();
+	ASTVec o;
+	for(ASTVec::iterator jt=c.begin(),jtend=c.end();jt!=jtend;jt++) {
+	  ASTNode aaa = *jt;
+	  aaa = SimplifyTerm(CreateTerm(BVEXTRACT,i_val+1,aaa,i,zero));
+	  o.push_back(aaa);
+	}
+	output = CreateTerm(a0.GetKind(),i_val+1,o);	
+	if(j_val != 0) {
+	  //add extraction only if j is not zero
+	  output = CreateTerm(BVEXTRACT,a_len,output,i,j);
+	}
+	break;
+      }
+      case BVAND:
+      case BVOR:
+      case BVXOR: {
+	//assumes these operators are binary
+	//
+	// (t op u)[i:j] <==> t[i:j] op u[i:j]
+	ASTNode t = a0[0];
+	ASTNode u = a0[1];
+	t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
+	u = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
+	BVTypeCheck(t);
+	BVTypeCheck(u);
+	output = CreateTerm(k1,a_len,t,u);
+	break;
+      }
+      case BVNEG:{
+	// (~t)[i:j] <==> ~(t[i:j])
+	ASTNode t = a0[0];
+	t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
+	output = CreateTerm(BVNEG,a_len,t);
+	break;
+      }
+      // case BVSX:{
+// 	//(BVSX(t,n)[i:j] <==> BVSX(t,i+1), if n >= i+1 and j=0 
+// 	ASTNode t = a0[0];
+// 	unsigned int bvsx_len = a0.GetValueWidth();
+// 	if(bvsx_len < a_len) {
+// 	  FatalError("SimplifyTerm: BVEXTRACT over BVSX:" 
+// 		     "the length of BVSX term must be greater than extract-len",inputterm);
+// 	}
+// 	if(j != zero) {
+// 	  output = CreateTerm(BVEXTRACT,a_len,a0,i,j);	  
+// 	}
+// 	else {
+// 	  output = CreateTerm(BVSX,a_len,t,CreateBVConst(32,a_len));
+// 	}
+// 	break;
+//       }
+      case ITE: {
+	ASTNode t0 = a0[0];
+	ASTNode t1 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[1],i,j));
+	ASTNode t2 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[2],i,j));
+	output = CreateSimplifiedTermITE(t0,t1,t2);
+	break;
+      }
+      default: {
+	output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
+	break;
+      }
+      }
+      break;
+    }
+    case BVNEG: {
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      unsigned len = inputValueWidth;
+      switch(a0.GetKind()) {
+      case BVCONST:
+	output = BVConstEvaluator(CreateTerm(BVNEG,len,a0));
+	break;
+      case BVNEG:
+	output = a0[0];
+	break;
+      // case ITE: {
+// 	ASTNode cond = a0[0];
+// 	ASTNode thenpart = SimplifyTerm(CreateTerm(BVNEG,len,a0[1]));
+// 	ASTNode elsepart = SimplifyTerm(CreateTerm(BVNEG,len,a0[2]));
+// 	output = CreateSimplifiedTermITE(cond,thenpart,elsepart);	
+// 	break;
+//       }
+      default:
+	output = CreateTerm(BVNEG,len,a0);
+	break;
+      }
+      break;
+    }
+    case BVSX:{
+      //a0 is the expr which is being sign extended
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      //a1 represents the length of the term BVSX(a0)
+      ASTNode a1 = inputterm[1];
+      //output length of the BVSX term
+      unsigned len = inputValueWidth;
+      
+      if(a0.GetValueWidth() == len) {
+	//nothing to signextend
+	return a0;
+      }
+
+      switch(a0.GetKind()) {
+      case BVCONST:
+	output = BVConstEvaluator(CreateTerm(BVSX,len,a0,a1));
+	break;
+      case BVNEG:
+	output = CreateTerm(a0.GetKind(),len,CreateTerm(BVSX,len,a0[0],a1));
+	break;
+      case BVAND:
+      case BVOR:
+	//assuming BVAND and BVOR are binary
+	output = CreateTerm(a0.GetKind(),len,
+			    CreateTerm(BVSX,len,a0[0],a1),
+			    CreateTerm(BVSX,len,a0[1],a1));
+	break;
+      case BVPLUS: {	
+	//BVSX(m,BVPLUS(n,BVSX(t1),BVSX(t2))) <==> BVPLUS(m,BVSX(m,t1),BVSX(m,t2))
+	ASTVec c = a0.GetChildren();
+	bool returnflag = false;
+	for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	  if(BVSX != it->GetKind()) {
+	    returnflag = true;
+	    break;
+	  }
+	}
+	if(returnflag) {
+	  output = CreateTerm(BVSX,len,a0,a1);
+	}
+	else {
+	  ASTVec o;
+	  for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	    ASTNode aaa = SimplifyTerm(CreateTerm(BVSX,len,*it,a1));
+	    o.push_back(aaa);
+	  }
+	  output = CreateTerm(a0.GetKind(),len,o);
+	}
+	break;
+      }
+      case BVSX: {
+	//if you have BVSX(m,BVSX(n,a)) then you can drop the inner
+	//BVSX provided m is greater than n.
+	a0 = SimplifyTerm(a0[0]);
+	output = CreateTerm(BVSX,len,a0,a1);
+	break;
+      }
+      case ITE: {
+	ASTNode cond = a0[0];
+	ASTNode thenpart = SimplifyTerm(CreateTerm(BVSX,len,a0[1],a1));
+	ASTNode elsepart = SimplifyTerm(CreateTerm(BVSX,len,a0[2],a1));
+	output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
+	break;
+      }
+      default:
+	output = CreateTerm(BVSX,len,a0,a1);
+	break;
+      }    
+      break;
+    }
+    case BVAND:
+    case BVOR:{
+      ASTNode max = CreateMaxConst(inputValueWidth);
+      ASTNode zero = CreateZeroConst(inputValueWidth);
+
+      ASTNode identity = (BVAND == k) ? max : zero;
+      ASTNode annihilator = (BVAND == k) ? zero : max;
+      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+      SortByExprNum(c);
+      ASTVec o;
+      bool constant = true;
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	if(BVCONST != aaa.GetKind()) {
+	  constant = false;
+	}
+
+	if(aaa == annihilator) {
+	  output = annihilator;
+	  //memoize
+	  UpdateSimplifyMap(inputterm,output,false);
+	  //cerr << "output of SimplifyTerm: " << output << endl;
+	  return output;
+	}
+	
+	if(aaa != identity) {
+	  o.push_back(aaa);
+	}
+      }
+      
+      switch(o.size()) {
+      case 0:
+	output = identity;
+	break;
+      case 1:
+	output = o[0];
+	break;
+      default:
+	SortByExprNum(o);
+	output = CreateTerm(k,inputValueWidth,o);
+	if(constant) {
+	  output = BVConstEvaluator(output);
+	}     
+	break;
+      }
+      break;
+    }
+    case BVCONCAT:{
+      ASTNode t = SimplifyTerm(inputterm[0]);
+      ASTNode u = SimplifyTerm(inputterm[1]);
+      Kind tkind = t.GetKind();
+      Kind ukind = u.GetKind();
+      
+      
+      if(BVCONST == tkind && BVCONST == ukind) {
+	output = BVConstEvaluator(CreateTerm(BVCONCAT,inputValueWidth,t,u));
+      }
+      else if(BVEXTRACT == tkind && 
+	      BVEXTRACT == ukind && 
+	      t[0] == u[0]) {
+	//to handle the case x[m:n]@x[n-1:k] <==> x[m:k]
+	ASTNode t_hi = t[1];
+	ASTNode t_low = t[2];
+	ASTNode u_hi = u[1];
+	ASTNode u_low = u[2];
+	ASTNode c = BVConstEvaluator(CreateTerm(BVPLUS,32,u_hi,CreateOneConst(32)));
+	if(t_low == c) {
+	  output = CreateTerm(BVEXTRACT,inputValueWidth,t[0],t_hi,u_low);
+	}
+	else {
+	  output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
+	}
+      }
+      else {
+	output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
+      }
+      break;
+    }
+    case BVXOR:
+    case BVXNOR:
+    case BVNAND:
+    case BVNOR:
+    case BVLEFTSHIFT:
+    case BVRIGHTSHIFT:
+    case BVVARSHIFT:
+    case BVSRSHIFT:
+    case BVDIV:
+    case BVMOD: {
+      ASTVec c = inputterm.GetChildren();
+      ASTVec o;
+      bool constant = true;
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	if(BVCONST != aaa.GetKind()) {
+	  constant = false;
+	}
+	o.push_back(aaa);
+      }
+      output = CreateTerm(k,inputValueWidth,o);
+      if(constant)
+	output = BVConstEvaluator(output);
+      break;
+    }
+    case READ: {
+      ASTNode out1;
+      //process only if not  in the substitution map. simplifymap
+      //has been checked already
+      if(!CheckSubstitutionMap(inputterm,out1)) {
+	if(WRITE == inputterm[0].GetKind()) {
+	  //get rid of all writes
+	  ASTNode nowrites = RemoveWrites_TopLevel(inputterm);
+	  out1 = nowrites;
+	}
+	else if (ITE == inputterm[0].GetKind()){
+	  ASTNode cond = SimplifyFormula(inputterm[0][0],false);
+	  ASTNode arr1 = SimplifyTerm(inputterm[0][1]);
+	  ASTNode arr2 = SimplifyTerm(inputterm[0][2]);
+
+	  ASTNode index = SimplifyTerm(inputterm[1]);
+	  
+	  ASTNode read1 = CreateTerm(READ,inputValueWidth,arr1,index);
+	  ASTNode read2 = CreateTerm(READ,inputValueWidth,arr2,index);
+	  out1 = CreateSimplifiedTermITE(cond,read1,read2);
+	}
+	else {
+	  //arr is a SYMBOL for sure
+	  ASTNode arr = inputterm[0];
+	  ASTNode index = SimplifyTerm(inputterm[1]);
+	  out1 = CreateTerm(READ,inputValueWidth,arr,index);     
+	}
+      }
+      //it is possible that after all the procesing the READ term
+      //reduces to READ(Symbol,const) and hence we should check the
+      //substitutionmap once again.      
+      if(!CheckSubstitutionMap(out1,output))
+	output = out1;      
+      break;
+    }
+    case ITE: {
+      ASTNode t0 = SimplifyFormula(inputterm[0],false);
+      ASTNode t1 = SimplifyTerm(inputterm[1]);
+      ASTNode t2 = SimplifyTerm(inputterm[2]);
+      output = CreateSimplifiedTermITE(t0,t1,t2);      
+      break;
+    }
+    case SBVMOD:
+    case SBVDIV: {
+      ASTVec c = inputterm.GetChildren();
+      ASTVec o;
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	o.push_back(aaa);
+      }
+      output = CreateTerm(k,inputValueWidth,o);
+      break;
+    }
+    case WRITE:     
+    default:
+      FatalError("SimplifyTerm: Control should never reach here:", inputterm, k);
+      return inputterm;
+      break;
+    }
+
+    //memoize
+    UpdateSimplifyMap(inputterm,output,false);
+    //cerr << "SimplifyTerm: output" << output << endl;
+    return output;
+  } //end of SimplifyTerm()
+
+
+  //At the end of each simplification call, we want the output to be
+  //always smaller or equal to the input in size.
+  void BeevMgr::CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output) {
+    //Don't do the check in optimized mode
+    if(optimize)
+      return;
+
+    if(NodeSize(a,true) < NodeSize(output,true)) {
+      cerr << "lhs := " << a << endl;
+      cerr << "NodeSize of lhs is: " << NodeSize(a, true) << endl;
+      cerr << endl;
+      cerr << "rhs := " << output << endl;
+      cerr << "NodeSize of rhs is: " << NodeSize(output, true) << endl;
+      FatalError("SimplifyFormula: The nodesize shoudl decrease from lhs to rhs: ",ASTUndefined);
+    }
+  }
+
+  //this function assumes that the input is a vector of childnodes of
+  //a BVPLUS term. it combines like terms and returns a bvplus
+  //term. e.g. 1.x + 2.x is converted to 3.x
+  ASTNode BeevMgr::CombineLikeTerms(const ASTNode& a) {
+    if(BVPLUS != a.GetKind())
+      return a;
+    
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,false)) {
+      //check memo table
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+    
+    ASTVec c = a.GetChildren();
+    //map from variables to vector of constants
+    ASTNodeToVecMap vars_to_consts;
+    //vector to hold constants
+    ASTVec constkids;
+    ASTVec outputvec;
+
+    //useful constants
+    unsigned int len = c[0].GetValueWidth();
+    ASTNode one = CreateOneConst(len);
+    ASTNode zero = CreateZeroConst(len);
+    ASTNode max = CreateMaxConst(len);
+
+    //go over the childnodes of the input bvplus, and collect like
+    //terms in a map. the key of the map are the variables, and the
+    //values are stored in a ASTVec
+    for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++){
+      ASTNode aaa = *it;
+      if(SYMBOL == aaa.GetKind()) {
+	vars_to_consts[aaa].push_back(one);
+      }
+      else if(BVMULT == aaa.GetKind() && 
+	      BVUMINUS == aaa[0].GetKind() &&
+	      BVCONST == aaa[0][0].GetKind()) {
+	//(BVUMINUS(c))*(y) <==> compute(BVUMINUS(c))*y
+	ASTNode compute_const = BVConstEvaluator(aaa[0]);
+	vars_to_consts[aaa[1]].push_back(compute_const);
+      }
+      else if(BVMULT == aaa.GetKind() && 
+	      BVUMINUS == aaa[1].GetKind() &&
+	      BVCONST == aaa[0].GetKind()) {
+	//c*(BVUMINUS(y)) <==> compute(BVUMINUS(c))*y
+	ASTNode cccc = BVConstEvaluator(CreateTerm(BVUMINUS,len,aaa[0]));
+	vars_to_consts[aaa[1][0]].push_back(cccc);      
+      }      
+      else if(BVMULT == aaa.GetKind() && BVCONST == aaa[0].GetKind()) {
+	//assumes that BVMULT is binary
+	vars_to_consts[aaa[1]].push_back(aaa[0]);
+      } 
+      else if(BVMULT == aaa.GetKind() && BVUMINUS == aaa[0].GetKind()) {
+	//(-1*x)*(y) <==> -1*(xy)
+	ASTNode cccc = CreateTerm(BVMULT,len,aaa[0][0],aaa[1]);
+	ASTVec cNodes = cccc.GetChildren();
+	SortByExprNum(cNodes);
+	vars_to_consts[cccc].push_back(max);
+      }
+      else if(BVMULT == aaa.GetKind() && BVUMINUS == aaa[1].GetKind()) {
+	//x*(-1*y) <==> -1*(xy)
+	ASTNode cccc = CreateTerm(BVMULT,len,aaa[0],aaa[1][0]);
+	ASTVec cNodes = cccc.GetChildren();
+	SortByExprNum(cNodes);
+	vars_to_consts[cccc].push_back(max);      
+      }
+      else if(BVCONST == aaa.GetKind()) {
+	constkids.push_back(aaa);
+      }
+      else if(BVUMINUS == aaa.GetKind()) {
+	//helps to convert BVUMINUS into a BVMULT. here the max
+	//constant represents -1. this transformation allows us to
+	//conclude that x + BVUMINUS(x) is 0.
+	vars_to_consts[aaa[0]].push_back(max);
+      }
+      else 
+	vars_to_consts[aaa].push_back(one);
+    } //end of for loop
+
+    //go over the map from variables to vector of values. combine the
+    //vector of values, multiply to the variable, and put the
+    //resultant monomial in the output BVPLUS.
+    for(ASTNodeToVecMap::iterator it=vars_to_consts.begin(),itend=vars_to_consts.end();
+	it!=itend;it++){
+      ASTVec ccc = it->second;
+      
+      ASTNode constant;
+      if(1 < ccc.size()) {
+	constant = CreateTerm(BVPLUS,ccc[0].GetValueWidth(),ccc);
+	constant = BVConstEvaluator(constant);
+      }
+      else
+	constant = ccc[0];
+      
+      //constant * var
+      ASTNode monom;
+      if(zero == constant) 
+	monom = zero;
+      else if (one == constant)
+	monom = it->first;
+      else
+	monom = 
+	  SimplifyTerm(CreateTerm(BVMULT,constant.GetValueWidth(),constant,it->first));
+      if(zero != monom) {
+	outputvec.push_back(monom);
+      }
+    } //end of for loop
+
+    if(constkids.size() > 1) {
+      ASTNode output = CreateTerm(BVPLUS,constkids[0].GetValueWidth(),constkids);
+      output = BVConstEvaluator(output);
+      if(output != zero)
+	outputvec.push_back(output);
+    }
+    else if (constkids.size() == 1) {
+      if(constkids[0] != zero)
+	outputvec.push_back(constkids[0]);
+    }
+
+    if (outputvec.size() > 1) {
+      output = CreateTerm(BVPLUS,len,outputvec);
+    }
+    else if(outputvec.size() == 1) {
+      output = outputvec[0];
+    }
+    else {
+      output = zero;
+    }
+
+    //memoize
+    //UpdateSimplifyMap(a,output,false);
+    return output;
+  } //end of CombineLikeTerms()
+
+  //accepts lhs and rhs, and returns lhs - rhs = 0. The function
+  //assumes that lhs and rhs have already been simplified. although
+  //this assumption is not needed for correctness, it is essential for
+  //performance. The function also assumes that lhs is a BVPLUS
+  ASTNode BeevMgr::LhsMinusRhs(const ASTNode& eq) {
+    //if input is not an equality, simply return it
+    if(EQ != eq.GetKind())
+      return eq;
+
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    Kind k_lhs = lhs.GetKind();
+    Kind k_rhs = rhs.GetKind();
+    //either the lhs has to be a BVPLUS or the rhs has to be a
+    //BVPLUS
+    if(!(BVPLUS == k_lhs || 
+	 BVPLUS == k_rhs ||
+	 (BVMULT == k_lhs && 
+	  BVMULT == k_rhs)
+	 )) {
+      return eq;
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(eq,output,false)) {
+      //check memo table
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+    
+    //if the lhs is not a BVPLUS, but the rhs is a BVPLUS, then swap
+    //the lhs and rhs
+    bool swap_flag = false;
+    if(BVPLUS != k_lhs && BVPLUS == k_rhs) {
+      ASTNode swap = lhs;
+      lhs = rhs;
+      rhs = swap;
+      swap_flag = true;
+    }
+
+    unsigned int len = lhs.GetValueWidth();
+    ASTNode zero = CreateZeroConst(len);
+    //right is -1*(rhs): Simplify(-1*rhs)
+    rhs = SimplifyTerm(CreateTerm(BVUMINUS,len,rhs));
+
+    ASTVec lvec = lhs.GetChildren();
+    ASTVec rvec = rhs.GetChildren();
+    ASTNode lhsplusrhs;
+    if(BVPLUS != lhs.GetKind() && BVPLUS != rhs.GetKind()) {
+      lhsplusrhs = CreateTerm(BVPLUS,len,lhs,rhs); 
+    }
+    else if(BVPLUS == lhs.GetKind() && BVPLUS == rhs.GetKind()) {
+      //combine the childnodes of the left and the right
+      lvec.insert(lvec.end(),rvec.begin(),rvec.end());
+      lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
+    }
+    else if(BVPLUS == lhs.GetKind() && BVPLUS != rhs.GetKind()){
+      lvec.push_back(rhs);
+      lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
+    }
+    else {
+      //Control should never reach here
+      FatalError("LhsMinusRhs: Control should never reach here\n");
+    }
+
+    //combine like terms
+    output = CombineLikeTerms(lhsplusrhs);
+    output = SimplifyTerm(output);
+    //
+    //Now make output into: lhs-rhs = 0
+    output = CreateSimplifiedEQ(output,zero);
+    //sort if BVPLUS
+    if(BVPLUS == output.GetKind()) {
+      ASTVec outv = output.GetChildren();
+      SortByExprNum(outv);
+      output = CreateTerm(BVPLUS,len,outv);
+    }
+    
+    //memoize
+    //UpdateSimplifyMap(eq,output,false);
+    return output;  
+  } //end of LhsMinusRHS()
+
+  //THis function accepts a BVMULT(t1,t2) and distributes the mult
+  //over plus if either or both t1 and t2 are BVPLUSes.
+  //
+  // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
+  //
+  // (y1 + y2 + ...+ yn)*x <==> x*y1 + x*y2 + ... + x*yn
+  //
+  // The function assumes that the BVPLUSes have been flattened
+  ASTNode BeevMgr::DistributeMultOverPlus(const ASTNode& a, bool startdistribution) {
+    if(!startdistribution)
+      return a;
+    Kind k = a.GetKind();
+    if(BVMULT != k)
+      return a;
+
+    ASTNode left = a[0];
+    ASTNode right = a[1];
+    Kind left_kind = left.GetKind();
+    Kind right_kind = right.GetKind();
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,false)) {
+      //check memo table
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+
+    //special case optimization: c1*(c2*t1) <==> (c1*c2)*t1
+    if(BVCONST == left_kind && 
+       BVMULT == right_kind && 
+       BVCONST == right[0].GetKind()) {
+      ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[0]));
+      c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[1]);
+      return c;
+      left = c[0];
+      right = c[1];
+      left_kind = left.GetKind();
+      right_kind = right.GetKind();    
+    }
+
+    //special case optimization: c1*(t1*c2) <==> (c1*c2)*t1
+    if(BVCONST == left_kind && 
+       BVMULT == right_kind && 
+       BVCONST == right[1].GetKind()) {
+      ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[1]));
+      c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[0]);
+      return c;
+      left = c[0];
+      right = c[1];
+      left_kind = left.GetKind();
+      right_kind = right.GetKind();    
+    }
+
+    //atleast one of left or right have to be BVPLUS
+    if(!(BVPLUS == left_kind || BVPLUS == right_kind)) {
+      return a;
+    }
+    
+    //if left is BVPLUS and right is not, then swap left and right. we
+    //can do this since BVMULT is communtative
+    ASTNode swap;
+    if(BVPLUS == left_kind && BVPLUS != right_kind) {
+      swap = left;
+      left = right;
+      right = swap;
+    }
+    left_kind = left.GetKind();
+    right_kind = right.GetKind();
+
+    //by this point we are gauranteed that right is a BVPLUS, but left
+    //may not be
+    ASTVec rightnodes = right.GetChildren();
+    ASTVec outputvec;
+    unsigned len = a.GetValueWidth();
+    ASTNode zero = CreateZeroConst(len);
+    ASTNode one = CreateOneConst(len);
+    if(BVPLUS != left_kind) {
+      //if the multiplier is not a BVPLUS then we have a special case
+      // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
+      if(zero == left) {
+	outputvec.push_back(zero);
+      }
+      else if(one == left) {
+	outputvec.push_back(left);
+      }
+      else {
+	for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
+	    j!=jend;j++) {
+	  ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,left,*j));
+	  outputvec.push_back(out);
+	}
+      }
+    }
+    else {
+      ASTVec leftnodes = left.GetChildren();
+      // (x1 + x2 + ... + xm)*(y1 + y2 + ...+ yn) <==> x1*y1 + x1*y2 +
+      // ... + x2*y1 + ... + xm*yn
+      for(ASTVec::iterator i=leftnodes.begin(),iend=leftnodes.end();
+	  i!=iend;i++) {
+	ASTNode multiplier = *i;
+	for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
+	    j!=jend;j++) {
+	  ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,multiplier,*j));
+	  outputvec.push_back(out);
+	}
+      }
+    }
+    
+    //compute output here
+    if(outputvec.size() > 1) {
+      output = CombineLikeTerms(CreateTerm(BVPLUS,len,outputvec));
+      output = SimplifyTerm(output);
+    }
+    else
+      output = SimplifyTerm(outputvec[0]);
+
+    //memoize
+    //UpdateSimplifyMap(a,output,false);
+    return output;
+  } //end of distributemultoverplus()
+
+  //converts the BVSX(len, a0) operator into ITE( check top bit,
+  //extend a0 by 1, extend a0 by 0)
+  ASTNode BeevMgr::ConvertBVSXToITE(const ASTNode& a) {
+    if(BVSX != a.GetKind())
+      return a;
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,false)) {
+      //check memo table
+      //cerr << "output of ConvertBVSXToITE Cache: " << output << endl;
+      return output;
+    }
+    
+    ASTNode a0 = a[0];
+    unsigned a_len = a.GetValueWidth();
+    unsigned a0_len = a0.GetValueWidth();
+    
+    if(a0_len > a_len){
+      FatalError("Trying to sign_extend a larger BV into a smaller BV");
+      return ASTUndefined; //to stop the compiler from producing bogus warnings
+    }
+    
+    //sign extend
+    unsigned extensionlen = a_len-a0_len;
+    if(0 == extensionlen) {
+      UpdateSimplifyMap(a,output,false);
+      return a;
+    }
+
+    std::string ones;
+    for(unsigned c=0; c < extensionlen;c++)
+      ones += '1';			   
+    std::string zeros;
+    for(unsigned c=0; c < extensionlen;c++)
+      zeros += '0';
+			   
+    //string of oness of length extensionlen
+    BEEV::ASTNode BVOnes = CreateBVConst(ones.c_str(),2);
+    //string of zeros of length extensionlen
+    BEEV::ASTNode BVZeros = CreateBVConst(zeros.c_str(),2);
+			   
+    //string of ones BVCONCAT a0
+    BEEV::ASTNode concatOnes = CreateTerm(BEEV::BVCONCAT,a_len,BVOnes,a0);
+    //string of zeros BVCONCAT a0
+    BEEV::ASTNode concatZeros = CreateTerm(BEEV::BVCONCAT,a_len,BVZeros,a0);
+
+    //extract top bit of a0
+    BEEV::ASTNode hi = CreateBVConst(32,a0_len-1);
+    BEEV::ASTNode low = CreateBVConst(32,a0_len-1);
+    BEEV::ASTNode topBit = CreateTerm(BEEV::BVEXTRACT,1,a0,hi,low);
+
+    //compare topBit of a0 with 0bin1
+    BEEV::ASTNode condition = CreateSimplifiedEQ(CreateBVConst(1,1),topBit);
+
+    //ITE(topbit = 0bin1, 0bin1111...a0, 0bin000...a0)
+    output = CreateSimplifiedTermITE(condition,concatOnes,concatZeros);
+    UpdateSimplifyMap(a,output,false);
+    return output;
+  } //end of ConvertBVSXToITE()
+
+
+  ASTNode BeevMgr::RemoveWrites_TopLevel(const ASTNode& term) {
+    if(READ != term.GetKind() && WRITE != term[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
+    }
+    
+    if(!Begin_RemoveWrites && 
+       !SimplifyWrites_InPlace_Flag && 
+       !start_abstracting) {
+      return term;
+    }
+    else if(!Begin_RemoveWrites && 
+	    SimplifyWrites_InPlace_Flag && 
+	    !start_abstracting) {
+      //return term;
+      return SimplifyWrites_InPlace(term);
+    }
+    else {
+      return RemoveWrites(term);
+    }
+  } //end of RemoveWrites_TopLevel()
+
+  ASTNode BeevMgr::SimplifyWrites_InPlace(const ASTNode& term) {
+    ASTNodeMultiSet WriteIndicesSeenSoFar;
+    bool SeenNonConstWriteIndex = false;
+
+    if(READ != term.GetKind() && 
+	WRITE != term[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
+    }
+    
+    ASTNode output;
+    if(CheckSimplifyMap(term,output,false)) {
+      return output;
+    }
+
+    ASTVec writeIndices, writeValues;
+    unsigned int width = term.GetValueWidth();
+    ASTNode write = term[0];
+    unsigned indexwidth = write.GetIndexWidth();
+    ASTNode readIndex = SimplifyTerm(term[1]);
+        
+    do {
+      ASTNode writeIndex = SimplifyTerm(write[1]);
+      ASTNode writeVal = SimplifyTerm(write[2]);
+          
+      //compare the readIndex and the current writeIndex and see if they
+      //simplify to TRUE or FALSE or UNDETERMINABLE at this stage
+      ASTNode compare_readwrite_indices = 
+	SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
+    
+      //if readIndex and writeIndex are equal
+      if(ASTTrue == compare_readwrite_indices && !SeenNonConstWriteIndex) {
+	UpdateSimplifyMap(term,writeVal,false);
+	return writeVal;
+      }
+
+      if(!(ASTTrue == compare_readwrite_indices || 
+	   ASTFalse == compare_readwrite_indices)) {
+	SeenNonConstWriteIndex = true;
+      }
+
+      //if (readIndex=writeIndex <=> FALSE)
+      if(ASTFalse == compare_readwrite_indices 
+	 ||
+	 (WriteIndicesSeenSoFar.find(writeIndex) != WriteIndicesSeenSoFar.end())
+	 ) {
+	//drop the current level write
+	//do nothing
+      }
+      else {
+	writeIndices.push_back(writeIndex);
+	writeValues.push_back(writeVal);
+      }
+      
+      //record the write indices seen so far
+      //if(BVCONST == writeIndex.GetKind()) {
+	WriteIndicesSeenSoFar.insert(writeIndex);
+	//}
+
+      //Setup the write for the new iteration, one level inner write
+      write = write[0];
+    }while (SYMBOL != write.GetKind());
+
+    ASTVec::reverse_iterator it_index = writeIndices.rbegin();
+    ASTVec::reverse_iterator itend_index = writeIndices.rend();
+    ASTVec::reverse_iterator it_values = writeValues.rbegin();
+    ASTVec::reverse_iterator itend_values = writeValues.rend();
+
+    //"write" must be a symbol at the control point before the
+    //begining of the "for loop"
+
+    for(;it_index!=itend_index;it_index++,it_values++) {
+      write = CreateTerm(WRITE,width,write,*it_index,*it_values);
+      write.SetIndexWidth(indexwidth);
+    }
+
+    output = CreateTerm(READ,width,write,readIndex);
+    UpdateSimplifyMap(term,output,false);
+    return output;
+  } //end of SimplifyWrites_In_Place() 
+
+  //accepts a read over a write and returns a term without the write
+  //READ(WRITE(A i val) j) <==> ITE(i=j,val,READ(A,j)). We use a memo
+  //table for this function called RemoveWritesMemoMap
+  ASTNode BeevMgr::RemoveWrites(const ASTNode& input) {   
+    //unsigned int width = input.GetValueWidth();
+    if(READ != input.GetKind() || WRITE != input[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",input);
+    }
+
+    ASTNodeMap::iterator it;
+    ASTNode output = input;
+    if(CheckSimplifyMap(input,output,false)) {
+      return output;
+    }
+        
+    if(!start_abstracting && Begin_RemoveWrites) {
+      output= ReadOverWrite_To_ITE(input);
+    }
+
+    if(start_abstracting) {
+      ASTNode newVar;
+      if(!CheckSimplifyMap(input,newVar,false)) {
+	newVar = NewVar(input.GetValueWidth());
+	ReadOverWrite_NewName_Map[input] = newVar;
+	NewName_ReadOverWrite_Map[newVar] = input;
+
+	UpdateSimplifyMap(input,newVar,false);
+	ASTNodeStats("New Var Name which replace Read_Over_Write: ", newVar);
+      }
+      output = newVar;
+    } //end of start_abstracting if condition
+
+    //memoize
+    UpdateSimplifyMap(input,output,false);
+    return output;
+  } //end of RemoveWrites()
+
+  ASTNode BeevMgr::ReadOverWrite_To_ITE(const ASTNode& term) {
+    unsigned int width = term.GetValueWidth();
+    ASTNode input = term;
+    if(READ != term.GetKind() || WRITE != term[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
+    }
+
+    ASTNodeMap::iterator it;
+    ASTNode output;
+    // if(CheckSimplifyMap(term,output,false)) {
+    //       return output;
+    //     }
+    
+    ASTNode partialITE = term;
+    ASTNode writeA = ASTTrue;
+    ASTNode oldRead = term;
+    //iteratively expand read-over-write
+    do {
+      ASTNode write = input[0];
+      ASTNode readIndex = SimplifyTerm(input[1]);
+      //DO NOT CALL SimplifyTerm() on write[0]. You will go into an
+      //infinite loop
+      writeA = write[0];
+      ASTNode writeIndex = SimplifyTerm(write[1]);
+      ASTNode writeVal = SimplifyTerm(write[2]);
+      
+      ASTNode cond = SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
+      ASTNode newRead = CreateTerm(READ,width,writeA,readIndex);
+      ASTNode newRead_memoized = newRead;
+      if(CheckSimplifyMap(newRead, newRead_memoized,false)) {
+	newRead = newRead_memoized;
+      }
+      
+      if(ASTTrue == cond && (term == partialITE)) {
+	//found the write-value in the first iteration itself. return
+	//it
+	output = writeVal;
+	UpdateSimplifyMap(term,output,false);
+	return output;
+      }
+      
+      if(READ == partialITE.GetKind() && WRITE == partialITE[0].GetKind()) {
+	//first iteration or (previous cond==ASTFALSE and partialITE is a "READ over WRITE")
+	partialITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
+      }
+      else if (ITE == partialITE.GetKind()){
+	//ITE(i1 = j, v1, R(A,j))
+	ASTNode ElseITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
+	//R(W(A,i1,v1),j) <==> ITE(i1 = j, v1, R(A,j))
+	UpdateSimplifyMap(oldRead,ElseITE,false);
+	//ITE(i2 = j, v2, R(W(A,i1,v1),j)) <==> ITE(i2 = j, v2, ITE(i1 = j, v1, R(A,j)))
+	partialITE = SimplifyTerm(partialITE);
+      }
+      else {
+	FatalError("RemoveWrites: Control should not reach here\n");
+      }
+      
+      if(ASTTrue == cond) {
+	//no more iterations required
+	output = partialITE;
+	UpdateSimplifyMap(term,output,false);
+	return output;
+      }
+      
+      input = newRead;
+      oldRead = newRead;
+    } while(READ == input.GetKind() && WRITE == input[0].GetKind());
+    
+    output = partialITE;
+    
+    //memoize
+    //UpdateSimplifyMap(term,output,false);
+    return output;
+  } //ReadOverWrite_To_ITE()
+
+  //compute the multiplicative inverse of the input
+  ASTNode BeevMgr::MultiplicativeInverse(const ASTNode& d) {
+    ASTNode c = d;
+    if(BVCONST != c.GetKind()) {
+      FatalError("Input must be a constant", c);
+    }
+
+    if(!BVConstIsOdd(c)) {
+      FatalError("MultiplicativeInverse: Input must be odd: ",c);
+    }
+    
+    //cerr << "input to multinverse function is: " << d << endl;
+    ASTNode inverse;
+    if(CheckMultInverseMap(d,inverse)) {
+      //cerr << "found the inverse of: " << d << "and it is: " << inverse << endl;
+      return inverse;
+    }
+
+    inverse = c;
+    unsigned inputwidth = c.GetValueWidth();
+
+#ifdef NATIVE_C_ARITH
+    ASTNode one = CreateOneConst(inputwidth);
+    while(c != one) {
+      //c = c*c
+      c = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,c,c));
+      //inverse = invsere*c
+      inverse = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,inverse,c));
+    }
+#else
+    //Compute the multiplicative inverse of c using the extended
+    //euclidian algorithm
+    //
+    //create a '0' which is 1 bit long
+    ASTNode onebit_zero = CreateZeroConst(1);
+    //zero pad t0, i.e. 0 @ t0
+    c = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,c));
+
+    //construct 2^(inputwidth), i.e. a bitvector of length
+    //'inputwidth+1', which is max(inputwidth)+1
+    //
+    //all 1's 
+    ASTNode max = CreateMaxConst(inputwidth);
+    //zero pad max
+    max = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,max));
+    //Create a '1' which has leading zeros of length 'inputwidth'
+    ASTNode inputwidthplusone_one = CreateOneConst(inputwidth+1);    
+    //add 1 to max
+    max = CreateTerm(BVPLUS,inputwidth+1,max,inputwidthplusone_one);
+    max = BVConstEvaluator(max);
+    
+    ASTNode zero = CreateZeroConst(inputwidth+1);
+    ASTNode max_bvgt_0 = CreateNode(BVGT,max,zero);
+    ASTNode quotient, remainder;
+    ASTNode x, x1, x2;
+
+    //x1 initialized to zero
+    x1 = zero;
+    //x2 initialized to one
+    x2 = CreateOneConst(inputwidth+1);
+    while (ASTTrue == BVConstEvaluator(max_bvgt_0)) {
+      //quotient = (c divided by max)
+      quotient = BVConstEvaluator(CreateTerm(BVDIV,inputwidth+1, c, max));
+
+      //remainder of (c divided by max)
+      remainder = BVConstEvaluator(CreateTerm(BVMOD,inputwidth+1, c, max));
+
+      //x = x2 - q*x1
+      x = CreateTerm(BVSUB,inputwidth+1,x2,CreateTerm(BVMULT,inputwidth+1,quotient,x1));
+      x = BVConstEvaluator(x);
+
+      //fix the inputs to the extended euclidian algo
+      c = max;
+      max = remainder;
+      max_bvgt_0 = CreateNode(BVGT,max,zero);
+      
+      x2 = x1;
+      x1 = x;
+    }
+    
+    ASTNode hi = CreateBVConst(32,inputwidth-1);
+    ASTNode low = CreateZeroConst(32);
+    inverse = CreateTerm(BVEXTRACT,inputwidth,x2,hi,low);
+    inverse = BVConstEvaluator(inverse);
+#endif
+
+    UpdateMultInverseMap(d,inverse);
+    //cerr << "output of multinverse function is: " << inverse << endl;
+    return inverse;
+  } //end of MultiplicativeInverse()
+
+  //returns true if the input is odd
+  bool BeevMgr::BVConstIsOdd(const ASTNode& c) {
+    if(BVCONST != c.GetKind()) {
+      FatalError("Input must be a constant", c);
+    }
+   
+    ASTNode zero = CreateZeroConst(1);
+    ASTNode hi = CreateZeroConst(32);
+    ASTNode low = hi;
+    ASTNode lowestbit = CreateTerm(BVEXTRACT,1,c,hi,low);
+    lowestbit =  BVConstEvaluator(lowestbit);
+
+    if(lowestbit == zero) {
+      return false;
+    }
+    else {
+      return true;
+    }
+  } //end of BVConstIsOdd()
+
+  //The big substitution function
+  ASTNode BeevMgr::CreateSubstitutionMap(const ASTNode& a){
+    if(!optimize)
+      return a;
+
+    ASTNode output = a;
+    //if the variable has been solved for, then simply return it
+    if(CheckSolverMap(a,output))
+      return output;
+
+    //traverse a and populate the SubstitutionMap 
+    Kind k = a.GetKind();
+    if(SYMBOL == k && BOOLEAN_TYPE == a.GetType()) {
+      bool updated = UpdateSubstitutionMap(a,ASTTrue);
+      output = updated ? ASTTrue : a;      
+      return output;          
+    }
+    if(NOT == k
+       && SYMBOL == a[0].GetKind()) {
+      bool updated = UpdateSubstitutionMap(a[0],ASTFalse);
+      output = updated ? ASTTrue : a;      
+      return output;          
+    }
+    
+    if(IFF == k) {
+      ASTVec c = a.GetChildren();
+      SortByExprNum(c);
+      if(SYMBOL != c[0].GetKind() || 
+    	 VarSeenInTerm(c[0],SimplifyFormula_NoRemoveWrites(c[1],false))) {
+	return a;
+      }
+      bool updated = UpdateSubstitutionMap(c[0],c[1]);
+      output = updated ? ASTTrue : a;      
+      return output;      
+    }
+    
+    if(EQ == k) {
+      //fill the arrayname readindices vector if e0 is a
+      //READ(Arr,index) and index is a BVCONST
+      ASTVec c = a.GetChildren();
+      SortByExprNum(c);
+      FillUp_ArrReadIndex_Vec(c[0],c[1]);
+
+      if(SYMBOL == c[0].GetKind() && 
+	 VarSeenInTerm(c[0],SimplifyTerm(c[1]))) {
+	return a;
+      }
+
+      if(1 == TermOrder(c[0],c[1]) &&
+	 READ == c[0].GetKind() &&
+	 VarSeenInTerm(c[0][0],SimplifyTerm(c[1]))) {
+	return a;
+      }
+      bool updated = UpdateSubstitutionMap(c[0],c[1]);      
+      output = updated ? ASTTrue : a;      
+      return output;      
+    }
+
+    if(AND == k){
+      ASTVec o;
+      ASTVec c = a.GetChildren();
+      for(ASTVec::iterator it = c.begin(),itend=c.end();it!=itend;it++) {
+	UpdateAlwaysTrueFormMap(*it);
+	ASTNode aaa = CreateSubstitutionMap(*it);
+	
+	if(ASTTrue != aaa) {
+	  if(ASTFalse == aaa)
+	    return ASTFalse;
+	  else
+	    o.push_back(aaa);
+	}
+      }
+      if(o.size() == 0)
+	return ASTTrue;
+
+      if(o.size() == 1)
+	return o[0];
+      
+      return CreateNode(AND,o);
+    }
+    return output;
+  } //end of CreateSubstitutionMap()
+
+
+  bool BeevMgr::VarSeenInTerm(const ASTNode& var, const ASTNode& term) {
+    if(READ == term.GetKind() && 
+       WRITE == term[0].GetKind() && !Begin_RemoveWrites) {
+      return false;
+    }
+
+    if(READ == term.GetKind() && 
+       WRITE == term[0].GetKind() && Begin_RemoveWrites) {
+      return true;
+    }
+
+    ASTNodeMap::iterator it;    
+    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
+      if(it->second == var) {
+	return false;
+      }
+    }
+
+    if(var == term) {
+      return true;
+    }
+
+    for(ASTVec::const_iterator it=term.begin(),itend=term.end();it!=itend;it++){
+      if(VarSeenInTerm(var,*it)) {
+	return true;
+      }
+      else {
+	TermsAlreadySeenMap[*it] = var;
+      }
+    }
+
+    TermsAlreadySeenMap[term] = var;
+    return false;
+  }
+};//end of namespace
diff --git a/test/CXX/ArrayNew.cpp b/test/CXX/ArrayNew.cpp
new file mode 100644
index 00000000..e6a41ddf
--- /dev/null
+++ b/test/CXX/ArrayNew.cpp
@@ -0,0 +1,38 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error --no-externals %t1.bc
+
+#include <cassert>
+
+static int decon = 0;
+
+class Test {
+  int x;
+
+public:
+  Test() {}
+  Test(int _x) : x(_x) { }
+  ~Test() { decon += x; }
+
+  int getX() { return x; }
+  void setX(int _x) { x = _x; }
+};
+
+int main(int argc) {
+  Test *rt = new Test[4];
+  int i;
+
+  for (i=0; i<4; i++)
+    rt[i].setX(i+1);
+
+  int sum = 0;
+  for (i=0; i<4; i++)
+    sum += rt[i].getX();
+  
+  assert(sum==10);
+
+  delete[] rt;
+
+  assert(decon==10);
+
+  return 0;
+}
diff --git a/test/CXX/New.cpp b/test/CXX/New.cpp
new file mode 100644
index 00000000..148dfed6
--- /dev/null
+++ b/test/CXX/New.cpp
@@ -0,0 +1,29 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error --no-externals %t1.bc
+
+#include <cassert>
+
+class Test {
+  int x;
+
+public:
+  Test(int _x) : x(_x) {
+  }
+  ~Test() {
+  }
+
+  int getX() { return x; }
+};
+
+// This doesn't do what I want because
+// it is being changed to alloca, but
+// it is also failing.
+int main(int argc) {
+  Test *rt = new Test(2);
+  
+  assert(rt->getX()==2);
+
+  delete rt;
+
+  return 0;
+}
diff --git a/test/CXX/SimpleVirtual.cpp b/test/CXX/SimpleVirtual.cpp
new file mode 100644
index 00000000..9dc2a0ac
--- /dev/null
+++ b/test/CXX/SimpleVirtual.cpp
@@ -0,0 +1,38 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error --no-externals %t1.bc
+
+#include <cassert>
+
+static int decon = 0;
+
+class Thing {
+public:
+  Thing() {}
+  virtual ~Thing() { decon += getX(); }
+
+  virtual int getX() { return 1; };
+};
+
+class Thing2 : public Thing {
+public:
+  virtual int getX() { return 2; };
+};
+
+Thing *getThing(bool which) { 
+  return which ? new Thing() : new Thing2();
+}
+
+int main(int argc) {
+  Thing *one = getThing(false);
+  Thing *two = getThing(true);
+
+  int x = one->getX() + two->getX();
+  assert(x==3);
+
+  delete two;
+  delete one;
+  
+  assert(decon==2);
+
+  return 0;
+}
diff --git a/test/CXX/StaticConstructor.cpp b/test/CXX/StaticConstructor.cpp
new file mode 100644
index 00000000..d4992ffe
--- /dev/null
+++ b/test/CXX/StaticConstructor.cpp
@@ -0,0 +1,25 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=klee --no-output --exit-on-error %t1.bc
+
+#include <cassert>
+
+// to make sure globals are initialized
+int aGlobal = 21;
+
+class Test {
+  int x;
+
+public:
+  Test() : x(aGlobal + 1) {}
+  ~Test() {}
+
+  int getX() { return x; }
+};
+
+Test t;
+
+int main() {
+  assert(t.getX()==22);
+
+  return 0;
+}
diff --git a/test/CXX/StaticDestructor.cpp b/test/CXX/StaticDestructor.cpp
new file mode 100644
index 00000000..7a765a8f
--- /dev/null
+++ b/test/CXX/StaticDestructor.cpp
@@ -0,0 +1,24 @@
+// don't optimize this, llvm likes to turn the *p into unreachable
+
+// RUN: %llvmgxx %s --emit-llvm -g -O0 -c -o %t1.bc
+// RUN: %klee --libc=klee --no-output %t1.bc 2> %t1.log
+// RUN: grep ":16: memory error" %t1.log
+
+#include <cassert>
+
+class Test {
+  int *p;
+
+public:
+  Test() : p(0) {}
+  ~Test() { 
+    assert(!p); 
+    assert(*p == 10); // crash here
+  }
+};
+
+Test t;
+
+int main() {
+  return 0;
+}
diff --git a/test/CXX/Trivial.cpp b/test/CXX/Trivial.cpp
new file mode 100644
index 00000000..b50e82b2
--- /dev/null
+++ b/test/CXX/Trivial.cpp
@@ -0,0 +1,22 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error %t1.bc
+
+#include <cassert>
+
+class Test {
+  int x;
+
+public:
+  Test(int _x) : x(_x) {}
+  ~Test() {}
+
+  int getX() { return x; }
+};
+
+int main() {
+  Test rt(2);
+  
+  assert(rt.getX()==2);
+
+  return 0;
+}
diff --git a/test/CXX/dg.exp b/test/CXX/dg.exp
new file mode 100644
index 00000000..879685ca
--- /dev/null
+++ b/test/CXX/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/test/Concrete/BitwiseOps.ll b/test/Concrete/BitwiseOps.ll
new file mode 100644
index 00000000..cf5e7e6b
--- /dev/null
+++ b/test/Concrete/BitwiseOps.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%a = or i32 12345678, 87654321
+	%b = and i32 %a, 87654321
+	%check = xor i32 %b, 87654321
+	%test = icmp eq i32 %check, 0
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/BoolReadWrite.ll b/test/Concrete/BoolReadWrite.ll
new file mode 100644
index 00000000..f37359f8
--- /dev/null
+++ b/test/Concrete/BoolReadWrite.ll
@@ -0,0 +1,13 @@
+declare void @print_i1(i1)
+
+define i32 @main() {
+        %mem = alloca i1
+        store i1 1, i1* %mem
+        %v = load i1* %mem
+        br i1 %v, label %ok, label %exit
+ok:
+	call void @print_i1(i1 %v)
+        br label %exit
+exit:
+	ret i32 0
+}
diff --git a/test/Concrete/Casts.ll b/test/Concrete/Casts.ll
new file mode 100755
index 00000000..1329a127
--- /dev/null
+++ b/test/Concrete/Casts.ll
@@ -0,0 +1,28 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 315904, 128
+	%b = trunc i32 %a to i8
+	%c0 = icmp eq i8 %b, 128
+	%d = zext i8 %b to i32
+	%c1 = icmp eq i32 %d, 128
+	%e = sext i8 %b to i32
+	%c2 = icmp eq i32 %e, -128
+	%c0i = zext i1 %c0 to i32
+	%c1i = zext i1 %c1 to i32
+	%c2i = zext i1 %c2 to i32
+	%c0is = shl i32 %c0i, 0
+	%c1is = shl i32 %c1i, 1
+	%c2is = shl i32 %c2i, 2
+	%tmp = add i32 %c0is, %c1is
+	%res = add i32 %tmp, %c2is
+	%p = icmp eq i32 %res, 7
+	br i1 %p, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/CmpEq.ll b/test/Concrete/CmpEq.ll
new file mode 100644
index 00000000..a8c2fe7a
--- /dev/null
+++ b/test/Concrete/CmpEq.ll
@@ -0,0 +1,14 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%a = add i8 0, 1
+	%b = add i8 %a, -1
+	%c = icmp eq i8 %b, 0
+	br i1 %c, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/ConcreteTest.py b/test/Concrete/ConcreteTest.py
new file mode 100755
index 00000000..758d0caa
--- /dev/null
+++ b/test/Concrete/ConcreteTest.py
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+
+import os
+import sys
+import popen2
+
+class TestError(Exception):
+    pass
+
+kLLIPath = '../../llvm/Debug/bin/lli'
+kKleePath = '../../Debug/bin/klee'
+
+def getFiles():
+    for name in os.listdir('.'):
+        if (name[0]!='.' and name[0]!='_' and
+            (name.endswith('.ll') or name.endswith('.c'))):
+            yield name
+
+def readFile(f):
+    s = ""
+    while 1:
+        data = f.read()
+        if not data:
+            break
+        s += data
+    return s
+
+def testFile(name, printOutput=False):
+    baseName,ext = os.path.splitext(name)
+    exeFile = 'Output/linked_%s.bc'%baseName
+    if printOutput:
+        redirectStderr = ''
+    else:
+        redirectStderr = '2> /dev/null'
+
+    if os.system('make %s > /dev/null %s'%(exeFile,redirectStderr)):
+        raise TestError('make failed')
+
+    if printOutput:
+        print '-- running lli --'
+    lli = popen2.Popen3('%s -force-interpreter=true %s %s'%(kLLIPath,exeFile,redirectStderr))
+    lliOut = readFile(lli.fromchild)
+    if lli.wait():
+        raise TestError('lli execution failed')
+
+    if printOutput:
+        print lliOut
+
+    if printOutput:
+        print '-- running klee --'
+    klee = popen2.Popen3('%s --no-output %s %s'%(kKleePath,exeFile,redirectStderr))
+    kleeOut = readFile(klee.fromchild)
+    if klee.wait():
+        raise TestError('klee execution failed')
+    if printOutput:
+        print kleeOut
+        
+    if lliOut!=kleeOut:
+        raise TestError('outputs differ')
+        
+def testOneFile(f, printOutput=False, log=None):
+    try:
+        testFile(f, printOutput)
+        code = ['pass','xpass'][f.startswith('broken')]
+        extra = ''
+    except TestError,e:
+        code = ['fail','xfail'][f.startswith('broken')]
+        extra = str(e)
+
+    print '%s: %s -- %s'%(code,f,extra)
+    if log:
+        print >>log,'%s: %s -- %s'%(code,f,extra)
+
+def test():
+    if not os.path.exists('Output'):
+        os.mkdir('Output')
+    log = open("Output/test.log","w")
+    files = list(getFiles())
+    files.sort(key = lambda n: n.lower())
+    for f in files:
+        testOneFile(f, log=log)
+    log.close()
+
+if __name__=='__main__':
+    args = sys.argv
+    args.pop(0)
+    
+    runAll = not args
+
+    while args:
+        arg = args.pop(0)
+        if arg=='--run':
+            testFile(args.pop(0), printOutput=True)
+        else:
+            raise ValueError,'invalid argument: %s'%arg
+
+    if runAll:
+        test()
+        
diff --git a/test/Concrete/ConstantExpr.ll b/test/Concrete/ConstantExpr.ll
new file mode 100644
index 00000000..2bc33a1e
--- /dev/null
+++ b/test/Concrete/ConstantExpr.ll
@@ -0,0 +1,166 @@
+@gInt = global i32 10
+@gIntWithConstant = global i32 sub(i32 ptrtoint(i32* @gInt to i32), 
+                                 i32 ptrtoint(i32* @gInt to i32))
+
+define void @"test_int_to_ptr"()
+begin
+  %t1 = add i8 ptrtoint(i8* inttoptr(i32 100 to i8*) to i8), 0
+  %t2 = add i32 ptrtoint(i32* inttoptr(i8 100 to i32*) to i32), 0
+  %t3 = add i32 ptrtoint(i32* inttoptr(i64 100 to i32*) to i32), 0
+  %t4 = add i64 ptrtoint(i8* inttoptr(i32 100 to i8*) to i64), 0
+
+  call void @print_i8(i8 %t1)
+  call void @print_i32(i32 %t2)
+  call void @print_i32(i32 %t3)
+  call void @print_i64(i64 %t4)
+    
+  ret void
+end
+
+define void @"test_constant_ops"()
+begin
+  %t1 = add i8 trunc(i64 add(i64 ptrtoint(i32* @gInt to i64), i64 -10) to i8), 10
+  %t2 = sub i64 sext(i32 ptrtoint(i32* @gInt to i32) to i64), ptrtoint(i32* @gInt to i64)
+  %t3 = sub i64 zext(i32 ptrtoint(i32* @gInt to i32) to i64), ptrtoint(i32* @gInt to i64)
+
+  %t4 = icmp eq i8 trunc(i64 ptrtoint(i32* @gInt to i64) to i8), %t1
+  %t5 = zext i1 %t4 to i8
+    
+  call void @print_i8(i8 %t5)
+  call void @print_i64(i64 %t2)
+  call void @print_i64(i64 %t3)
+  
+  ret void
+end
+
+define void @"test_logical_ops"()
+begin
+  %t1 = add i32 -10, and(i32 ptrtoint(i32* @gInt to i32), i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 -1))
+  %t2 = add i32 -10, or(i32 ptrtoint(i32* @gInt to i32), i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 -1))
+  %t3 = add i32 -10, xor(i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 1024),  i32 ptrtoint(i32* @gInt to i32))
+
+  call void @print_i32(i32 %t1)
+  call void @print_i32(i32 %t2)
+  call void @print_i32(i32 %t3)
+  
+  %t4 = shl i32 lshr(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  %t5 = shl i32 ashr(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  %t6 = lshr i32 shl(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  
+  %t7 = icmp eq i32 %t4, %t5     
+  %t8 = icmp ne i32 %t4, %t6     
+  
+  %t9 = zext i1 %t7 to i8
+  %t10 = zext i1 %t8 to i8
+  
+  call void @print_i8(i8 %t9)
+  call void @print_i8(i8 %t10)
+  
+  ret void   
+end
+
+%test.struct.type = type { i32, i32 }
+@test_struct = global %test.struct.type { i32 0, i32 10 }
+
+define void @"test_misc"()
+begin
+  ; probability that @gInt == 100 is very very low 
+  %t1 = add i32 select(i1 icmp eq (i32* @gInt, i32* inttoptr(i32 100 to i32*)), i32 10, i32 0), 0
+  call void @print_i32(i32 %t1)
+
+  %t2 = load i32* getelementptr(%test.struct.type* @test_struct, i32 0, i32 1)
+  call void @print_i32(i32 %t2)                             
+        
+  ret void
+end
+
+define void @"test_simple_arith"()
+begin
+  %t1 = add i32 add(i32 ptrtoint(i32* @gInt to i32), i32 0), 0
+  %t2 = add i32 sub(i32 0, i32 ptrtoint(i32* @gInt to i32)), %t1
+  %t3 = mul i32 mul(i32 ptrtoint(i32* @gInt to i32), i32 10), %t2
+
+  call void @print_i32(i32 %t3)
+
+  ret void     
+end
+
+define void @"test_div_and_mod"()
+begin
+  %t1 = add i32 udiv(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t2 = add i32 urem(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t3 = add i32 sdiv(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t4 = add i32 srem(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+
+  %p = ptrtoint i32* @gInt to i32
+
+  %i1 = udiv i32 %p, 13
+  %i2 = urem i32 %p, 13
+  %i3 = sdiv i32 %p, 13
+  %i4 = srem i32 %p, 13
+
+  %x1 = sub i32 %t1, %i1
+  %x2 = sub i32 %t2, %i2
+  %x3 = sub i32 %t3, %i3
+  %x4 = sub i32 %t4, %i4
+
+  call void @print_i32(i32 %x1)
+  call void @print_i32(i32 %x2)
+  call void @print_i32(i32 %x3)
+  call void @print_i32(i32 %x4)
+
+  ret void     
+end
+        
+define void @test_cmp()
+begin
+  %t1 = add i8 zext(i1 icmp ult (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t2 = add i8 zext(i1 icmp ule (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t3 = add i8 zext(i1 icmp uge (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t4 = add i8 zext(i1 icmp ugt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t5 = add i8 zext(i1 icmp slt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t6 = add i8 zext(i1 icmp sle (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t7 = add i8 zext(i1 icmp sge (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t8 = add i8 zext(i1 icmp sgt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t9 = add i8 zext(i1 icmp eq (i32 ptrtoint(i32* @gInt to i32), i32 10) to i8), 1
+  %t10 = add i8 zext(i1 icmp ne (i32 ptrtoint(i32* @gInt to i32), i32 10) to i8), 1
+
+  call void @print_i1(i8 %t1)
+  call void @print_i1(i8 %t2)
+  call void @print_i1(i8 %t3)
+  call void @print_i1(i8 %t4)
+  call void @print_i1(i8 %t5)
+  call void @print_i1(i8 %t6)
+  call void @print_i1(i8 %t7)
+  call void @print_i1(i8 %t8)
+  call void @print_i1(i8 %t9)
+  call void @print_i1(i8 %t10)
+
+  ret void
+end
+
+define i32 @main()
+begin
+    call void @test_simple_arith()
+
+    call void @test_div_and_mod()
+
+    call void @test_cmp()
+ 
+    call void @test_int_to_ptr()
+
+    call void @test_constant_ops()
+
+    call void @test_logical_ops()
+
+    call void @test_misc()
+    
+    ret i32 0
+end
+
+; defined in print_int.c
+declare void @print_i1(i8)
+declare void @print_i8(i8)
+declare void @print_i16(i16)
+declare void @print_i32(i32)
+declare void @print_i64(i64)
diff --git a/test/Concrete/FloatingPointOps.ll b/test/Concrete/FloatingPointOps.ll
new file mode 100644
index 00000000..7f23dcef
--- /dev/null
+++ b/test/Concrete/FloatingPointOps.ll
@@ -0,0 +1,685 @@
+%struct.stdout = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct.stdout*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i32, i32, [40 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct.stdout*, i32 }
+@stdout = external global %struct.stdout*
+
+; casting error messages
+@.strTrunc     = internal constant [15 x i8] c"FPTrunc broken\00"
+@.strExt       = internal constant [13 x i8] c"FPExt broken\00"
+@.strFPToUIFlt = internal constant [20 x i8] c"FPToUI float broken\00"
+@.strFPToUIDbl = internal constant [21 x i8] c"FPToUI double broken\00"
+@.strFPToSIFlt = internal constant [20 x i8] c"FPToSI float broken\00"
+@.strFPToSIDbl = internal constant [21 x i8] c"FPToSI double broken\00"
+@.strUIToFPFlt = internal constant [20 x i8] c"UIToFP float broken\00"
+@.strUIToFPDbl = internal constant [21 x i8] c"UIToFP double broken\00"
+@.strSIToFPFlt = internal constant [20 x i8] c"SIToFP float broken\00"
+@.strSIToFPDbl = internal constant [21 x i8] c"SIToFP double broken\00"
+
+; mathematical operator error messages
+@.strDivFlt    = internal constant [18 x i8] c"FDiv float broken\00"
+@.strDivDbl    = internal constant [19 x i8] c"FDiv double broken\00"
+@.strRemFlt    = internal constant [18 x i8] c"FRem float broken\00"
+@.strRemDbl    = internal constant [19 x i8] c"FRem double broken\00"
+@.strAddInt    = internal constant [16 x i8] c"Add ints broken\00"
+@.strAddFlt    = internal constant [18 x i8] c"Add floats broken\00"
+@.strAddDbl    = internal constant [19 x i8] c"Add doubles broken\00"
+@.strSubInt    = internal constant [16 x i8] c"Sub ints broken\00"
+@.strSubFlt    = internal constant [18 x i8] c"Sub floats broken\00"
+@.strSubDbl    = internal constant [19 x i8] c"Sub doubles broken\00"
+@.strMulInt    = internal constant [16 x i8] c"Mul ints broken\00"
+@.strMulFlt    = internal constant [18 x i8] c"Mul floats broken\00"
+@.strMulDbl    = internal constant [19 x i8] c"Mul doubles broken\00"
+
+; fcmp error messages
+@.strCmpTrFlt  = internal constant [19 x i8] c"floats TRUE broken\00" ; fcmp::generic broken msgs
+@.strCmpFaFlt  = internal constant [20 x i8] c"floats FALSE broken\00"
+@.strCmpTrDbl  = internal constant [19 x i8] c"double TRUE broken\00"
+@.strCmpFaDbl  = internal constant [20 x i8] c"double FALSE broken\00"
+@.strCmpEqFlt  = internal constant [17 x i8] c"floats == broken\00" ; fcmp::ordered broken msgs
+@.strCmpGeFlt  = internal constant [17 x i8] c"floats >= broken\00"
+@.strCmpGtFlt  = internal constant [17 x i8] c"floats >  broken\00"
+@.strCmpLeFlt  = internal constant [17 x i8] c"floats <= broken\00"
+@.strCmpLtFlt  = internal constant [17 x i8] c"floats <  broken\00"
+@.strCmpNeFlt  = internal constant [17 x i8] c"floats != broken\00"
+@.strCmpOrdFlt = internal constant [18 x i8] c"floats ORD broken\00"
+@.strCmpEqDbl  = internal constant [18 x i8] c"doubles == broken\00"
+@.strCmpGeDbl  = internal constant [18 x i8] c"doubles >= broken\00"
+@.strCmpGtDbl  = internal constant [18 x i8] c"doubles >  broken\00"
+@.strCmpLeDbl  = internal constant [18 x i8] c"doubles <= broken\00"
+@.strCmpLtDbl  = internal constant [18 x i8] c"doubles <  broken\00"
+@.strCmpNeDbl  = internal constant [18 x i8] c"doubles != broken\00"
+@.strCmpOrdDbl = internal constant [19 x i8] c"doubles ORD broken\00"
+@.strCmpEqFltU = internal constant [17 x i8] c"U:floats==broken\00" ; fcmp::unordered broken msgs
+@.strCmpGeFltU = internal constant [17 x i8] c"U:floats>=broken\00"
+@.strCmpGtFltU = internal constant [17 x i8] c"U:floats> broken\00"
+@.strCmpLeFltU = internal constant [17 x i8] c"U:floats<=broken\00"
+@.strCmpLtFltU = internal constant [17 x i8] c"U:floats< broken\00"
+@.strCmpNeFltU = internal constant [17 x i8] c"U:floats!=broken\00"
+@.strCmpUnoFlt = internal constant [20 x i8] c"U:floats UNO broken\00"
+@.strCmpEqDblU = internal constant [18 x i8] c"U:doubles==broken\00"
+@.strCmpGeDblU = internal constant [18 x i8] c"U:doubles>=broken\00"
+@.strCmpGtDblU = internal constant [18 x i8] c"U:doubles> broken\00"
+@.strCmpLeDblU = internal constant [18 x i8] c"U:doubles<=broken\00"
+@.strCmpLtDblU = internal constant [18 x i8] c"U:doubles< broken\00"
+@.strCmpNeDblU = internal constant [18 x i8] c"U:doubles!=broken\00"
+@.strCmpUnoDbl = internal constant [21 x i8] c"U:doubles UNO broken\00"
+
+@.strWorks     = internal constant [20 x i8] c"Everything works!\0D\0A\00"
+@.strNL        = internal constant [3 x i8]  c"\0D\0A\00"
+
+declare i32 @fprintf(%struct.stdout*, i8*, ...)
+declare void @exit(i32)
+declare void @llvm.memcpy.i32(i8*, i8*, i32, i32)
+
+; if isOk is false, then print errMsg to stdout and exit(1)
+define void @failCheck(i1 %isOk, i8* %errMsg) {
+entry:
+  %fail = icmp eq i1 %isOk, 0
+  br i1 %fail, label %failed, label %return
+
+failed:
+  ; print the error msg
+  %err_stream = load %struct.stdout** @stdout
+  %ret = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %errMsg )
+
+  ; add a newline to the ostream
+  %nl = getelementptr [3 x i8]* @.strNL, i32 0, i32 0
+  %ret2 = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %nl )
+
+  ; exit with return value 1 to denote that an error occurred
+  call void @exit( i32 1 )
+  unreachable
+
+return:
+  ret void
+}
+
+; test FPTrunc which casts doubles to floats
+define void @testFPTrunc() {
+entry:
+  %d_addr = alloca double, align 8
+  store double 8.000000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %f = fptrunc double %d to float
+  %matches = fcmp oeq float %f, 8.000000e+00
+  %err_msg = getelementptr [15 x i8]* @.strTrunc, i32 0, i32 0
+  call void @failCheck( i1 %matches, i8* %err_msg )
+  ret void
+}
+
+; test FPExt which casts floats to doubles
+define void @testFPExt() {
+entry:
+  %f_addr = alloca float, align 4
+  store float 8.000000e+00, float* %f_addr
+  %f = load float* %f_addr
+  %d = fpext float %f to double
+  %matches = fcmp oeq double %d, 8.000000e+00
+  %err_msg = getelementptr [13 x i8]* @.strExt, i32 0, i32 0
+  call void @failCheck( i1 %matches, i8* %err_msg )
+  ret void
+}
+
+; test casting fp to an unsigned int
+define void @testFPToUI() {
+entry:
+  %f_addr = alloca float, align 4
+  %d_addr = alloca double, align 8
+
+  ; test float to UI
+  store float 0x4020333340000000, float* %f_addr; %f = 8.1
+  %f = load float* %f_addr
+  %uf = fptoui float %f to i32
+  %matchesf = icmp eq i32 %uf, 8
+  %err_msgf = getelementptr [20 x i8]* @.strFPToUIFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double to UI
+  store double 8.100000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %ud = fptoui double %d to i32
+  %matchesd = icmp eq i32 %ud, 8
+  %err_msgd = getelementptr [21 x i8]* @.strFPToUIDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting fp to a signed int
+define void @testFPToSI() {
+entry:
+  %f_addr = alloca float, align 4
+  %d_addr = alloca double, align 8
+
+  ; test float 8.1 to signed int
+  store float 0x4020333340000000, float* %f_addr
+  %f = load float* %f_addr
+  %sf = fptosi float %f to i32
+  %matchesf = icmp eq i32 %sf, 8
+  %err_msgf = getelementptr [20 x i8]* @.strFPToSIFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double -8.1 to signed int
+  store double -8.100000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %sd = fptosi double %d to i32
+  %matchesd = icmp eq i32 %sd, -8
+  %err_msgd = getelementptr [21 x i8]* @.strFPToSIDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting unsigned int to fp
+define void @testUIToFP() {
+entry:
+  ; unsigned int to float
+  %f = uitofp i32 7 to float
+  %matchesf = fcmp oeq float %f, 7.000000e+00
+  %err_msgf = getelementptr [20 x i8]* @.strUIToFPFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; unsigned int to double
+  %d = uitofp i32 7 to double
+  %matchesd = fcmp oeq double %d, 7.000000e+00
+  %err_msgd = getelementptr [21 x i8]* @.strUIToFPDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting signed int to fp
+define void @testSIToFP() {
+entry:
+  ; signed int to float
+  %f = sitofp i32 -7 to float
+  %matchesf = fcmp oeq float %f, -7.000000e+00
+  %err_msgf = getelementptr [20 x i8]* @.strSIToFPFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; signed int to double
+  %d = sitofp i32 -7 to double
+  %matchesd = fcmp oeq double %d, -7.000000e+00
+  %err_msgd = getelementptr [21 x i8]* @.strSIToFPDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; testing fp division
+define void @testFDiv() {
+entry:
+  %fN_addr = alloca float, align 4
+  %fD_addr = alloca float, align 4
+  %dN_addr = alloca double, align 8
+  %dD_addr = alloca double, align 8
+
+  ; float division
+  store float 2.200000e+01, float* %fN_addr
+  store float 4.000000e+00, float* %fD_addr
+  %fN = load float* %fN_addr
+  %fD = load float* %fD_addr
+  %f = fdiv float %fN, %fD
+  %matchesf = fcmp oeq float %f, 5.500000e+00
+  %err_msgf = getelementptr [18 x i8]* @.strDivFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; double division
+  store double 2.200000e+01, double* %dN_addr
+  store double -4.000000e+00, double* %dD_addr
+  %dN = load double* %dN_addr
+  %dD = load double* %dD_addr
+  %d = fdiv double %dN, %dD
+  %matchesd = fcmp oeq double %d, -5.500000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strDivDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; testing fp modulo
+define void @testFRem() {
+entry:
+  %fN_addr = alloca float, align 4
+  %fD_addr = alloca float, align 4
+  %dN_addr = alloca double, align 8
+  %dD_addr = alloca double, align 8
+
+  ; float modoulo
+  store float 2.200000e+01, float* %fN_addr
+  store float 4.000000e+00, float* %fD_addr
+  %fN = load float* %fN_addr
+  %fD = load float* %fD_addr
+  %f = frem float %fN, %fD
+  %matchesf = fcmp oeq float %f, 2.000000e+00
+  %err_msgf = getelementptr [18 x i8]* @.strRemFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; double modulo
+  store double -2.200000e+01, double* %dN_addr
+  store double 4.000000e+00, double* %dD_addr
+  %dN = load double* %dN_addr
+  %dD = load double* %dD_addr
+  %d = frem double %dN, %dD
+  %matchesd = fcmp oeq double %d, -2.000000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strRemDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test addition (fp and int since add is polymorphic)
+define void @testAdd() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer addition (3 + 4)
+  %sumi = add i32 3, 4
+  %matchesi = icmp eq i32 %sumi, 7
+  %err_msgi = getelementptr [16 x i8]* @.strAddInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float addition (3.5 + 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %sumf = add float %f1, %f2
+  %matchesf = fcmp oeq float %sumf, 0x401ECCCCC0000000
+  %err_msgf = getelementptr [18 x i8]* @.strAddFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double addition (3.5 + -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %sumd = add double %d1, %d2
+  %matchesd = fcmp oeq double %sumd, 0xBFE6666666666668
+  %err_msgd = getelementptr [19 x i8]* @.strAddDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test subtraction (fp and int since sub is polymorphic)
+define void @testSub() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer subtraction (3 - 4)
+  %subi = sub i32 3, 4
+  %matchesi = icmp eq i32 %subi, -1
+  %err_msgi = getelementptr [16 x i8]* @.strSubInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float subtraction (3.5 - 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %subf = sub float %f1, %f2
+  %matchesf = fcmp oeq float %subf, 0xBFE6666600000000
+  %err_msgf = getelementptr [18 x i8]* @.strSubFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double subtraction (3.5 - -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %subd = sub double %d1, %d2
+  %matchesd = fcmp oeq double %subd, 7.700000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strSubDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test multiplication (fp and int since mul is polymorphic)
+define void @testMul() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer multiplication (3 * 4)
+  %muli = mul i32 3, 4
+  %matchesi = icmp eq i32 %muli, 12
+  %err_msgi = getelementptr [16 x i8]* @.strMulInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float multiplication (3.5 * 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %mulf = mul float %f1, %f2
+  %matchesf = fcmp oeq float %mulf, 0x402D666640000000
+  %err_msgf = getelementptr [18 x i8]* @.strMulFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double multiplication (3.5 * -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %muld = mul double %d1, %d2
+  %matchesd = fcmp oeq double %muld, 0xC02D666666666667
+  %err_msgd = getelementptr [19 x i8]* @.strMulDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test float comparisons (ordered)
+define void @testFCmpFOrdered(float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  ; test fcmp::true -- should always return true
+  %cmp_t    = fcmp true float %f1, %f2
+  %cmp_t_ok = icmp eq i1 %cmp_t, 1
+  %cmp_t_em = getelementptr [19 x i8]* @.strCmpTrFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_t_ok, i8* %cmp_t_em )
+
+  ; test fcmp::false -- should always return false
+  %cmp_f    = fcmp false float %f1, %f2
+  %cmp_f_ok = icmp eq i1 %cmp_f, 0
+  %cmp_f_em = getelementptr [20 x i8]* @.strCmpFaFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_f_ok, i8* %cmp_f_em )
+
+  ; test fcmp::ord -- should return true if neither operand is NaN
+  %cmp_o    = fcmp ord float %f1, %f2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %ord
+  %cmp_o_em = getelementptr [18 x i8]* @.strCmpOrdFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if neither operand is a NaN and they are equal
+  %cmp_eq    = fcmp oeq float %f1, %f2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [17 x i8]* @.strCmpEqFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if neither operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp oge float %f1, %f2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [17 x i8]* @.strCmpGeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if neither operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ogt float %f1, %f2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [17 x i8]* @.strCmpGtFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if neither operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ole float %f1, %f2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [17 x i8]* @.strCmpLeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if neither operand is a NaN and the first is less
+  %cmp_lt    = fcmp olt float %f1, %f2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [17 x i8]* @.strCmpLtFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if neither operand is a NaN and they are not equal
+  %cmp_ne    = fcmp one float %f1, %f2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [17 x i8]* @.strCmpNeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test double comparisons (ordered)
+define void @testFCmpDOrdered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  ; test fcmp::true -- should always return true
+  %cmp_t    = fcmp true double %d1, %d2
+  %cmp_t_ok = icmp eq i1 %cmp_t, 1
+  %cmp_t_em = getelementptr [19 x i8]* @.strCmpTrDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_t_ok, i8* %cmp_t_em )
+
+  ; test fcmp::false -- should always return false
+  %cmp_f    = fcmp false double %d1, %d2
+  %cmp_f_ok = icmp eq i1 %cmp_f, 0
+  %cmp_f_em = getelementptr [20 x i8]* @.strCmpFaDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_f_ok, i8* %cmp_f_em )
+
+  ; test fcmp::ord -- should return true if neither operand is NaN
+  %cmp_o    = fcmp ord double %d1, %d2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %ord
+  %cmp_o_em = getelementptr [19 x i8]* @.strCmpOrdDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if neither operand is a NaN and they are equal
+  %cmp_eq    = fcmp oeq double %d1, %d2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [18 x i8]* @.strCmpEqDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if neither operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp oge double %d1, %d2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [18 x i8]* @.strCmpGeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if neither operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ogt double %d1, %d2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [18 x i8]* @.strCmpGtDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if neither operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ole double %d1, %d2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [18 x i8]* @.strCmpLeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if neither operand is a NaN and the first is less
+  %cmp_lt    = fcmp olt double %d1, %d2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [18 x i8]* @.strCmpLtDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if neither operand is a NaN and they are not equal
+  %cmp_ne    = fcmp one double %d1, %d2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [18 x i8]* @.strCmpNeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test floating point comparisons (ordered)
+define void @testFCmpBothOrdered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  call void @testFCmpDOrdered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+
+  %f1 = fptrunc double %d1 to float
+  %f2 = fptrunc double %d2 to float
+  call void @testFCmpFOrdered( float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+
+  ret void
+}
+
+; test float comparisons (unordered)
+define void @testFCmpFUnordered(float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  ; test fcmp::uno -- should return true if either operand is NaN
+  %cmp_o    = fcmp uno float %f1, %f2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %uno
+  %cmp_o_em = getelementptr [20 x i8]* @.strCmpUnoFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if either operand is a NaN and they are equal
+  %cmp_eq    = fcmp ueq float %f1, %f2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [17 x i8]* @.strCmpEqFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if either operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp uge float %f1, %f2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [17 x i8]* @.strCmpGeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if either operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ugt float %f1, %f2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [17 x i8]* @.strCmpGtFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if either operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ule float %f1, %f2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [17 x i8]* @.strCmpLeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if either operand is a NaN and the first is less
+  %cmp_lt    = fcmp ult float %f1, %f2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [17 x i8]* @.strCmpLtFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if either operand is a NaN and they are not equal
+  %cmp_ne    = fcmp une float %f1, %f2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [17 x i8]* @.strCmpNeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test double comparisons (unordered)
+define void @testFCmpDUnordered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  ; test fcmp::uno -- should return true if either operand is NaN
+  %cmp_o    = fcmp uno double %d1, %d2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %uno
+  %cmp_o_em = getelementptr [21 x i8]* @.strCmpUnoDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::ueq -- should return true if either operand is a NaN and they are equal
+  %cmp_eq    = fcmp ueq double %d1, %d2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [18 x i8]* @.strCmpEqDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::uge -- should return true if either operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp uge double %d1, %d2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [18 x i8]* @.strCmpGeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ugt -- should return true if either operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ugt double %d1, %d2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [18 x i8]* @.strCmpGtDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ule -- should return true if either operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ule double %d1, %d2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [18 x i8]* @.strCmpLeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::ult -- should return true if either operand is a NaN and the first is less
+  %cmp_lt    = fcmp ult double %d1, %d2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [18 x i8]* @.strCmpLtDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::une -- should return true if either operand is a NaN and they are not equal
+  %cmp_ne    = fcmp une double %d1, %d2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [18 x i8]* @.strCmpNeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test floating point comparisons (unordered)
+define void @testFCmpBothUnordered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  call void @testFCmpDUnordered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  %f1 = fptrunc double %d1 to float
+  %f2 = fptrunc double %d2 to float
+  call void @testFCmpFUnordered( float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  ret void
+}
+
+; test floating point comparisons (ordered and unordered)
+define void @testFCmpBoth(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord, i1 %uno) {
+entry:
+  call void @testFCmpBothOrdered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+  call void @testFCmpBothUnordered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  ret void
+}
+
+; test floating point comparisons (ordered and unordered) with a variety of real numbers and NaNs as operands
+define void @testFCmp() {
+entry:
+  %x = alloca i64, align 8
+  %nan = alloca double, align 8
+
+  ; test FCmp on some real number inputs
+  call void @testFCmpBoth( double 0.000000e+00, double 0.000000e+00, i1 1, i1 1, i1 0, i1 1, i1 0, i1 0, i1 1, i1 0 )
+  call void @testFCmpBoth( double 0.000000e+00, double 1.000000e+00, i1 0, i1 0, i1 0, i1 1, i1 1, i1 1, i1 1, i1 0 )
+  call void @testFCmpBoth( double 1.000000e+00, double 0.000000e+00, i1 0, i1 1, i1 1, i1 0, i1 0, i1 1, i1 1, i1 0 )
+
+  ; build NaN
+  store i64 -1, i64* %x
+  %nan_as_i8 = bitcast double* %nan to i8*
+  %x_as_i8 = bitcast i64* %x to i8*
+  call void @llvm.memcpy.i32( i8* %nan_as_i8, i8* %x_as_i8, i32 8, i32 8 )
+
+  ; load two copies of our NaN
+  %nan1 = load double* %nan
+  %nan2 = load double* %nan
+
+  ; Warning: NaN comparisons with normal operators is BROKEN in LLVM JIT v2.0.  Fixed in v2.1.
+  ; NaNs do different things depending on ordered vs unordered
+;  call void @testFCmpBothOrdered( double %nan1, double 0.000000e+00, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0 )
+;  call void @testFCmpBothOrdered( double %nan1, double %nan2, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0 )
+;  call void @testFCmpBothUnordered( double %nan1, double 0.000000e+00, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1 )
+;  call void @testFCmpBothUnordered( double %nan1, double %nan2, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1 )
+
+  ret void
+}
+
+; tes all floating point instructions
+define i32 @main() {
+entry:
+  call void @testFPTrunc( )
+  call void @testFPExt( )
+  call void @testFPToUI( )
+  call void @testFPToSI( )
+  call void @testUIToFP( )
+  call void @testSIToFP( )
+
+  call void @testFDiv( )
+  call void @testFRem( )
+  call void @testAdd( )
+  call void @testSub( )
+  call void @testMul( )
+
+  call void @testFCmp( )
+
+  ; everything worked -- print a message saying so
+  %works_msg = getelementptr [20 x i8]* @.strWorks, i32 0, i32 0
+  %err_stream = load %struct.stdout** @stdout
+  %ret = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %works_msg )
+
+  ret i32 0
+}
diff --git a/test/Concrete/GlobalInitializers.ll b/test/Concrete/GlobalInitializers.ll
new file mode 100755
index 00000000..b4d95de6
--- /dev/null
+++ b/test/Concrete/GlobalInitializers.ll
@@ -0,0 +1,47 @@
+; (cd .. && make) && ../llvm/Release/bin/llvm-as test.ll -o=- | ../Debug/bin/klee 
+
+declare void @print_i32(i32)
+
+%simple = type { i8, i16, i32, i64 }
+@gInt = global i32 2
+@gInts = global [2 x i32] [ i32 3, i32 5 ]
+@gStruct = global %simple { i8 7, i16 11, i32 13, i64 17 }
+@gZero = global %simple zeroinitializer
+
+define i32 @main() {
+entry:
+	%addr0 = getelementptr i32* @gInt, i32 0
+	%addr1 = getelementptr [2 x i32]* @gInts, i32 0, i32 0
+	%addr2 = getelementptr [2 x i32]* @gInts, i32 0, i32 1
+	%addr3 = getelementptr %simple* @gStruct, i32 0, i32 0
+	%addr4 = getelementptr %simple* @gStruct, i32 0, i32 1
+	%addr5 = getelementptr %simple* @gStruct, i32 0, i32 2
+	%addr6 = getelementptr %simple* @gStruct, i32 0, i32 3
+	%addr7 = getelementptr %simple* @gZero, i32 0, i32 2
+	%contents0 = load i32* %addr0
+	%contents1 = load i32* %addr1
+	%contents2 = load i32* %addr2
+	%contents3tmp = load i8* %addr3
+	%contents3 = zext i8 %contents3tmp to i32
+	%contents4tmp = load i16* %addr4
+	%contents4 = zext i16 %contents4tmp to i32
+	%contents5 = load i32* %addr5
+	%contents6tmp = load i64* %addr6
+	%contents6 = trunc i64 %contents6tmp to i32
+	%contents7 = load i32* %addr7
+	%tmp0 = mul i32 %contents0, %contents1
+	%tmp1 = mul i32 %tmp0, %contents2
+	%tmp2 = mul i32 %tmp1, %contents3
+	%tmp3 = mul i32 %tmp2, %contents4
+	%tmp4 = mul i32 %tmp3, %contents5
+	%tmp5 = mul i32 %tmp4, %contents6
+	%tmp6 = add i32 %tmp5, %contents7
+	%p = icmp eq i32 %tmp5, 510510
+	br i1 %p, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/GlobalVariable.ll b/test/Concrete/GlobalVariable.ll
new file mode 100644
index 00000000..d15df064
--- /dev/null
+++ b/test/Concrete/GlobalVariable.ll
@@ -0,0 +1,9 @@
+declare void @print_i32(i32)
+
+@anInt = global i32 1
+@aRef = global i32* @anInt
+
+define i32 @main() {
+        call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/ICmp.ll b/test/Concrete/ICmp.ll
new file mode 100644
index 00000000..e2a1ef24
--- /dev/null
+++ b/test/Concrete/ICmp.ll
@@ -0,0 +1,245 @@
+declare void @print_i32(i32)
+
+define i1 @checkSlt() {
+	%c0 = icmp slt i8 -1, 1		; 1
+	%c1 = icmp slt i8 0, 1		; 1
+	%c2 = icmp slt i8 1, 1		; 0
+	%c3 = icmp slt i8 1, -1		; 0
+	%c4 = icmp slt i8 1, 0		; 0
+	%c5 = icmp slt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 3	; 0bin000011
+	ret i1 %test
+}
+
+define i1 @checkSle() {
+	%c0 = icmp sle i8 -1, 1		; 1
+	%c1 = icmp sle i8 0, 1		; 1
+	%c2 = icmp sle i8 1, 1		; 1
+	%c3 = icmp sle i8 1, -1		; 0
+	%c4 = icmp sle i8 1, 0		; 0
+	%c5 = icmp sle i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 39	; 0bin100111
+	ret i1 %test
+}
+
+define i1 @checkSgt() {
+	%c0 = icmp sgt i8 -1, 1		; 0
+	%c1 = icmp sgt i8 0, 1		; 0
+	%c2 = icmp sgt i8 1, 1		; 0
+	%c3 = icmp sgt i8 1, -1		; 1
+	%c4 = icmp sgt i8 1, 0		; 1
+	%c5 = icmp sgt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 24	; 0bin011000
+	ret i1 %test
+}
+
+define i1 @checkSge() {
+	%c0 = icmp sge i8 -1, 1		; 0
+	%c1 = icmp sge i8 0, 1		; 0
+	%c2 = icmp sge i8 1, 1		; 1
+	%c3 = icmp sge i8 1, -1		; 1
+	%c4 = icmp sge i8 1, 0		; 1
+	%c5 = icmp sge i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 60	; 0bin111100
+	ret i1 %test
+}
+
+define i1 @checkUlt() {
+	%c0 = icmp ult i8 -1, 1		; 0
+	%c1 = icmp ult i8 0, 1		; 1
+	%c2 = icmp ult i8 1, 1		; 0
+	%c3 = icmp ult i8 1, -1		; 1
+	%c4 = icmp ult i8 1, 0		; 0
+	%c5 = icmp ult i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 10	; 0bin001010
+	ret i1 %test
+}
+
+define i1 @checkUle() {
+	%c0 = icmp ule i8 -1, 1		; 0
+	%c1 = icmp ule i8 0, 1		; 1
+	%c2 = icmp ule i8 1, 1		; 1
+	%c3 = icmp ule i8 1, -1		; 1
+	%c4 = icmp ule i8 1, 0		; 0
+	%c5 = icmp ule i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 46	; 0bin101110
+	ret i1 %test
+}
+
+define i1 @checkUgt() {
+	%c0 = icmp ugt i8 -1, 1		; 1
+	%c1 = icmp ugt i8 0, 1		; 0
+	%c2 = icmp ugt i8 1, 1		; 0
+	%c3 = icmp ugt i8 1, -1		; 0
+	%c4 = icmp ugt i8 1, 0		; 1
+	%c5 = icmp ugt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 17	; 0bin010001
+	ret i1 %test
+}
+
+define i1 @checkUge() {
+	%c0 = icmp uge i8 -1, 1		; 1
+	%c1 = icmp uge i8 0, 1		; 0
+	%c2 = icmp uge i8 1, 1		; 1
+	%c3 = icmp uge i8 1, -1		; 0
+	%c4 = icmp uge i8 1, 0		; 1
+	%c5 = icmp uge i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 53	; 0bin110101
+	ret i1 %test
+}
+
+define i1 @checkEq() {
+	%c0 = icmp eq i8 -1, 1		; 0
+	%c1 = icmp eq i8 1, 1		; 1
+	%c2 = icmp eq i8 1, -1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum = add i8 %sum0, %a2
+	%test = icmp eq i8 %sum, 2
+	ret i1 %test
+}
+
+define i1 @checkNe() {
+	%c0 = icmp ne i8 -1, 1		; 1
+	%c1 = icmp ne i8 1, 1		; 0
+	%c2 = icmp ne i8 1, -1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum = add i8 %sum0, %a2
+	%test = icmp eq i8 %sum, 5
+	ret i1 %test
+}
+
+define i32 @main() {
+	%c0 = call i1 @checkSlt ()
+	%c1 = call i1 @checkSle ()
+	%c2 = call i1 @checkSgt ()
+	%c3 = call i1 @checkSge ()
+	%c4 = call i1 @checkUlt ()
+	%c5 = call i1 @checkUle ()
+	%c6 = call i1 @checkUgt ()
+	%c7 = call i1 @checkUge ()
+	%c8 = call i1 @checkEq ()
+	%c9 = call i1 @checkNe ()
+	%a0 = select i1 %c0, i16 1, i16 0
+	%a1 = select i1 %c1, i16 2, i16 0
+	%a2 = select i1 %c2, i16 4, i16 0
+	%a3 = select i1 %c3, i16 8, i16 0
+	%a4 = select i1 %c4, i16 16, i16 0
+	%a5 = select i1 %c5, i16 32, i16 0
+	%a6 = select i1 %c6, i16 64, i16 0
+	%a7 = select i1 %c7, i16 128, i16 0
+	%a8 = select i1 %c8, i16 256, i16 0
+	%a9 = select i1 %c9, i16 512, i16 0
+	%sum0 = add i16 %a0, %a1
+	%sum1 = add i16 %sum0, %a2
+	%sum2 = add i16 %sum1, %a3
+	%sum3 = add i16 %sum2, %a4
+	%sum4 = add i16 %sum3, %a5
+	%sum5 = add i16 %sum4, %a6
+	%sum6 = add i16 %sum5, %a7
+	%sum7 = add i16 %sum6, %a8
+	%sum8 = add i16 %sum7, %a9
+	%t = shl i16 63, 10
+	%sum = add i16 %sum8, %t
+	%test = icmp eq i16 %sum, -1
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/InvokeAndReturn.ll b/test/Concrete/InvokeAndReturn.ll
new file mode 100644
index 00000000..f73c242a
--- /dev/null
+++ b/test/Concrete/InvokeAndReturn.ll
@@ -0,0 +1,18 @@
+declare void @print_i32(i32)
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = add i8 %a, %b
+	ret i8 %c
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/InvokeAndUnwindOnce.ll b/test/Concrete/InvokeAndUnwindOnce.ll
new file mode 100644
index 00000000..2834ec82
--- /dev/null
+++ b/test/Concrete/InvokeAndUnwindOnce.ll
@@ -0,0 +1,18 @@
+declare void @print_i32(i32)
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = add i8 %a, %b
+	unwind
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/InvokeAndUnwindTwice.ll b/test/Concrete/InvokeAndUnwindTwice.ll
new file mode 100644
index 00000000..81760b86
--- /dev/null
+++ b/test/Concrete/InvokeAndUnwindTwice.ll
@@ -0,0 +1,22 @@
+declare void @print_i32(i32)
+
+define i8 @myadd(i8 %a, i8 %b) {
+	unwind
+}
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = call i8 @myadd(i8 %a, i8 %b)
+	ret i8 %c
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/Makefile b/test/Concrete/Makefile
new file mode 100644
index 00000000..4acfadad
--- /dev/null
+++ b/test/Concrete/Makefile
@@ -0,0 +1,55 @@
+LEVEL = ../..
+
+# hard-coding bad. will get fixed.
+LCCFLAGS  += -O0 -Wall
+LCXXFLAGS += -O0 -Wall
+LLCFLAGS =
+
+test:
+	./ConcreteTest.py
+
+clean::
+	-rm -rf Output klee-last klee-out* test.log
+	-rm -rf *.bc
+
+# We do not want to make .d files for tests! 
+DISABLE_AUTO_DEPENDENCIES=1
+
+include ${LEVEL}/Makefile.common
+
+# Compile from X.c to Output/X.ll
+Output/%.ll: %.c $(LCC1) Output/.dir $(INCLUDES)
+	$(LLVMGCCWITHPATH) --emit-llvm $(CPPFLAGS) $(LCCFLAGS) -S $< -o $@
+
+# Compile from X.cpp to Output/X.ll
+Output/%.ll: %.cpp $(LCC1XX) Output/.dir $(INCLUDES)
+	$(LLVMGXXWITHPATH) --emit-llvm $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# Compile from X.cc to Output/X.ll
+Output/%.ll: %.cc $(LCC1XX) Output/.dir $(INCLUDES)
+	$(LLVMGXXWITHPATH) --emit-llvm $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# LLVM Assemble from Output/X.ll to Output/X.bc.  Output/X.ll must have come
+# from GCC output, so use GCCAS.
+#
+Output/%.bc: Output/%.ll $(LLVMAS)
+	$(LLVMAS) -f $< -o $@
+
+# LLVM Assemble from X.ll to Output/X.bc.  Because we are coming directly from
+# LLVM source, use the non-transforming assembler.
+#
+Output/%.bc: %.ll $(LLVMAS) Output/.dir
+	$(LLVMAS) -f $< -o $@
+
+Output/linked_%.bc: Output/%.bc Output/_testingUtils.bc
+	$(LLVMLD) -disable-opt -link-as-library Output/_testingUtils.bc $< -o $@
+
+.PRECIOUS: Output/.dir
+
+## Cancel built-in implicit rules that override above rules
+%: %.s
+
+%: %.c
+
+%.o: %.c
+
diff --git a/test/Concrete/OneCall.ll b/test/Concrete/OneCall.ll
new file mode 100644
index 00000000..d8b94b37
--- /dev/null
+++ b/test/Concrete/OneCall.ll
@@ -0,0 +1,12 @@
+declare void @print_i32(i32)
+
+define i32 @sum(i32 %a, i32 %b) {
+	%c = sub i32 %a, %b
+	ret i32 %c
+}
+
+define i32 @main() {
+	%a = call i32 @sum(i32 54, i32 2)
+	call void @print_i32(i32 %a)
+	ret i32 0
+}
diff --git a/test/Concrete/OverlappingPhiNodes.ll b/test/Concrete/OverlappingPhiNodes.ll
new file mode 100644
index 00000000..d3dc76ab
--- /dev/null
+++ b/test/Concrete/OverlappingPhiNodes.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	br label %test
+test:
+	%a = phi i32 [10, %entry], [%b, %test]
+	%b = phi i32 [20, %entry], [%a, %test]
+	%c = phi i32 [0, %entry], [1, %test]
+	%d = icmp eq i32 %c, 1
+	br i1 %d, label %exit, label %test
+exit:
+	call void @print_i32(i32 %b)
+	ret i32 0
+}
diff --git a/test/Concrete/Select.ll b/test/Concrete/Select.ll
new file mode 100644
index 00000000..29b81e3e
--- /dev/null
+++ b/test/Concrete/Select.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%ten = select i1 true, i32 10, i32 0
+	%five = select i1 false, i32 0, i32 5
+	%check = add i32 %ten, %five
+	%test = icmp eq i32 %check, 15
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/Shifts.ll b/test/Concrete/Shifts.ll
new file mode 100644
index 00000000..2430f879
--- /dev/null
+++ b/test/Concrete/Shifts.ll
@@ -0,0 +1,21 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%amt = add i8 2, 5
+	%a = shl i8 1, 5
+	%b = lshr i8 %a, 5
+	%c = shl i8 %b, %amt
+	%d = lshr i8 %c, %amt
+	%e = shl i8 %d, 7
+	%f = ashr i8 %e, 7
+	%g = shl i8 %f, %amt
+	%h = ashr i8 %g, %amt
+	%test = icmp eq i8 %h, -1
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/SimpleStoreAndLoad.ll b/test/Concrete/SimpleStoreAndLoad.ll
new file mode 100644
index 00000000..0201ba15
--- /dev/null
+++ b/test/Concrete/SimpleStoreAndLoad.ll
@@ -0,0 +1,17 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = alloca i32, i32 4
+	%tmp1 = getelementptr i32* %a, i32 0
+	store i32 0, i32* %tmp1
+	%tmp2 = load i32* %tmp1
+	%tmp3 = icmp eq i32 %tmp2, 0
+	br i1 %tmp3, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/UnconditionalBranch.ll b/test/Concrete/UnconditionalBranch.ll
new file mode 100644
index 00000000..81e2f931
--- /dev/null
+++ b/test/Concrete/UnconditionalBranch.ll
@@ -0,0 +1,10 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 0, 1
+	br label %exit
+exit:
+	call void @print_i32(i32 %a)
+	ret i32 0
+}
diff --git a/test/Concrete/UnconditionalBranchWithSimplePhi.ll b/test/Concrete/UnconditionalBranchWithSimplePhi.ll
new file mode 100644
index 00000000..551ddf5d
--- /dev/null
+++ b/test/Concrete/UnconditionalBranchWithSimplePhi.ll
@@ -0,0 +1,14 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 0, 1
+	br label %exit
+unused:
+	%b = add i32 1, 2
+	br label %exit
+exit:
+	%c = phi i32 [%a, %entry], [%b, %unused]
+	call void @print_i32(i32 %c)
+	ret i32 0
+}
diff --git a/test/Concrete/UnorderedPhiNodes.ll b/test/Concrete/UnorderedPhiNodes.ll
new file mode 100644
index 00000000..3ecd5083
--- /dev/null
+++ b/test/Concrete/UnorderedPhiNodes.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	br label %test
+test:
+	%a = phi i32 [10, %entry], [%b, %test]
+	%b = phi i32 [%a, %test], [20, %entry]
+	%c = phi i32 [0, %entry], [1, %test]
+	%d = icmp eq i32 %c, 1
+	br i1 %d, label %exit, label %test
+exit:
+	call void @print_i32(i32 %b)
+	ret i32 0
+}
diff --git a/test/Concrete/_testingUtils.c b/test/Concrete/_testingUtils.c
new file mode 100644
index 00000000..02d0529e
--- /dev/null
+++ b/test/Concrete/_testingUtils.c
@@ -0,0 +1,32 @@
+int putchar(int x);
+
+void print_int(unsigned long long val);
+
+#define TYPED_PRINT(_name_type, _arg_type)  \
+    void print_ ## _name_type(_arg_type val) { print_int(val); }
+ 
+TYPED_PRINT(i1, unsigned char)
+TYPED_PRINT(i8, unsigned char)
+TYPED_PRINT(i16, unsigned short)
+TYPED_PRINT(i32, unsigned int)
+TYPED_PRINT(i64, unsigned long long)
+
+void print_int(unsigned long long val) {
+    int cur = 1;
+
+    // effectively do a log (can't call log because it returns floats)
+    // do the nasty divide to prevent overflow
+    while (cur <= val / 10)
+        cur *= 10;
+
+    while (cur) {
+        int digit = val / cur;
+
+        putchar(digit + '0');
+        
+        val = val % cur;
+        cur /= 10;
+    }
+    
+    putchar('\n');
+}
diff --git a/test/Concrete/ackermann.c b/test/Concrete/ackermann.c
new file mode 100644
index 00000000..0f21a3ab
--- /dev/null
+++ b/test/Concrete/ackermann.c
@@ -0,0 +1,16 @@
+// llvm-gcc -O2 --emit-llvm -c ackermann.c && ../../Debug/bin/klee ackermann.o 2 2
+
+#include <stdio.h>
+
+int ackermann(int m, int n) {
+   if (m == 0)
+     return n+1;
+   else
+     return ackermann(m-1, (n==0) ? 1 : ackermann(m, n-1));
+ }
+
+int main() {
+  printf("ackerman(%d, %d) = %d\n", 2, 2, ackermann(2, 2));
+
+  return 0;
+}
diff --git a/test/Concrete/arith_test.ll b/test/Concrete/arith_test.ll
new file mode 100644
index 00000000..5624462b
--- /dev/null
+++ b/test/Concrete/arith_test.ll
@@ -0,0 +1,76 @@
+define void @"test_simple_arith"(i16 %i0, i16 %j0)
+begin
+  %t1 = add i16 %i0, %j0
+  %t2 = sub i16 %i0, %j0
+  %t3 = mul i16 %t1, %t2
+
+  call void @print_i16(i16 %t3)
+
+  ret void     
+end
+
+define void @"test_div_and_mod"(i16 %op1, i16 %op2)
+begin
+  %t1 = udiv i16 %op1, %op2
+  %t2 = urem i16 %op1, %op2  
+  %t3 = sdiv i16 %op1, %op2  
+  %t4 = srem i16 %op1, %op2  
+
+  call void @print_i16(i16 %t1)
+  call void @print_i16(i16 %t2)
+  call void @print_i16(i16 %t3)
+  call void @print_i16(i16 %t4)
+
+  ret void     
+end
+        
+define void @test_cmp(i16 %op1, i16 %op2)
+begin
+  %t1 = icmp ule i16 %op1, %op2
+  %t2 = icmp ult i16 %op1, %op2  
+  %t3 = icmp uge i16 %op1, %op2  
+  %t4 = icmp ugt i16 %op1, %op2  
+  %t6 = icmp slt i16 %op1, %op2  
+  %t5 = icmp sle i16 %op1, %op2
+  %t7 = icmp sge i16 %op1, %op2  
+  %t8 = icmp sgt i16 %op1, %op2  
+  %t9 = icmp eq i16 %op1, %op2  
+  %t10 = icmp ne i16 %op1, %op2  
+
+  call void @print_i1(i1 %t1)
+  call void @print_i1(i1 %t2)
+  call void @print_i1(i1 %t3)
+  call void @print_i1(i1 %t4)
+  call void @print_i1(i1 %t5)
+  call void @print_i1(i1 %t6)
+  call void @print_i1(i1 %t7)
+  call void @print_i1(i1 %t8)
+  call void @print_i1(i1 %t9)
+  call void @print_i1(i1 %t10)
+
+  ret void
+end
+
+define i32 @main()
+begin
+    call void @test_simple_arith(i16 111, i16 100)
+
+    call void @test_div_and_mod(i16 63331, i16 3123)
+    call void @test_div_and_mod(i16 1000, i16 55444)
+    call void @test_div_and_mod(i16 49012, i16 55444)
+    call void @test_div_and_mod(i16 1000, i16 25)
+
+    call void @test_cmp(i16 63331, i16 3123)
+    call void @test_cmp(i16 1000, i16 55444)
+    call void @test_cmp(i16 49012, i16 55444)
+    call void @test_cmp(i16 1000, i16 25)
+        
+    ret i32 0
+end
+
+; defined in print_int.c
+declare void @print_i1(i1)
+declare void @print_i8(i8)
+declare void @print_i16(i16)
+declare void @print_i32(i32)
+declare void @print_i64(i64)
diff --git a/test/Coverage/ReadArgs.c b/test/Coverage/ReadArgs.c
new file mode 100644
index 00000000..7ebf056e
--- /dev/null
+++ b/test/Coverage/ReadArgs.c
@@ -0,0 +1,9 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: rm -rf xxx
+// RUN: echo " --output-dir=xxx " > %t1.args
+// RUN: %klee --read-args %t1.args %t1.bc
+// RUN: test -d xxx
+
+int main() {
+  return 0;
+}
diff --git a/test/Coverage/ReplayOutDir.c b/test/Coverage/ReplayOutDir.c
new file mode 100644
index 00000000..3ca6fb80
--- /dev/null
+++ b/test/Coverage/ReplayOutDir.c
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: rm -rf %t1.out %t1.replay
+// RUN: %klee --output-dir=%t1.out %t1.bc
+// RUN: %klee --output-dir=%t1.replay --replay-out-dir=%t1.out %t1.bc
+
+int main() {
+  int i;
+  klee_make_symbolic(&i, sizeof i);
+  klee_print_range("i", i);
+  return 0;
+}
diff --git a/test/Coverage/dg.exp b/test/Coverage/dg.exp
new file mode 100644
index 00000000..879685ca
--- /dev/null
+++ b/test/Coverage/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/test/Dogfood/ImmutableSet.cpp b/test/Dogfood/ImmutableSet.cpp
new file mode 100644
index 00000000..7b816de4
--- /dev/null
+++ b/test/Dogfood/ImmutableSet.cpp
@@ -0,0 +1,134 @@
+// RUN: llvm-g++ -I../../../include -g -DMAX_ELEMENTS=4 -fno-exceptions --emit-llvm -c -o %t1.bc %s
+// RUN: %klee --libc=klee --max-forks=200 --no-output --exit-on-error --optimize --disable-inlining --use-non-uniform-random-search --use-cex-cache %t1.bc
+
+#include "klee/klee.h"
+#include "klee/Internal/ADT/ImmutableSet.h"
+
+using namespace klee;
+
+typedef ImmutableSet<unsigned> T;
+
+bool iff(bool a, bool b) {
+  return !!a == !!b;
+}
+
+template<typename InputIterator, typename T>
+bool contains(InputIterator begin, InputIterator end, T item) {
+  for (; begin!=end; ++begin)
+    if (*begin == item)
+      return true;
+  return false;
+}
+
+bool equal(T &a, T &b) {
+  T::iterator aIt=a.begin(), ae=a.end(), bIt=b.begin(), be=b.end();
+  for (; aIt!=ae && bIt!=be; ++aIt, ++bIt)
+    if (*aIt != *bIt)
+      return false;
+  if (aIt!=ae) return false;
+  if (bIt!=be) return false;
+  return true;
+}
+
+template<typename InputIterator, typename T>
+void remove(InputIterator begin, InputIterator end, T item) {
+  InputIterator out = begin;
+  for (; begin!=end; ++begin) {
+    if (*begin!=item) {
+      if (out!=begin)
+        *out = *begin;
+      ++out;
+    }
+  }
+}
+
+void check_set(T &set, unsigned num, unsigned *values) {
+  assert(set.size() == num);
+
+  // must contain only values
+  unsigned item = klee_range(0, 256, "range");
+  assert(iff(contains(values, values+num, item),
+             set.count(item)));
+
+  // each value must be findable, must be its own lower bound, and
+  // must be one behind its upper bound
+  for (unsigned i=0; i<num; i++) {
+    unsigned item = values[i];
+    assert(set.count(item));
+    T::iterator it = set.find(item);
+    T::iterator lb = set.lower_bound(item);
+    T::iterator ub = set.upper_bound(item);
+    assert(it != set.end());                // must exit
+    assert(*it == item);                    // must be itself
+    assert(lb == it);                       // must be own lower bound
+    assert(--ub == it);                     // must be one behind upper
+  }
+
+  // for items not in the set...
+  unsigned item2 = klee_range(0, 256, "range");
+  if (!set.count(item2)) {
+    assert(set.find(item2) == set.end());
+
+    T::iterator lb = set.lower_bound(item2);
+    for (T::iterator it=set.begin(); it!=lb; ++it)      
+      assert(*it < item2);
+    for (T::iterator it=lb, ie=set.end(); it!=ie; ++it)
+      assert(*it >= item2);
+
+    T::iterator ub = set.upper_bound(item2);
+    for (T::iterator it=set.begin(); it!=ub; ++it)
+      assert(*it <= item2);
+    for (T::iterator it=ub, ie=set.end(); it!=ie; ++it)
+      assert(*it > item2);
+  }
+}
+
+#ifndef MAX_ELEMENTS
+#define MAX_ELEMENTS 4
+#endif
+
+void test() {
+  unsigned num=0, values[MAX_ELEMENTS];
+  T set;
+
+  assert(MAX_ELEMENTS >= 0);
+  for (unsigned i=0; i<klee_range(0,MAX_ELEMENTS+1, "range"); i++) {
+    unsigned item = klee_range(0, 256, "range");
+    if (contains(values, values+num, item))
+      klee_silent_exit(0);
+
+    set = set.insert(item);
+    values[num++] = item;
+  }
+  
+  check_set(set, num, values);
+
+  unsigned item = klee_range(0, 256, "range");  
+  if (contains(values, values+num, item)) { // in tree
+    // insertion is invariant
+    T set2 = set.insert(item);
+    assert(equal(set2, set));
+
+    // check remove
+    T set3 = set.remove(item);
+    assert(!equal(set3, set)); // mostly just for coverage
+    assert(set3.size() + 1 == set.size());
+    assert(!set3.count(item));
+  } else { // not in tree
+    // removal is invariant
+    T set2 = set.remove(item);
+    assert(equal(set2, set));
+
+    // check insert
+    T set3 = set.insert(item);
+    assert(!equal(set3, set)); // mostly just for coverage
+    assert(set3.size() == set.size() + 1);
+    assert(set3.count(item));
+  }
+}
+
+int main(int argc, char **argv) {
+  test();
+  assert(T::getAllocated() == 0);
+  return 0;
+}
diff --git a/test/Dogfood/dg.exp b/test/Dogfood/dg.exp
new file mode 100644
index 00000000..879685ca
--- /dev/null
+++ b/test/Dogfood/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/test/Expr/dg.exp b/test/Expr/dg.exp
new file mode 100644
index 00000000..879685ca
--- /dev/null
+++ b/test/Expr/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/test/Feature/Alias.c b/test/Feature/Alias.c
new file mode 100644
index 00000000..9300e2c7
--- /dev/null
+++ b/test/Feature/Alias.c
@@ -0,0 +1,25 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+// Darwin does not have strong aliases.
+// XFAIL: darwin
+
+#include <assert.h>
+
+// alias for global
+int b = 52;
+extern int a __attribute__((alias("b")));
+
+// alias for function
+int __foo() { return 52; }
+extern int foo() __attribute__((alias("__foo")));
+
+int *c = &a;
+
+int main() { 
+  assert(a == 52);
+  assert(foo() == 52);
+  assert(*c == 52);
+  
+  return 0;
+}
diff --git a/test/Feature/AliasFunction.c b/test/Feature/AliasFunction.c
new file mode 100644
index 00000000..e7acfc19
--- /dev/null
+++ b/test/Feature/AliasFunction.c
@@ -0,0 +1,33 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: grep -c foo %t1.log | grep 5
+// RUN: grep -c bar %t1.log | grep 3
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void foo() { printf("  foo()\n"); }
+void bar() { printf("  bar()\n"); }
+
+int main() {
+  int x;
+  klee_make_symbolic_name(&x, sizeof(x), "x");
+
+  // no aliases
+  foo();
+
+  if (x > 10)
+  {
+    // foo -> bar
+    klee_alias_function("foo", "bar");    
+
+    if (x > 20)
+      foo();
+  }
+  
+  foo();
+
+  // undo
+  klee_alias_function("foo", "foo");
+  foo();
+}
diff --git a/test/Feature/AliasFunctionExit.c b/test/Feature/AliasFunctionExit.c
new file mode 100644
index 00000000..fcaf7e6c
--- /dev/null
+++ b/test/Feature/AliasFunctionExit.c
@@ -0,0 +1,30 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: grep -c START %t1.log | grep 1
+// RUN: grep -c END %t1.log | grep 2
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void start(int x) {
+  printf("START\n");
+  if (x == 53)
+    exit(1);
+}
+
+void end(int status) {
+  klee_alias_function("exit", "exit");
+  printf("END: status = %d\n", status);
+  exit(status);
+}
+
+
+int main() {
+  int x;
+  klee_make_symbolic_name(&x, sizeof(x), "x");
+
+  klee_alias_function("exit", "end");
+  start(x);
+  end(0);
+}
diff --git a/test/Feature/AsmAddresses.c b/test/Feature/AsmAddresses.c
new file mode 100644
index 00000000..a58fc059
--- /dev/null
+++ b/test/Feature/AsmAddresses.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc -g -c -o %t.bc %s
+// RUN: %klee --exit-on-error --use-asm-addresses %t.bc
+// RUN: %llvmgcc -DOVERLAP -g -c -o %t.bc %s
+// RUN: not %klee --exit-on-error --use-asm-addresses %t.bc
+
+#include <assert.h>
+
+
+volatile unsigned char x0 __asm ("0x0021");
+volatile unsigned char whee __asm ("0x0WHEE");
+
+#ifdef OVERLAP
+volatile unsigned int y0 __asm ("0x0030");
+volatile unsigned int y1 __asm ("0x0032");
+#endif
+
+int main() {
+  assert(&x0 == (void*) 0x0021);
+  assert(&whee != (void*) 0x0);
+
+  return 0;
+}
diff --git a/test/Feature/ByteSwap.c b/test/Feature/ByteSwap.c
new file mode 100644
index 00000000..f85ac3b1
--- /dev/null
+++ b/test/Feature/ByteSwap.c
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=klee --exit-on-error %t1.bc
+
+#include <arpa/inet.h>
+#include <assert.h>
+
+int main() {
+  
+  uint32_t n = 0;
+  klee_make_symbolic(&n, sizeof(n));
+  
+  uint32_t h = ntohl(n);
+  assert(htonl(h) == n);
+  
+  return 0;
+}
diff --git a/test/Feature/CallToUndefinedExternal.cpp b/test/Feature/CallToUndefinedExternal.cpp
new file mode 100644
index 00000000..2f11f29d
--- /dev/null
+++ b/test/Feature/CallToUndefinedExternal.cpp
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.external.err
+
+extern "C" void poof(void);
+
+int main() {
+  poof();
+
+  return 0;
+}
diff --git a/test/Feature/CheckForImpliedValue.c.failing b/test/Feature/CheckForImpliedValue.c.failing
new file mode 100644
index 00000000..7a088354
--- /dev/null
+++ b/test/Feature/CheckForImpliedValue.c.failing
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: rm -f %t1.log
+// RUN: %klee --log-file %t1.log --debug-check-for-implied-values %t1.bc
+// RUN: grep "= 0 (ok)" %t1.log
+// RUN: grep "= 2 (missed)" %t1.log
+
+#define swap(x) (((x)>>16) | (((x)&0xFFFF)<<16))
+int main() {
+  unsigned x, y;
+  
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+
+  if (!x) { // should give x = 0 hit by ivc
+    printf("ok\n");
+  } else {
+    if (swap(y) == 0x00020000) { // should give y = 2 missed by ivc
+      printf("ok\n");
+    }
+  }
+
+  return 0;
+}
diff --git a/test/Feature/CheckMemoryAccess.c b/test/Feature/CheckMemoryAccess.c
new file mode 100644
index 00000000..dd6e8745
--- /dev/null
+++ b/test/Feature/CheckMemoryAccess.c
@@ -0,0 +1,26 @@
+// RUN: %llvmgcc -g -c %s -o %t.bc
+// RUN: %klee %t.bc > %t.log
+// RUN: grep -q "good" %t.log
+// RUN: not grep -q "bad" %t.log
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  char buf[4];
+
+  klee_check_memory_access(&buf, 1);
+  printf("good\n");
+  if (klee_range(0, 2, "range1")) {
+    klee_check_memory_access(0, 1);
+    printf("null pointer deref: bad\n");
+  }
+
+  if (klee_range(0, 2, "range2")) {
+    klee_check_memory_access(buf, 5);
+    printf("oversize access: bad\n");
+  }
+
+  return 0;
+}
diff --git a/test/Feature/CopyOnWrite.c b/test/Feature/CopyOnWrite.c
new file mode 100644
index 00000000..ee3ea15e
--- /dev/null
+++ b/test/Feature/CopyOnWrite.c
@@ -0,0 +1,26 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --use-random-search --exit-on-error %t1.bc
+
+#include <assert.h>
+
+#define N 5
+
+unsigned branches = 0;
+
+void explode(int *ap, int i, int *result) {
+  if (i<N) {
+    (*result)++;
+    if (ap[i]) // just cause a fork
+      branches++; 
+    return explode(ap, i+1, result);
+  }
+}
+
+int main() {
+  int result = 0;
+  int a[N];
+  klee_make_symbolic(a, sizeof a);
+  explode(a,0,&result);
+  assert(result==N);
+  return 0;
+}
diff --git a/test/Feature/DanglingConcreteReadExpr.c b/test/Feature/DanglingConcreteReadExpr.c
new file mode 100644
index 00000000..1bf44c3f
--- /dev/null
+++ b/test/Feature/DanglingConcreteReadExpr.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: grep "total queries = 2" klee-last/info
+
+#include <assert.h>
+
+int main() {
+  unsigned char x, y;
+
+  klee_make_symbolic(&x, sizeof x);
+  
+  y = x;
+
+  // should be exactly two queries (prove x is/is not 10)
+  // eventually should be 0 when we have fast solver
+  if (x==10) {
+    assert(y==10);
+  }
+
+  klee_silent_exit(0);
+  return 0;
+}
diff --git a/test/Feature/DefineFixedObject.c b/test/Feature/DefineFixedObject.c
new file mode 100644
index 00000000..36822434
--- /dev/null
+++ b/test/Feature/DefineFixedObject.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdio.h>
+
+#define ADDRESS ((int*) 0x0080)
+
+int main() {
+  klee_define_fixed_object(ADDRESS, 4);
+  
+  int *p = ADDRESS;
+
+  *p = 10;
+  printf("*p: %d\n", *p);
+
+  return 0;
+}
diff --git a/test/Feature/DoubleFree.c b/test/Feature/DoubleFree.c
new file mode 100644
index 00000000..3727ef2b
--- /dev/null
+++ b/test/Feature/DoubleFree.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  free(x);
+  free(x);
+  return 0;
+}
diff --git a/test/Feature/DumpStatesOnHalt.c b/test/Feature/DumpStatesOnHalt.c
new file mode 100644
index 00000000..7e9cf46a
--- /dev/null
+++ b/test/Feature/DumpStatesOnHalt.c
@@ -0,0 +1,8 @@
+// RUN: %llvmgcc %s -g -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --stop-after-n-instructions=1 --dump-states-on-halt=true %t1.bc
+// RUN: test -f klee-last/test000001.bout
+
+int main() {
+  int x = 10;
+  return x;
+}
diff --git a/test/Feature/Envp.c b/test/Feature/Envp.c
new file mode 100644
index 00000000..f1f62a72
--- /dev/null
+++ b/test/Feature/Envp.c
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main(int argc, char **argv, char **envp) {
+  unsigned i;
+  assert(argv[argc] == 0);
+  printf("argc: %d, argv: %p, envp: %p\n", argc, argv, envp);
+  printf("--environ--\n");
+  int haspwd = 0;
+  for (i=0; envp[i]; i++) {
+    printf("%d: %s\n", i, envp[i]);
+    haspwd |= strncmp(envp[i], "PWD=", 4)==0;
+  }
+  assert(haspwd);
+  return 0;
+}
diff --git a/test/Feature/ExprLogging.c b/test/Feature/ExprLogging.c
new file mode 100644
index 00000000..2abf0070
--- /dev/null
+++ b/test/Feature/ExprLogging.c
@@ -0,0 +1,43 @@
+// RUN: %llvmgcc %s -emit-llvm -g -O0 -c -o %t1.bc
+// RUN: %klee --use-query-pc-log --write-pcs --write-cvcs %t1.bc 2> %t2.log
+// RUN: %kleaver -print-ast klee-last/test000001.pc
+
+// FIXME: Ideally we would verify a roundtrip that we parsed the pc
+// file and can dump it back out as the same file.
+
+#include <assert.h>
+
+int constantArr[16 ] = {
+  1 <<  0, 1 <<  1, 1 <<  2, 1 <<  3,
+  1 <<  4, 1 <<  5, 1 <<  6, 1 <<  7,
+  1 <<  8, 1 <<  9, 1 << 10, 1 << 11,
+  1 << 12, 1 << 13, 1 << 14, 1 << 15
+};
+
+
+int main() {
+  char buf[4];
+  klee_make_symbolic(buf, sizeof buf);
+
+  buf[1] = 'a';
+
+  constantArr[klee_range(0, 16, "idx.0")] = buf[0];
+
+  // Use this to trigger an interior update list usage.
+  int y = constantArr[klee_range(0, 16, "idx.1")];  
+
+  constantArr[klee_range(0, 16, "idx.2")] = buf[3];
+  
+  buf[klee_range(0, 4, "idx.3")] = 0;
+  klee_assume(buf[0] == 'h');
+  
+  int x = *((int*) buf);
+  klee_assume(x > 2);
+  klee_assume(x == constantArr[12]);
+
+  klee_assume(y != (1 << 5));
+
+  assert(0);
+
+  return 0;
+}
diff --git a/test/Feature/ExternalWeakLinkage.c b/test/Feature/ExternalWeakLinkage.c
new file mode 100644
index 00000000..c2008136
--- /dev/null
+++ b/test/Feature/ExternalWeakLinkage.c
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+void __attribute__((weak)) IAmSoWeak(int);
+
+int main() {
+  assert(IAmSoWeak==0);
+  return 0;
+}
diff --git a/test/Feature/FunctionPointer.c b/test/Feature/FunctionPointer.c
new file mode 100644
index 00000000..e1ae1e37
--- /dev/null
+++ b/test/Feature/FunctionPointer.c
@@ -0,0 +1,36 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error %t1.bc
+
+#include <stdio.h>
+
+void foo(const char *msg) { printf("foo: %s\n", msg); }
+void baz(const char *msg) { printf("baz: %s\n", msg); }
+
+void (*xx)(const char *) = foo;
+
+void bar(void (*fp)(const char *)) { fp("called via bar"); }
+
+int main(int argc, char **argv) {
+  void (*fp)(const char *) = foo;
+
+  printf("going to call through fp\n");
+  fp("called via fp");
+
+  printf("calling via pass through\n");
+  bar(foo);
+        
+  fp = baz;
+  fp("called via fp");
+
+  xx("called via xx");
+
+#if 0
+  klee_make_symbolic(&fp, sizeof fp);
+  if(fp == baz) {
+    printf("fp = %p, baz = %p\n", fp, baz);
+    fp("calling via symbolic!");
+  }
+#endif
+
+  return 0;
+}
diff --git a/test/Feature/GetValue.c b/test/Feature/GetValue.c
new file mode 100644
index 00000000..391b68e3
--- /dev/null
+++ b/test/Feature/GetValue.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdio.h>
+#include <assert.h>
+
+int main() {
+  int x = klee_int("x");
+  klee_assume(x > 10);
+  klee_assume(x < 20);
+
+  assert(!klee_is_symbolic(klee_get_value(x)));
+  assert(klee_get_value(x) > 10);
+  assert(klee_get_value(x) < 20);
+
+  return 0;
+}
diff --git a/test/Feature/ImpliedValue.c.failing b/test/Feature/ImpliedValue.c.failing
new file mode 100644
index 00000000..2f169970
--- /dev/null
+++ b/test/Feature/ImpliedValue.c.failing
@@ -0,0 +1,147 @@
+// RUN: rm -f %t4.out %t4.err %t4.log
+// RUN: %llvmgcc %s -emit-llvm -O2 -c -o %t1.bc
+// RUN: llvm-as -f ../_utils._ll -o %t2.bc
+// RUN: llvm-ld -disable-opt -link-as-library %t1.bc %t2.bc -o %t3.bc
+// RUN: %klee --log-file %t4.log --debug-check-for-implied-values %t3.bc > %t4.out 2> %t4.err
+// RUN: ls klee-last | not grep .err
+// RUN: not grep "(missed)" %t4.log
+
+#include <assert.h>
+
+#include "utils.h"
+
+int main() {
+  unsigned char which;
+  volatile unsigned char a,b,c,d,e,f,g,h;
+
+  klee_make_symbolic(&which, sizeof which);
+  klee_make_symbolic(&a, sizeof a);
+  klee_make_symbolic(&b, sizeof b);
+  klee_make_symbolic(&c, sizeof c);
+  klee_make_symbolic(&d, sizeof d);
+  klee_make_symbolic(&e, sizeof e);
+  klee_make_symbolic(&f, sizeof f);
+  klee_make_symbolic(&g, sizeof g);
+  klee_make_symbolic(&h, sizeof h);
+
+  switch (which) {
+// RUN: grep "simple read(2) = value case" %t4.out
+  case 0:
+    if (a == 2) {
+      assert(!klee_is_symbolic(a));
+      printf("simple read(%d) = value case\n", a);
+    }
+    break;
+
+// RUN: grep "select(0) has distinct constant result case (false)" %t4.out
+  case 1:
+    if (util_make_select(a, 12, 14) == 14) {
+      assert(!klee_is_symbolic(a));
+      printf("select(%d) has distinct constant result case (false)\n", a);
+    }
+    break;
+
+// RUN: grep "select(0) has distinct constant result case (true)" %t4.out
+  case 2:
+    if (util_make_select(!a, 12, 14) == 12) {
+      assert(!klee_is_symbolic(a));
+      printf("select(%d) has distinct constant result case (true)\n", a);
+    }
+    break;
+
+// RUN: grep "concat2(0xBE,0xEF) = value case" %t4.out
+  case 3:
+    if (util_make_concat2(a,b) == 0xBEEF) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      printf("concat2(0x%X,0x%X) = value case\n",
+             a, b);
+    }
+    break;
+
+// RUN: grep "concat4(0xDE,0xAD,0xBE,0xEF) = value case" %t4.out
+  case 4:
+    if (util_make_concat4(a,b,c,d) == 0xDEADBEEF) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      assert(!klee_is_symbolic(c));
+      assert(!klee_is_symbolic(d));
+      printf("concat4(0x%X,0x%X,0x%X,0x%X) = value case\n",
+             a, b, c, d);
+    }
+    break;
+
+// RUN: grep "concat8(0xDE,0xAD,0xBE,0xEF,0xAB,0xCD,0xAB,0xCD) = value case" %t4.out
+  case 5:
+    if (util_make_concat8(a,b,c,d,e,f,g,h) == 0xDEADBEEFABCDABCDLL) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      assert(!klee_is_symbolic(c));
+      assert(!klee_is_symbolic(d));
+      assert(!klee_is_symbolic(e));
+      assert(!klee_is_symbolic(f));
+      assert(!klee_is_symbolic(g));
+      assert(!klee_is_symbolic(h));
+      printf("concat8(0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X) = value case\n",
+             a, b, c, d, e, f, g, h);
+    }
+    break;
+
+// RUN: grep "and(0,0) = true case" %t4.out
+  case 6:
+    if (util_make_and_i1(!a, !b)) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));      
+      printf("and(%d,%d) = true case\n", a, b);
+    }
+    break;
+
+// RUN: grep "or(0,0) = false case" %t4.out
+  case 7:
+    if (!util_make_or_i1(a, b)) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));      
+      printf("or(%d,%d) = false case\n", a, b);
+    }
+    break;
+
+    // we use concat to prevent folding, will need to fix if that gets
+    // partial evaluated
+// RUN: grep "add constant case: 0xDE" %t4.out
+  case 8:
+    if (util_make_concat2(a+0xCD,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("add constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "sub constant case: 0x60" %t4.out
+  case 9:
+    if (util_make_concat2(0x0B-a,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("sub constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "xor constant case: 0xA0" %t4.out
+  case 10:
+    if (util_make_concat2(0x0B ^ a,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("xor constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "sext constant case: 244" %t4.out
+  case 11:
+    if (! util_make_or_i1(((short) (signed char) a) + 12,b)) {
+      assert(!klee_is_symbolic(a));
+      printf("sext constant case: %d\n", a);
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return 0;
+}
diff --git a/test/Feature/InAndOutOfBounds.c b/test/Feature/InAndOutOfBounds.c
new file mode 100644
index 00000000..18e5d2b2
--- /dev/null
+++ b/test/Feature/InAndOutOfBounds.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err -o -f klee-last/test000002.ptr.err 
+// RUN: test ! -f klee-last/test000001.ptr.err -o ! -f klee-last/test000002.ptr.err 
+// RUN: test ! -f klee-last/test000003.bout
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int main() {
+  int *x = malloc(4);
+  x[klee_urange(0,2)] = 1;
+  free(x);
+  return 0;
+}
diff --git a/test/Feature/IndirectCallToBuiltin.c b/test/Feature/IndirectCallToBuiltin.c
new file mode 100644
index 00000000..591a5601
--- /dev/null
+++ b/test/Feature/IndirectCallToBuiltin.c
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  void *(*allocator)(size_t) = malloc;
+  int *mem = allocator(10);
+
+  printf("mem: %p\n", mem);
+  printf("mem[0]: %d\n", mem[0]);
+
+  return 0;
+}
diff --git a/test/Feature/IndirectCallToExternal.c b/test/Feature/IndirectCallToExternal.c
new file mode 100644
index 00000000..4603213b
--- /dev/null
+++ b/test/Feature/IndirectCallToExternal.c
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+int main() {
+  int (*scmp)(char*,char*) = strcmp;
+
+  assert(scmp("hello","hi") < 0);
+
+  return 0;
+}
diff --git a/test/Feature/InvalidBitfieldAccess.c.failing b/test/Feature/InvalidBitfieldAccess.c.failing
new file mode 100644
index 00000000..ae8bfe5e
--- /dev/null
+++ b/test/Feature/InvalidBitfieldAccess.c.failing
@@ -0,0 +1,28 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+// This is a bug in llvm-gcc4.0 but seems to be fixed in llvm-gcc4.2,
+// its included here mostly as a reminder. 
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct foo {
+  unsigned int a : 5;
+  unsigned int b : 10;
+  unsigned int c : 1;
+} __attribute__((packed));
+
+int main() {
+  struct foo *a = malloc(sizeof *a);
+
+  a->b = 12; // problem here is that llvm-gcc emits a 4 byte access
+             // which is out of bounds.
+
+  int x = a->b;
+
+  assert(x == 12);
+
+  return 0;
+}
diff --git a/test/Feature/IsSymbolic.c b/test/Feature/IsSymbolic.c
new file mode 100644
index 00000000..4a86368a
--- /dev/null
+++ b/test/Feature/IsSymbolic.c
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int x, y, z = 0;
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+  if (x) {
+    assert(klee_is_symbolic(y));
+  } else {
+    assert(!klee_is_symbolic(z));
+  }
+  return 0;
+}
diff --git a/test/Feature/KleeReportError.c b/test/Feature/KleeReportError.c
new file mode 100644
index 00000000..dda72fd0
--- /dev/null
+++ b/test/Feature/KleeReportError.c
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --emit-all-errors %t2.bc > %t3.log
+// RUN: ls klee-last/ | grep .my.err | wc -l | grep 2
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  int x, y, *p = 0;
+  
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+
+  if (x)
+    fprintf(stderr, "x\n");
+  else fprintf(stderr, "!x\n");
+
+  if (y) {
+    fprintf(stderr, "My error\n");
+    klee_report_error(__FILE__, __LINE__, "My error", "my.err");
+  }
+
+  return 0;
+}
diff --git a/test/Feature/LongDoubleSupport.c b/test/Feature/LongDoubleSupport.c
new file mode 100644
index 00000000..b4631832
--- /dev/null
+++ b/test/Feature/LongDoubleSupport.c
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc > %t2.out
+
+#include <stdio.h>
+#include <float.h>
+
+// FIXME: This doesn't really work at all, it just doesn't
+// crash. Until we have wide constant support, that is all we care
+// about; the only reason this comes up is in initialization of
+// constants, we don't actually end up seeing much code which uses long
+// double.
+int main() {
+  long double a = LDBL_MAX;
+  long double b = -1;
+  long double c = a + b;
+  printf("a = %Lg\n", a);
+  printf("b = %Lg\n", b);
+  printf("c = %Lg\n", c);
+  return 0;
+}
diff --git a/test/Feature/LowerSwitch.c b/test/Feature/LowerSwitch.c
new file mode 100644
index 00000000..c4d9644a
--- /dev/null
+++ b/test/Feature/LowerSwitch.c
@@ -0,0 +1,30 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t.bc
+// RUN: %klee --exit-on-error --allow-external-sym-calls --switch-type=internal %t.bc
+// RUN: not test -f klee-last/test000010.bout
+// RUN: %klee --exit-on-error --allow-external-sym-calls --switch-type=simple %t.bc
+// RUN: test -f klee-last/test000010.bout
+
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  int c = klee_range(0, 256, "range");
+  
+  switch(c) {
+  case 0: printf("0\n"); break;
+  case 10: printf("10\n"); break;
+  case 16: printf("16\n"); break;
+  case 17: printf("17\n"); break;
+  case 18: printf("18\n"); break;
+  case 19: printf("19\n"); break;
+#define C(x) case x: case x+1: case x+2: case x+3
+#define C2(x) C(x): C(x+4): C(x+8): C(x+12)
+#define C3(x) C2(x): C2(x+16): C2(x+32): C2(x+48)
+  C3(128):
+    printf("bignums: %d\n", c); break;
+  default: 
+    printf("default\n");
+    break;
+  }
+
+  return 0;
+}
diff --git a/test/Feature/MakeConcreteSymbolic.c b/test/Feature/MakeConcreteSymbolic.c
new file mode 100644
index 00000000..29b43a04
--- /dev/null
+++ b/test/Feature/MakeConcreteSymbolic.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+// RUN: grep "done: total queries = 0" klee-last/info
+// RUN: %klee --make-concrete-symbolic=1 --exit-on-error %t1.bc
+// RUN: grep "done: total queries = 2" klee-last/info
+
+
+#include <assert.h>
+
+#define N 2
+int main() {
+  int i;
+  char a;
+  
+  a = 10;
+  assert(a == 10);
+
+  return 0;
+}
diff --git a/test/Feature/MakeSymbolicName.c b/test/Feature/MakeSymbolicName.c
new file mode 100644
index 00000000..c1f11424
--- /dev/null
+++ b/test/Feature/MakeSymbolicName.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --use-random-search --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int a[4] = {1, 2, 3, 4};
+  unsigned i;
+
+  klee_make_symbolic_name(&i, sizeof(i), "index");  
+  if (i > 3)
+    klee_silent_exit(0);
+
+  assert(a[i] << 1 != 5);
+  if (a[i] << 1 == 6)
+    assert(i == 2);
+}
diff --git a/test/Feature/MemoryLimit.c b/test/Feature/MemoryLimit.c
new file mode 100644
index 00000000..3b1bacaf
--- /dev/null
+++ b/test/Feature/MemoryLimit.c
@@ -0,0 +1,37 @@
+// RUN: %llvmgcc -DLITTLE_ALLOC -g -c %s -o %t.little.bc
+// RUN: %llvmgcc -g -c %s -o %t.big.bc
+// RUN: %klee --max-memory=20 %t.little.bc > %t.little.log
+// RUN: %klee --max-memory=20 %t.big.bc > %t.big.log
+// RUN: not grep -q "DONE" %t.little.log
+// RUN: not grep -q "DONE" %t.big.log
+
+#include <stdlib.h>
+
+int main() {
+  int i, j, x=0;
+  
+#ifdef LITTLE_ALLOC
+  printf("IN LITTLE ALLOC\n");
+    
+  // 200 MBs total (in 32 byte chunks)
+  for (i=0; i<100; i++) {
+    for (j=0; j<(1<<16); j++)
+      malloc(1<<5);
+  }
+#else
+  printf("IN BIG ALLOC\n");
+  
+  // 200 MBs total
+  for (i=0; i<100; i++) {
+    malloc(1<<21);
+    
+    // Ensure we hit the periodic check
+    for (j=0; j<10000; j++)
+      x++;
+  }
+#endif
+
+  printf("DONE!\n");
+
+  return x;
+}
diff --git a/test/Feature/MultipleFreeResolution.c b/test/Feature/MultipleFreeResolution.c
new file mode 100644
index 00000000..872d6856
--- /dev/null
+++ b/test/Feature/MultipleFreeResolution.c
@@ -0,0 +1,39 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --emit-all-errors %t1.bc
+// RUN: ls klee-last/ | grep .out | wc -l | grep 4
+// RUN: ls klee-last/ | grep .err | wc -l | grep 3
+
+#include <stdlib.h>
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s;
+
+  for (i=0; i<3; i++)
+    buf[i] = make_int(i);
+  buf[3] = 0;
+
+  s = klee_urange(0,4);
+
+  free(buf[s]);
+
+  for (i=0; i<3; i++) {
+    printf("*buf[%d] = %d\n", i, *buf[i]);
+  }
+
+  return 0;
+}
diff --git a/test/Feature/MultipleReadResolution.c b/test/Feature/MultipleReadResolution.c
new file mode 100644
index 00000000..9297cf8d
--- /dev/null
+++ b/test/Feature/MultipleReadResolution.c
@@ -0,0 +1,43 @@
+// RUN: echo "x" > %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: diff %t1.res %t1.log
+
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s,t;
+
+  for (i=0; i<4; i++)
+    buf[i] = make_int((i+1)*2);
+
+  s = klee_urange(0,4);
+
+  int x = *buf[s];
+
+  if (x == 4)
+    if (s!=1)
+      abort();
+
+  printf("x\n");
+  fflush(stdout);
+
+  return 0;
+}
diff --git a/test/Feature/MultipleReallocResolution.c b/test/Feature/MultipleReallocResolution.c
new file mode 100644
index 00000000..b1a14ace
--- /dev/null
+++ b/test/Feature/MultipleReallocResolution.c
@@ -0,0 +1,63 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last/ | grep .err | wc -l | grep 2
+// RUN: ls klee-last/ | grep .ptr.err | wc -l | grep 2
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i, int N) {
+  int *x = malloc(sizeof(*x) * N);
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+
+  buf[0] = malloc(sizeof(int)*4);
+  buf[1] = malloc(sizeof(int));
+  buf[2] = 0; // gets malloc'd
+  buf[3] = (int*) 0xdeadbeef; // boom
+
+  buf[0][0] = 10;
+  buf[0][1] = 42;
+  buf[1][0] = 20;
+
+  int i = klee_urange(0,4);
+  int new_size = 2 * sizeof(int) * klee_urange(0,2); // 0 or 8
+
+  // whee, party time, needs to:
+  // Fork if size == 0, in which case all buffers get free'd and
+  // we will crash in prints below.
+  // Fork if buf[s] == 0, in which case the buffer gets malloc'd (for s==2)
+  // Fork on other buffers (s in [0,1]) and do realloc
+  //   for s==0 this is shrinking
+  //   for s==1 this is growing
+  buf[i] = realloc(buf[i], new_size);
+
+  if (new_size == 0) {
+    assert(!buf[2]); // free(0) is a no-op
+    if (i==0) assert(!buf[0] && buf[1]);
+    if (i==1) assert(buf[0] && !buf[1]);
+    assert(i != 3); // we should have crashed on free of invalid
+  } else {
+    assert(new_size == sizeof(int)*2);
+    assert(buf[0][0] == 10);
+    assert(buf[0][1] == 42); // make sure copied
+    assert(buf[1][0] == 20);
+    if (i==1) { int x = buf[1][1]; } // should be safe
+    if (i==2) { int x = buf[2][0]; } // should be safe
+    assert(i != 3); // we should have crashed on realloc of invalid
+  }
+
+  return 0;
+}
diff --git a/test/Feature/MultipleWriteResolution.c b/test/Feature/MultipleWriteResolution.c
new file mode 100644
index 00000000..f07b9710
--- /dev/null
+++ b/test/Feature/MultipleWriteResolution.c
@@ -0,0 +1,43 @@
+// RUN: echo "x" > %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: diff %t1.res %t1.log
+
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s,t;
+
+  for (i=0; i<4; i++)
+    buf[i] = make_int((i+1)*2);
+
+  s = klee_urange(0,4);
+
+  *buf[s] = 5;
+
+  if ((*buf[0] + *buf[1] + *buf[2] + *buf[3]) == 17)
+    if (s!=3)
+      abort();
+
+  printf("x\n");
+  fflush(stdout);
+
+  return 0;
+}
diff --git a/test/Feature/NamedSeedMatching.c b/test/Feature/NamedSeedMatching.c
new file mode 100644
index 00000000..6d52e7a4
--- /dev/null
+++ b/test/Feature/NamedSeedMatching.c
@@ -0,0 +1,41 @@
+// RUN: %llvmgcc -c -g %s -o %t.bc
+// RUN: rm -rf %t.out
+// RUN: %klee --output-dir=%t.out %t.bc "initial"
+// RUN: test -f %t.out/test000001.bout
+// RUN: not test -f %t.out/test000002.bout
+// RUN: %klee --only-replay-seeds --named-seed-matching --seed-out %t.out/test000001.bout %t.bc > %t.log
+// RUN: grep -q "a==3" %t.log
+// RUN: grep -q "b==4" %t.log
+// RUN: grep -q "c==5" %t.log
+// RUN: grep -q "x==6" %t.log
+
+#include <string.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  int a, b, c, x;
+
+  if (argc==2 && strcmp(argv[1], "initial") == 0) {
+    klee_make_symbolic_name(&a, sizeof a, "a");
+    klee_make_symbolic_name(&b, sizeof b, "b");
+    klee_make_symbolic_name(&c, sizeof c, "c");
+    klee_make_symbolic_name(&x, sizeof x, "a");
+
+    klee_assume(a == 3);
+    klee_assume(b == 4);
+    klee_assume(c == 5);
+    klee_assume(x == 6);
+  } else {
+    klee_make_symbolic_name(&a, sizeof a, "a");
+    klee_make_symbolic_name(&c, sizeof c, "c");
+    klee_make_symbolic_name(&b, sizeof b, "b");
+    klee_make_symbolic_name(&x, sizeof x, "a");
+  }
+
+  if (a==3) printf("a==3\n");
+  if (b==4) printf("b==4\n");
+  if (c==5) printf("c==5\n");
+  if (x==6) printf("x==6\n");
+
+  return 0;
+}
diff --git a/test/Feature/OneFreeError.c b/test/Feature/OneFreeError.c
new file mode 100644
index 00000000..8eb13298
--- /dev/null
+++ b/test/Feature/OneFreeError.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  free(x);
+  x[0] = 1;
+  return 0;
+}
diff --git a/test/Feature/OneOutOfBounds.c b/test/Feature/OneOutOfBounds.c
new file mode 100644
index 00000000..11a9eecb
--- /dev/null
+++ b/test/Feature/OneOutOfBounds.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  x[1] = 1;
+  free(x);
+  return 0;
+}
diff --git a/test/Feature/Optimize.c b/test/Feature/Optimize.c
new file mode 100644
index 00000000..3c9159c7
--- /dev/null
+++ b/test/Feature/Optimize.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s --emit-llvm -O0 -c -o %t2.bc
+// RUN: rm -f %t2.log
+// RUN: %klee --stop-after-n-instructions=100 --optimize %t2.bc > %t3.log
+// RUN: echo "good" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+// should complete by 100 instructions if opt is on
+
+int main() {
+  int i, res = 0;
+
+  for (i=1; i<=1000; i++)
+    res += i;
+
+  if (res == (1000*1001)/2) {
+    printf("good\n");
+  } else {
+    printf("bad\n");
+  }
+  
+  return 0;
+}
diff --git a/test/Feature/OverlappedError.c b/test/Feature/OverlappedError.c
new file mode 100644
index 00000000..3c79380c
--- /dev/null
+++ b/test/Feature/OverlappedError.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -g -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last/ | grep .out | wc -l | grep 4
+// RUN: ls klee-last/ | grep .ptr.err | wc -l | grep 2
+
+#include <stdlib.h>
+
+int main() {
+  if (klee_range(0,2, "range")) {
+    char *x = malloc(8);
+    *((int*) &x[klee_range(0,6, "range")]) = 1;
+    free(x);
+  } else {
+    char *x = malloc(8);
+    *((int*) &x[klee_range(-1,5, "range")]) = 1;
+        free(x);
+  }
+  return 0;
+}
diff --git a/test/Feature/PreferCex.c b/test/Feature/PreferCex.c
new file mode 100644
index 00000000..d73b6076
--- /dev/null
+++ b/test/Feature/PreferCex.c
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+// RUN: klee-bout-tool klee-last/test000001.bout | grep -F 'Hi\x00\x00'
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  char buf[4];
+
+  klee_make_symbolic(buf, sizeof buf);
+  klee_prefer_cex(buf, buf[0]=='H');
+  klee_prefer_cex(buf, buf[1]=='i');
+  klee_prefer_cex(buf, buf[2]=='\0');
+
+  return 0;
+}
diff --git a/test/Feature/RaiseAsm.c b/test/Feature/RaiseAsm.c
new file mode 100644
index 00000000..5b8acab4
--- /dev/null
+++ b/test/Feature/RaiseAsm.c
@@ -0,0 +1,39 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+typedef unsigned short uint16;
+typedef unsigned int   uint32;
+
+uint16 byteswap_uint16(uint16 x) {
+  return (x << 8) | (x >> 8);
+}
+uint32 byteswap_uint32(uint32 x) {
+  return ((byteswap_uint16(x) << 16) |
+          (byteswap_uint16(x >> 16)));
+}
+
+uint16 byteswap_uint16_asm(uint16 x) {
+  uint16 res;
+  __asm__("rorw $8, %w0" : "=r" (res) : "0" (x) : "cc");
+  return res;
+}
+
+uint32 byteswap_uint32_asm(uint32 x) {
+  uint32 res;
+  __asm__("rorw $8, %w0;"
+          "rorl $16, %0;"
+          "rorw $8, %w0" : "=r" (res) : "0" (x) : "cc");
+  return res;
+}
+
+int main() {
+  uint16 ui16 = klee_int("ui16");
+  uint32 ui32 = klee_int("ui32");
+
+  assert(ui16 == byteswap_uint16(byteswap_uint16_asm(ui16)));
+  assert(ui32 == byteswap_uint32(byteswap_uint32_asm(ui32)));
+
+  return 0;
+}
diff --git a/test/Feature/ReallocFailure.c b/test/Feature/ReallocFailure.c
new file mode 100644
index 00000000..e5105c33
--- /dev/null
+++ b/test/Feature/ReallocFailure.c
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  int *p = malloc(sizeof(int)*2);
+  assert(p);
+  p[1] = 52;
+
+  int *p2 = realloc(p, 1<<30);
+  assert(p2 == 0);
+  assert(p[1] == 52);
+
+  return 0;
+}
diff --git a/test/Feature/ReplayPath.c b/test/Feature/ReplayPath.c
new file mode 100644
index 00000000..3f01fa80
--- /dev/null
+++ b/test/Feature/ReplayPath.c
@@ -0,0 +1,27 @@
+// RUN: echo "1" > %t1.path
+// RUN: echo "0" >> %t1.path
+// RUN: echo "1" >> %t1.path
+// RUN: echo "0" >> %t1.path
+// RUN: echo "1" >> %t1.path
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --replay-path %t1.path %t2.bc > %t3.log
+// RUN: echo "res: 110" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+int main() {
+  int res = 1;
+  int x;
+
+  klee_make_symbolic(&x, sizeof x);
+
+  if (x&1) res *= 2;
+  if (x&2) res *= 3;
+  if (x&4) res *= 5;
+
+  // get forced branch coverage
+  if (x&2) res *= 7;
+  if (!(x&2)) res *= 11;
+  printf("res: %d\n", res);
+ 
+  return 0;
+}
diff --git a/test/Feature/Searchers.c b/test/Feature/Searchers.c
new file mode 100644
index 00000000..95ebddf2
--- /dev/null
+++ b/test/Feature/Searchers.c
@@ -0,0 +1,52 @@
+// RUN: %llvmgcc %s --emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee %t2.bc
+// RUN: %klee --use-random-search %t2.bc
+// RUN: %klee --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-batching-search %t2.bc
+// RUN: %klee --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-merge --debug-log-merge --debug-log-state-merge %t2.bc
+// RUN: %klee --use-merge --use-batching-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+
+
+/* this test is basically just for coverage and doesn't really do any
+   correctness check (aside from testing that the various combinations
+   don't crash) */
+
+int validate(char *buf, int N) {
+
+  int i;
+
+  for (i=0; i<N; i++) {
+    if (buf[i]==0) {
+      klee_merge();
+      return 0;
+    }
+  }
+  
+  klee_merge();
+  return 1;
+}
+
+#ifndef SYMBOLIC_SIZE
+#define SYMBOLIC_SIZE 15
+#endif
+int main(int argc, char **argv) {
+  int N = SYMBOLIC_SIZE;
+  unsigned char *buf = malloc(N);
+  int i;
+  
+  klee_make_symbolic(buf, N);
+  if (validate(buf, N))
+    return buf[0];
+  return 0;
+}
diff --git a/test/Feature/SetForking.c b/test/Feature/SetForking.c
new file mode 100644
index 00000000..8620110d
--- /dev/null
+++ b/test/Feature/SetForking.c
@@ -0,0 +1,28 @@
+// RUN: %llvmgcc -g -c %s -o %t.bc
+// RUN: %klee %t.bc > %t.log
+// RUN: sort %t.log | uniq -c > %t.uniq.log
+// RUN: grep "1 A" %t.uniq.log
+// RUN: grep "1 B" %t.uniq.log
+// RUN: grep "1 C" %t.uniq.log
+
+#include <stdio.h>
+
+int main() {
+  klee_set_forking(0);
+  
+  if (klee_range(0, 2, "range")) {
+    printf("A\n");
+  } else {
+    printf("A\n");
+  }
+
+  klee_set_forking(1);
+
+  if (klee_range(0, 2, "range")) {
+    printf("B\n");
+  } else {
+    printf("C\n");
+  }
+
+  return 0;
+}
diff --git a/test/Feature/Vararg.c b/test/Feature/Vararg.c
new file mode 100644
index 00000000..f782c15e
--- /dev/null
+++ b/test/Feature/Vararg.c
@@ -0,0 +1,82 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t2.out
+// RUN: grep "types: (52, 37, 2.00, (9,12,15))" %t2.out
+// RUN: test -f klee-last/test000001.ptr.err
+
+#include <stdarg.h>
+#include <assert.h>
+#include <stdio.h>
+
+struct triple {
+  int first, second, third;
+};
+
+int test1(int x, ...) {
+  va_list ap;
+  va_start(ap, x);
+  int i32 = va_arg(ap, int);
+  long long i64 = va_arg(ap, long long);
+  double d = va_arg(ap, double);
+  struct triple p = va_arg(ap, struct triple);
+  printf("types: (%d, %lld, %.2f, (%d,%d,%d))\n", i32, i64, d, p.first, p.second, p.third);
+  va_end(ap);
+}
+
+int sum(int N, ...) {
+  int i, res = 0;
+  va_list ap,ap2;
+  
+  va_start(ap, N);
+  for (i=0; i<N; i++) {
+    if (i==1)
+      va_copy(ap2, ap);
+    res += va_arg(ap, int);
+  }
+  for (i=0; i<N-1; i++)
+    res += va_arg(ap2, int);
+  va_end(ap);
+
+  return res;
+}
+
+// test using aps in an array (no multiple resolution
+// testing, though)
+int va_array(int N, ...) {
+  va_list aps[2];
+  unsigned i;
+  unsigned sum1 = 0, sum2 = 0;
+
+  for (i=0; i<2; i++)
+    va_start(aps[i], N);
+  
+  for (i=0; i<N; i++) {
+    unsigned cmd = va_arg(aps[0], int);
+
+    if (cmd==0) {
+      sum1 += va_arg(aps[0],int);
+    } else if (cmd==1) {
+      sum2 += va_arg(aps[1],int);
+    } else if (cmd==2) {
+      va_copy(aps[1], aps[0]);
+    }
+  }
+
+  for (i=0; i<2; i++)
+    va_end(aps[i]);
+
+  return 3*sum1 + 5*sum2;
+}
+
+int main() {
+  struct triple p = { 9, 12, 15 };
+  test1(-1, 52, 37ll, 2.0, p);
+
+  assert(sum(2, 3, 4) == 11);
+  assert(sum(0) == 0);
+  assert(va_array(5, 0, 5, 1, 1, 2, 1)==45); // 15 + 30
+
+  // should give memory error
+  test1(-1, 52, 37, 2.0, p);
+
+  return 0;
+}
diff --git a/test/Feature/WithLibc.c b/test/Feature/WithLibc.c
new file mode 100644
index 00000000..5e84eb4a
--- /dev/null
+++ b/test/Feature/WithLibc.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --libc=klee %t2.bc > %t3.log
+// RUN: echo "good" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+int main() {
+  char buf[4];
+  char *s = "foo";
+
+  klee_make_symbolic(buf, sizeof buf);
+  buf[3] = 0;
+
+  if (strcmp(buf, s)==0) {
+    if (buf[0]=='f' && buf[1]=='o' && buf[2]=='o' && buf[3]==0) {
+      printf("good\n");
+    } else {
+      printf("bad\n");
+    }
+  }
+  
+  return 0;
+}
diff --git a/test/Feature/WriteCov.c b/test/Feature/WriteCov.c
new file mode 100644
index 00000000..defc7e59
--- /dev/null
+++ b/test/Feature/WriteCov.c
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t2.bc
+// RUN: %klee --exit-on-error --write-cov %t2.bc
+// RUN: grep WriteCov.c:10 klee-last/test000002.cov
+// RUN: grep WriteCov.c:12 klee-last/test000001.cov
+
+#include <assert.h>
+
+int main() {
+  if (klee_range(0,2, "range")) {
+    assert(__LINE__ == 10); printf("__LINE__ = %d\n", __LINE__);
+  } else {
+    assert(__LINE__ == 12); printf("__LINE__ = %d\n", __LINE__);
+  }
+  return 0;
+}
diff --git a/test/Feature/_utils._ll b/test/Feature/_utils._ll
new file mode 100644
index 00000000..32a73bb1
--- /dev/null
+++ b/test/Feature/_utils._ll
@@ -0,0 +1,71 @@
+define i32 @util_make_and_i1(i32 %a, i32 %b) {
+        %a_i1 = icmp ne i32 %a, 0
+        %b_i1 = icmp ne i32 %b, 0
+        %res_i1 = and i1 %a_i1, %b_i1
+        %res = zext i1 %res_i1 to i32
+        ret i32 %res
+}
+
+define i32 @util_make_or_i1(i32 %a, i32 %b) {
+        %a_i1 = icmp ne i32 %a, 0
+        %b_i1 = icmp ne i32 %b, 0
+        %res_i1 = or i1 %a_i1, %b_i1
+        %res = zext i1 %res_i1 to i32
+        ret i32 %res
+}
+
+define i16 @util_make_concat2(i8 %a, i8 %b) {
+        %tmp = alloca i16
+        %tmp8 = bitcast i16* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        store i8 %b, i8* %p0
+        store i8 %a, i8* %p1
+        %concat = load i16* %tmp
+        ret i16 %concat
+}
+
+define i32 @util_make_concat4(i8 %a, i8 %b, i8 %c, i8 %d) {
+        %tmp = alloca i32
+        %tmp8 = bitcast i32* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        %p2 = getelementptr i8* %tmp8, i32 2
+        %p3 = getelementptr i8* %tmp8, i32 3
+        store i8 %d, i8* %p0
+        store i8 %c, i8* %p1
+        store i8 %b, i8* %p2
+        store i8 %a, i8* %p3
+        %concat = load i32* %tmp
+        ret i32 %concat
+}
+
+define i64 @util_make_concat8(i8 %a, i8 %b, i8 %c, i8 %d, 
+                              i8 %e, i8 %f, i8 %g, i8 %h) {
+        %tmp = alloca i64
+        %tmp8 = bitcast i64* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        %p2 = getelementptr i8* %tmp8, i32 2
+        %p3 = getelementptr i8* %tmp8, i32 3
+        %p4 = getelementptr i8* %tmp8, i32 4
+        %p5 = getelementptr i8* %tmp8, i32 5
+        %p6 = getelementptr i8* %tmp8, i32 6
+        %p7 = getelementptr i8* %tmp8, i32 7
+        store i8 %h, i8* %p0
+        store i8 %g, i8* %p1
+        store i8 %f, i8* %p2
+        store i8 %e, i8* %p3
+        store i8 %d, i8* %p4
+        store i8 %c, i8* %p5
+        store i8 %b, i8* %p6
+        store i8 %a, i8* %p7
+        %concat = load i64* %tmp
+        ret i64 %concat
+}
+
+define i32 @util_make_select(i32 %cond, i32 %t, i32 %f) {
+        %cond_i1 = icmp ne i32 %cond, 0
+        %res = select i1 %cond_i1, i32 %t, i32 %f
+        ret i32 %res
+}
\ No newline at end of file
diff --git a/test/Feature/const_array_opt1.c b/test/Feature/const_array_opt1.c
new file mode 100644
index 00000000..96c46fb9
--- /dev/null
+++ b/test/Feature/const_array_opt1.c
@@ -0,0 +1,37 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --const-array-opt --max-time=10 --only-output-states-covering-new %t.bc >%t.log
+// grep -q "Finished successfully!\n"
+
+/* This is testing the const array optimization.  On my 2.3GHz machine
+   this takes under 2 seconds w/ the optimization and almost 6 minutes
+   w/o.  So we kill it in 10 sec and check if it has finished
+   successfully. */
+
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+  
+int main() {
+#define N 8192
+#define N_IDX 16
+  unsigned char a[N];
+  unsigned i, k[N_IDX];
+
+  for (i=0; i<N; i++)
+    a[i] = i % 256;
+  
+  klee_make_symbolic_name(k, sizeof(k), "k");
+  
+  for (i=0; i<N_IDX; i++) {
+    if (k[i] >= N)
+      klee_silent_exit(0);
+
+    if (a[k[i]] == i)
+      assert(k[i] % 256 == i);
+    else klee_silent_exit(0);
+  }
+
+  printf("Finished successfully!\n");
+
+  return 0;
+}
diff --git a/test/Feature/dg.exp b/test/Feature/dg.exp
new file mode 100644
index 00000000..879685ca
--- /dev/null
+++ b/test/Feature/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/test/Feature/utils.h b/test/Feature/utils.h
new file mode 100644
index 00000000..5423a0dc
--- /dev/null
+++ b/test/Feature/utils.h
@@ -0,0 +1,16 @@
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+uint32_t util_make_and_i1(uint32_t a, uint32_t b);
+uint32_t util_make_or_i1(uint32_t a, uint32_t b);
+
+uint16_t util_make_concat2(uint8_t a, uint8_t b);
+uint32_t util_make_concat4(uint8_t a, uint8_t b, 
+                           uint8_t c, uint8_t d);
+uint64_t util_make_concat8(uint8_t a, uint8_t b,
+                           uint8_t c, uint8_t d,
+                           uint8_t e, uint8_t f,
+                           uint8_t g, uint8_t h);
+uint32_t util_make_select(uint32_t cond, uint32_t true, uint32_t false);
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 00000000..0c42a6f6
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,101 @@
+#===- test/Makefile ----------------------------------------*- Makefile -*--===#
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+# 
+#===------------------------------------------------------------------------===#
+
+LEVEL  = ..
+DIRS   = 
+
+#
+# Make Dejagnu the default for testing
+#
+all:: check-local
+
+# Include other test rules
+include Makefile.tests
+
+#===------------------------------------------------------------------------===#
+# DejaGNU testing support
+#===------------------------------------------------------------------------===#
+
+ifdef TESTSUITE
+CLEANED_TESTSUITE := $(patsubst %/,%,$(TESTSUITE))
+CLEANED_TESTSUITE := $(patsubst test/%,%,$(CLEANED_TESTSUITE))
+RUNTESTFLAGS := --tool $(CLEANED_TESTSUITE)
+endif
+
+ifneq ($(RUNTEST),)
+check-local:: site.exp
+	( ulimit -t 600 ; ulimit -d 512000 ; \
+	  PATH="$(ToolDir):$(LLVMToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \
+	  $(RUNTEST) $(RUNTESTFLAGS) ;  \
+	  ! grep FAIL testrun.log )
+else
+check-local:: site.exp
+	@echo "*** dejagnu not found.  Make sure runtest is in your PATH, then reconfigure llvm."
+endif
+
+ifdef TESTONE
+CLEANED_TESTONE := $(patsubst %/,%,$(TESTONE))
+CLEANED_TESTONE := $(patsubst test/%,%,$(CLEANED_TESTONE))
+SUBDIR := $(shell dirname $(CLEANED_TESTONE))
+TESTPATH := $(PROJ_SRC_ROOT)/test/$(CLEANED_TESTONE)
+check-one: site.exp $(TCLSH)
+	$(Verb)( echo "source $(PROJ_OBJ_ROOT)/test/site.exp" ; \
+	  echo "set subdir $(SUBDIR)" ; \
+	  echo "proc pass  { msg } { puts \"PASS: \$$msg\" } "; \
+	  echo "proc fail  { msg } { puts \"FAIL: \$$msg\" }" ; \
+	  echo "proc xfail { msg } { puts \"XFAIL: \$$msg\" }" ; \
+	  echo "proc xpass { msg } { puts \"XPASS: \$$msg\" }" ; \
+	  echo "source $(PROJ_SRC_ROOT)/test/lib/llvm.exp" ; \
+	  echo "RunLLVMTests $(TESTPATH)" ) | \
+	( ulimit -t 600 ; ulimit -d 512000 ; \
+	  PATH="$(ToolDir):$(LLVMToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \
+	  $(TCLSH) )
+endif
+
+clean::
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name Output -type d -print`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'ft-out*' -type d -print`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'ft-last' -print`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'klee-last'`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'klee-out*'`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name '*~'`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name test.log`
+	rm -f site.exp
+
+site.exp: Makefile $(LEVEL)/Makefile.config
+	@echo 'Making a new site.exp file...'
+	@echo '## these variables are automatically generated by make ##' >site.tmp
+	@echo '# Do not edit here.  If you wish to override these values' >>site.tmp
+	@echo '# edit the last section' >>site.tmp
+	@echo 'set target_triplet "$(TARGET_TRIPLE)"' >> site.tmp
+	@echo 'set ENABLE_UCLIBC "$(ENABLE_UCLIBC)"' >> site.tmp
+	@echo 'set ENABLE_POSIX_RUNTIME "$(ENABLE_POSIX_RUNTIME)"' >> site.tmp
+	@echo 'set TEST_FEATURE_LIST "$(TEST_FEATURE_LIST)"' >> site.tmp
+	@echo 'set prcontext "$(TCLSH) $(LLVM_SRC_ROOT)/test/Scripts/prcontext.tcl"' >> site.tmp
+	@echo 'set llvmtoolsdir "$(ToolDir)"' >>site.tmp
+	@echo 'set llvmlibsdir "$(LibDir)"' >>site.tmp
+	@echo 'set srcroot "$(PROJ_SRC_ROOT)"' >>site.tmp
+	@echo 'set objroot "$(PROJ_OBJ_ROOT)"' >>site.tmp
+	@echo 'set srcdir "$(PROJ_SRC_ROOT)/test"' >>site.tmp
+	@echo 'set objdir "$(PROJ_OBJ_ROOT)/test"' >>site.tmp
+	@echo 'set gccpath "$(CC)"' >>site.tmp
+	@echo 'set gxxpath "$(CXX)"' >>site.tmp
+	@echo 'set compile_c "$(CC) $(CPP.Flags) $(C.Flags) $(CompileCommonOpts) -c "' >>site.tmp
+	@echo 'set compile_cxx "$(CXX) $(CPP.Flags) $(CXX.Flags) $(CompileCommonOpts) - c"' >> site.tmp
+	@echo 'set link "$(CXX) $(CPP.Flags) $(CXX.Flags) $(CompileCommonOpts) $(LD.Flags)"' >>site.tmp
+	@echo 'set llvmgcc "$(LLVMGCC)"' >> site.tmp
+	@echo 'set llvmgxx "$(LLVMGCC)"' >> site.tmp
+	@echo 'set llvmgccmajvers "$(LLVMGCC_MAJVERS)"' >> site.tmp
+	@echo 'set shlibext "$(SHLIBEXT)"' >> site.tmp
+	@echo '## All variables above are generated by configure. Do Not Edit ## ' >>site.tmp
+	@test ! -f site.exp || \
+	sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+	@-rm -f site.bak
+	@test ! -f site.exp || mv site.exp site.bak
+	@mv site.tmp site.exp
diff --git a/test/Makefile.tests b/test/Makefile.tests
new file mode 100644
index 00000000..ad9f2eab
--- /dev/null
+++ b/test/Makefile.tests
@@ -0,0 +1,80 @@
+##----------------------------------------------------------*- Makefile -*-===##
+##
+## Common rules for generating, linking, and compiling via LLVM.  This is
+## used to implement a robust testing framework for LLVM
+##
+##-------------------------------------------------------------------------===##
+
+# If the user specified a TEST= option on the command line, we do not want to do
+# the default testing type.  Instead, we change the default target to be the
+# test:: target.
+#
+ifdef TEST
+test::
+endif
+
+# We do not want to make .d files for tests! 
+DISABLE_AUTO_DEPENDENCIES=1
+
+include ${LEVEL}/Makefile.common
+
+# Specify ENABLE_STATS on the command line to enable -stats and -time-passes
+# output from gccas and gccld.
+ifdef ENABLE_STATS
+STATS = -stats -time-passes
+endif
+
+.PHONY: clean default
+
+# These files, which might be intermediate results, should not be deleted by
+# make
+.PRECIOUS: Output/%.bc  Output/%.ll
+.PRECIOUS: Output/%.tbc Output/%.tll
+.PRECIOUS: Output/.dir
+.PRECIOUS: Output/%.llvm.bc
+.PRECIOUS: Output/%.llvm
+
+LCCFLAGS  += -O2 -Wall
+LCXXFLAGS += -O2 -Wall
+LLCFLAGS =
+TESTRUNR = @echo Running test: $<; \
+             PATH="$(LLVMTOOLCURRENT):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \
+                  $(LLVM_SRC_ROOT)/test/TestRunner.sh
+
+LLCLIBS := $(LLCLIBS) -lm
+
+clean::
+	$(RM) -f a.out core
+	$(RM) -rf Output/
+
+# Compile from X.c to Output/X.ll
+Output/%.ll: %.c $(LCC1) Output/.dir $(INCLUDES)
+	-$(LLVMGCCWITHPATH) $(CPPFLAGS) $(LCCFLAGS) -S $< -o $@
+
+# Compile from X.cpp to Output/X.ll
+Output/%.ll: %.cpp $(LCC1XX) Output/.dir $(INCLUDES)
+	-$(LLVMGXXWITHPATH) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# Compile from X.cc to Output/X.ll
+Output/%.ll: %.cc $(LCC1XX) Output/.dir $(INCLUDES)
+	-$(LLVMGXXWITHPATH) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# LLVM Assemble from Output/X.ll to Output/X.bc.  Output/X.ll must have come
+# from GCC output, so use GCCAS.
+#
+Output/%.bc: Output/%.ll $(LGCCAS)
+	-$(LGCCAS) $(STATS) $< -o $@
+
+# LLVM Assemble from X.ll to Output/X.bc.  Because we are coming directly from
+# LLVM source, use the non-transforming assembler.
+#
+Output/%.bc: %.ll $(LLVMAS) Output/.dir
+	-$(LLVMAS) -f $< -o $@
+
+## Cancel built-in implicit rules that override above rules
+%: %.s
+
+%: %.c
+
+%.o: %.c
+
diff --git a/test/README b/test/README
new file mode 100644
index 00000000..53d30ce2
--- /dev/null
+++ b/test/README
@@ -0,0 +1 @@
+about tests....
diff --git a/test/Runtime/POSIX/DirConsistency.c b/test/Runtime/POSIX/DirConsistency.c
new file mode 100644
index 00000000..613655e9
--- /dev/null
+++ b/test/Runtime/POSIX/DirConsistency.c
@@ -0,0 +1,64 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --run-in=/tmp --use-random-search --init-env --libc=uclibc --posix-runtime --exit-on-error %t.bc --sym-files 1 1 > %t1.log
+// RUN: %llvmgcc -D_FILE_OFFSET_BITS=64 %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --run-in=/tmp --use-random-search --init-env --libc=uclibc --posix-runtime --exit-on-error %t.bc --sym-files 1 1 > %t2.log
+// RUN: sort %t1.log %t2.log | uniq -c > %t3.log
+// RUN: grep -q "4 COUNT" %t3.log
+
+// For this test really to work as intended it needs to be run in a
+// directory large enough to cause uclibc to do multiple getdents
+// calls (otherwise uclibc will handle the seeks itself). We should
+// create a bunch of files or something.
+//
+// It is even more important for this test because it requires the
+// directory not to change while running, which might be a lot to
+// demand of /tmp.
+
+#define _LARGEFILE64_SOURCE
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+int main(int argc, char **argv) {
+  struct stat s;
+  int res = stat("A", &s);
+  int hasA = !(res!=0 && errno==ENOENT);
+
+  //printf("sizeof(dirent) = %d\n", sizeof(struct dirent));
+  //printf("sizeof(dirent64) = %d\n", sizeof(struct dirent64));
+
+  //printf("\"A\" exists: %d\n", hasA);
+
+  DIR *d = opendir(".");
+  assert(d);
+
+  int snum = 1;
+  if (klee_range(0,2,"range")) {
+    snum = 2;
+    printf("state%d\n", snum);
+  }
+
+  int foundA = 0, count = 0;
+  struct dirent *de;
+  while ((de = readdir(d))) {
+    //    printf("state%d: dirent: %s\n", snum, de->d_name);
+    if (strcmp(de->d_name, "A") == 0)
+      foundA = 1;
+    count++;
+  }
+  
+  closedir(d);
+
+  //printf("found A: %d\n", foundA);
+
+  // Ensure atomic write
+  char buf[64];
+  sprintf(buf, "COUNT: %d\n", count);
+  fputs(buf, stdout);
+  assert(hasA == foundA);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/DirSeek.c b/test/Runtime/POSIX/DirSeek.c
new file mode 100644
index 00000000..1735fdb8
--- /dev/null
+++ b/test/Runtime/POSIX/DirSeek.c
@@ -0,0 +1,57 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --run-in=/tmp --init-env --libc=uclibc --posix-runtime --exit-on-error %t2.bc --sym-files 2 2
+// RUN: %klee --run-in=/tmp --init-env --libc=uclibc --posix-runtime --exit-on-error %t2.bc --sym-files 1 2
+// RUN: %klee --run-in=/tmp --init-env --libc=uclibc --posix-runtime --exit-on-error %t2.bc --sym-files 0 2
+
+// For this test really to work as intended it needs to be run in a
+// directory large enough to cause uclibc to do multiple getdents
+// calls (otherwise uclibc will handle the seeks itself). We should
+// create a bunch of files or something.
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  struct stat s;
+
+  char first[256], second[256];
+  DIR *d = opendir(".");
+  struct dirent *de = readdir(d);
+  assert(de);
+  strcpy(first, de->d_name);
+  off_t pos = telldir(d);
+  printf("pos: %d\n", telldir(d));
+  de = readdir(d);
+  assert(de);
+  strcpy(second, de->d_name);
+
+  // Go back to second and check
+  seekdir(d, pos);
+  de = readdir(d);
+  assert(de);
+  assert(strcmp(de->d_name, second) == 0);
+
+  // Go to end, then back to 2nd
+  while (de)
+    de = readdir(d);
+  assert(!errno);
+  seekdir(d, pos);
+  assert(telldir(d) == pos);
+  de = readdir(d);
+  assert(de);
+  assert(strcmp(de->d_name, second) == 0);
+
+  // Go to beginning and check
+  rewinddir(d);
+  de = readdir(d);
+  assert(de);
+  assert(strcmp(de->d_name, first) == 0);  
+  closedir(d);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/FDNumbers.c b/test/Runtime/POSIX/FDNumbers.c
new file mode 100644
index 00000000..e576f9bb
--- /dev/null
+++ b/test/Runtime/POSIX/FDNumbers.c
@@ -0,0 +1,24 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t2.bc --sym-files 1 10
+
+#include <assert.h>
+#include <fcntl.h>
+#include <errno.h>
+
+int main(int argc, char **argv) {
+  int fd = open("A", O_TRUNC);
+  assert(fd == 3);
+  assert(!close(0));
+  assert(!close(1));
+  assert(close(0) == -1);
+  assert(close(1) == -1);
+  assert(open("A", O_TRUNC) == 0);  
+  assert(dup(0) == 1);
+  assert(open("A", O_TRUNC) == 4);
+  assert(!close(1));
+  assert(open("A", O_TRUNC) == 1);
+  assert(dup(0) != 1);
+  assert(dup2(0,1) == 1);
+  
+  return 0;
+}
diff --git a/test/Runtime/POSIX/FD_Fail.c b/test/Runtime/POSIX/FD_Fail.c
new file mode 100644
index 00000000..cf1d4d5a
--- /dev/null
+++ b/test/Runtime/POSIX/FD_Fail.c
@@ -0,0 +1,25 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=uclibc --posix-runtime --init-env %t1.bc --sym-files 0 0 --max-fail 1 > %t.log
+// RUN: grep -q "fread(): ok" %t.log
+// RUN: grep -q "fread(): fail" %t.log
+// RUN: grep -q "fclose(): ok" %t.log
+// RUN: grep -q "fclose(): fail" %t.log
+
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  char buf[1024];  
+  FILE* f = fopen("/etc/fstab", "r");
+  assert(f);
+    
+  int r = fread(buf, 1, 100, f);
+  printf("fread(): %s\n", 
+         r ? "ok" : "fail");
+
+  r = fclose(f);
+  printf("fclose(): %s\n", 
+         r ? "ok" : "fail");
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/FD_Fail2.c b/test/Runtime/POSIX/FD_Fail2.c
new file mode 100644
index 00000000..c9195f66
--- /dev/null
+++ b/test/Runtime/POSIX/FD_Fail2.c
@@ -0,0 +1,34 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=uclibc --posix-runtime --init-env %t1.bc --sym-files 0 0 --max-fail 1
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: test -f klee-last/test000003.bout
+// RUN: test -f klee-last/test000004.bout
+// RUN: test -f klee-last/test000005.bout
+// RUN: test -f klee-last/test000006.bout
+// RUN: test -f klee-last/test000007.bout
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int main(int argc, char** argv) {
+  char buf[1024];  
+  int fd = open("/etc/fstab", O_RDONLY);
+  assert(fd != -1);
+    
+  int r = read(fd, buf, 1, 100);
+  if (r != -1)
+    printf("read() succeeded\n");
+  else printf("read() failed with errno %s\n", strerror(errno));
+
+  r = close(fd);
+  if (r != -1)
+    printf("close() succeeded\n");
+  else printf("close() failed with errno %s\n", strerror(errno));
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/Fcntl.c b/test/Runtime/POSIX/Fcntl.c
new file mode 100644
index 00000000..139fb1f3
--- /dev/null
+++ b/test/Runtime/POSIX/Fcntl.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t2.bc --sym-files 1 10
+
+#include <assert.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv) {
+  int fd = open("A", O_RDWR|O_TRUNC);
+  if (fd == -1)
+    klee_silent_exit(0);
+  assert(fd == 3);
+  assert((fcntl(fd, F_GETFD) & FD_CLOEXEC) == 0);
+  assert(fcntl(fd, F_SETFD, FD_CLOEXEC, 1) == 0);
+  assert((fcntl(fd, F_GETFD) & FD_CLOEXEC) != 0);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/FilePerm.c b/test/Runtime/POSIX/FilePerm.c
new file mode 100644
index 00000000..818d482f
--- /dev/null
+++ b/test/Runtime/POSIX/FilePerm.c
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --posix-runtime --init-env %t.bc --sym-files 1 10 --sym-stdout 2>%t.log 
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: test -f klee-last/test000003.bout
+
+#include <stdio.h>       
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int main(int argc, char** argv) {
+  int fd = open("A", O_RDWR);
+  if (fd != -1)
+    fprintf(stderr, "File 'A' opened successfully\n");
+  else fprintf(stderr, "Cannot open file 'A'\n");
+
+  if (fd != -1)
+    close(fd);
+}
diff --git a/test/Runtime/POSIX/FreeArgv.c b/test/Runtime/POSIX/FreeArgv.c
new file mode 100644
index 00000000..37909b80
--- /dev/null
+++ b/test/Runtime/POSIX/FreeArgv.c
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --init-env --posix-runtime %t.bc --sym-args 1 1 1
+// RUN: test -f klee-last/test000001.free.err
+// RUN: test -f klee-last/test000002.free.err
+// RUN: test -f klee-last/test000003.free.err
+
+int main(int argc, char **argv) {
+  switch(klee_range(0, 3, "range")) {
+  case 0:
+    free(argv);
+    break;
+  case 1:
+    free(argv[0]);
+    break;
+  case 2:
+    free(argv[1]);
+    break;
+  }
+  return 0;
+}
diff --git a/test/Runtime/POSIX/Getenv.c b/test/Runtime/POSIX/Getenv.c
new file mode 100644
index 00000000..7ec66788
--- /dev/null
+++ b/test/Runtime/POSIX/Getenv.c
@@ -0,0 +1,21 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --libc=klee --posix-runtime --exit-on-error %t2.bc --sym-files 1 10
+
+#include <assert.h>
+
+int main(int argc, char **argv) {
+  char *g = getenv("PWD");
+  if (g) {
+    printf("have PWD\n");
+  } else {
+    printf("have no PWD\n");
+  }
+
+  g = getenv("HELLO");
+  if (!g || strcmp(g, "nice")==0) {
+    printf("getenv(\"HELLO\") = %p\n", g);
+    if (g) assert(strcmp(getenv("HELLO"),"nice") == 0);
+  }
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/Ioctl.c b/test/Runtime/POSIX/Ioctl.c
new file mode 100644
index 00000000..0e7b2cad
--- /dev/null
+++ b/test/Runtime/POSIX/Ioctl.c
@@ -0,0 +1,31 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t.bc --sym-files 0 4
+
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <asm/ioctls.h>
+#include <errno.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  struct stat s;
+  struct termios ts;
+
+  assert(fstat(0, &s) == 0);
+
+  assert(ioctl(10, FIONREAD, &ts) == -1 && errno == EBADF);
+
+  if (S_ISCHR(s.st_mode)) {
+    printf("is chr\n");
+    assert(ioctl(0, TIOCGWINSZ, &ts) == 0);
+  } else {
+    printf("not chr\n");
+    // I think TC* ioctls basically always fail on nonchr?
+    assert(ioctl(0, TIOCGWINSZ, &ts) == -1);
+    assert(errno == ENOTTY);
+  }
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/Isatty.c b/test/Runtime/POSIX/Isatty.c
new file mode 100644
index 00000000..6a78dc96
--- /dev/null
+++ b/test/Runtime/POSIX/Isatty.c
@@ -0,0 +1,33 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 0 10 --sym-stdout 2>%t.log
+
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: test -f klee-last/test000003.bout
+// RUN: test -f klee-last/test000004.bout
+
+// RUN: grep -q "stdin is a tty" %t.log
+// RUN: grep -q "stdin is NOT a tty" %t.log
+// RUN: grep -q "stdout is a tty" %t.log
+// RUN: grep -q "stdout is NOT a tty" %t.log
+
+#include <unistd.h>
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  int fd0 = 0; // stdin
+  int fd1 = 1; // stdout
+
+  int r = isatty(fd0);
+  if (r) 
+    fprintf(stderr, "stdin is a tty\n");
+  else fprintf(stderr, "stdin is NOT a tty\n");
+  
+  r = isatty(fd1);
+  if (r) 
+    fprintf(stderr, "stdout is a tty\n");
+  else fprintf(stderr, "stdout is NOT a tty\n");
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/PrgName.c b/test/Runtime/POSIX/PrgName.c
new file mode 100644
index 00000000..19a56889
--- /dev/null
+++ b/test/Runtime/POSIX/PrgName.c
@@ -0,0 +1,31 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t2.bc --sym-arg 10 >%t.log
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: grep -q "No" %t.log
+// RUN: grep -qv "Yes" %t.log
+
+
+/* Simple test for argv[0] */
+
+#include <stdio.h>
+
+int f(int argc, char **argv) {
+
+  if (argv[0][5] == '7')
+    printf("Yes\n");
+  else printf("No\n");
+
+  printf("%c\n", argv[0][5]);
+
+  if (argv[1][1] == 4)
+    printf("4\n");
+  printf("not 4\n");
+
+  return 0;
+}
+
+
+int main(int argc, char **argv) {
+  f(argc, argv);
+}
diff --git a/test/Runtime/POSIX/Read1.c b/test/Runtime/POSIX/Read1.c
new file mode 100644
index 00000000..3b24bfb9
--- /dev/null
+++ b/test/Runtime/POSIX/Read1.c
@@ -0,0 +1,34 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --exit-on-error --posix-runtime --init-env %t.bc --sym-files 1 8 >%t.log
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  char buf[32];
+
+  // If count is zero, read() returns zero and has  no  other  results. (man page)
+  int x = read(0, 0, 0);
+  assert(x == 0);
+  
+  int fd = open("A", O_RDONLY);
+  assert(fd != -1);
+
+  // EFAULT buf is outside your accessible address space. (man page)
+  x = read(fd, 0, 1);
+  assert(x == -1 && errno == EFAULT);
+ 
+  // EBADF  fd is not a valid file descriptor (man page)
+  x = read(-1, buf, 1);
+  assert(x == -1 && errno == EBADF);
+
+  fd = open("A", O_RDONLY);
+  assert(fd != -1);
+  x = read(fd, buf, 1);
+  assert(x == 1);  
+}
+
diff --git a/test/Runtime/POSIX/SELinux.c b/test/Runtime/POSIX/SELinux.c
new file mode 100644
index 00000000..65dd1a7f
--- /dev/null
+++ b/test/Runtime/POSIX/SELinux.c
@@ -0,0 +1,30 @@
+/* Very basic test, as right now SELinux support is extremely basic */
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --posix-runtime --exit-on-error %t1.bc --sym-arg 2 > %t.log
+// XFAIL: no-selinux
+
+#include <selinux/selinux.h>
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+
+  security_context_t con;
+
+  assert(argc == 2);
+
+  int selinux = is_selinux_enabled();
+  printf("selinux enabled = %d\n", selinux);
+  
+  if (setfscreatecon(argv[1]) < 0)
+    printf("Error: set\n");
+  else printf("Success: set\n");
+  
+  if (getfscreatecon(&con) < 0)
+    printf("Error: get\n");
+  else printf("Success: get\n");
+
+  printf("create_con = %s\n", con);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/SeedAndFail.c b/test/Runtime/POSIX/SeedAndFail.c
new file mode 100644
index 00000000..64cf79bd
--- /dev/null
+++ b/test/Runtime/POSIX/SeedAndFail.c
@@ -0,0 +1,38 @@
+// RUN: %llvmgcc %s -emit-llvm -g -O0 -c -o %t.bc
+// RUN: rm -rf tmp-123
+// RUN: %klee --libc=klee --output-dir=tmp-123 --posix-runtime --init-env %t.bc --sym-files 1 10  2>%t.log
+// RUN: klee --seed-out-dir=tmp-123 --zero-seed-extension --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 1 10 --max-fail 1
+// RUN: ls klee-last | grep -c assert | grep 4
+
+
+
+#include <stdio.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+int main(int argc, char** argv) {
+  char buf[32];
+  
+  int fd = open("A", O_RDWR | O_CREAT, S_IRWXU);
+  assert(fd != -1);
+  int nbytes = write(fd, "Hello", sizeof("Hello"));
+  assert(nbytes == sizeof("Hello"));
+
+  off_t off = lseek(fd, 0, SEEK_SET);
+  assert(off != (off_t) -1);
+
+  nbytes = read(fd, buf, sizeof("Hello"));
+  assert(nbytes == sizeof("Hello"));
+  
+  int r = close(fd);
+  assert(r == 0);
+
+  r = memcmp(buf, "Hello", sizeof("Hello"));
+  assert(r == 0);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/Stdin.c b/test/Runtime/POSIX/Stdin.c
new file mode 100644
index 00000000..065533a1
--- /dev/null
+++ b/test/Runtime/POSIX/Stdin.c
@@ -0,0 +1,56 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --init-env --libc=klee --posix-runtime --exit-on-error %t.bc --sym-files 0 4 > %t.log
+// RUN: grep "mode:file" %t.log
+// RUN: grep "mode:dir" %t.log
+// RUN: grep "mode:chr" %t.log
+// RUN: grep "mode:blk" %t.log
+// RUN: grep "mode:fifo" %t.log
+// RUN: grep "mode:lnk" %t.log
+// RUN: grep "read:sym:yes" %t.log
+// RUN: grep "read:sym:no" %t.log
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+int main(int argc, char **argv) {
+  struct stat stats;
+  assert(fstat(0, &stats) == 0);
+
+  if (S_ISREG(stats.st_mode)) {
+    printf("mode:file\n");
+  } else if (S_ISDIR(stats.st_mode)) {
+    printf("mode:dir\n");
+  } else if (S_ISCHR(stats.st_mode)) {
+    printf("mode:chr\n");
+  } else if (S_ISBLK(stats.st_mode)) {
+    printf("mode:blk\n");
+  } else if (S_ISFIFO(stats.st_mode)) {
+    printf("mode:fifo\n");
+  } else if (S_ISLNK(stats.st_mode)) {
+    printf("mode:lnk\n");
+  } else if (S_ISSOCK(stats.st_mode)) {
+    printf("mode:sock\n");
+  } else {
+    printf("unknown mode\n");
+  }
+
+  assert(stats.st_size==4);
+
+  if (S_ISREG(stats.st_mode)) {
+    char buf[10];
+    int n = read(0, buf, 5);
+    assert(n == 4);
+    
+    if (strcmp(buf, "HI!")) {
+      printf("read:sym:yes\n");
+    } else {
+      printf("read:sym:no\n");
+    }
+  }
+
+  fflush(stdout);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/Write1.c b/test/Runtime/POSIX/Write1.c
new file mode 100644
index 00000000..73902363
--- /dev/null
+++ b/test/Runtime/POSIX/Write1.c
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --exit-on-error --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 1 10 --sym-stdout 2>%t.log
+
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  char buf[32];
+  
+  FILE* f = fopen("A", "w");
+  if (!f)
+    klee_silent_exit(0);
+  fwrite("Hello", sizeof("Hello"), 1, f);
+  fclose(f);
+  
+  f = fopen("A", "r");
+  fread(buf, sizeof("Hello"), 1, f);
+  fclose(f);
+
+  assert(memcmp(buf, "Hello", sizeof("Hello")) == 0);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/Write2.c b/test/Runtime/POSIX/Write2.c
new file mode 100644
index 00000000..4865b479
--- /dev/null
+++ b/test/Runtime/POSIX/Write2.c
@@ -0,0 +1,21 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --exit-on-error --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 1 10 --sym-stdout 2>%t.log
+
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  const char* msg = "This will eventually overflow stdout. ";
+  char buf[32];
+  int i;
+  
+  FILE* f = stdout;//fopen("A", "w");
+  if (!f)
+    klee_silent_exit(0);
+
+  for (i = 0; i < 300; i++)
+    fwrite(msg, sizeof(msg), 1, f);
+  fclose(f);
+
+  return 0;
+}
diff --git a/test/Runtime/POSIX/dg.exp b/test/Runtime/POSIX/dg.exp
new file mode 100644
index 00000000..88406208
--- /dev/null
+++ b/test/Runtime/POSIX/dg.exp
@@ -0,0 +1,5 @@
+load_lib llvm.exp
+
+if { [klee_supports_posix_runtime] } {
+    RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
+}
diff --git a/test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c b/test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c
new file mode 100644
index 00000000..83e6a57a
--- /dev/null
+++ b/test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error --optimize --libc=uclibc %t1.bc
+
+#include <string.h>
+#include <assert.h>
+
+int main() {
+  int a;
+
+  klee_make_symbolic(&a, sizeof a);
+
+  memset(&a, 0, sizeof a);
+
+  if (a) {
+    assert(0);
+  }
+  
+  return 0;
+}
diff --git a/test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c b/test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c
new file mode 100644
index 00000000..686bec19
--- /dev/null
+++ b/test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c
@@ -0,0 +1,12 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error --libc=uclibc %t1.bc
+
+// just make sure atexit works ok
+
+void boo() {
+}
+
+int main() {
+  atexit(boo);
+  return 0;
+}
diff --git a/test/Runtime/Uclibc/Environ.c b/test/Runtime/Uclibc/Environ.c
new file mode 100644
index 00000000..63892db5
--- /dev/null
+++ b/test/Runtime/Uclibc/Environ.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --libc=uclibc --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main() {
+  printf("HOME: %s\n", getenv("HOME"));
+  assert(getenv("HOME") != 0);
+  return 0;
+}
diff --git a/test/Runtime/Uclibc/dg.exp b/test/Runtime/Uclibc/dg.exp
new file mode 100644
index 00000000..9c1663c3
--- /dev/null
+++ b/test/Runtime/Uclibc/dg.exp
@@ -0,0 +1,5 @@
+load_lib llvm.exp
+
+if { [klee_supports_uclibc] } {
+    RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
+}
diff --git a/test/TestRunner.sh b/test/TestRunner.sh
new file mode 100755
index 00000000..3e2cace4
--- /dev/null
+++ b/test/TestRunner.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+#  TestRunner.sh - This script is used to run the deja-gnu tests exactly like
+#  deja-gnu does, by executing the Tcl script specified in the test case's 
+#  RUN: lines. This is made possible by a simple make target supported by the
+#  test/Makefile. All this script does is invoke that make target. 
+#
+#  Usage:
+#     TestRunner.sh {script_names}
+#
+#     This script is typically used by cd'ing to a test directory and then
+#     running TestRunner.sh with a list of test file names you want to run.
+#
+TESTPATH=`pwd`
+SUBDIR=""
+if test `dirname $1` = "." ; then
+  while test `basename $TESTPATH` != "test" -a ! -z "$TESTPATH" ; do
+    tmp=`basename $TESTPATH`
+    SUBDIR="$tmp/$SUBDIR"
+    TESTPATH=`dirname $TESTPATH`
+  done
+fi
+
+for TESTFILE in "$@" ; do 
+  if test `dirname $TESTFILE` = . ; then
+    if test -d "$TESTPATH" ; then
+      cd $TESTPATH
+      make check-one TESTONE="$SUBDIR$TESTFILE"
+      cd $PWD
+    else
+      echo "Can't find klee/test directory in " `pwd`
+    fi
+  else
+    make check-one TESTONE=$TESTFILE
+  fi
+done
diff --git a/test/lib/llvm.exp b/test/lib/llvm.exp
new file mode 100644
index 00000000..2857dd82
--- /dev/null
+++ b/test/lib/llvm.exp
@@ -0,0 +1,213 @@
+# This procedure executes one line of a test case's execution script.
+proc execOneLine { test PRS outcome lineno line } {
+  set status 0
+  set resultmsg ""
+  set retval [ catch { eval exec -keepnewline -- $line } errmsg ]
+  if { $retval != 0 } {
+    set code [lindex $::errorCode 0]
+    set lineno [expr $lineno + 1]
+    if { $PRS != ""} {
+      set PRS " for $PRS" 
+    }
+    set errmsg " at line $lineno\nwhile running: $line\n$errmsg"
+    switch "$code" {
+      CHILDSTATUS {
+        set status [lindex $::errorCode 2]
+        if { $status != 0 } {
+          set resultmsg "$test$PRS\nFailed with exit($status)$errmsg"
+        }
+      }
+      CHILDKILLED {
+        set signal [lindex $::errorCode 2]
+        set resultmsg "$test$PRS\nFailed with signal($signal)$errmsg"
+      }
+      CHILDSUSP {
+        set signal [lindex $::errorCode 2]
+        set resultmsg "$test$PRS\nFailed with suspend($signal)$errmsg"
+      }
+      POSIX {
+        set posixNum [lindex $::errorCode 1]
+        set posixMsg [lindex $::errorCode 2]
+        set resultmsg "$test$PRS\nFailed with posix($posixNum,$posixMsg)$errmsg"
+      }
+      NONE {
+      }
+      default {
+      }
+    }
+  } 
+  return $resultmsg
+}
+
+# This procedure performs variable substitutions on the RUN: lines of a test
+# cases.
+proc substitute { line test tmpFile } {
+  global srcroot objroot srcdir objdir subdir target_triplet prcontext 
+  global llvmgcc llvmgxx llvmgcc_version llvmgccmajvers 
+  global gccpath gxxpath compile_c compile_cxx link shlibext llvmlibsdir
+  global llvmtoolsdir
+  set path [file join $srcdir $subdir]
+
+  # Substitute all Tcl variables.
+  set new_line [subst $line ]
+
+  #replace %prcontext with prcontext.tcl (Must replace before %p)
+  regsub -all {%prcontext} $new_line $prcontext new_line
+  #replace %llvmgcc with actual path to llvmgcc
+  regsub -all {%llvmgcc} $new_line "$llvmgcc -emit-llvm" new_line
+  #replace %llvmgxx with actual path to llvmg++
+  regsub -all {%llvmgxx} $new_line "$llvmgxx -emit-llvm" new_line
+  #replace %compile_c with C compilation command
+  regsub -all {%compile_c} $new_line "$compile_c" new_line
+  #replace %compile_cxx with C++ compilation command
+  regsub -all {%compile_cxx} $new_line "$compile_cxx" new_line
+  #replace %link with C++ link command
+  regsub -all {%link} $new_line "$link" new_line
+  #replace %shlibext with shared library extension
+  regsub -all {%shlibext} $new_line "$shlibext" new_line
+  #replace %llvmlibsdir with configure library directory
+  regsub -all {%llvmlibsdir} $new_line "$llvmlibsdir" new_line
+  #replace %klee with klee binary
+  regsub -all {%klee} $new_line "klee" new_line
+  #replace %kleaver with kleaver binary
+  regsub -all {%kleaver} $new_line "kleaver" new_line
+  #replace %p with path to source, 
+  regsub -all {%p} $new_line [file join $srcdir $subdir] new_line
+  #replace %s with filename
+  regsub -all {%s} $new_line $test new_line
+  #replace %t with temp filenames
+  regsub -all {%t} $new_line $tmpFile new_line
+  #replace %% with %
+  regsub -all {%%} $new_line % new_line
+  return $new_line
+}
+
+# This procedure runs the set of tests for the test_source_files array.
+proc RunLLVMTests { test_source_files } {
+  global srcroot objroot srcdir objdir subdir TEST_FEATURE_LIST target_triplet
+  set timeout 60
+
+  set path [file join $objdir $subdir]
+  
+  #Make Output Directory if it does not exist already
+  if { [file exists path] } {
+    cd $path
+  } else {
+    file mkdir $path
+    cd $path
+  }
+  
+  file mkdir Output
+  cd Output
+
+  foreach test $test_source_files {
+    #Should figure out best way to set the timeout
+    #set timeout 40
+    
+    set filename [file tail $test]
+    set outcome PASS
+    set tmpFile "$filename.tmp"
+
+    #set hasRunline bool to check if testcase has a runline
+    set numLines 0
+
+    # Open the test file and start reading lines
+    set testFileId [ open $test r]
+    set runline ""
+    set PRNUMS ""
+    foreach line [split [read $testFileId] \n] {
+
+      # if its the END. line then stop parsing (optimization for big files)
+      if {[regexp {END.[ *]$} $line match endofscript]} {
+        break
+
+      # if the line is continued, concatenate and continue the loop
+      } elseif {[regexp {RUN: *(.+)(\\)$} $line match oneline suffix]} {
+        set runline "$runline$oneline "
+
+      # if its a terminating RUN: line then do substitution on the whole line
+      # and then save the line.
+      } elseif {[regexp {RUN: *([^&]+)(&&)?} $line match oneline suffix]} {
+        set runline "$runline$oneline"
+        set runline [ substitute $runline $test $tmpFile ]
+        set lines($numLines) $runline
+        set numLines [expr $numLines + 1]
+        set runline ""
+
+      # if its an PR line, save the problem report number
+      } elseif {[regexp {PR([0-9]+)} $line match prnum]} {
+        if {$PRNUMS == ""} {
+          set PRNUMS "PR$prnum"
+        } else {
+          set PRNUMS "$PRNUMS,$prnum"
+        }
+      # if its an XFAIL line, see if we should be XFAILing or not.
+      } elseif {[regexp {XFAIL:[ *](.+)} $line match features]} {
+        set features
+
+        foreach feature [split $features ,] {
+          if { [regexp {\*} $feature match] } {
+              set outcome XFAIL
+          } elseif { [regexp $feature $target_triplet match] } {
+              set outcome XFAIL
+          } elseif { [regexp $feature $TEST_FEATURE_LIST match] } {
+              set outcome XFAIL
+          }
+        }
+      }
+    }
+    
+    # Done reading the script
+    close $testFileId
+    
+    
+    if { $numLines == 0 } {
+      fail "$test: \nDoes not have a RUN line\n"
+    } else {
+      set failed 0
+      for { set i 0 } { $i < $numLines } { set i [ expr $i + 1 ] } {
+        regsub ^.*RUN:(.*) $lines($i) \1 theLine
+        set resultmsg [execOneLine $test $PRNUMS $outcome $i $theLine ]
+        if { $resultmsg != "" } {
+          if { $outcome == "XFAIL" } {
+            xfail "$resultmsg"
+          } else {
+            fail "$resultmsg"
+          }
+          set failed 1
+          break
+        }
+      }
+      if { $failed } {
+        continue
+      } else {
+        if { $PRNUMS != "" } {
+          set PRNUMS " for $PRNUMS"
+        }
+        if { $outcome == "XFAIL" } {
+          xpass "$test$PRNUMS"
+        } else {
+          pass "$test$PRNUMS"
+        }
+      }
+    }
+  }
+}
+
+# Check if klee was configured with POSIX runtime support.
+proc klee_supports_posix_runtime { } {
+    global ENABLE_POSIX_RUNTIME
+    if { $ENABLE_POSIX_RUNTIME == "1" } {
+        return 1
+    }
+    return 0
+}
+
+# Check if klee was configured with uclibc support.
+proc klee_supports_uclibc { } {
+    global ENABLE_UCLIBC
+    if { $ENABLE_UCLIBC == "1" } {
+        return 1
+    }
+    return 0
+}
diff --git a/test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c b/test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c
new file mode 100644
index 00000000..ad585ddd
--- /dev/null
+++ b/test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main(void) {
+  char c[2];
+
+  klee_make_symbolic(&c, sizeof(c));
+
+  if (c[0] > 10) {
+    int x;
+
+    c[1] = 1; // copy object state
+
+    assert(c[0] > 10);
+  }
+
+  return 0;
+}
diff --git a/test/regression/2007-07-30-unflushed-byte.c b/test/regression/2007-07-30-unflushed-byte.c
new file mode 100644
index 00000000..ba8a08a7
--- /dev/null
+++ b/test/regression/2007-07-30-unflushed-byte.c
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  char i, x[3];
+
+  klee_make_symbolic(&i, sizeof i);
+
+  x[0] = i;
+
+  // DEMAND FAILED:Memory.cpp:read8:199: <isByteFlushed(offset)> is false: "unflushed byte without cache value"
+  char y =  x[1];
+
+  return 0;
+}
+
diff --git a/test/regression/2007-08-01-bool-zext-in-call.ll b/test/regression/2007-08-01-bool-zext-in-call.ll
new file mode 100644
index 00000000..3f3e26ab
--- /dev/null
+++ b/test/regression/2007-08-01-bool-zext-in-call.ll
@@ -0,0 +1,22 @@
+; RUN: llvm-as -f %s -o - | %klee 2> %t1.log
+; RUN: not test -f klee-last/test0001.abort.err
+
+declare void @klee_abort()
+
+define i32 @foo(i8 signext %val) {
+        %tmp = zext i8 %val to i32
+	ret i32 %tmp
+}
+
+define i32 @main() {
+	%res = call i32 bitcast (i32 (i8 signext)* @foo to i32 (i1)*)( i1 1 )
+        %check = icmp ne i32 %res, 255
+        br i1 %check, label %error, label %exit
+
+error:
+        call void @klee_abort()
+        unreachable
+
+exit:
+	ret i32 0
+}
diff --git a/test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c b/test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c
new file mode 100644
index 00000000..15f4e90e
--- /dev/null
+++ b/test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c
@@ -0,0 +1,25 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+#include <stdio.h>
+
+int main() {  
+  unsigned char x;
+
+  klee_make_symbolic(&x, sizeof x);
+  if (x >= 2) klee_silent_exit(0);
+
+  char delete[2] = {0,1};
+
+  char tmp = delete[ x ];
+  char tmp2 = delete[0];
+  delete[ x ] = tmp2;
+
+  if (x==1) {
+    assert(delete[1] == 0);
+    return 0;
+  }
+
+  return 0;
+}
diff --git a/test/regression/2007-08-06-64bit-shift.c b/test/regression/2007-08-06-64bit-shift.c
new file mode 100644
index 00000000..958e56c0
--- /dev/null
+++ b/test/regression/2007-08-06-64bit-shift.c
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int d;
+  
+  klee_make_symbolic( &d, sizeof(d) );
+
+  int l = d - 1;
+  unsigned long long m = ((unsigned long long) l << 32) / d;
+  if (d==2) {
+    assert(m == 2147483648u);
+  }
+
+  klee_silent_exit(0);
+
+  return 0;
+}
diff --git a/test/regression/2007-08-06-access-after-free.c b/test/regression/2007-08-06-access-after-free.c
new file mode 100644
index 00000000..a1812062
--- /dev/null
+++ b/test/regression/2007-08-06-access-after-free.c
@@ -0,0 +1,29 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int a;
+  unsigned char *p = malloc(4);
+
+  klee_make_symbolic(&a, sizeof a);
+  klee_make_symbolic(p, sizeof p);
+
+  p[0] |= 16;
+
+  if (a) {
+    free(p);
+
+    // this should give an error instead of
+    // pulling the state from the parent, where
+    // it is not free
+    assert(p[0] > 10);
+   
+    return 0;
+  }
+  
+  assert(p[0] > 10);
+
+  return 0;
+}
diff --git a/test/regression/2007-08-08-free-zero.c b/test/regression/2007-08-08-free-zero.c
new file mode 100644
index 00000000..964889a1
--- /dev/null
+++ b/test/regression/2007-08-08-free-zero.c
@@ -0,0 +1,8 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last | not grep *.err
+
+int main() {
+  free(0);
+  return 0;
+}
diff --git a/test/regression/2007-08-16-invalid-constant-value.c b/test/regression/2007-08-16-invalid-constant-value.c
new file mode 100644
index 00000000..ecb3283f
--- /dev/null
+++ b/test/regression/2007-08-16-invalid-constant-value.c
@@ -0,0 +1,31 @@
+// RUN: rm -f %t4.out %t4.err %t4.log
+// RUN: %llvmgcc %s -emit-llvm -O2 -c -o %t1.bc
+// RUN: llvm-as -f ../../Feature/_utils._ll -o %t2.bc
+// RUN: llvm-ld -disable-opt %t1.bc %t2.bc -o %t3
+// RUN: %klee %t3.bc
+
+#include <assert.h>
+
+#include "../Feature/utils.h"
+
+int main() {
+  unsigned char a;
+
+  klee_make_symbolic(&a, sizeof a);
+
+  // demand was firing here because an invalid constant
+  // value was being created when implied value did not
+  // subtract using the proper type (so overflowed into
+  // invalid bits)
+  if (util_make_concat2(a+0xCD,0xCD) == 0xABCD) { 
+    assert(!klee_is_symbolic(a));
+    printf("add constant case: %d\n", a);
+  }
+
+  if (util_make_concat2(0x0B-a,0xCD) == 0xABCD) { 
+    assert(!klee_is_symbolic(a));
+    printf("sub constant case: %d\n", a);
+  }
+
+  return 0;
+}
diff --git a/test/regression/2007-08-16-valid-write-to-freed-object.c b/test/regression/2007-08-16-valid-write-to-freed-object.c
new file mode 100644
index 00000000..472b7de8
--- /dev/null
+++ b/test/regression/2007-08-16-valid-write-to-freed-object.c
@@ -0,0 +1,24 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+unsigned sym() {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  return x;
+}
+
+int main() {
+  unsigned x, y;
+
+  // sym returns a symbolic object, but because it is
+  // alloca'd it is freed on sym()s return. thats fine,
+  // but the problem is that IVC is going to try to write
+  // into the object right here.
+  //
+  // to support this we need to have a facility for making
+  // state local copies of a freed object.
+  if (sym() == 0) 
+    printf("ok\n");
+
+  return 0;
+}
diff --git a/test/regression/2007-10-11-free-of-alloca.c b/test/regression/2007-10-11-free-of-alloca.c
new file mode 100644
index 00000000..71a16f6b
--- /dev/null
+++ b/test/regression/2007-10-11-free-of-alloca.c
@@ -0,0 +1,9 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.free.err
+
+int main() {
+  int buf[4];
+  free(buf); // this should give runtime error, not crash
+  return 0;
+}
diff --git a/test/regression/2007-10-11-illegal-access-after-free-and-branch.c b/test/regression/2007-10-11-illegal-access-after-free-and-branch.c
new file mode 100644
index 00000000..fbbb99c3
--- /dev/null
+++ b/test/regression/2007-10-11-illegal-access-after-free-and-branch.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --optimize %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char **argv) {
+  unsigned char *buf = malloc(3);
+  klee_make_symbolic(buf, 3);
+  if (buf[0]>4) klee_silent_exit(0);
+  unsigned char x = buf[1];
+  free(buf);
+  if (x)
+    return buf[2];
+  klee_silent_exit(0);
+  return 0;
+}
diff --git a/test/regression/2007-10-12-failed-make-symbolic-after-copy.c b/test/regression/2007-10-12-failed-make-symbolic-after-copy.c
new file mode 100644
index 00000000..144281fa
--- /dev/null
+++ b/test/regression/2007-10-12-failed-make-symbolic-after-copy.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.bout
+
+int main() {
+  unsigned x, y[4];
+
+  klee_make_symbolic(&x,sizeof x);
+  if (x>=4) klee_silent_exit(0);
+  
+  y[x] = 0;
+
+  if (x) { // force branch so y is copied
+    klee_make_symbolic(&y, sizeof y);
+    if (y[x]==0) klee_silent_exit(0);
+    return 0; // should be reachable
+  } else {
+    // force read here in case we try to optimize copies smartly later
+    if (y[x]==0) klee_silent_exit(0);
+    return 0; // not reachable
+  }
+}
diff --git a/test/regression/2008-02-11-phi-nodes-after-invoke.ll b/test/regression/2008-02-11-phi-nodes-after-invoke.ll
new file mode 100644
index 00000000..f6077f25
--- /dev/null
+++ b/test/regression/2008-02-11-phi-nodes-after-invoke.ll
@@ -0,0 +1,47 @@
+; RUN: llvm-as -f %s -o - | %klee --no-output --exit-on-error
+
+declare void @klee_abort()
+
+define i32 @foo(i32 %val, i32 %fail) {
+        %code = icmp ne i32 0, %fail
+        br i1 %code, label %failing, label %return
+failing:   
+        unwind        
+return:        
+	ret i32 %val
+}
+
+define void @test(i32 %should_fail) {
+entry:  
+	%res0 = invoke i32 (i32, i32)* @foo(i32 0, i32 %should_fail) 
+                        to label %check_phi unwind label %error
+        
+error:
+        %res1 = zext i8 1 to i32
+        br label %check_phi
+
+check_phi:
+        %val = phi i32 [%never_used, %never_used_label], [%res0, %entry], [%res1, %error]
+        %ok = icmp eq i32 %val, %should_fail
+        br i1 %ok, label %exit, label %on_error
+        call void @klee_abort()
+        unreachable
+
+on_error:
+        call void @klee_abort()
+        unreachable
+            
+exit:
+	ret void
+
+        ;; this is so we hopefully fail if incomingBBIndex isn't set properly
+never_used_label:       
+        %never_used = zext i8 undef to i32
+        br label %check_phi
+}
+
+define i32 @main() {
+        call void (i32)* @test(i32 0)
+        call void (i32)* @test(i32 1)
+	ret i32 0
+}
diff --git a/test/regression/2008-03-04-free-of-global.c b/test/regression/2008-03-04-free-of-global.c
new file mode 100644
index 00000000..7821398d
--- /dev/null
+++ b/test/regression/2008-03-04-free-of-global.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.free.err
+
+int buf[4];
+
+int main() {
+  free(buf); // this should give runtime error, not crash
+  return 0;
+}
diff --git a/test/regression/2008-03-11-free-of-malloc-zero.c b/test/regression/2008-03-11-free-of-malloc-zero.c
new file mode 100644
index 00000000..d096818b
--- /dev/null
+++ b/test/regression/2008-03-11-free-of-malloc-zero.c
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdlib.h>
+
+int main() {
+  // concrete case
+  void *p = malloc(0);
+  free(p);
+
+  p = malloc(0);
+  void *arr[4] = { p, 0, 0, 0 };
+
+  // symbolic case
+  free(arr[klee_range(0, 4, "range")]);
+}
diff --git a/test/regression/2008-04-10-bad-alloca-free.c b/test/regression/2008-04-10-bad-alloca-free.c
new file mode 100644
index 00000000..46e2b0cf
--- /dev/null
+++ b/test/regression/2008-04-10-bad-alloca-free.c
@@ -0,0 +1,12 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+void f(int *addr) {
+  klee_make_symbolic_name(addr, sizeof *addr, "moo");
+}
+
+int main() {
+  int x;
+  f(&x);
+  return x;
+}
diff --git a/test/regression/2008-05-23-gep-with-global-const.c b/test/regression/2008-05-23-gep-with-global-const.c
new file mode 100644
index 00000000..5e03ec1d
--- /dev/null
+++ b/test/regression/2008-05-23-gep-with-global-const.c
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc -O0 -c -o %t.bc %s
+// RUN: %klee --exit-on-error %t.bc
+
+#include <assert.h>
+
+int a;
+
+int main() {
+  void *p1 = &((char*) 0)[(long) &a];
+  void *p2 = &a;
+
+  assert(p1 == p2);
+
+  return 0;
+}
diff --git a/test/regression/dg.exp b/test/regression/dg.exp
new file mode 100644
index 00000000..879685ca
--- /dev/null
+++ b/test/regression/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644
index 00000000..8c3501da
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,21 @@
+#===-- tools/Makefile --------------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+#
+# Relative path to the top of the source tree.
+#
+LEVEL=..
+
+#
+# List all of the subdirectories that we will compile.
+#
+PARALLEL_DIRS=klee kleaver klee-bout-tool gen-random-bout
+# FIXME: Move qplayer functionality into kleaver
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/gen-random-bout/Makefile b/tools/gen-random-bout/Makefile
new file mode 100644
index 00000000..97315af2
--- /dev/null
+++ b/tools/gen-random-bout/Makefile
@@ -0,0 +1,7 @@
+##===- tools/klee/Makefile ---------------*- Makefile -*-===##
+
+LEVEL=../..
+TOOLNAME = gen-random-bout
+USEDLIBS = kleeBasic.a
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/gen-random-bout/gen-random-bout.cpp b/tools/gen-random-bout/gen-random-bout.cpp
new file mode 100644
index 00000000..044c3d24
--- /dev/null
+++ b/tools/gen-random-bout/gen-random-bout.cpp
@@ -0,0 +1,124 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "klee/Internal/ADT/BOut.h"
+
+// --sym-args 0 1 10 --sym-args 0 2 2 --sym-files 1 8 --sym-stdout
+static int getint(char *i) {
+  if(!i) {
+    fprintf(stderr, "ran out of arguments!\n");
+    assert(i);
+  }
+  return atoi(i);
+}
+
+#define MAX 64
+static void push_obj(BOut *b, const char *name, unsigned non_zero_bytes, 
+                     unsigned total_bytes) {
+  BOutObject *o = &b->objects[b->numObjects++];
+  assert(b->numObjects < MAX);
+
+  o->name = strdup(name);
+  o->numBytes = total_bytes;
+  o->bytes = (unsigned char *)malloc(o->numBytes);
+
+  unsigned i;
+  for(i = 0; i < non_zero_bytes; i++)
+    o->bytes[i] = random();
+
+  for(i = non_zero_bytes; i < total_bytes; i++)
+    o->bytes[i] = 0;
+}
+
+
+static void push_range(BOut *b, const char *name, unsigned value) {
+  BOutObject *o = &b->objects[b->numObjects++];
+  assert(b->numObjects < MAX);
+
+  o->name = strdup(name);
+  o->numBytes = 4;
+  o->bytes = (unsigned char *)malloc(o->numBytes);
+
+  *(unsigned*)o->bytes = value;
+}
+
+int main(int argc, char *argv[]) {
+  unsigned i, narg;
+  unsigned sym_stdout = 0;
+
+  if (argc < 2) {
+    fprintf(stderr, "Usage: %s <random-seed> <argument-types>\n", argv[0]);
+    fprintf(stderr, "       If <random-seed> is 0, time(NULL)*getpid() is used as a seed\n");
+    fprintf(stderr, "       <argument-types> are the ones accepted by KLEE: --sym-args, --sym-files etc.\n");
+    fprintf(stderr, "   Ex: %s 100 --sym-args 0 2 2 --sym-files 1 8\n", argv[0]);
+    exit(1);
+  }
+
+  unsigned seed = atoi(argv[1]);
+  if (seed)
+    srandom(seed);
+  else srandom(time(NULL) * getpid());
+
+  BOut b;
+  b.numArgs = argc;
+  b.args = argv;
+  b.symArgvs = 0;
+  b.symArgvLen = 0;
+
+  b.numObjects = 0;
+  b.objects = (BOutObject *)malloc(MAX * sizeof *b.objects);
+
+  for(i = 2; i < (unsigned)argc; i++) {
+    if(strcmp(argv[i], "--sym-args") == 0) {
+      unsigned lb = getint(argv[++i]);
+      unsigned ub = getint(argv[++i]);
+      unsigned nbytes = getint(argv[++i]);
+
+      narg = random() % (ub - lb) + lb;
+      push_range(&b, "range", narg);
+
+      while(narg-- > 0) {
+        unsigned x = random() % (nbytes + 1);
+
+        // A little different than how klee does it but more natural
+        // for random.
+        static int total_args;
+        char arg[1024];
+
+        sprintf(arg, "arg%d", total_args++);
+        push_obj(&b, arg, x, nbytes+1);
+      }
+    } else if(strcmp(argv[i], "--sym-stdout") == 0) {
+      if(!sym_stdout) {
+        sym_stdout = 1;
+        push_obj(&b, "stdout", 1024, 1024);
+        push_obj(&b, "stdout-stat", sizeof(struct stat64), 
+                 sizeof(struct stat64));
+      }
+    } else if(strcmp(argv[i], "--sym-files") == 0) {
+      unsigned nfiles = getint(argv[++i]);
+      unsigned nbytes = getint(argv[++i]);
+
+      while(nfiles-- > 0) {
+        push_obj(&b, "file", nbytes, nbytes);
+        push_obj(&b, "file-stat", sizeof(struct stat64), sizeof(struct stat64));
+      }
+
+      push_obj(&b, "stdin", nbytes, nbytes);
+      push_obj(&b, "stdin-stat", sizeof(struct stat64), sizeof(struct stat64));
+    } else {
+      fprintf(stderr, "unexpected option <%s>\n", argv[i]);
+      assert(0);
+    }
+  }
+
+  if (!bOut_toFile(&b, "file.bout"))
+    assert(0);
+  return 0;
+}
diff --git a/tools/kleaver/Makefile b/tools/kleaver/Makefile
new file mode 100644
index 00000000..283b5bef
--- /dev/null
+++ b/tools/kleaver/Makefile
@@ -0,0 +1,19 @@
+#===-- tools/kleaver/Makefile ------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+TOOLNAME = kleaver
+# FIXME: Ideally we wouldn't have any LLVM dependencies here, which
+# means kicking out klee's Support.
+USEDLIBS = kleaverExpr.a kleaverSolver.a kleeSupport.a kleeBasic.a
+LINK_COMPONENTS = support
+
+include $(LEVEL)/Makefile.common
+
+LIBS += -lstp
diff --git a/tools/kleaver/main.cpp b/tools/kleaver/main.cpp
new file mode 100644
index 00000000..621776ee
--- /dev/null
+++ b/tools/kleaver/main.cpp
@@ -0,0 +1,120 @@
+#include "expr/Lexer.h"
+#include "expr/Parser.h"
+
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+#include "klee/util/ExprPPrinter.h"
+#include "klee/util/ExprVisitor.h"
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/System/Signals.h"
+
+#include <iomanip>
+#include <sstream>
+
+using namespace llvm;
+using namespace klee;
+using namespace klee::expr;
+
+namespace {
+  llvm::cl::opt<std::string>
+  InputFile(llvm::cl::desc("<input query log>"), llvm::cl::Positional,
+            llvm::cl::init("-"));
+
+  enum ToolActions {
+    PrintTokens,
+    PrintAST
+  };
+
+  static llvm::cl::opt<ToolActions> 
+  ToolAction(llvm::cl::desc("Tool actions:"),
+             llvm::cl::init(PrintTokens),
+             llvm::cl::values(
+             clEnumValN(PrintTokens, "print-tokens",
+                        "Print tokens from the input file."),
+             clEnumValN(PrintAST, "print-ast",
+                        "Print parsed AST nodes from the input file."),
+             clEnumValEnd));
+}
+
+static std::string escapedString(const char *start, unsigned length) {
+  std::stringstream s;
+  for (unsigned i=0; i<length; ++i) {
+    char c = start[i];
+    if (isprint(c)) {
+      s << c;
+    } else if (c == '\n') {
+      s << "\\n";
+    } else {
+      s << "\\x" << hexdigit(((unsigned char) c >> 4) & 0xF) << hexdigit((unsigned char) c & 0xF);
+    }
+  }
+  return s.str();
+}
+
+static void PrintInputTokens(const MemoryBuffer *MB) {
+  Lexer L(MB);
+  Token T;
+  do {
+    L.Lex(T);
+    llvm::cout << "(Token \"" << T.getKindName() << "\" "
+               << "\"" << escapedString(T.start, T.length) << "\" "
+               << T.length << " "
+               << T.line << " " << T.column << ")\n";
+  } while (T.kind != Token::EndOfFile);
+}
+
+static bool PrintInputAST(const char *Filename,
+                          const MemoryBuffer *MB) {
+  Parser *P = Parser::Create(Filename, MB);
+  P->SetMaxErrors(20);
+  while (Decl *D = P->ParseTopLevelDecl()) {
+    if (!P->GetNumErrors())
+      D->dump();
+    delete D;
+  }
+
+  bool success = true;
+  if (unsigned N = P->GetNumErrors()) {
+    llvm::cerr << Filename << ": parse failure: "
+               << N << " errors.\n";
+    success = false;
+  }
+  delete P;
+
+  return success;
+}
+
+int main(int argc, char **argv) {
+  bool success = true;
+
+  llvm::sys::PrintStackTraceOnErrorSignal();
+  llvm::cl::ParseCommandLineOptions(argc, argv);
+
+  std::string ErrorStr;
+  MemoryBuffer *MB = MemoryBuffer::getFileOrSTDIN(InputFile.c_str(), &ErrorStr);
+  if (!MB) {
+    llvm::cerr << argv[0] << ": ERROR: " << ErrorStr << "\n";
+    return 1;
+  }
+
+  switch (ToolAction) {
+  case PrintTokens:
+    PrintInputTokens(MB);
+    break;
+  case PrintAST:
+    success = PrintInputAST(InputFile=="-" ? "<stdin>" : InputFile.c_str(), MB);
+    break;
+  default:
+    llvm::cerr << argv[0] << ": ERROR: Unknown program action!\n";
+  }
+
+  delete MB;
+
+  llvm::llvm_shutdown();
+  return success ? 0 : 1;
+}
diff --git a/tools/klee-bout-tool/Makefile b/tools/klee-bout-tool/Makefile
new file mode 100644
index 00000000..28e80841
--- /dev/null
+++ b/tools/klee-bout-tool/Makefile
@@ -0,0 +1,46 @@
+#===-- tools/klee-bout-tool/Makefile -----------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL = ../..
+
+TOOLSCRIPTNAME := klee-bout-tool
+
+include $(LEVEL)/Makefile.common
+
+# FIXME: Move this stuff (to "build" a script) into Makefile.rules.
+
+ToolBuildPath := $(ToolDir)/$(TOOLSCRIPTNAME)
+
+all-local:: $(ToolBuildPath)
+
+$(ToolBuildPath): $(ToolDir)/.dir
+
+$(ToolBuildPath): $(TOOLSCRIPTNAME)
+	$(Echo) Copying $(BuildMode) script $(TOOLSCRIPTNAME)
+	$(Verb) $(CP) -f $(TOOLSCRIPTNAME) "$@"
+	$(Verb) chmod 0755 "$@"
+
+ifdef NO_INSTALL
+install-local::
+	$(Echo) Install circumvented with NO_INSTALL
+uninstall-local::
+	$(Echo) Uninstall circumvented with NO_INSTALL
+else
+DestTool = $(PROJ_bindir)/$(TOOLSCRIPTNAME)
+
+install-local:: $(DestTool)
+
+$(DestTool): $(ToolBuildPath) $(PROJ_bindir)
+	$(Echo) Installing $(BuildMode) $(DestTool)
+	$(Verb) $(ProgInstall) $(ToolBuildPath) $(DestTool)
+
+uninstall-local::
+	$(Echo) Uninstalling $(BuildMode) $(DestTool)
+	-$(Verb) $(RM) -f $(DestTool)
+endif
diff --git a/tools/klee-bout-tool/klee-bout-tool b/tools/klee-bout-tool/klee-bout-tool
new file mode 100755
index 00000000..19c9e893
--- /dev/null
+++ b/tools/klee-bout-tool/klee-bout-tool
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+
+import os
+import struct
+import sys
+
+version_no=2
+
+class BOutError(Exception):
+    pass
+
+class BOut:
+    @staticmethod
+    def fromfile(path):
+        if not os.path.exists(path):
+            print "ERROR: file %s not found" % (path)
+            sys.exit(1)
+            
+        f = open(path,'rb')
+        hdr = f.read(5)
+        if len(hdr)!=5 or hdr!='BOUT\n':
+            raise BOutError,'unrecognized file'
+        version, = struct.unpack('>i', f.read(4))
+        if version > version_no:
+            raise BOutError,'unrecognized version'
+        numArgs, = struct.unpack('>i', f.read(4))
+        args = []
+        for i in range(numArgs):
+            size, = struct.unpack('>i', f.read(4))
+            args.append(f.read(size))
+            
+        if version >= 2:
+            symArgvs, = struct.unpack('>i', f.read(4))
+            symArgvLen, = struct.unpack('>i', f.read(4))
+        else:
+            symArgvs = 0
+            symArgvLen = 0
+
+        numObjects, = struct.unpack('>i', f.read(4))
+        objects = []
+        for i in range(numObjects):
+            size, = struct.unpack('>i', f.read(4))
+            name = f.read(size)
+            size, = struct.unpack('>i', f.read(4))
+            bytes = f.read(size)
+            objects.append( (name,bytes) )
+
+        # Create an instance
+        b = BOut(version, args, symArgvs, symArgvLen, objects)
+        # Augment with extra filename field
+        b.filename = path
+        return b
+    
+    def __init__(self, version, args, symArgvs, symArgvLen, objects):
+        self.version = version
+        self.symArgvs = symArgvs
+        self.symArgvLen = symArgvLen
+        self.args = args
+        self.objects = objects
+
+        # add a field that represents the name of the program used to
+        # generate this .bout file:
+        program_full_path = self.args[0]
+        program_name = os.path.basename(program_full_path)
+        # sometimes program names end in .bc, so strip them
+        if program_name.endswith('.bc'):
+          program_name = program_name[:-3]
+        self.programName = program_name
+        
+def trimZeros(str):
+    for i in range(len(str))[::-1]:
+        if str[i] != '\x00':
+            return str[:i+1]
+    return ''
+    
+def main(args):
+    from optparse import OptionParser
+    op = OptionParser("usage: %prog [options] files")
+    op.add_option('','--trim-zeros', dest='trimZeros', action='store_true', 
+                  default=False,
+                  help='trim trailing zeros')
+    
+    opts,args = op.parse_args()
+    if not args:
+        op.error("incorrect number of arguments")
+
+    for file in args:
+        b = BOut.fromfile(file)
+        pos = 0
+        print 'bout file  : %r' % file
+        print 'args       : %r' % b.args
+        print 'num objects: %r' % len(b.objects)
+        for i,(name,data) in enumerate(b.objects):
+            if opts.trimZeros:
+                str = trimZeros(data)
+            else:
+                str = data
+
+            print 'object %4d: name: %r' % (i, name)
+            print 'object %4d: size: %r' % (i, len(data))
+            print 'object %4d: data: %r' % (i, str)
+        if file != args[-1]:
+            print
+
+if __name__=='__main__':
+    main(sys.argv)
diff --git a/tools/klee/Debug.cpp b/tools/klee/Debug.cpp
new file mode 100644
index 00000000..d11a79a7
--- /dev/null
+++ b/tools/klee/Debug.cpp
@@ -0,0 +1,12 @@
+#include <klee/Expr.h>
+#include <iostream>
+
+void kdb_printExpr(klee::Expr *e) {
+  llvm::cerr << "expr: " << e << " -- ";
+  if (e) {
+    llvm::cerr << *e;
+  } else {
+    llvm::cerr << "(null)";
+  }
+  llvm::cerr << "\n";
+}
diff --git a/tools/klee/Makefile b/tools/klee/Makefile
new file mode 100644
index 00000000..b556175d
--- /dev/null
+++ b/tools/klee/Makefile
@@ -0,0 +1,22 @@
+#===-- tools/klee/Makefile ---------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+TOOLNAME = klee
+USEDLIBS = kleeCore.a kleeModule.a kleaverSolver.a kleaverExpr.a kleeSupport.a kleeBasic.a
+LINK_COMPONENTS = bitreader bitwriter ipo linker engine
+
+include $(LEVEL)/Makefile.common
+
+ifeq ($(ENABLE_STPLOG), 1)
+	LIBS += -lstplog
+endif
+
+LIBS += -lstp 
+#-ltcmalloc
diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp
new file mode 100644
index 00000000..39b208ec
--- /dev/null
+++ b/tools/klee/main.cpp
@@ -0,0 +1,1422 @@
+/* -*- mode: c++; c-basic-offset: 2; -*- */
+
+// FIXME: This does not belong here.
+#include "../lib/Core/Common.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Expr.h"
+#include "klee/Interpreter.h"
+#include "klee/Statistics.h"
+#include "klee/Config/config.h"
+#include "klee/Internal/ADT/BOut.h"
+#include "klee/Internal/ADT/TreeStream.h"
+#include "klee/Internal/Support/ModuleUtil.h"
+#include "klee/Internal/System/Time.h"
+
+#include "llvm/Constants.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Type.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+#include <fstream>
+#include <cerrno>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+#include <iostream>
+#include <iterator>
+#include <fstream>
+#include <sstream>
+
+using namespace llvm;
+using namespace klee;
+
+namespace {
+  cl::opt<std::string>
+  InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));
+
+  cl::opt<std::string>
+  RunInDir("run-in", cl::desc("Change to the given directory prior to executing"));
+
+  cl::opt<std::string>
+  Environ("environ", cl::desc("Parse environ from given file (in \"env\" format)"));
+
+  cl::list<std::string>
+  InputArgv(cl::ConsumeAfter, 
+            cl::desc("<program arguments>..."));
+
+  cl::opt<bool>
+  NoOutput("no-output", 
+           cl::desc("Don't generate test files"));
+    
+  cl::opt<bool>
+  WarnAllExternals("warn-all-externals", 
+                   cl::desc("Give initial warning for all externals."));
+    
+  cl::opt<bool>
+  WriteCVCs("write-cvcs", 
+            cl::desc("Write .cvc files for each test case"));
+
+  cl::opt<bool>
+  WritePCs("write-pcs", 
+            cl::desc("Write .pc files for each test case"));
+  
+  cl::opt<bool>
+  WriteCov("write-cov", 
+           cl::desc("Write coverage information for each test case"));
+  
+  cl::opt<bool>
+  WriteTestInfo("write-test-info", 
+                cl::desc("Write additional test case information"));
+  
+  cl::opt<bool>
+  WritePaths("write-paths", 
+                cl::desc("Write .path files for each test case"));
+    
+  cl::opt<bool>
+  WriteSymPaths("write-sym-paths", 
+                cl::desc("Write .sym.path files for each test case"));
+    
+  cl::opt<bool>
+  ExitOnError("exit-on-error", 
+              cl::desc("Exit if errors occur"));
+    
+
+  enum LibcType {
+    NoLibc, KleeLibc, UcLibc
+  };
+
+  cl::opt<LibcType>
+  Libc("libc", 
+       cl::desc("Choose libc version (none by default)."),
+       cl::values(clEnumValN(NoLibc, "none", "Don't link in a libc"),
+                  clEnumValN(KleeLibc, "klee", "Link in klee libc"),
+		  clEnumValN(UcLibc, "uclibc", "Link in uclibc (adapted for klee)"),
+		  clEnumValEnd),
+       cl::init(NoLibc));
+
+    
+  cl::opt<bool>
+  WithPOSIXRuntime("posix-runtime", 
+		cl::desc("Link with POSIX runtime"),
+		cl::init(false));
+    
+  cl::opt<bool>
+  OptimizeModule("optimize", 
+                 cl::desc("Optimize before execution"));
+
+  cl::opt<bool>
+  CheckDivZero("check-div-zero", 
+               cl::desc("Inject checks for division-by-zero"),
+               cl::init(true));
+    
+  cl::opt<std::string>
+  OutputDir("output-dir", 
+            cl::desc("Directory to write results in (defaults to klee-out-N)"),
+            cl::init(""));
+
+  // this is a fake entry, its automagically handled
+  cl::list<std::string>
+  ReadArgsFilesFake("read-args", 
+                    cl::desc("File to read arguments from (one arg per line)"));
+    
+  cl::opt<bool>
+  ReplayKeepSymbolic("replay-keep-symbolic", 
+                     cl::desc("Replay the test cases only by asserting"
+                              "the bytes, not necessarily making them concrete."));
+    
+  cl::list<std::string>
+  ReplayOutFile("replay-out",
+                cl::desc("Specify an out file to replay"),
+                cl::value_desc("out file"));
+
+  cl::list<std::string>
+  ReplayOutDir("replay-out-dir",
+	       cl::desc("Specify a directory to replay .out files from"),
+	       cl::value_desc("output directory"));
+
+  cl::opt<std::string>
+  ReplayPathFile("replay-path",
+                 cl::desc("Specify a path file to replay"),
+                 cl::value_desc("path file"));
+
+  cl::list<std::string>
+  SeedOutFile("seed-out");
+  
+  cl::list<std::string>
+  SeedOutDir("seed-out-dir");
+  
+  cl::opt<unsigned>
+  MakeConcreteSymbolic("make-concrete-symbolic",
+                       cl::desc("Rate at which to make concrete reads symbolic (0=off)"),
+                       cl::init(0));
+
+  cl::opt<bool>
+  InitEnv("init-env",
+	  cl::desc("Create custom environment.  Options that can be passed as arguments to the programs are: --sym-argv <max-len>  --sym-argvs <min-argvs> <max-argvs> <max-len> + file model options"));
+ 
+  cl::opt<unsigned>
+  StopAfterNTests("stop-after-n-tests",
+	     cl::desc("Stop execution after generating the given number of tests.  Extra tests corresponding to partially explored paths will also be dumped."),
+	     cl::init(0));
+
+  cl::opt<bool>
+  Watchdog("watchdog",
+           cl::desc("Use a watchdog process to enforce --max-time."),
+           cl::init(0));
+}
+
+extern bool WriteTraces;
+extern cl::opt<double> MaxTime;
+
+/***/
+
+class KleeHandler : public InterpreterHandler {
+private:
+  Interpreter *m_interpreter;
+  TreeStreamWriter *m_pathWriter, *m_symPathWriter;
+  std::ostream *m_infoFile;
+
+  char m_outputDirectory[1024];
+  unsigned m_testIndex;  // number of tests written so far
+  unsigned m_pathsExplored; // number of paths explored so far
+
+  // used for writing .bout files
+  int m_argc;
+  char **m_argv;
+
+public:
+  KleeHandler(int argc, char **argv);
+  ~KleeHandler();
+
+  std::ostream &getInfoStream() const { return *m_infoFile; }
+  unsigned getNumTestCases() { return m_testIndex; }
+  unsigned getNumPathsExplored() { return m_pathsExplored; }
+  void incPathsExplored() { m_pathsExplored++; }
+
+  void setInterpreter(Interpreter *i);
+
+  void processTestCase(const ExecutionState  &state,
+                       const char *errorMessage, 
+                       const char *errorSuffix);
+
+  std::string getOutputFilename(const std::string &filename);
+  std::ostream *openOutputFile(const std::string &filename);
+  std::string getTestFilename(const std::string &suffix, unsigned id);
+  std::ostream *openTestFile(const std::string &suffix, unsigned id);
+
+  // load a .out file
+  static void loadOutFile(std::string name, 
+                          std::vector<unsigned char> &buffer);
+
+  // load a .path file
+  static void loadPathFile(std::string name, 
+                           std::vector<bool> &buffer);
+
+  static void getOutFiles(std::string path,
+			  std::vector<std::string> &results);
+};
+
+KleeHandler::KleeHandler(int argc, char **argv) 
+  : m_interpreter(0),
+    m_pathWriter(0),
+    m_symPathWriter(0),
+    m_infoFile(0),
+    m_testIndex(0),
+    m_pathsExplored(0),
+    m_argc(argc),
+    m_argv(argv) {
+  std::string theDir;
+
+  if (OutputDir=="") {
+    llvm::sys::Path directory(InputFile);
+    std::string dirname = "";
+    directory.eraseComponent();
+    
+    if (directory.isEmpty())
+      directory.set(".");
+    
+    for (int i = 0; ; i++) {
+      char buf[256], tmp[64];
+      sprintf(tmp, "klee-out-%d", i);
+      dirname = tmp;
+      sprintf(buf, "%s/%s", directory.c_str(), tmp);
+      theDir = buf;
+      
+      if (DIR *dir = opendir(theDir.c_str())) {
+        closedir(dir);
+      } else {
+        break;
+      }
+    }    
+
+    llvm::cerr << "KLEE: output directory = \"" << dirname << "\"\n";
+
+    llvm::sys::Path klee_last(directory);
+    klee_last.appendComponent("klee-last");
+      
+    if ((unlink(klee_last.c_str()) < 0) && (errno != ENOENT)) {
+      perror("Cannot unlink klee-last");
+      assert(0 && "exiting.");
+    }
+    
+    if (symlink(dirname.c_str(), klee_last.c_str()) < 0) {
+      perror("Cannot make symlink");
+      assert(0 && "exiting.");
+    }
+  } else {
+    theDir = OutputDir;
+  }
+  
+  sys::Path p(theDir);
+  if (!p.isAbsolute()) {
+    sys::Path cwd = sys::Path::GetCurrentDirectory();
+    cwd.appendComponent(theDir);
+    p = cwd;
+  }
+  strcpy(m_outputDirectory, p.c_str());
+
+  if (mkdir(m_outputDirectory, 0775) < 0) {
+    llvm::cerr << "KLEE: ERROR: Unable to make output directory: \"" 
+               << m_outputDirectory 
+               << "\", refusing to overwrite.\n";
+    exit(1);
+  }
+
+  char fname[1024];
+  snprintf(fname, sizeof(fname), "%s/warnings.txt", m_outputDirectory);
+  klee_warning_file = fopen(fname, "w");
+  assert(klee_warning_file);
+
+  snprintf(fname, sizeof(fname), "%s/messages.txt", m_outputDirectory);
+  klee_message_file = fopen(fname, "w");
+  assert(klee_message_file);
+
+  m_infoFile = openOutputFile("info");
+}
+
+KleeHandler::~KleeHandler() {
+  if (m_pathWriter) delete m_pathWriter;
+  if (m_symPathWriter) delete m_symPathWriter;
+  delete m_infoFile;
+}
+
+void KleeHandler::setInterpreter(Interpreter *i) {
+  m_interpreter = i;
+
+  if (WritePaths) {
+    m_pathWriter = new TreeStreamWriter(getOutputFilename("paths.ts"));
+    assert(m_pathWriter->good());
+    m_interpreter->setPathWriter(m_pathWriter);
+  }
+
+  if (WriteSymPaths) {
+    m_symPathWriter = new TreeStreamWriter(getOutputFilename("symPaths.ts"));
+    assert(m_symPathWriter->good());
+    m_interpreter->setSymbolicPathWriter(m_symPathWriter);
+  }
+}
+
+std::string KleeHandler::getOutputFilename(const std::string &filename) {
+  char outfile[1024];
+  sprintf(outfile, "%s/%s", m_outputDirectory, filename.c_str());
+  return outfile;
+}
+
+std::ostream *KleeHandler::openOutputFile(const std::string &filename) {
+  std::ios::openmode io_mode = std::ios::out | std::ios::trunc 
+                             | std::ios::binary;
+  std::ostream *f;
+  std::string path = getOutputFilename(filename);
+  f = new std::ofstream(path.c_str(), io_mode);
+  if (!f) {
+    klee_warning("out of memory");
+  } else if (!f->good()) {
+    klee_warning("error opening: %s", filename.c_str());
+    delete f;
+    f = NULL;
+  }
+
+  return f;
+}
+
+std::string KleeHandler::getTestFilename(const std::string &suffix, unsigned id) {
+  char filename[1024];
+  sprintf(filename, "test%06d.%s", id, suffix.c_str());
+  return getOutputFilename(filename);
+}
+
+std::ostream *KleeHandler::openTestFile(const std::string &suffix, unsigned id) {
+  char filename[1024];
+  sprintf(filename, "test%06d.%s", id, suffix.c_str());
+  return openOutputFile(filename);
+}
+
+
+/* Outputs all files (.bout, .pc, .cov etc.) describing a test case */
+void KleeHandler::processTestCase(const ExecutionState &state,
+                                  const char *errorMessage, 
+                                  const char *errorSuffix) {
+  if (errorMessage && ExitOnError) {
+    llvm::cerr << "EXITING ON ERROR: " << errorMessage << "\n";
+    abort();
+  }
+
+  if (!NoOutput) {
+    std::vector< std::pair<std::string, std::vector<unsigned char> > > out;
+    bool success = m_interpreter->getSymbolicSolution(state, out);
+
+    if (!success)
+      klee_warning("unable to get symbolic solution, losing test case");
+
+    double start_time = util::getWallTime();
+
+    unsigned id = ++m_testIndex;
+
+    if (success) {
+      BOut b;      
+      b.numArgs = m_argc;
+      b.args = m_argv;
+      b.symArgvs = 0;
+      b.symArgvLen = 0;
+      b.numObjects = out.size();
+      b.objects = new BOutObject[b.numObjects];
+      assert(b.objects);
+      for (unsigned i=0; i<b.numObjects; i++) {
+        BOutObject *o = &b.objects[i];
+        o->name = const_cast<char*>(out[i].first.c_str());
+        o->numBytes = out[i].second.size();
+        o->bytes = new unsigned char[o->numBytes];
+        assert(o->bytes);
+        std::copy(out[i].second.begin(), out[i].second.end(), o->bytes);
+      }
+      
+      if (!bOut_toFile(&b, getTestFilename("bout", id).c_str())) {
+        klee_warning("unable to write output test case, losing it");
+      }
+      
+      for (unsigned i=0; i<b.numObjects; i++)
+        delete[] b.objects[i].bytes;
+      delete[] b.objects;
+    }
+
+    if (errorMessage) {
+      std::ostream *f = openTestFile(errorSuffix, id);
+      *f << errorMessage;
+      delete f;
+    }
+    
+    if (m_pathWriter) {
+      std::vector<unsigned char> concreteBranches;
+      m_pathWriter->readStream(m_interpreter->getPathStreamID(state),
+                               concreteBranches);
+      std::ostream *f = openTestFile("path", id);
+      std::copy(concreteBranches.begin(), concreteBranches.end(), 
+                std::ostream_iterator<unsigned char>(*f, "\n"));
+      delete f;
+    }
+   
+    if (errorMessage || WritePCs) {
+      std::string constraints;
+      m_interpreter->getConstraintLog(state, constraints);
+      std::ostream *f = openTestFile("pc", id);
+      *f << constraints;
+      delete f;
+    }
+
+    if (WriteCVCs) {
+      std::string constraints;
+      m_interpreter->getConstraintLog(state, constraints, true);
+      std::ostream *f = openTestFile("cvc", id);
+      *f << constraints;
+      delete f;
+    }
+    
+    if (m_symPathWriter) {
+      std::vector<unsigned char> symbolicBranches;
+      m_symPathWriter->readStream(m_interpreter->getSymbolicPathStreamID(state),
+                                  symbolicBranches);
+      std::ostream *f = openTestFile("sym.path", id);
+      std::copy(symbolicBranches.begin(), symbolicBranches.end(), 
+                std::ostream_iterator<unsigned char>(*f, "\n"));
+      delete f;
+    }
+
+    if (WriteCov) {
+      std::map<const std::string*, std::set<unsigned> > cov;
+      m_interpreter->getCoveredLines(state, cov);
+      std::ostream *f = openTestFile("cov", id);
+      for (std::map<const std::string*, std::set<unsigned> >::iterator
+             it = cov.begin(), ie = cov.end();
+           it != ie; ++it) {
+        for (std::set<unsigned>::iterator
+               it2 = it->second.begin(), ie = it->second.end();
+             it2 != ie; ++it2)
+          *f << *it->first << ":" << *it2 << "\n";
+      }
+      delete f;
+    }
+
+    if (WriteTraces) {
+      std::ostream *f = openTestFile("trace", id);
+      state.exeTraceMgr.printAllEvents(*f);
+      delete f;
+    }
+
+    if (m_testIndex == StopAfterNTests)
+      m_interpreter->setHaltExecution(true);
+
+    if (WriteTestInfo) {
+      double elapsed_time = util::getWallTime() - start_time;
+      std::ostream *f = openTestFile("info", id);
+      *f << "Time to generate test case: " 
+         << elapsed_time << "s\n";
+      delete f;
+    }
+  }
+}
+
+  // load a .path file
+void KleeHandler::loadPathFile(std::string name, 
+                                     std::vector<bool> &buffer) {
+  std::ifstream f(name.c_str(), std::ios::in | std::ios::binary);
+
+  if (!f.good())
+    assert(0 && "unable to open path file");
+
+  while (f.good()) {
+    unsigned value;
+    f >> value;
+    buffer.push_back(!!value);
+    f.get();
+  }
+}
+
+void KleeHandler::getOutFiles(std::string path,
+			      std::vector<std::string> &results) {
+  llvm::sys::Path p(path);
+  std::set<llvm::sys::Path> contents;
+  std::string error;
+  if (p.getDirectoryContents(contents, &error)) {
+    llvm::cerr << "ERROR: unable to read output directory: " << path << ": " << error << "\n";
+    exit(1);
+  }
+  for (std::set<llvm::sys::Path>::iterator it = contents.begin(),
+         ie = contents.end(); it != ie; ++it) {
+    std::string f = it->toString();
+    if (f.substr(f.size()-5,f.size()) == ".bout") {
+      results.push_back(f);
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// main Driver function
+//
+#if ENABLE_STPLOG == 1
+extern "C" void STPLOG_init(const char *);
+#endif
+
+static std::string strip(std::string &in) {
+  unsigned len = in.size();
+  unsigned lead = 0, trail = len;
+  while (lead<len && isspace(in[lead]))
+    ++lead;
+  while (trail>lead && isspace(in[trail-1]))
+    --trail;
+  return in.substr(lead, trail-lead);
+}
+
+static void readArgumentsFromFile(char *file, std::vector<std::string> &results) {
+  std::ifstream f(file);
+  assert(f.is_open() && "unable to open input for reading arguments");
+  while (!f.eof()) {
+    std::string line;
+    std::getline(f, line);
+    line = strip(line);
+    if (!line.empty())
+      results.push_back(line);
+  }
+  f.close();
+}
+
+static void parseArguments(int argc, char **argv) {
+  std::vector<std::string> arguments;
+
+  for (int i=1; i<argc; i++) {
+    if (!strcmp(argv[i],"--read-args") && i+1<argc) {
+      readArgumentsFromFile(argv[++i], arguments);
+    } else {
+      arguments.push_back(argv[i]);
+    }
+  }
+    
+  int numArgs = arguments.size() + 1;
+  const char **argArray = new const char*[numArgs+1];
+  argArray[0] = argv[0];
+  argArray[numArgs] = 0;
+  for (int i=1; i<numArgs; i++) {
+    argArray[i] = arguments[i-1].c_str();
+  }
+
+  cl::ParseCommandLineOptions(numArgs, (char**) argArray, " klee\n");
+  delete[] argArray;
+}
+
+
+
+static int initEnv(Module *mainModule) {
+
+  /*
+    nArgcP = alloc oldArgc->getType()
+    nArgvV = alloc oldArgv->getType()
+    store oldArgc nArgcP
+    store oldArgv nArgvP
+    klee_init_environment(nArgcP, nArgvP)
+    nArgc = load nArgcP
+    nArgv = load nArgvP
+    oldArgc->replaceAllUsesWith(nArgc)
+    oldArgv->replaceAllUsesWith(nArgv)
+  */
+
+  Function *mainFn = mainModule->getFunction("main");
+    
+  if (mainFn->arg_size() < 2) {
+    llvm::cerr << "Cannot handle ""-init-env"" when main() has less than two arguments.\n";
+    return -1;
+  }
+
+  Instruction* firstInst = mainFn->begin()->begin();
+
+  Value* oldArgc = mainFn->arg_begin();
+  Value* oldArgv = ++mainFn->arg_begin();
+  
+  AllocaInst* argcPtr = new AllocaInst(oldArgc->getType(), "argcPtr", firstInst);
+  AllocaInst* argvPtr = new AllocaInst(oldArgv->getType(), "argvPtr", firstInst);
+
+  /* Insert void klee_init_env(int* argc, char*** argv) */
+  std::vector<const Type*> params;
+  params.push_back(Type::Int32Ty);
+  params.push_back(Type::Int32Ty);
+  Function* initEnvFn = 
+    cast<Function>(mainModule->getOrInsertFunction("klee_init_env",
+                                                   Type::VoidTy,
+                                                   argcPtr->getType(),
+                                                   argvPtr->getType(),
+                                                   NULL));
+  assert(initEnvFn);    
+  std::vector<Value*> args;
+  args.push_back(argcPtr);
+  args.push_back(argvPtr);
+  Instruction* initEnvCall = CallInst::Create(initEnvFn, args.begin(), args.end(), 
+					      "", firstInst);
+  Value *argc = new LoadInst(argcPtr, "newArgc", firstInst);
+  Value *argv = new LoadInst(argvPtr, "newArgv", firstInst);
+  
+  oldArgc->replaceAllUsesWith(argc);
+  oldArgv->replaceAllUsesWith(argv);
+
+  new StoreInst(oldArgc, argcPtr, initEnvCall);
+  new StoreInst(oldArgv, argvPtr, initEnvCall);
+
+  return 0;
+}
+
+
+// This is a terrible hack until we get some real modelling of the
+// system. All we do is check the undefined symbols and m and warn about
+// any "unrecognized" externals and about any obviously unsafe ones.
+
+// Symbols we explicitly support
+static const char *modelledExternals[] = {
+  "_ZTVN10__cxxabiv117__class_type_infoE",
+  "_ZTVN10__cxxabiv120__si_class_type_infoE",
+  "_ZTVN10__cxxabiv121__vmi_class_type_infoE",
+
+  // special functions
+  "_assert", 
+  "__assert_fail", 
+  "__assert_rtn", 
+  "calloc", 
+  "_exit", 
+  "exit", 
+  "free", 
+  "abort", 
+  "klee_abort", 
+  "klee_assume", 
+  "klee_check_memory_access",
+  "klee_define_fixed_object",
+  "klee_get_errno", 
+  "klee_get_value",
+  "klee_get_obj_size", 
+  "klee_is_symbolic", 
+  "klee_make_symbolic_name", 
+  "klee_mark_global", 
+  "klee_malloc_n", 
+  "klee_merge", 
+  "klee_prefer_cex",
+  "klee_print_expr", 
+  "klee_print_range", 
+  "klee_report_error", 
+  "klee_revirt_objects", 
+  "klee_set_forking",
+  "klee_silent_exit", 
+  "klee_under_constrained", 
+  "klee_warning", 
+  "klee_warning_once", 
+  "klee_alias_function",
+  "llvm.dbg.stoppoint", 
+  "llvm.va_start", 
+  "llvm.va_end", 
+  "malloc", 
+  "realloc", 
+  "_ZdaPv", 
+  "_ZdlPv", 
+  "_Znaj", 
+  "_Znwj", 
+  "_Znam", 
+  "_Znwm", 
+};
+// Symbols we aren't going to warn about
+static const char *dontCareExternals[] = {
+#if 0
+  // stdio
+  "fprintf",
+  "fflush",
+  "fopen",
+  "fclose",
+  "fputs_unlocked",
+  "putchar_unlocked",
+  "vfprintf",
+  "fwrite",
+  "puts",
+  "printf",
+  "stdin",
+  "stdout",
+  "stderr",
+  "_stdio_term",
+  "__errno_location",
+  "fstat",
+#endif
+
+  // static information, pretty ok to return
+  "getegid",
+  "geteuid",
+  "getgid",
+  "getuid",
+  "getpid",
+  "gethostname",
+  "getpgrp",
+  "getppid",
+  "getpagesize",
+  "getpriority",
+  "getgroups",
+  "getdtablesize",
+  "getrlimit",
+  "getrlimit64",
+  "getcwd",
+  "getwd",
+  "gettimeofday",
+  "uname",
+
+  // fp stuff we just don't worry about yet
+  "frexp",  
+  "ldexp",
+  "__isnan",
+  "__signbit",
+};
+// Extra symbols we aren't going to warn about with klee-libc
+static const char *dontCareKlee[] = {
+  "__ctype_b_loc",
+  "__ctype_get_mb_cur_max",
+
+  // io system calls
+  "open",
+  "write",
+  "read",
+  "close",
+};
+// Extra symbols we aren't going to warn about with uclibc
+static const char *dontCareUclibc[] = {
+  "__dso_handle",
+
+  // Don't warn about these since we explicitly commented them out of
+  // uclibc.
+  "printf",
+  "vprintf"
+};
+// Symbols we consider unsafe
+static const char *unsafeExternals[] = {
+  "fork", // oh lord
+  "exec", // heaven help us
+  "error", // calls _exit
+  "raise", // yeah
+  "kill", // mmmhmmm
+};
+#define NELEMS(array) (sizeof(array)/sizeof(array[0]))
+void externalsAndGlobalsCheck(const Module *m) {
+  std::map<std::string, bool> externals;
+  std::set<std::string> modelled(modelledExternals, 
+                                 modelledExternals+NELEMS(modelledExternals));
+  std::set<std::string> dontCare(dontCareExternals, 
+                                 dontCareExternals+NELEMS(dontCareExternals));
+  std::set<std::string> unsafe(unsafeExternals, 
+                               unsafeExternals+NELEMS(unsafeExternals));
+
+  switch (Libc) {
+  case KleeLibc: 
+    dontCare.insert(dontCareKlee, dontCareKlee+NELEMS(dontCareKlee));
+    break;
+  case UcLibc:
+    dontCare.insert(dontCareUclibc,
+                    dontCareUclibc+NELEMS(dontCareUclibc));
+    break;
+  case NoLibc: /* silence compiler warning */
+    break;
+  }
+  
+
+  if (WithPOSIXRuntime)
+    dontCare.insert("syscall");
+
+  for (Module::const_iterator fnIt = m->begin(), fn_ie = m->end(); 
+       fnIt != fn_ie; ++fnIt) {
+    if (fnIt->isDeclaration() && !fnIt->use_empty())
+      externals.insert(std::make_pair(fnIt->getName(), false));
+    for (Function::const_iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
+         bbIt != bb_ie; ++bbIt) {
+      for (BasicBlock::const_iterator it = bbIt->begin(), ie = bbIt->end(); 
+           it != it; ++it) {
+        if (const CallInst *ci = dyn_cast<CallInst>(it)) {
+          if (isa<InlineAsm>(ci->getCalledValue())) {
+            klee_warning_once(&*fnIt,
+                              "function \"%s\" has inline asm", 
+                              fnIt->getName().c_str());
+          }
+        }
+      }
+    }
+  }
+  for (Module::const_global_iterator 
+         it = m->global_begin(), ie = m->global_end(); 
+       it != ie; ++it)
+    if (it->isDeclaration() && !it->use_empty())
+      externals.insert(std::make_pair(it->getName(), true));
+  // and remove aliases (they define the symbol after global
+  // initialization)
+  for (Module::const_alias_iterator 
+         it = m->alias_begin(), ie = m->alias_end(); 
+       it != ie; ++it) {
+    std::map<std::string, bool>::iterator it2 = 
+      externals.find(it->getName());
+    if (it2!=externals.end())
+      externals.erase(it2);
+  }
+
+  std::map<std::string, bool> foundUnsafe;
+  for (std::map<std::string, bool>::iterator
+         it = externals.begin(), ie = externals.end();
+       it != ie; ++it) {
+    const std::string &ext = it->first;
+    if (!modelled.count(ext) && (WarnAllExternals || 
+                                 !dontCare.count(ext))) {
+      if (unsafe.count(ext)) {
+        foundUnsafe.insert(*it);
+      } else {
+        klee_warning("undefined reference to %s: %s",
+                     it->second ? "variable" : "function",
+                     ext.c_str());
+      }
+    }
+  }
+
+  for (std::map<std::string, bool>::iterator
+         it = foundUnsafe.begin(), ie = foundUnsafe.end();
+       it != ie; ++it) {
+    const std::string &ext = it->first;
+    klee_warning("undefined reference to %s: %s (UNSAFE)!",
+                 it->second ? "variable" : "function",
+                 ext.c_str());
+  }
+}
+
+static Interpreter *theInterpreter = 0;
+
+static bool interrupted = false;
+
+// Pulled out so it can be easily called from a debugger.
+extern "C"
+void halt_execution() {
+  theInterpreter->setHaltExecution(true);
+}
+
+extern "C"
+void stop_forking() {
+  theInterpreter->setInhibitForking(true);
+}
+
+static void interrupt_handle() {
+  if (!interrupted && theInterpreter) {
+    llvm::cerr << "KLEE: ctrl-c detected, requesting interpreter to halt.\n";
+    halt_execution();
+    sys::SetInterruptFunction(interrupt_handle);
+  } else {
+    llvm::cerr << "KLEE: ctrl-c detected, exiting.\n";
+    exit(1);
+  }
+  interrupted = true;
+}
+
+// This is a temporary hack. If the running process has access to
+// externals then it can disable interrupts, which screws up the
+// normal "nice" watchdog termination process. We try to request the
+// interpreter to halt using this mechanism as a last resort to save
+// the state data before going ahead and killing it.
+static void halt_via_gdb(int pid) {
+  char buffer[256];
+  sprintf(buffer, 
+          "gdb --batch --eval-command=\"p halt_execution()\" "
+          "--eval-command=detach --pid=%d &> /dev/null",
+          pid);
+  //  fprintf(stderr, "KLEE: WATCHDOG: running: %s\n", buffer);
+  if (system(buffer)==-1) 
+    perror("system");
+}
+
+// returns the end of the string put in buf
+static char *format_tdiff(char *buf, long seconds)
+{
+  assert(seconds >= 0);
+
+  long minutes = seconds / 60;  seconds %= 60;
+  long hours   = minutes / 60;  minutes %= 60;
+  long days    = hours   / 24;  hours   %= 24;
+
+  buf = strrchr(buf, '\0');
+  if (days > 0) buf += sprintf(buf, "%ld days, ", days);
+  buf += sprintf(buf, "%02ld:%02ld:%02ld", hours, minutes, seconds);
+  return buf;
+}
+
+#ifndef KLEE_UCLIBC
+static llvm::Module *linkWithUclibc(llvm::Module *mainModule) {
+  fprintf(stderr, "error: invalid libc, no uclibc support!\n");
+  exit(1);
+  return 0;
+}
+#else
+static llvm::Module *linkWithUclibc(llvm::Module *mainModule) {
+  Function *f;
+  // force import of __uClibc_main
+  mainModule->getOrInsertFunction("__uClibc_main",
+                                  FunctionType::get(Type::VoidTy,
+                                                    std::vector<const Type*>(),
+                                                    true));
+  
+  // force various imports
+  if (WithPOSIXRuntime) {
+    mainModule->getOrInsertFunction("realpath",
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+    mainModule->getOrInsertFunction("getutent",
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+    mainModule->getOrInsertFunction("__fgetc_unlocked",
+                                    Type::Int32Ty,
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+    mainModule->getOrInsertFunction("__fputc_unlocked",
+                                    Type::Int32Ty,
+                                    Type::Int32Ty,
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+  }
+
+  f = mainModule->getFunction("__ctype_get_mb_cur_max");
+  if (f) f->setName("_stdlib_mb_cur_max");
+
+  // Strip of asm prefixes for 64 bit versions because they are not
+  // present in uclibc and we want to make sure stuff will get
+  // linked. In the off chance that both prefixed and unprefixed
+  // versions are present in the module, make sure we don't create a
+  // naming conflict.
+  for (Module::iterator fi = mainModule->begin(), fe = mainModule->end();
+       fi != fe;) {
+    Function *f = fi;
+    ++fi;
+    const std::string &name = f->getName();
+    if (name[0]=='\01') {
+      unsigned size = name.size();
+      if (name[size-2]=='6' && name[size-1]=='4') {
+        std::string unprefixed = name.substr(1);
+
+        // See if the unprefixed version exists.
+        if (Function *f2 = mainModule->getFunction(unprefixed)) {
+          f->replaceAllUsesWith(f2);
+          f->eraseFromParent();
+        } else {
+          f->setName(unprefixed);
+        }
+      }
+    }
+  }
+  
+  mainModule = klee::linkWithLibrary(mainModule, 
+                                     KLEE_UCLIBC "/lib/libc.a");
+  assert(mainModule && "unable to link with uclibc");
+
+  // more sighs, this is horrible but just a temp hack
+  //    f = mainModule->getFunction("__fputc_unlocked");
+  //    if (f) f->setName("fputc_unlocked");
+  //    f = mainModule->getFunction("__fgetc_unlocked");
+  //    if (f) f->setName("fgetc_unlocked");
+  
+  Function *f2;
+  f = mainModule->getFunction("open");
+  f2 = mainModule->getFunction("__libc_open");
+  if (f2) {
+    if (f) {
+      f2->replaceAllUsesWith(f);
+      f2->eraseFromParent();
+    } else {
+      f2->setName("open");
+      assert(f2->getName() == "open");
+    }
+  }
+
+  f = mainModule->getFunction("fcntl");
+  f2 = mainModule->getFunction("__libc_fcntl");
+  if (f2) {
+    if (f) {
+      f2->replaceAllUsesWith(f);
+      f2->eraseFromParent();
+    } else {
+      f2->setName("fcntl");
+      assert(f2->getName() == "fcntl");
+    }
+  }
+
+  // XXX we need to rearchitect so this can also be used with
+  // programs externally linked with uclibc.
+
+  // We now need to swap things so that __uClibc_main is the entry
+  // point, in such a way that the arguments are passed to
+  // __uClibc_main correctly. We do this by renaming the user main
+  // and generating a stub function to call __uClibc_main. There is
+  // also an implicit cooperation in that runFunctionAsMain sets up
+  // the environment arguments to what uclibc expects (following
+  // argv), since it does not explicitly take an envp argument.
+  Function *userMainFn = mainModule->getFunction("main");
+  assert(userMainFn && "unable to get user main");    
+  Function *uclibcMainFn = mainModule->getFunction("__uClibc_main");
+  assert(uclibcMainFn && "unable to get uclibc main");    
+  userMainFn->setName("__user_main");
+
+  const FunctionType *ft = uclibcMainFn->getFunctionType();
+  assert(ft->getNumParams() == 7);
+
+  std::vector<const Type*> fArgs;
+  fArgs.push_back(ft->getParamType(1)); // argc
+  fArgs.push_back(ft->getParamType(2)); // argv
+  Function *stub = Function::Create(FunctionType::get(Type::Int32Ty, fArgs, false),
+      			      GlobalVariable::ExternalLinkage,
+      			      "main",
+      			      mainModule);
+  BasicBlock *bb = BasicBlock::Create("entry", stub);
+
+  std::vector<llvm::Value*> args;
+  args.push_back(llvm::ConstantExpr::getBitCast(userMainFn, 
+                                                ft->getParamType(0)));
+  args.push_back(stub->arg_begin()); // argc
+  args.push_back(++stub->arg_begin()); // argv    
+  args.push_back(Constant::getNullValue(ft->getParamType(3))); // app_init
+  args.push_back(Constant::getNullValue(ft->getParamType(4))); // app_fini
+  args.push_back(Constant::getNullValue(ft->getParamType(5))); // rtld_fini
+  args.push_back(Constant::getNullValue(ft->getParamType(6))); // stack_end
+  CallInst::Create(uclibcMainFn, args.begin(), args.end(), "", bb);
+  
+  new UnreachableInst(bb);
+
+  return mainModule;
+}
+#endif
+
+int main(int argc, char **argv, char **envp) {  
+#if ENABLE_STPLOG == 1
+  STPLOG_init("stplog.c");
+#endif
+
+  atexit(llvm_shutdown);  // Call llvm_shutdown() on exit.
+  parseArguments(argc, argv);
+  sys::PrintStackTraceOnErrorSignal();
+
+  if (Watchdog) {
+    if (MaxTime==0) {
+      klee_error("--watchdog used without --max-time");
+    }
+
+    int pid = fork();
+    if (pid<0) {
+      klee_error("unable to fork watchdog");
+    } else if (pid) {
+      fprintf(stderr, "KLEE: WATCHDOG: watching %d\n", pid);
+      fflush(stderr);
+
+      double nextStep = util::getWallTime() + MaxTime*1.1;
+      int level = 0;
+
+      // Simple stupid code...
+      while (1) {
+        sleep(1);
+
+        int status, res = waitpid(pid, &status, WNOHANG);
+
+        if (res < 0) {
+          if (errno==ECHILD) { // No child, no need to watch but
+                               // return error since we didn't catch
+                               // the exit.
+            fprintf(stderr, "KLEE: watchdog exiting (no child)\n");
+            return 1;
+          } else if (errno!=EINTR) {
+            perror("watchdog waitpid");
+            exit(1);
+          }
+        } else if (res==pid && WIFEXITED(status)) {
+          return WEXITSTATUS(status);
+        } else {
+          double time = util::getWallTime();
+
+          if (time > nextStep) {
+            ++level;
+            
+            if (level==1) {
+              fprintf(stderr, "KLEE: WATCHDOG: time expired, attempting halt via INT\n");
+              kill(pid, SIGINT);
+            } else if (level==2) {
+              fprintf(stderr, "KLEE: WATCHDOG: time expired, attempting halt via gdb\n");
+              halt_via_gdb(pid);
+            } else {
+              fprintf(stderr, "KLEE: WATCHDOG: kill(9)ing child (I tried to be nice)\n");
+              kill(pid, SIGKILL);
+              return 1; // what more can we do
+            }
+
+            // Ideally this triggers a dump, which may take a while,
+            // so try and give the process extra time to clean up.
+            nextStep = util::getWallTime() + std::max(15., MaxTime*.1);
+          }
+        }
+      }
+
+      return 0;
+    }
+  }
+
+  sys::SetInterruptFunction(interrupt_handle);
+
+  // Load the bytecode...
+  std::string ErrorMsg;
+  ModuleProvider *MP = 0;
+  if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile, &ErrorMsg)) {
+    MP = getBitcodeModuleProvider(Buffer, &ErrorMsg);
+    if (!MP) delete Buffer;
+  }
+  
+  if (!MP)
+    klee_error("error loading program '%s': %s", InputFile.c_str(), ErrorMsg.c_str());
+
+  Module *mainModule = MP->materializeModule();
+  MP->releaseModule();
+  delete MP;
+
+  assert(mainModule && "unable to materialize");
+  
+  if (WithPOSIXRuntime)
+    InitEnv = true;
+
+  if (InitEnv) {
+    int r = initEnv(mainModule);
+    if (r != 0)
+      return r;
+  }
+
+  llvm::sys::Path LibraryDir(KLEE_DIR "/" RUNTIME_CONFIGURATION "/lib");
+  Interpreter::ModuleOptions Opts(LibraryDir.c_str(),
+                                  /*Optimize=*/OptimizeModule, 
+                                  /*CheckDivZero=*/CheckDivZero);
+  
+  switch (Libc) {
+  case NoLibc: /* silence compiler warning */
+    break;
+
+  case KleeLibc: {
+    // FIXME: Find a reasonable solution for this.
+    llvm::sys::Path Path(Opts.LibraryDir);
+    Path.appendComponent("libklee-libc.bca");
+    mainModule = klee::linkWithLibrary(mainModule, Path.c_str());
+    assert(mainModule && "unable to link with klee-libc");
+    break;
+  }
+
+  case UcLibc:
+    mainModule = linkWithUclibc(mainModule);
+    break;
+  }
+
+  if (WithPOSIXRuntime) {
+    llvm::sys::Path Path(Opts.LibraryDir);
+    Path.appendComponent("libkleeRuntimePOSIX.bca");
+    klee_message("NOTE: Using model: %s", Path.c_str());
+    mainModule = klee::linkWithLibrary(mainModule, Path.c_str());
+    assert(mainModule && "unable to link with simple model");
+  }  
+
+  // Get the desired main function.  klee_main initializes uClibc
+  // locale and other data and then calls main.
+  Function *mainFn = mainModule->getFunction("main");
+  if (!mainFn) {
+    llvm::cerr << "'main' function not found in module.\n";
+    return -1;
+  }
+
+  // FIXME: Change me to std types.
+  int pArgc;
+  char **pArgv;
+  char **pEnvp;
+  if (Environ != "") {
+    std::vector<std::string> items;
+    std::ifstream f(Environ.c_str());
+    if (!f.good())
+      klee_error("unable to open --environ file: %s", Environ.c_str());
+    while (!f.eof()) {
+      std::string line;
+      std::getline(f, line);
+      line = strip(line);
+      if (!line.empty())
+        items.push_back(line);
+    }
+    f.close();
+    pEnvp = new char *[items.size()+1];
+    unsigned i=0;
+    for (; i != items.size(); ++i)
+      pEnvp[i] = strdup(items[i].c_str());
+    pEnvp[i] = 0;
+  } else {
+    pEnvp = envp;
+  }
+
+  pArgc = InputArgv.size() + 1; 
+  pArgv = new char *[pArgc];
+  for (unsigned i=0; i<InputArgv.size()+1; i++) {
+    std::string &arg = (i==0 ? InputFile : InputArgv[i-1]);
+    unsigned size = arg.size() + 1;
+    char *pArg = new char[size];
+    
+    std::copy(arg.begin(), arg.end(), pArg);
+    pArg[size - 1] = 0;
+    
+    pArgv[i] = pArg;
+  }
+
+  std::vector<bool> replayPath;
+
+  if (ReplayPathFile != "") {
+    KleeHandler::loadPathFile(ReplayPathFile, replayPath);
+  }
+
+  Interpreter::InterpreterOptions IOpts;
+  IOpts.MakeConcreteSymbolic = MakeConcreteSymbolic;
+  KleeHandler *handler = new KleeHandler(pArgc, pArgv);
+  Interpreter *interpreter = 
+    theInterpreter = Interpreter::create(IOpts, handler);
+  handler->setInterpreter(interpreter);
+  
+  std::ostream &infoFile = handler->getInfoStream();
+  for (int i=0; i<argc; i++) {
+    infoFile << argv[i] << (i+1<argc ? " ":"\n");
+  }
+  infoFile << "PID: " << getpid() << "\n";
+
+  const Module *finalModule = 
+    interpreter->setModule(mainModule, Opts);
+  externalsAndGlobalsCheck(finalModule);
+
+  if (ReplayPathFile != "") {
+    interpreter->setReplayPath(&replayPath);
+  }
+
+  char buf[256];
+  time_t t[2];
+  t[0] = time(NULL);
+  strftime(buf, sizeof(buf), "Started: %Y-%m-%d %H:%M:%S\n", localtime(&t[0]));
+  infoFile << buf;
+  infoFile.flush();
+
+  if (!ReplayOutDir.empty() || !ReplayOutFile.empty()) {
+    assert(SeedOutFile.empty());
+    assert(SeedOutDir.empty());
+
+    std::vector<std::string> outFiles = ReplayOutFile;
+    for (std::vector<std::string>::iterator
+           it = ReplayOutDir.begin(), ie = ReplayOutDir.end();
+         it != ie; ++it)
+      KleeHandler::getOutFiles(*it, outFiles);    
+    std::vector<BOut*> bOuts;
+    for (std::vector<std::string>::iterator
+           it = outFiles.begin(), ie = outFiles.end();
+         it != ie; ++it) {
+      BOut *out = bOut_fromFile(it->c_str());
+      if (out) {
+        bOuts.push_back(out);
+      } else {
+        llvm::cerr << "KLEE: unable to open: " << *it << "\n";
+      }
+    }
+
+    if (RunInDir != "") {
+      int res = chdir(RunInDir.c_str());
+      if (res < 0) {
+        klee_error("Unable to change directory to: %s", RunInDir.c_str());
+      }
+    }
+
+    unsigned i=0;
+    for (std::vector<BOut*>::iterator
+           it = bOuts.begin(), ie = bOuts.end();
+         it != ie; ++it) {
+      BOut *out = *it;
+      interpreter->setReplayOut(out);
+      llvm::cerr << "KLEE: replaying: " << *it << " (" << bOut_numBytes(out) << " bytes)"
+                 << " (" << ++i << "/" << outFiles.size() << ")\n";
+      // XXX should put envp in .bout ?
+      interpreter->runFunctionAsMain(mainFn, out->numArgs, out->args, pEnvp);
+      if (interrupted) break;
+    }
+    interpreter->setReplayOut(0);
+    while (!bOuts.empty()) {
+      bOut_free(bOuts.back());
+      bOuts.pop_back();
+    }
+  } else {
+    std::vector<BOut *> seeds;
+    for (std::vector<std::string>::iterator
+           it = SeedOutFile.begin(), ie = SeedOutFile.end();
+         it != ie; ++it) {
+      BOut *out = bOut_fromFile(it->c_str());
+      if (!out) {
+        llvm::cerr << "KLEE: unable to open: " << *it << "\n";
+        exit(1);
+      }
+      seeds.push_back(out);
+    } 
+    for (std::vector<std::string>::iterator
+           it = SeedOutDir.begin(), ie = SeedOutDir.end();
+         it != ie; ++it) {
+      std::vector<std::string> outFiles;
+      KleeHandler::getOutFiles(*it, outFiles);
+      for (std::vector<std::string>::iterator
+             it2 = outFiles.begin(), ie = outFiles.end();
+           it2 != ie; ++it2) {
+        BOut *out = bOut_fromFile(it2->c_str());
+        if (!out) {
+          llvm::cerr << "KLEE: unable to open: " << *it2 << "\n";
+          exit(1);
+        }
+        seeds.push_back(out);
+      }
+      if (outFiles.empty()) {
+        llvm::cerr << "KLEE: seeds directory is empty: " << *it << "\n";
+        exit(1);
+      }
+    }
+       
+    if (!seeds.empty()) {
+      llvm::cerr << "KLEE: using " << seeds.size() << " seeds\n";
+      interpreter->useSeeds(&seeds);
+    }
+    if (RunInDir != "") {
+      int res = chdir(RunInDir.c_str());
+      if (res < 0) {
+        klee_error("Unable to change directory to: %s", RunInDir.c_str());
+      }
+    }
+    interpreter->runFunctionAsMain(mainFn, pArgc, pArgv, pEnvp);
+
+    while (!seeds.empty()) {
+      bOut_free(seeds.back());
+      seeds.pop_back();
+    }
+  }
+      
+  t[1] = time(NULL);
+  strftime(buf, sizeof(buf), "Finished: %Y-%m-%d %H:%M:%S\n", localtime(&t[1]));
+  infoFile << buf;
+
+  strcpy(buf, "Elapsed: ");
+  strcpy(format_tdiff(buf, t[1] - t[0]), "\n");
+  infoFile << buf;
+
+  // Free all the args.
+  for (unsigned i=0; i<InputArgv.size()+1; i++)
+    delete[] pArgv[i];
+  delete[] pArgv;
+
+  delete interpreter;
+
+  uint64_t queries = 
+    *theStatisticManager->getStatisticByName("Queries");
+  uint64_t queriesValid = 
+    *theStatisticManager->getStatisticByName("QueriesValid");
+  uint64_t queriesInvalid = 
+    *theStatisticManager->getStatisticByName("QueriesInvalid");
+  uint64_t queryCounterexamples = 
+    *theStatisticManager->getStatisticByName("QueriesCEX");
+  uint64_t queryConstructs = 
+    *theStatisticManager->getStatisticByName("QueriesConstructs");
+  uint64_t instructions = 
+    *theStatisticManager->getStatisticByName("Instructions");
+  uint64_t forks = 
+    *theStatisticManager->getStatisticByName("Forks");
+
+  handler->getInfoStream() 
+    << "KLEE: done: explored paths = " << 1 + forks << "\n";
+
+  // Write some extra information in the info file which users won't
+  // necessarily care about or understand.
+  if (queries)
+    handler->getInfoStream() 
+      << "KLEE: done: avg. constructs per query = " 
+                             << queryConstructs / queries << "\n";  
+  handler->getInfoStream() 
+    << "KLEE: done: total queries = " << queries << "\n"
+    << "KLEE: done: valid queries = " << queriesValid << "\n"
+    << "KLEE: done: invalid queriers = " << queriesInvalid << "\n"
+    << "KLEE: done: query cex = " << queryCounterexamples << "\n";
+
+  std::stringstream stats;
+  stats << "KLEE: done: total instructions = " 
+             << instructions << "\n";
+  stats << "KLEE: done: completed paths = " 
+             << handler->getNumPathsExplored() << "\n";
+  stats << "KLEE: done: generated tests = " 
+             << handler->getNumTestCases() << "\n";
+  llvm::cerr << stats.str();
+  handler->getInfoStream() << stats.str();
+
+  delete handler;
+
+  return 0;
+}
diff --git a/unittests/Expr/ExprTest.cpp b/unittests/Expr/ExprTest.cpp
new file mode 100644
index 00000000..9220c53e
--- /dev/null
+++ b/unittests/Expr/ExprTest.cpp
@@ -0,0 +1,112 @@
+//===-- ExprTest.cpp ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "klee/Expr.h"
+
+using namespace klee;
+
+namespace {
+
+ref<Expr> getConstant(int value, Expr::Width width) {
+  int64_t ext = value;
+  uint64_t trunc = ext & (((uint64_t) -1LL) >> (64 - width));
+  return ConstantExpr::create(trunc, width);
+}
+
+TEST(ExprTest, BasicConstruction) {
+  EXPECT_EQ(ref<Expr>(0, 32),
+            SubExpr::create(ref<Expr>(10, 32),
+                            ref<Expr>(10, 32)));
+}
+
+TEST(ExprTest, ConcatExtract) {
+  Array *array = new Array(0, 1, 256);
+  ref<Expr> read8 = Expr::createTempRead(array, 8);
+  Array *array2 = new Array(0, 2, 256);
+  ref<Expr> read8_2 = Expr::createTempRead(array2, 8);
+  ref<Expr> c100 = getConstant(100, 8);
+
+  ref<Expr> concat1 = ConcatExpr::create4(read8, read8, c100, read8_2);
+  EXPECT_EQ(2U, concat1.getNumKids());
+  EXPECT_EQ(2U, concat1.getKid(1).getNumKids());
+  EXPECT_EQ(2U, concat1.getKid(1).getKid(1).getNumKids());
+
+  ref<Expr> extract1 = ExtractExpr::create(concat1, 8, 16);
+  EXPECT_EQ(Expr::Concat, extract1.getKind());
+  EXPECT_EQ(read8, extract1.getKid(0));
+  EXPECT_EQ(c100, extract1.getKid(1));
+
+  ref<Expr> extract2 = ExtractExpr::create(concat1, 6, 26);
+  EXPECT_EQ( Expr::Concat, extract2.getKind());
+  EXPECT_EQ( read8, extract2.getKid(0));
+  EXPECT_EQ( Expr::Concat, extract2.getKid(1).getKind());
+  EXPECT_EQ( read8, extract2.getKid(1).getKid(0));
+  EXPECT_EQ( Expr::Concat, extract2.getKid(1).getKid(1).getKind());
+  EXPECT_EQ( c100, extract2.getKid(1).getKid(1).getKid(0));
+  EXPECT_EQ( Expr::Extract, extract2.getKid(1).getKid(1).getKid(1).getKind());
+  
+  ref<Expr> extract3 = ExtractExpr::create(concat1, 24, 1);
+  EXPECT_EQ(Expr::Extract, extract3.getKind());
+
+  ref<Expr> extract4 = ExtractExpr::create(concat1, 27, 2);
+  EXPECT_EQ(Expr::Extract, extract4.getKind());
+  const ExtractExpr* tmp = dyn_ref_cast<ExtractExpr>(extract4);
+  EXPECT_EQ(3U, tmp->offset);
+  EXPECT_EQ(2U, tmp->getWidth());
+
+  ref<Expr> extract5 = ExtractExpr::create(concat1, 17, 5);
+  EXPECT_EQ(Expr::Extract, extract5.getKind());
+
+  ref<Expr> extract6 = ExtractExpr::create(concat1, 3, 26);
+  EXPECT_EQ(Expr::Concat, extract6.getKind());
+  EXPECT_EQ(Expr::Extract, extract6.getKid(0).getKind());
+  EXPECT_EQ(Expr::Concat, extract6.getKid(1).getKind());
+  EXPECT_EQ(read8, extract6.getKid(1).getKid(0));
+  EXPECT_EQ(Expr::Concat, extract6.getKid(1).getKid(1).getKind());
+  EXPECT_EQ(c100, extract6.getKid(1).getKid(1).getKid(0));
+  EXPECT_EQ(Expr::Extract, extract6.getKid(1).getKid(1).getKid(1).getKind());
+
+  ref<Expr> concat10 = ConcatExpr::create4(read8, c100, c100, read8);    
+  ref<Expr> extract10 = ExtractExpr::create(concat10, 8, 16);
+  EXPECT_EQ(Expr::Constant, extract10.getKind());
+}
+
+TEST(ExprTest, ExtractConcat) {
+  Array *array = new Array(0, 3, 256);
+  ref<Expr> read64 = Expr::createTempRead(array, 64);
+
+  Array *array2 = new Array(0, 4, 256);
+  ref<Expr> read8_2 = Expr::createTempRead(array2, 8);
+  
+  ref<Expr> extract1 = ExtractExpr::create(read64, 36, 4);
+  ref<Expr> extract2 = ExtractExpr::create(read64, 32, 4);
+  
+  ref<Expr> extract3 = ExtractExpr::create(read64, 12, 3);
+  ref<Expr> extract4 = ExtractExpr::create(read64, 10, 2);
+  ref<Expr> extract5 = ExtractExpr::create(read64, 2, 8);
+   
+  ref<Expr> kids1[6] = { extract1, extract2,
+			 read8_2,
+			 extract3, extract4, extract5 };
+  ref<Expr> concat1 = ConcatExpr::createN(6, kids1);
+  EXPECT_EQ(29U, concat1.getWidth());
+  
+  ref<Expr> extract6 = ExtractExpr::create(read8_2, 2, 5);
+  ref<Expr> extract7 = ExtractExpr::create(read8_2, 1, 1);
+  
+  ref<Expr> kids2[3] = { extract1, extract6, extract7 };
+  ref<Expr> concat2 = ConcatExpr::createN(3, kids2);
+  EXPECT_EQ(10U, concat2.getWidth());
+  EXPECT_EQ(Expr::Extract, concat2.getKid(0).getKind());
+  EXPECT_EQ(Expr::Extract, concat2.getKid(1).getKind());
+}
+
+}
diff --git a/unittests/Expr/Makefile b/unittests/Expr/Makefile
new file mode 100644
index 00000000..14945b1a
--- /dev/null
+++ b/unittests/Expr/Makefile
@@ -0,0 +1,11 @@
+##===- unittests/Expr/Makefile -----------------------------*- Makefile -*-===##
+
+LEVEL := ../..
+TESTNAME := Expr
+USEDLIBS := kleaverExpr.a kleeBasic.a
+LINK_COMPONENTS := support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+
+LIBS += -lstp 
diff --git a/unittests/Makefile b/unittests/Makefile
new file mode 100755
index 00000000..545d7fa7
--- /dev/null
+++ b/unittests/Makefile
@@ -0,0 +1,18 @@
+##===- unittests/Makefile ----------------------------------*- Makefile -*-===##
+
+LEVEL = ..
+
+include $(LEVEL)/Makefile.config
+
+LIBRARYNAME = UnitTestMain
+BUILD_ARCHIVE = 1
+CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/
+CPP.Flags += -Wno-variadic-macros
+
+# FIXME: Parallel dirs is broken?
+DIRS = Expr Solver
+
+include $(LEVEL)/Makefile.common
+
+clean::
+	$(Verb) $(RM) -f *Tests
diff --git a/unittests/Solver/Makefile b/unittests/Solver/Makefile
new file mode 100644
index 00000000..583025fb
--- /dev/null
+++ b/unittests/Solver/Makefile
@@ -0,0 +1,11 @@
+##===- unittests/Solver/Makefile ---------------------------*- Makefile -*-===##
+
+LEVEL := ../..
+TESTNAME := Solver
+USEDLIBS := kleaverSolver.a kleaverExpr.a kleeSupport.a kleeBasic.a
+LINK_COMPONENTS := support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+
+LIBS += -lstp 
diff --git a/unittests/Solver/SolverTest.cpp b/unittests/Solver/SolverTest.cpp
new file mode 100644
index 00000000..1b1e0f3f
--- /dev/null
+++ b/unittests/Solver/SolverTest.cpp
@@ -0,0 +1,164 @@
+//===-- SolverTest.cpp ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+
+using namespace klee;
+
+namespace {
+
+const int g_constants[] = { -1, 1, 4, 17, 0 };
+const Expr::Width g_types[] = { Expr::Bool,
+				Expr::Int8,
+				Expr::Int16,
+				Expr::Int32,
+				Expr::Int64 };
+
+ref<Expr> getConstant(int value, Expr::Width width) {
+  int64_t ext = value;
+  uint64_t trunc = ext & (((uint64_t) -1LL) >> (64 - width));
+  return ConstantExpr::create(trunc, width);
+}
+
+
+template<class T>
+void testOperation(Solver &solver,
+                   int value,
+                   Expr::Width operandWidth,
+                   Expr::Width resultWidth) {
+  std::vector<Expr::CreateArg> symbolicArgs;
+  
+  for (unsigned i = 0; i < T::numKids; i++) {
+    if (!T::isValidKidWidth(i, operandWidth))
+      return;
+
+    unsigned size = Expr::getMinBytesForWidth(operandWidth);
+    static unsigned id = 0;
+    Array *array = new Array(0, ++id, size);
+    symbolicArgs.push_back(Expr::CreateArg(Expr::createTempRead(array, 
+                                                                operandWidth)));
+  }
+  
+  if (T::needsResultType())
+    symbolicArgs.push_back(Expr::CreateArg(resultWidth));
+  
+  ref<Expr> fullySymbolicExpr = Expr::createFromKind(T::kind, symbolicArgs);
+
+  // For each kid, replace the kid with a constant value and verify
+  // that the fully symbolic expression is equivalent to it when the
+  // replaced value is appropriated constrained.
+  for (unsigned kid = 0; kid < T::numKids; kid++) {
+    std::vector<Expr::CreateArg> partiallyConstantArgs(symbolicArgs);
+    for (unsigned i = 0; i < T::numKids; i++)
+      if (i==kid)
+        partiallyConstantArgs[i] = getConstant(value, operandWidth);
+
+    ref<Expr> expr = 
+      NotOptimizedExpr::create(EqExpr::create(partiallyConstantArgs[kid].expr,
+                                              symbolicArgs[kid].expr));
+    
+    ref<Expr> partiallyConstantExpr =
+      Expr::createFromKind(T::kind, partiallyConstantArgs);
+    
+    ref<Expr> queryExpr = EqExpr::create(fullySymbolicExpr, 
+                                         partiallyConstantExpr);
+    
+    ConstraintManager constraints;
+    constraints.addConstraint(expr);
+    bool res;
+    bool success = solver.mustBeTrue(Query(constraints, queryExpr), res);
+    EXPECT_EQ(true, success) << "Constraint solving failed";
+
+    if (success) {
+      EXPECT_EQ(true, res) << "Evaluation failed!\n" 
+                           << "query " << queryExpr 
+                           << " with " << expr;
+    }
+  }
+}
+
+template<class T>
+void testOpcode(Solver &solver, bool tryBool = true, bool tryZero = true, 
+                unsigned maxWidth = 64) {
+  for (unsigned j=0; j<sizeof(g_types)/sizeof(g_types[0]); j++) {
+    Expr::Width type = g_types[j]; 
+
+    if (type > maxWidth) continue;
+
+    for (unsigned i=0; i<sizeof(g_constants)/sizeof(g_constants[0]); i++) {
+      int value = g_constants[i];
+      if (!tryZero && !value) continue;
+      if (type == Expr::Bool && !tryBool) continue;
+
+      if (!T::needsResultType()) {
+        testOperation<T>(solver, value, type, type);
+        continue;
+      }
+
+      for (unsigned k=0; k<sizeof(g_types)/sizeof(g_types[0]); k++) {
+        Expr::Width resultType = g_types[k];
+          
+        // nasty hack to give only Trunc/ZExt/SExt the right types
+        if (T::kind == Expr::SExt || T::kind == Expr::ZExt) {
+          if (Expr::getMinBytesForWidth(type) >= 
+              Expr::getMinBytesForWidth(resultType)) 
+            continue;
+        }
+            
+        testOperation<T>(solver, value, type, resultType);
+      }
+    }
+  }
+}
+
+TEST(SolverTest, Evaluation) {
+  STPSolver *stpSolver = new STPSolver(true); 
+  Solver *solver = stpSolver;
+
+  solver = createCexCachingSolver(solver);
+  solver = createCachingSolver(solver);
+  solver = createIndependentSolver(solver);
+
+  testOpcode<SelectExpr>(*solver);
+  testOpcode<ZExtExpr>(*solver);
+  testOpcode<SExtExpr>(*solver);
+  
+  testOpcode<AddExpr>(*solver);
+  testOpcode<SubExpr>(*solver);
+  testOpcode<MulExpr>(*solver, false, true, 8);
+  testOpcode<SDivExpr>(*solver, false, false, 8);
+  testOpcode<UDivExpr>(*solver, false, false, 8);
+  testOpcode<SRemExpr>(*solver, false, false, 8);
+  testOpcode<URemExpr>(*solver, false, false, 8);
+  testOpcode<ShlExpr>(*solver, false);
+  testOpcode<LShrExpr>(*solver, false);
+  testOpcode<AShrExpr>(*solver, false);
+  testOpcode<AndExpr>(*solver);
+  testOpcode<OrExpr>(*solver);
+  testOpcode<XorExpr>(*solver);
+
+  testOpcode<EqExpr>(*solver);
+  testOpcode<NeExpr>(*solver);
+  testOpcode<UltExpr>(*solver);
+  testOpcode<UleExpr>(*solver);
+  testOpcode<UgtExpr>(*solver);
+  testOpcode<UgeExpr>(*solver);
+  testOpcode<SltExpr>(*solver);
+  testOpcode<SleExpr>(*solver);
+  testOpcode<SgtExpr>(*solver);
+  testOpcode<SgeExpr>(*solver);
+
+  delete solver;
+}
+
+}
diff --git a/unittests/TestMain.cpp b/unittests/TestMain.cpp
new file mode 100644
index 00000000..095076b2
--- /dev/null
+++ b/unittests/TestMain.cpp
@@ -0,0 +1,15 @@
+//===--- unittests/TestMain.cpp - unittest driver -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/utils/emacs/klee-pc-mode.el b/utils/emacs/klee-pc-mode.el
new file mode 100644
index 00000000..a398adbf
--- /dev/null
+++ b/utils/emacs/klee-pc-mode.el
@@ -0,0 +1,64 @@
+(provide 'klee-pc-mode)
+
+(require 'font-lock)
+
+(defvar klee-pc-mode-syntax-table nil 
+  "Syntax table used while in ft-bt mode.")
+
+;;; --------------------------------------------------
+;;;setup the syntax table
+;;; --------------------------------------------------
+(unless klee-pc-mode-syntax-table
+  (setq klee-pc-mode-syntax-table (make-syntax-table))
+  ;;misc
+  (modify-syntax-entry ?\_   "w"       klee-pc-mode-syntax-table)
+  (modify-syntax-entry ?\.   "."       klee-pc-mode-syntax-table))
+
+;;;------------------------------------------------------------
+;;; local keymap
+;;;------------------------------------------------------------
+
+(defvar klee-pc-local-keymap nil)
+
+;;; --------------------------------------------------
+;;; set keywords
+;;; --------------------------------------------------
+
+(defvar klee-pc-mode-font-lock-keywords
+  (list
+   ;; Comments
+   '("#.*" . font-lock-comment-face)
+   ;; Identifiers
+   '("%[_a-zA-Z][a-zA-Z_.0-9]*" . font-lock-variable-name-face)
+   ;; Numbers
+   '("[+-]?0b[01_]+" . font-lock-preprocessor-face)
+   '("[+-]?0o[0-7_]+" . font-lock-preprocessor-face)
+   '("[+-]?0x[a-zA-Z0-9_]+" . font-lock-preprocessor-face)
+   '("[+-]?[0-9]+" . font-lock-preprocessor-face)
+   ;; Keywords
+   '("\\bdef\\b\\|\\bvar\\b\\|\\btrue\\b\\|\\barray\\b\\|\\bfalse\\b\\|\\bquery\\b\\|\\bdefine\\b\\|\\bdeclare\\b" . font-lock-keyword-face)
+   )
+  "klee-PC mode keywords")
+
+;;; --------------------------------------------------
+;;; major mode function
+;;; --------------------------------------------------
+(defun klee-pc-mode ()
+  "Switch to the klee-pc major mode"
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'klee-pc-mode)
+  (setq mode-name "klee-pc")
+
+  ;; handle keymap
+  (use-local-map klee-pc-local-keymap)
+
+  ;;handle syntax table
+  (set-syntax-table klee-pc-mode-syntax-table)
+  ;;handle fontlock
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '(klee-pc-mode-font-lock-keywords
+			     nil t))
+
+  ;;handle hook
+  (run-hooks 'klee-pc-mode-hook))
diff --git a/utils/valgrind/README.txt b/utils/valgrind/README.txt
new file mode 100644
index 00000000..9f7cb318
--- /dev/null
+++ b/utils/valgrind/README.txt
@@ -0,0 +1,2 @@
+A few valgrind suppression files for known leaks. The LLVM ones may be
+fixed by now.
diff --git a/utils/valgrind/valgrind-llvm.supp b/utils/valgrind/valgrind-llvm.supp
new file mode 100644
index 00000000..43bc5389
--- /dev/null
+++ b/utils/valgrind/valgrind-llvm.supp
@@ -0,0 +1,24 @@
+{ 
+   LLVM:Tmp1
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZN4llvm*
+}
+{ 
+   LLVM:Tmp2
+   Memcheck:Leak
+   fun:_vgrZU_libcZdsoZa_malloc
+   fun:_ZN4llvm*
+}
+{ 
+   LLVM:Tmp3
+   Memcheck:Leak
+   fun:*nwj*
+   fun:*llvm*
+}
+{ 
+   LLVM:Tmp4
+   Memcheck:Leak
+   fun:malloc
+   fun:*llvm*
+}
diff --git a/utils/valgrind/valgrind-stp.supp b/utils/valgrind/valgrind-stp.supp
new file mode 100644
index 00000000..9dba58f1
--- /dev/null
+++ b/utils/valgrind/valgrind-stp.supp
@@ -0,0 +1,32 @@
+{
+   STP:BeevMgr
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZN4BEEV7BeevMgr*
+}
+{
+   STP:BeevMgr:strdup
+   Memcheck:Leak
+   fun:_vgrZU_libcZdsoZa_malloc
+   fun:strdup
+   fun:_ZN4BEEV7BeevMgr*
+}
+{
+   STP:c_interface
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:vc_*
+}
+{
+   STP:BeevMgr:vector
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZNSt6vector*
+   fun:_ZN4BEEV7BeevMgr*
+}
+{ 
+   LLVM:Tmp1
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZN4llvm*
+}
diff --git a/www/Examples.html b/www/Examples.html
new file mode 100644
index 00000000..23584053
--- /dev/null
+++ b/www/Examples.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>KLEE - Examples</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>KLEE Examples</h1>
+
+<p>FIXME: Intro.</p>
+
+<h2>Basic Sort Example</h2>
+
+<p>FIXME: Write.</p>
+
+<h2>FIXME: More complicated example</h2>
+
+<p>FIXME: Write: show the important klee.h functions.</p>
+
+<p>FIXME: Write: show the important klee tools.</p>
+
+<p>FIXME: Write: show the important klee options.</p>
+
+</div>
+</body>
+</html>
diff --git a/www/GetInvolved.html b/www/GetInvolved.html
new file mode 100644
index 00000000..b8afcbb3
--- /dev/null
+++ b/www/GetInvolved.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>klee - Get Involved</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Getting Involved with the klee Project</h1>
+
+<p>FIXME: Intro.</p>
+
+<h2>Mailing Lists</h2>
+
+<p>klee-dev</p>
+
+<p>klee-commits</p>
+
+<h2>Working with the Code</h2>
+
+<p>FIXME: Point at pertinent LLVM docs.</p>
+ 
+<p>FIXME: Point at doxygen.</p>
+
+</div>
+</body>
+</html>
diff --git a/www/GetStarted.html b/www/GetStarted.html
new file mode 100644
index 00000000..07083d4f
--- /dev/null
+++ b/www/GetStarted.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>KLEE - Getting Started</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Getting Started: Building and Running KLEE</h1>
+
+<!-- <p>FIXME: Intro and disclaimer.</p> -->
+
+<h2 id="build">Building KLEE and Working with the Code</h2>
+
+<p>If you would like to check out and build KLEE, the current procedure is as
+follows:</p>
+
+KLEE is built on LLVM; the first steps are to get a working LLVM
+installation. See <a href="http://llvm.org/docs/GettingStarted.html">Getting
+Started with the LLVM System</a> for more information.
+
+<ol>
+<li>Install llvm-gcc:</li>
+<ul>
+<li>Download and install the LLVM 2.5 release of <tt>llvm-gcc</tt>
+  from <a href="http://llvm.org/releases/download.html">here</a>. It
+  is important to do this first so that it is found in
+  subsequent <tt>configure</tt> steps. <tt>llvm-gcc</tt> will be used
+  later to compile programs that KLEE can execute.</li>
+</ul>
+
+<li><a href="http://www.llvm.org/docs/GettingStarted.html#checkout">Checkout
+    and build LLVM</a> from SVN head:
+    
+  <code class="instr"> <code>
+    svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
+    cd llvm
+    ./configure --enable-optimized
+    make
+  </code></code>
+
+(the <tt>--enable-optimized</tt> configure argument is not
+necessary, but KLEE runs very slowly in Debug mode).
+  </li>
+
+  <li>Checkout KLEE (to any path you like):
+    <div class="instr">
+      svn co http://llvm.org/svn/llvm-project/klee/trunk klee
+    </div>
+  </li>
+  
+  <li>Configure KLEE (from the KLEE source directory): 
+    <div class="instr">
+      ./configure --with-llvm=<i>path/to/llvm</i>
+    </div>
+    
+    <p>This assumes that you compiled LLVM in-place.  If you used a
+      different directory for the object files then use:
+      <div class="instr">
+	./configure --with-llvmsrc=<i>path/to/llvm/src</i>--with-llvmobj=<i>path/to/llvm/obj</i>
+      </div>
+  </li>
+
+  <li>Build KLEE (from the KLEE source directory):
+    <div class="instr">
+      make
+    </div>
+  </li>
+
+  <li>Run DejaGNU and unit tests to verify your build:
+    <div class="instr">
+      make check<br>
+      make unittests<br>
+    </div>
+  </li>
+
+  <li>You're ready to go!  Go to the <a href="tutorials.html">Tutorials</a> page
+  to try KLEE.</li>
+</ol>
+
+<!--   <h2> Full Installation </h2> -->
+  
+<!--   If you need uCLibc and/or POSIX support add <i>-with-uclibc</i> -->
+<!--   and <i>-enable-posix-runtime</i> to configure.  Thus, to enable -->
+<!--   both, replace step 3 above with: -->
+  
+<!--   <div class="instr"> -->
+<!--     ./configure -with-llvm=<i>path/to/llvm</i> -with-uclibc -enable-posix-runtime ENABLE_OPTIMIZED=1 -->
+<!--   </div> -->
+<!--   However, note that... -->
+
+</div>
+</body>
+</html>
diff --git a/www/bugs.html b/www/bugs.html
index bd5dd86c..fca13033 100644
--- a/www/bugs.html
+++ b/www/bugs.html
@@ -9,7 +9,7 @@
   <link type="text/css" rel="stylesheet" href="content.css">
 </head>
 <body>
-<include virtual="menu.html.incl">
+<!--#include virtual="menu.html.incl"-->
 <div id="content">
   <!--*********************************************************************-->
   <h1>KLEE Bug Reports</h1>
diff --git a/www/content.css b/www/content.css
index caee1f00..9571114d 100644
--- a/www/content.css
+++ b/www/content.css
@@ -1,6 +1,8 @@
 html, body {
   padding:0px;
-  font-size:small; font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222;
+  font-size:small; 
+  font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; 
+  background-color: #fff; color: #222;
   line-height:1.5;
 }
 
@@ -24,11 +26,23 @@ IMG.img_slide {
 /* Tables */
 tr { vertical-align:top }
 
-/* Code */
-div.code{
+/* Instructions */
+div.instr{
     border: 1px solid LightSteelBlue ;
     font-family: Courier New;
     background-color: #E3E3E3;
     padding: 7px;
     margin: 7px;
 }
+
+/* Code */
+pre.code{
+    display:table;
+    text-align: left;
+    border: 1px solid LightSteelBlue ;
+    font-family: Courier New;
+    background-color: #E3E3E3;
+    margin: 10px;
+    padding: 10px;
+}
+
diff --git a/www/index.html b/www/index.html
index ea60335a..4b9e5f3b 100644
--- a/www/index.html
+++ b/www/index.html
@@ -27,7 +27,9 @@
   the <a href="http://llvm.org/pubs/2008-12-OSDI-KLEE.html">OSDI
   2008</a> paper.</p>
 
+<!--  <p>FIXME: Somewhere need to describe what KLEE can do well and what
+      is more "experimental" or research level. This should also address
+      how KLEE could be used by outside groups (i.e. kleaver).</p> -->
 </div>
-
 </body>
 </html>
diff --git a/www/install.html b/www/install.html
index b01f2105..79aeb4b1 100644
--- a/www/install.html
+++ b/www/install.html
@@ -9,7 +9,7 @@
   <link type="text/css" rel="stylesheet" href="content.css">
 </head>
 <body>
-<include virtual="menu.html.incl">
+<!--#include virtual="menu.html.incl"-->
 <div id="content">
   <!--*********************************************************************-->
   <h1>KLEE Installation Guide</h1>
diff --git a/www/menu.html.incl b/www/menu.html.incl
index 2fbffaef..ef450ca7 100644
--- a/www/menu.html.incl
+++ b/www/menu.html.incl
@@ -6,7 +6,10 @@
   <div class="submenu">
     <label>klee Info</label>
     <a href="index.html">About</a>
-    <a href="install.html">Download &amp; Install</a>
+    <a href="GetStarted.html">Get Started</a>
+    <a href="GetInvolved.html">Get Involved</a>
+    <a href="tutorials.html">Tutorials</a>
+    <a href="Examples.html">Examples</a>
   </div>
 
   <div class="submenu">
@@ -14,5 +17,7 @@
     <a href="http://keeda.stanford.edu/mailman/listinfo/klee-dev">klee-dev</a>
     <a href="http://llvm.org/svn/llvm-project/klee/trunk/">Browse SVN</a>
     <a href="http://llvm.org/viewvc/llvm-project/klee/trunk/">Browse ViewVC</a>
+    <a href="http://t1.minormatter.com/~ddunbar/klee-doxygen/index.html">doxygen</a>
+    <a href="http://t1.minormatter.com/~ddunbar/klee-cov/index.html">Testing Coverage</a>
   </div>
 </div>
diff --git a/www/tutorials.html b/www/tutorials.html
index db5220e4..08e9e4f7 100644
--- a/www/tutorials.html
+++ b/www/tutorials.html
@@ -4,12 +4,12 @@
 <html>
 <head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <title>The klee Symbolic Virtual Machine</title>
+  <title>The KLEE Symbolic Virtual Machine</title>
   <link type="text/css" rel="stylesheet" href="menu.css">
   <link type="text/css" rel="stylesheet" href="content.css">
 </head>
 <body>
-<include virtual="menu.html.incl">
+<!--#include virtual="menu.html.incl"-->
 <div id="content">
   <!--*********************************************************************-->
   <h1>KLEE Tutorials</h1>