diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp
index ae6cdf7..2229e47 100644
--- a/Analysis/GRConstants.cpp
+++ b/Analysis/GRConstants.cpp
@@ -15,6 +15,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "RValues.h"
+#include "ValueState.h"
+
 #include "clang/Analysis/PathSensitive/GREngine.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
@@ -44,726 +47,6 @@
 using llvm::APSInt;
 
 //===----------------------------------------------------------------------===//
-/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
-///  Stmt*.  Use cast<> or dyn_cast<> to get actual pointer type
-//===----------------------------------------------------------------------===//
-namespace {
-
-class SymbolID {
-  unsigned Data;
-public:
-  SymbolID() : Data(~0) {}
-  SymbolID(unsigned x) : Data(x) {}
-  
-  bool isInitialized() const { return Data != (unsigned) ~0; }
-  operator unsigned() const { assert (isInitialized()); return Data; }
-};
-
-class VISIBILITY_HIDDEN ValueKey {
-  uintptr_t Raw;  
-  void operator=(const ValueKey& RHS); // Do not implement.
-  
-public:
-  enum  Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
-               IsSymbol=0x3, // Symbol Bindings.
-               Flags=0x3 };
-  
-  inline Kind getKind() const {
-    return (Kind) (Raw & Flags);
-  }
-  
-  inline void* getPtr() const { 
-    assert (getKind() != IsSymbol);
-    return reinterpret_cast<void*>(Raw & ~Flags);
-  }
-  
-  inline SymbolID getSymbolID() const {
-    assert (getKind() == IsSymbol);
-    return Raw >> 2;
-  }
-  
-  ValueKey(const ValueDecl* VD)
-    : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
-      assert(VD && "ValueDecl cannot be NULL.");
-    }
-
-  ValueKey(Stmt* S, bool isBlkExpr = false) 
-    : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
-      assert(S && "Tracked statement cannot be NULL.");
-    }
-  
-  ValueKey(SymbolID V)
-    : Raw((V << 2) | IsSymbol) {}  
-  
-  bool isSymbol()  const { return getKind() == IsSymbol; }
-  bool isSubExpr() const { return getKind() == IsSubExpr; }
-  bool isBlkExpr() const { return getKind() == IsBlkExpr; }
-  bool isDecl()    const { return getKind() == IsDecl; }
-  bool isStmt()    const { return getKind() <= IsBlkExpr; }
-  
-  inline void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger(isSymbol() ? 1 : 0);
-
-    if (isSymbol())
-      ID.AddInteger(getSymbolID());
-    else    
-      ID.AddPointer(getPtr());
-  }
-  
-  inline bool operator==(const ValueKey& X) const {
-    return isSymbol() ? getSymbolID() == X.getSymbolID()
-                      : getPtr() == X.getPtr();
-  }
-  
-  inline bool operator!=(const ValueKey& X) const {
-    return !operator==(X);
-  }
-  
-  inline bool operator<(const ValueKey& X) const { 
-    if (isSymbol())
-      return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
-    
-    return getPtr() < X.getPtr();
-  }
-};
-} // end anonymous namespace
-
-// Machinery to get cast<> and dyn_cast<> working with ValueKey.
-namespace llvm {
-  template<> inline bool isa<ValueDecl,ValueKey>(const ValueKey& V) {
-    return V.getKind() == ValueKey::IsDecl;
-  }
-  template<> inline bool isa<Stmt,ValueKey>(const ValueKey& V) {
-    return ((unsigned) V.getKind()) < ValueKey::IsDecl;
-  }
-  template<> struct VISIBILITY_HIDDEN cast_retty_impl<ValueDecl,ValueKey> {
-    typedef const ValueDecl* ret_type;
-  };
-  template<> struct VISIBILITY_HIDDEN cast_retty_impl<Stmt,ValueKey> {
-    typedef const Stmt* ret_type;
-  };
-  template<> struct VISIBILITY_HIDDEN simplify_type<ValueKey> {
-    typedef void* SimpleType;
-    static inline SimpleType getSimplifiedValue(const ValueKey &V) {
-      return V.getPtr();
-    }
-  };
-} // end llvm namespace
-
-
-//===----------------------------------------------------------------------===//
-// SymbolManager.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN SymbolData {
-  uintptr_t Data;
-public:
-  enum Kind { ParmKind = 0x0, Mask = 0x3 };
-  
-  SymbolData(ParmVarDecl* D)
-    : Data(reinterpret_cast<uintptr_t>(D) | ParmKind) {}
-  
-  inline Kind getKind() const { return (Kind) (Data & Mask); }
-  inline void* getPtr() const { return reinterpret_cast<void*>(Data & ~Mask); }  
-  inline bool operator==(const SymbolData& R) const { return Data == R.Data; }  
-};
-}
-
-// Machinery to get cast<> and dyn_cast<> working with SymbolData.
-namespace llvm {
-  template<> inline bool isa<ParmVarDecl,SymbolData>(const SymbolData& V) {
-    return V.getKind() == SymbolData::ParmKind;
-  }
-  template<> struct VISIBILITY_HIDDEN cast_retty_impl<ParmVarDecl,SymbolData> {
-    typedef const ParmVarDecl* ret_type;
-  };
-  template<> struct VISIBILITY_HIDDEN simplify_type<SymbolData> {
-    typedef void* SimpleType;
-    static inline SimpleType getSimplifiedValue(const SymbolData &V) {
-      return V.getPtr();
-    }
-  };
-} // end llvm namespace
-
-namespace {
-class VISIBILITY_HIDDEN SymbolManager {
-  std::vector<SymbolData> SymbolToData;
-  
-  typedef llvm::DenseMap<void*,SymbolID> MapTy;
-  MapTy DataToSymbol;
-  
-public:
-  SymbolData getSymbolData(SymbolID id) const {
-    assert (id < SymbolToData.size());
-    return SymbolToData[id];
-  }
-  
-  SymbolID getSymbol(ParmVarDecl* D);
-};
-} // end anonymous namespace
-
-SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
-  SymbolID& X = DataToSymbol[D];
-
-  if (!X.isInitialized()) {
-    X = SymbolToData.size();
-    SymbolToData.push_back(D);
-  }
-  
-  return X;
-}
-
-//===----------------------------------------------------------------------===//
-// ValueManager.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-typedef llvm::ImmutableSet<APSInt > APSIntSetTy;
-
-  
-class VISIBILITY_HIDDEN ValueManager {
-  ASTContext& Ctx;
-  
-  typedef  llvm::FoldingSet<llvm::FoldingSetNodeWrapper<APSInt> > APSIntSetTy;
-  APSIntSetTy APSIntSet;
-  
-  llvm::BumpPtrAllocator BPAlloc;
-  
-public:
-  ValueManager(ASTContext& ctx) : Ctx(ctx) {}
-  ~ValueManager();
-  
-  ASTContext& getContext() const { return Ctx; }  
-  APSInt& getValue(const APSInt& X);
-  APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
-  APSInt& getValue(uint64_t X, QualType T,
-                   SourceLocation Loc = SourceLocation());
-};
-} // end anonymous namespace
-
-ValueManager::~ValueManager() {
-  // Note that the dstor for the contents of APSIntSet will never be called,
-  // so we iterate over the set and invoke the dstor for each APSInt.  This
-  // frees an aux. memory allocated to represent very large constants.
-  for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
-    I->getValue().~APSInt();
-}
-
-APSInt& ValueManager::getValue(const APSInt& X) {
-  llvm::FoldingSetNodeID ID;
-  void* InsertPos;
-  typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
-  
-  X.Profile(ID);
-  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
-  
-  if (!P) {  
-    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
-    new (P) FoldNodeTy(X);
-    APSIntSet.InsertNode(P, InsertPos);
-  }
-  
-  return *P;
-}
-
-APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth, bool isUnsigned) {
-  APSInt V(BitWidth, isUnsigned);
-  V = X;  
-  return getValue(V);
-}
-
-APSInt& ValueManager::getValue(uint64_t X, QualType T, SourceLocation Loc) {
-  unsigned bits = Ctx.getTypeSize(T, Loc);
-  APSInt V(bits, T->isUnsignedIntegerType());
-  V = X;
-  return getValue(V);
-}
-
-//===----------------------------------------------------------------------===//
-// Expression Values.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-class VISIBILITY_HIDDEN RValue {
-public:
-  enum BaseKind { LValueKind=0x0, NonLValueKind=0x1,
-                  UninitializedKind=0x2, InvalidKind=0x3 };
-  
-  enum { BaseBits = 2, BaseMask = 0x3 };
-    
-private:
-  void* Data;
-  unsigned Kind;
-    
-protected:
-  RValue(const void* d, bool isLValue, unsigned ValKind)
-    : Data(const_cast<void*>(d)),
-      Kind((isLValue ? LValueKind : NonLValueKind) | (ValKind << BaseBits)) {}
-  
-  explicit RValue(BaseKind k)
-    : Data(0), Kind(k) {}
-
-  void* getRawPtr() const {
-    return reinterpret_cast<void*>(Data);
-  }
-  
-public:
-  ~RValue() {};
-
-  RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
-  
-  unsigned getRawKind() const { return Kind; }
-  BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
-  unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
-  
-  void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger((unsigned) getRawKind());
-    ID.AddPointer(reinterpret_cast<void*>(Data));
-  }
-  
-  bool operator==(const RValue& RHS) const {
-    return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
-  }
-  
-  static RValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
-
-  inline bool isValid() const { return getRawKind() != InvalidKind; }
-  inline bool isInvalid() const { return getRawKind() == InvalidKind; }
-  
-  void print(std::ostream& OS) const;
-  void print() const { print(*llvm::cerr.stream()); }
-
-  // Implement isa<T> support.
-  static inline bool classof(const RValue*) { return true; }
-};
-
-class VISIBILITY_HIDDEN InvalidValue : public RValue {
-public:
-  InvalidValue() : RValue(InvalidKind) {}
-  
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() == InvalidKind;
-  }  
-};
-  
-class VISIBILITY_HIDDEN UninitializedValue : public RValue {
-public:
-  UninitializedValue() : RValue(UninitializedKind) {}
-  
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() == UninitializedKind;
-  }  
-};
-
-class VISIBILITY_HIDDEN NonLValue : public RValue {
-protected:
-  NonLValue(unsigned SubKind, const void* d) : RValue(d, false, SubKind) {}
-  
-public:
-  void print(std::ostream& Out) const;
-  
-  // Arithmetic operators.
-  NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Mul(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Div(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue Rem(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const;
-  
-  // Equality operators.
-  NonLValue EQ(ValueManager& ValMgr, const NonLValue& RHS) const;
-  NonLValue NE(ValueManager& ValMgr, const NonLValue& RHS) const;
-
-  // Utility methods to create NonLValues.
-  static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
-                            SourceLocation Loc = SourceLocation());
-  
-  static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
-  
-  static inline NonLValue GetIntTruthValue(ValueManager& ValMgr, bool X) {
-    return GetValue(ValMgr, X ? 1U : 0U, ValMgr.getContext().IntTy);
-  }
-    
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() >= NonLValueKind;
-  }
-};
-  
-class VISIBILITY_HIDDEN LValue : public RValue {
-protected:
-  LValue(unsigned SubKind, void* D) : RValue(D, true, SubKind) {}
-  
-public:
-  void print(std::ostream& Out) const;
-  
-  // Equality operators.
-  NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const;
-  NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
-  
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getBaseKind() == LValueKind;
-  }
-};
-    
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// LValues.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-enum { SymbolicLValueKind, LValueDeclKind, NumLValueKind };
-
-class VISIBILITY_HIDDEN SymbolicLValue : public LValue {
-public:
-  SymbolicLValue(unsigned SymID)
-   : LValue(SymbolicLValueKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
-  
-  SymbolID getSymbolID() const {
-    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
-  }
-  
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == SymbolicLValueKind;
-  }  
-};
-  
-class VISIBILITY_HIDDEN LValueDecl : public LValue {
-public:
-  LValueDecl(const ValueDecl* vd) 
-  : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
-  
-  ValueDecl* getDecl() const {
-    return static_cast<ValueDecl*>(getRawPtr());
-  }
-  
-  inline bool operator==(const LValueDecl& R) const {
-    return getDecl() == R.getDecl();
-  }
-
-  inline bool operator!=(const LValueDecl& R) const {
-    return getDecl() != R.getDecl();
-  }
-  
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == LValueDeclKind;
-  }
-};
-  
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Non-LValues.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  
-enum { SymbolicNonLValueKind, ConcreteIntKind, ConstrainedIntegerKind,
-       NumNonLValueKind };
-
-class VISIBILITY_HIDDEN SymbolicNonLValue : public NonLValue {
-public:
-  SymbolicNonLValue(unsigned SymID)
-    : NonLValue(SymbolicNonLValueKind,
-                reinterpret_cast<void*>((uintptr_t) SymID)) {}
-  
-  SymbolID getSymbolID() const {
-    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
-  }
-  
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == SymbolicNonLValueKind;
-  }  
-};
-  
-class VISIBILITY_HIDDEN ConcreteInt : public NonLValue {
-public:
-  ConcreteInt(const APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
-  
-  const APSInt& getValue() const {
-    return *static_cast<APSInt*>(getRawPtr());
-  }
-
-  // Arithmetic operators.
-  
-  ConcreteInt Add(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() + V.getValue());
-  }
-  
-  ConcreteInt Sub(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() - V.getValue());
-  }
-  
-  ConcreteInt Mul(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() * V.getValue());
-  }
-  
-  ConcreteInt Div(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() / V.getValue());
-  }
-  
-  ConcreteInt Rem(ValueManager& ValMgr, const ConcreteInt& V) const {
-    return ValMgr.getValue(getValue() % V.getValue());
-  }
-  
-  ConcreteInt UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
-    assert (U->getType() == U->getSubExpr()->getType());  
-    assert (U->getType()->isIntegerType());  
-    return ValMgr.getValue(-getValue()); 
-  }
-  
-  // Casting.
-  
-  ConcreteInt Cast(ValueManager& ValMgr, Expr* CastExpr) const {
-    assert (CastExpr->getType()->isIntegerType());
-    
-    APSInt X(getValue());  
-    X.extOrTrunc(ValMgr.getContext().getTypeSize(CastExpr->getType(),
-                                                 CastExpr->getLocStart()));
-    return ValMgr.getValue(X);
-  }
-  
-  // Equality operators.
-
-  ConcreteInt EQ(ValueManager& ValMgr, const ConcreteInt& V) const {
-    const APSInt& Val = getValue();    
-    return ValMgr.getValue(Val == V.getValue() ? 1U : 0U,
-                           Val.getBitWidth(), Val.isUnsigned());
-  }
-  
-  ConcreteInt NE(ValueManager& ValMgr, const ConcreteInt& V) const {
-    const APSInt& Val = getValue();    
-    return ValMgr.getValue(Val != V.getValue() ? 1U : 0U,
-                           Val.getBitWidth(), Val.isUnsigned());
-  }
-
-  // Implement isa<T> support.
-  static inline bool classof(const RValue* V) {
-    return V->getSubKind() == ConcreteIntKind;
-  }
-};
-  
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Transfer function dispatch for Non-LValues.
-//===----------------------------------------------------------------------===//
-
-RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
-  switch (getSubKind()) {
-    case ConcreteIntKind:
-      return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr);
-    default:
-      return InvalidValue();
-  }
-}
-
-NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
-  switch (getSubKind()) {
-    case ConcreteIntKind:
-      return cast<ConcreteInt>(this)->UnaryMinus(ValMgr, U);
-    default:
-      return cast<NonLValue>(InvalidValue());
-  }
-}
-
-#define NONLVALUE_DISPATCH_CASE(k1,k2,Op)\
-case (k1##Kind*NumNonLValueKind+k2##Kind):\
-  return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
-
-#define NONLVALUE_DISPATCH(Op)\
-switch (getSubKind()*NumNonLValueKind+RHS.getSubKind()){\
-  NONLVALUE_DISPATCH_CASE(ConcreteInt,ConcreteInt,Op)\
-  default:\
-    if (getBaseKind() == UninitializedKind ||\
-        RHS.getBaseKind() == UninitializedKind)\
-      return cast<NonLValue>(UninitializedValue());\
-    assert (!isValid() || !RHS.isValid() && "Missing case.");\
-    break;\
-}\
-return cast<NonLValue>(InvalidValue());
-
-NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Add)
-}
-
-NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Sub)
-}
-
-NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Mul)
-}
-
-NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Div)
-}
-
-NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(Rem)
-}
-
-NonLValue NonLValue::EQ(ValueManager& ValMgr, const NonLValue& RHS) const {  
-  NONLVALUE_DISPATCH(EQ)
-}
-
-NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const {
-  NONLVALUE_DISPATCH(NE)
-}
-
-#undef NONLVALUE_DISPATCH_CASE
-#undef NONLVALUE_DISPATCH
-
-//===----------------------------------------------------------------------===//
-// Transfer function dispatch for LValues.
-//===----------------------------------------------------------------------===//
-
-
-NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
-  if (getSubKind() != RHS.getSubKind())
-    return NonLValue::GetIntTruthValue(ValMgr, false);
-  
-  switch (getSubKind()) {
-    default:
-      assert(false && "EQ not implemented for this LValue.");
-      return cast<NonLValue>(InvalidValue());
-      
-    case LValueDeclKind: {
-      bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS);
-      return NonLValue::GetIntTruthValue(ValMgr, b);
-    }
-  }
-}
-
-NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
-  if (getSubKind() != RHS.getSubKind())
-    return NonLValue::GetIntTruthValue(ValMgr, true);
-
-  switch (getSubKind()) {
-    default:
-      assert(false && "EQ not implemented for this LValue.");
-      return cast<NonLValue>(InvalidValue());
-      
-    case LValueDeclKind: {
-      bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS);
-      return NonLValue::GetIntTruthValue(ValMgr, b);
-    }
-  }
-}
-
-
-//===----------------------------------------------------------------------===//
-// Utility methods for constructing Non-LValues.
-//===----------------------------------------------------------------------===//
-
-NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
-                              SourceLocation Loc) {
-
-  return ConcreteInt(ValMgr.getValue(X, T, Loc));
-}
-
-NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
-  return ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
-                                       I->getType()->isUnsignedIntegerType())));
-}
-
-RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
-  QualType T = D->getType();
-  
-  if (T->isPointerType() || T->isReferenceType())
-    return SymbolicLValue(SymMgr.getSymbol(D));
-  else
-    return SymbolicNonLValue(SymMgr.getSymbol(D));
-}
-
-//===----------------------------------------------------------------------===//
-// Pretty-Printing.
-//===----------------------------------------------------------------------===//
-
-void RValue::print(std::ostream& Out) const {
-  switch (getBaseKind()) {
-    case InvalidKind:
-      Out << "Invalid";
-      break;
-      
-    case NonLValueKind:
-      cast<NonLValue>(this)->print(Out);
-      break;
-
-    case LValueKind:
-      cast<LValue>(this)->print(Out);
-      break;
-      
-    case UninitializedKind:
-      Out << "Uninitialized";
-      break;
-      
-    default:
-      assert (false && "Invalid RValue.");
-  }
-}
-
-void NonLValue::print(std::ostream& Out) const {
-  switch (getSubKind()) {  
-    case ConcreteIntKind:
-      Out << cast<ConcreteInt>(this)->getValue().toString();
-      break;
-      
-    case SymbolicNonLValueKind:
-      Out << '$' << cast<SymbolicNonLValue>(this)->getSymbolID();
-      break;
-      
-    default:
-      assert (false && "Pretty-printed not implemented for this NonLValue.");
-      break;
-  }
-}
-
-void LValue::print(std::ostream& Out) const {
-  switch (getSubKind()) {  
-    case SymbolicLValueKind:
-      Out << '$' << cast<SymbolicLValue>(this)->getSymbolID();
-      break;
-      
-    case LValueDeclKind:
-      Out << '&' 
-          << cast<LValueDecl>(this)->getDecl()->getIdentifier()->getName();
-      break;
-      
-    default:
-      assert (false && "Pretty-printed not implemented for this LValue.");
-      break;
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// ValueMapTy - A ImmutableMap type Stmt*/Decl*/Symbols to RValues.
-//===----------------------------------------------------------------------===//
-
-typedef llvm::ImmutableMap<ValueKey,RValue> ValueMapTy;
-
-namespace clang {
-  template<>
-  struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
-    static inline void* toPtr(ValueMapTy M) {
-      return reinterpret_cast<void*>(M.getRoot());
-    }  
-    static inline ValueMapTy toState(void* P) {
-      return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
-    }
-  };
-}
-
-typedef ValueMapTy StateTy;
-
-//===----------------------------------------------------------------------===//
 // The Checker.
 //
 //  FIXME: This checker logic should be eventually broken into two components.
@@ -780,7 +63,7 @@
 class VISIBILITY_HIDDEN GRConstants {
     
 public:
-  typedef ValueMapTy StateTy;
+  typedef ValueState StateTy;
   typedef GRStmtNodeBuilder<GRConstants> StmtNodeBuilder;
   typedef GRBranchNodeBuilder<GRConstants> BranchNodeBuilder;
   typedef ExplodedGraph<GRConstants> GraphTy;
@@ -822,7 +105,7 @@
   StmtNodeBuilder* Builder;
   
   /// StateMgr - Object that manages the data for all created states.
-  ValueMapTy::Factory StateMgr;
+  StateTy::Factory StateMgr;
   
   /// ValueMgr - Object that manages the data for all created RValues.
   ValueManager ValMgr;
@@ -1493,13 +776,13 @@
 // "Assume" logic.
 //===----------------------------------------------------------------------===//
 
-StateTy GRConstants::Assume(StateTy St, LValue Cond, bool Assumption, 
-                            bool& isFeasible) {    
+GRConstants::StateTy GRConstants::Assume(StateTy St, LValue Cond, bool Assumption, 
+                                         bool& isFeasible) {    
   return St;
 }
 
-StateTy GRConstants::Assume(StateTy St, NonLValue Cond, bool Assumption, 
-                            bool& isFeasible) {
+GRConstants::StateTy GRConstants::Assume(StateTy St, NonLValue Cond, bool Assumption, 
+                                         bool& isFeasible) {
   
   switch (Cond.getSubKind()) {
     default:
diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp
new file mode 100644
index 0000000..4008e76
--- /dev/null
+++ b/Analysis/RValues.cpp
@@ -0,0 +1,272 @@
+//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines RValue, LValue, and NonLValue, classes that represent
+//  abstract r-values for use with path-sensitive value tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RValues.h"
+
+using namespace clang;
+using llvm::dyn_cast;
+using llvm::cast;
+using llvm::APSInt;
+
+//===----------------------------------------------------------------------===//
+// SymbolManager.
+//===----------------------------------------------------------------------===//
+
+SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
+  SymbolID& X = DataToSymbol[D];
+  
+  if (!X.isInitialized()) {
+    X = SymbolToData.size();
+    SymbolToData.push_back(D);
+  }
+  
+  return X;
+}
+
+SymbolManager::SymbolManager() {}
+SymbolManager::~SymbolManager() {}
+
+//===----------------------------------------------------------------------===//
+// ValueManager.
+//===----------------------------------------------------------------------===//
+
+ValueManager::~ValueManager() {
+  // Note that the dstor for the contents of APSIntSet will never be called,
+  // so we iterate over the set and invoke the dstor for each APSInt.  This
+  // frees an aux. memory allocated to represent very large constants.
+  for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
+    I->getValue().~APSInt();
+}
+
+APSInt& ValueManager::getValue(const APSInt& X) {
+  llvm::FoldingSetNodeID ID;
+  void* InsertPos;
+  typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
+  
+  X.Profile(ID);
+  FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
+  
+  if (!P) {  
+    P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
+    new (P) FoldNodeTy(X);
+    APSIntSet.InsertNode(P, InsertPos);
+  }
+  
+  return *P;
+}
+
+APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth, bool isUnsigned) {
+  APSInt V(BitWidth, isUnsigned);
+  V = X;  
+  return getValue(V);
+}
+
+APSInt& ValueManager::getValue(uint64_t X, QualType T, SourceLocation Loc) {
+  unsigned bits = Ctx.getTypeSize(T, Loc);
+  APSInt V(bits, T->isUnsignedIntegerType());
+  V = X;
+  return getValue(V);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Transfer function dispatch for Non-LValues.
+//===----------------------------------------------------------------------===//
+
+RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
+  switch (getSubKind()) {
+    case ConcreteIntKind:
+      return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr);
+    default:
+      return InvalidValue();
+  }
+}
+
+NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
+  switch (getSubKind()) {
+    case ConcreteIntKind:
+      return cast<ConcreteInt>(this)->UnaryMinus(ValMgr, U);
+    default:
+      return cast<NonLValue>(InvalidValue());
+  }
+}
+
+#define NONLVALUE_DISPATCH_CASE(k1,k2,Op)\
+case (k1##Kind*NumNonLValueKind+k2##Kind):\
+return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
+
+#define NONLVALUE_DISPATCH(Op)\
+switch (getSubKind()*NumNonLValueKind+RHS.getSubKind()){\
+NONLVALUE_DISPATCH_CASE(ConcreteInt,ConcreteInt,Op)\
+default:\
+if (getBaseKind() == UninitializedKind ||\
+RHS.getBaseKind() == UninitializedKind)\
+return cast<NonLValue>(UninitializedValue());\
+assert (!isValid() || !RHS.isValid() && "Missing case.");\
+break;\
+}\
+return cast<NonLValue>(InvalidValue());
+
+NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Add)
+}
+
+NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Sub)
+}
+
+NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Mul)
+}
+
+NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Div)
+}
+
+NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(Rem)
+}
+
+NonLValue NonLValue::EQ(ValueManager& ValMgr, const NonLValue& RHS) const {  
+  NONLVALUE_DISPATCH(EQ)
+}
+
+NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const {
+  NONLVALUE_DISPATCH(NE)
+}
+
+#undef NONLVALUE_DISPATCH_CASE
+#undef NONLVALUE_DISPATCH
+
+//===----------------------------------------------------------------------===//
+// Transfer function dispatch for LValues.
+//===----------------------------------------------------------------------===//
+
+
+NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
+  if (getSubKind() != RHS.getSubKind())
+    return NonLValue::GetIntTruthValue(ValMgr, false);
+  
+  switch (getSubKind()) {
+    default:
+      assert(false && "EQ not implemented for this LValue.");
+      return cast<NonLValue>(InvalidValue());
+      
+    case LValueDeclKind: {
+      bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS);
+      return NonLValue::GetIntTruthValue(ValMgr, b);
+    }
+  }
+}
+
+NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
+  if (getSubKind() != RHS.getSubKind())
+    return NonLValue::GetIntTruthValue(ValMgr, true);
+  
+  switch (getSubKind()) {
+    default:
+      assert(false && "EQ not implemented for this LValue.");
+      return cast<NonLValue>(InvalidValue());
+      
+    case LValueDeclKind: {
+      bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS);
+      return NonLValue::GetIntTruthValue(ValMgr, b);
+    }
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Utility methods for constructing Non-LValues.
+//===----------------------------------------------------------------------===//
+
+NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
+                              SourceLocation Loc) {
+  
+  return ConcreteInt(ValMgr.getValue(X, T, Loc));
+}
+
+NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
+  return ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
+                                            I->getType()->isUnsignedIntegerType())));
+}
+
+RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
+  QualType T = D->getType();
+  
+  if (T->isPointerType() || T->isReferenceType())
+    return SymbolicLValue(SymMgr.getSymbol(D));
+  else
+    return SymbolicNonLValue(SymMgr.getSymbol(D));
+}
+
+//===----------------------------------------------------------------------===//
+// Pretty-Printing.
+//===----------------------------------------------------------------------===//
+
+void RValue::print(std::ostream& Out) const {
+  switch (getBaseKind()) {
+    case InvalidKind:
+      Out << "Invalid";
+      break;
+      
+    case NonLValueKind:
+      cast<NonLValue>(this)->print(Out);
+      break;
+      
+    case LValueKind:
+      cast<LValue>(this)->print(Out);
+      break;
+      
+    case UninitializedKind:
+      Out << "Uninitialized";
+      break;
+      
+    default:
+      assert (false && "Invalid RValue.");
+  }
+}
+
+void NonLValue::print(std::ostream& Out) const {
+  switch (getSubKind()) {  
+    case ConcreteIntKind:
+      Out << cast<ConcreteInt>(this)->getValue().toString();
+      break;
+      
+    case SymbolicNonLValueKind:
+      Out << '$' << cast<SymbolicNonLValue>(this)->getSymbolID();
+      break;
+      
+    default:
+      assert (false && "Pretty-printed not implemented for this NonLValue.");
+      break;
+  }
+}
+
+void LValue::print(std::ostream& Out) const {
+  switch (getSubKind()) {  
+    case SymbolicLValueKind:
+      Out << '$' << cast<SymbolicLValue>(this)->getSymbolID();
+      break;
+      
+    case LValueDeclKind:
+      Out << '&' 
+      << cast<LValueDecl>(this)->getDecl()->getIdentifier()->getName();
+      break;
+      
+    default:
+      assert (false && "Pretty-printed not implemented for this LValue.");
+      break;
+  }
+}
diff --git a/Analysis/RValues.h b/Analysis/RValues.h
new file mode 100644
index 0000000..90446a2
--- /dev/null
+++ b/Analysis/RValues.h
@@ -0,0 +1,393 @@
+//== RValues.h - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines RValue, LValue, and NonLValue, classes that represent
+//  abstract r-values for use with path-sensitive value tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
+#define LLVM_CLANG_ANALYSIS_RVALUE_H
+
+// FIXME: reduce the number of includes.
+
+#include "clang/Analysis/PathSensitive/GREngine.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+
+#include <functional>
+
+//==------------------------------------------------------------------------==//
+//  RValue "management" data structures.
+//==------------------------------------------------------------------------==// 
+
+namespace clang {
+
+class SymbolID {
+  unsigned Data;
+public:
+  SymbolID() : Data(~0) {}
+  SymbolID(unsigned x) : Data(x) {}
+  
+  bool isInitialized() const { return Data != (unsigned) ~0; }
+  operator unsigned() const { assert (isInitialized()); return Data; }
+};
+  
+class SymbolData {
+  uintptr_t Data;
+public:
+  enum Kind { ParmKind = 0x0, Mask = 0x3 };
+  
+  SymbolData(ParmVarDecl* D)
+  : Data(reinterpret_cast<uintptr_t>(D) | ParmKind) {}
+  
+  inline Kind getKind() const { return (Kind) (Data & Mask); }
+  inline void* getPtr() const { return reinterpret_cast<void*>(Data & ~Mask); }  
+  inline bool operator==(const SymbolData& R) const { return Data == R.Data; }  
+};
+
+class SymbolManager {
+  std::vector<SymbolData> SymbolToData;
+  
+  typedef llvm::DenseMap<void*,SymbolID> MapTy;
+  MapTy DataToSymbol;
+  
+public:
+  SymbolManager();
+  ~SymbolManager();
+  
+  SymbolData getSymbolData(SymbolID id) const {
+    assert (id < SymbolToData.size());
+    return SymbolToData[id];
+  }
+  
+  SymbolID getSymbol(ParmVarDecl* D);
+};
+
+class ValueManager {
+  typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
+          APSIntSetTy;
+  
+  ASTContext& Ctx;
+  APSIntSetTy APSIntSet;
+  llvm::BumpPtrAllocator BPAlloc;
+  
+public:
+  ValueManager(ASTContext& ctx) : Ctx(ctx) {}
+  ~ValueManager();
+  
+  ASTContext& getContext() const { return Ctx; }  
+  llvm::APSInt& getValue(const llvm::APSInt& X);
+  llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
+  llvm::APSInt& getValue(uint64_t X, QualType T,
+                   SourceLocation Loc = SourceLocation());
+};
+
+//==------------------------------------------------------------------------==//
+//  Base RValue types.
+//==------------------------------------------------------------------------==// 
+
+class RValue {
+public:
+  enum BaseKind { LValueKind=0x0,
+                  NonLValueKind=0x1,
+                  UninitializedKind=0x2,
+                  InvalidKind=0x3 };
+  
+  enum { BaseBits = 2, 
+         BaseMask = 0x3 };
+  
+private:
+  void* Data;
+  unsigned Kind;
+  
+protected:
+  RValue(const void* d, bool isLValue, unsigned ValKind)
+  : Data(const_cast<void*>(d)),
+    Kind((isLValue ? LValueKind : NonLValueKind) | (ValKind << BaseBits)) {}
+  
+  explicit RValue(BaseKind k)
+    : Data(0), Kind(k) {}
+  
+  void* getRawPtr() const {
+    return reinterpret_cast<void*>(Data);
+  }
+  
+public:
+  ~RValue() {};
+  
+  RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
+  
+  unsigned getRawKind() const { return Kind; }
+  BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
+  unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned) getRawKind());
+    ID.AddPointer(reinterpret_cast<void*>(Data));
+  }
+  
+  bool operator==(const RValue& RHS) const {
+    return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
+  }
+  
+  static RValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
+  
+  inline bool isValid() const { return getRawKind() != InvalidKind; }
+  inline bool isInvalid() const { return getRawKind() == InvalidKind; }
+  
+  void print(std::ostream& OS) const;
+  void print() const { print(*llvm::cerr.stream()); }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue*) { return true; }
+};
+
+class InvalidValue : public RValue {
+public:
+  InvalidValue() : RValue(InvalidKind) {}
+  
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() == InvalidKind;
+  }  
+};
+
+class UninitializedValue : public RValue {
+public:
+  UninitializedValue() : RValue(UninitializedKind) {}
+  
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() == UninitializedKind;
+  }  
+};
+
+class NonLValue : public RValue {
+protected:
+  NonLValue(unsigned SubKind, const void* d) : RValue(d, false, SubKind) {}
+  
+public:
+  void print(std::ostream& Out) const;
+  
+  // Arithmetic operators.
+  NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Mul(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Div(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue Rem(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const;
+  
+  // Equality operators.
+  NonLValue EQ(ValueManager& ValMgr, const NonLValue& RHS) const;
+  NonLValue NE(ValueManager& ValMgr, const NonLValue& RHS) const;
+  
+  // Utility methods to create NonLValues.
+  static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
+                            SourceLocation Loc = SourceLocation());
+  
+  static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
+  
+  static inline NonLValue GetIntTruthValue(ValueManager& ValMgr, bool X) {
+    return GetValue(ValMgr, X ? 1U : 0U, ValMgr.getContext().IntTy);
+  }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() >= NonLValueKind;
+  }
+};
+
+class LValue : public RValue {
+protected:
+  LValue(unsigned SubKind, void* D) : RValue(D, true, SubKind) {}
+  
+public:
+  void print(std::ostream& Out) const;
+  
+  // Equality operators.
+  NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const;
+  NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getBaseKind() == LValueKind;
+  }
+};
+
+//==------------------------------------------------------------------------==//
+//  Subclasses of LValue.
+//==------------------------------------------------------------------------==// 
+  
+enum LValueKind { SymbolicLValueKind, LValueDeclKind, NumLValueKind };
+
+class SymbolicLValue : public LValue {
+public:
+  SymbolicLValue(unsigned SymID)
+  : LValue(SymbolicLValueKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
+  
+  SymbolID getSymbolID() const {
+    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+  }
+  
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == SymbolicLValueKind;
+  }  
+};
+
+class LValueDecl : public LValue {
+public:
+  LValueDecl(const ValueDecl* vd) 
+  : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
+  
+  ValueDecl* getDecl() const {
+    return static_cast<ValueDecl*>(getRawPtr());
+  }
+  
+  inline bool operator==(const LValueDecl& R) const {
+    return getDecl() == R.getDecl();
+  }
+  
+  inline bool operator!=(const LValueDecl& R) const {
+    return getDecl() != R.getDecl();
+  }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == LValueDeclKind;
+  }
+};
+  
+//==------------------------------------------------------------------------==//
+//  Subclasses of NonLValue.
+//==------------------------------------------------------------------------==// 
+
+enum NonLValueKind { SymbolicNonLValueKind, ConcreteIntKind,
+NumNonLValueKind };
+
+class SymbolicNonLValue : public NonLValue {
+public:
+  SymbolicNonLValue(unsigned SymID)
+  : NonLValue(SymbolicNonLValueKind,
+              reinterpret_cast<void*>((uintptr_t) SymID)) {}
+  
+  SymbolID getSymbolID() const {
+    return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
+  }
+  
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == SymbolicNonLValueKind;
+  }  
+};
+
+class ConcreteInt : public NonLValue {
+public:
+  ConcreteInt(const llvm::APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
+  
+  const llvm::APSInt& getValue() const {
+    return *static_cast<llvm::APSInt*>(getRawPtr());
+  }
+  
+  // Arithmetic operators.
+  
+  ConcreteInt Add(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() + V.getValue());
+  }
+  
+  ConcreteInt Sub(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() - V.getValue());
+  }
+  
+  ConcreteInt Mul(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() * V.getValue());
+  }
+  
+  ConcreteInt Div(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() / V.getValue());
+  }
+  
+  ConcreteInt Rem(ValueManager& ValMgr, const ConcreteInt& V) const {
+    return ValMgr.getValue(getValue() % V.getValue());
+  }
+  
+  ConcreteInt UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
+    assert (U->getType() == U->getSubExpr()->getType());  
+    assert (U->getType()->isIntegerType());  
+    return ValMgr.getValue(-getValue()); 
+  }
+  
+  // Casting.
+  
+  ConcreteInt Cast(ValueManager& ValMgr, Expr* CastExpr) const {
+    assert (CastExpr->getType()->isIntegerType());
+    
+    llvm::APSInt X(getValue());  
+    X.extOrTrunc(ValMgr.getContext().getTypeSize(CastExpr->getType(),
+                                                 CastExpr->getLocStart()));
+    return ValMgr.getValue(X);
+  }
+  
+  // Equality operators.
+  
+  ConcreteInt EQ(ValueManager& ValMgr, const ConcreteInt& V) const {
+    const llvm::APSInt& Val = getValue();    
+    return ValMgr.getValue(Val == V.getValue() ? 1U : 0U,
+                           Val.getBitWidth(), Val.isUnsigned());
+  }
+  
+  ConcreteInt NE(ValueManager& ValMgr, const ConcreteInt& V) const {
+    const llvm::APSInt& Val = getValue();    
+    return ValMgr.getValue(Val != V.getValue() ? 1U : 0U,
+                           Val.getBitWidth(), Val.isUnsigned());
+  }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const RValue* V) {
+    return V->getSubKind() == ConcreteIntKind;
+  }
+};
+  
+} // end clang namespace  
+
+//==------------------------------------------------------------------------==//
+// Casting machinery to get cast<> and dyn_cast<> working with SymbolData.
+//==------------------------------------------------------------------------==//
+
+namespace llvm {
+
+template<> inline bool
+isa<clang::ParmVarDecl,clang::SymbolData>(const clang::SymbolData& V) {
+  return V.getKind() == clang::SymbolData::ParmKind;
+}
+
+template<> struct cast_retty_impl<clang::ParmVarDecl,clang::SymbolData> {
+  typedef const clang::ParmVarDecl* ret_type;
+};
+
+template<> struct simplify_type<clang::SymbolData> {
+  typedef void* SimpleType;
+  static inline SimpleType getSimplifiedValue(const clang::SymbolData &V) {
+    return V.getPtr();
+  }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/Analysis/ValueState.h b/Analysis/ValueState.h
new file mode 100644
index 0000000..ef9f89a
--- /dev/null
+++ b/Analysis/ValueState.h
@@ -0,0 +1,162 @@
+//== ValueState.h - Path-Sens. "State" for tracking valuues -----*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines SymbolID, ValueKey, and ValueState.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
+#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
+
+// FIXME: Reduce the number of includes.
+
+#include "RValues.h"
+
+#include "clang/Analysis/PathSensitive/GREngine.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+
+#include <functional>
+
+namespace clang {  
+
+/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
+///  Stmt*.  Use cast<> or dyn_cast<> to get actual pointer type
+class ValueKey {
+  uintptr_t Raw;  
+  void operator=(const ValueKey& RHS); // Do not implement.
+  
+public:
+  enum  Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
+               IsSymbol=0x3, // Symbol Bindings.
+               Mask=0x3 };
+  
+  inline Kind getKind() const {
+    return (Kind) (Raw & Mask);
+  }
+  
+  inline void* getPtr() const { 
+    assert (getKind() != IsSymbol);
+    return reinterpret_cast<void*>(Raw & ~Mask);
+  }
+  
+  inline SymbolID getSymbolID() const {
+    assert (getKind() == IsSymbol);
+    return Raw >> 2;
+  }
+  
+  ValueKey(const ValueDecl* VD)
+  : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
+    assert(VD && "ValueDecl cannot be NULL.");
+  }
+  
+  ValueKey(Stmt* S, bool isBlkExpr = false) 
+  : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
+    assert(S && "Tracked statement cannot be NULL.");
+  }
+  
+  ValueKey(SymbolID V)
+  : Raw((V << 2) | IsSymbol) {}  
+  
+  bool isSymbol()  const { return getKind() == IsSymbol; }
+  bool isSubExpr() const { return getKind() == IsSubExpr; }
+  bool isBlkExpr() const { return getKind() == IsBlkExpr; }
+  bool isDecl()    const { return getKind() == IsDecl; }
+  bool isStmt()    const { return getKind() <= IsBlkExpr; }
+  
+  inline void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger(isSymbol() ? 1 : 0);
+    
+    if (isSymbol())
+      ID.AddInteger(getSymbolID());
+    else    
+      ID.AddPointer(getPtr());
+  }
+  
+  inline bool operator==(const ValueKey& X) const {
+    return isSymbol() ? getSymbolID() == X.getSymbolID()
+    : getPtr() == X.getPtr();
+  }
+  
+  inline bool operator!=(const ValueKey& X) const {
+    return !operator==(X);
+  }
+  
+  inline bool operator<(const ValueKey& X) const { 
+    if (isSymbol())
+      return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
+    
+    return getPtr() < X.getPtr();
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// ValueState - An ImmutableMap type Stmt*/Decl*/Symbols to RValues.
+//===----------------------------------------------------------------------===//
+
+typedef llvm::ImmutableMap<ValueKey,RValue> ValueState;
+
+template<>
+struct GRTrait<ValueState> {
+  static inline void* toPtr(ValueState M) {
+    return reinterpret_cast<void*>(M.getRoot());
+  }  
+  static inline ValueState toState(void* P) {
+    return ValueState(static_cast<ValueState::TreeTy*>(P));
+  }
+};
+  
+} // end clang namespace
+
+//==------------------------------------------------------------------------==//
+// Casting machinery to get cast<> and dyn_cast<> working with ValueKey.
+//==------------------------------------------------------------------------==//
+
+namespace llvm {
+  
+  template<> inline bool
+  isa<clang::ValueDecl,clang::ValueKey>(const clang::ValueKey& V) {
+    return V.getKind() == clang::ValueKey::IsDecl;
+  }
+  
+  template<> inline bool
+  isa<clang::Stmt,clang::ValueKey>(const clang::ValueKey& V) {
+    return ((unsigned) V.getKind()) < clang::ValueKey::IsDecl;
+  }
+  
+  template<> struct cast_retty_impl<clang::ValueDecl,clang::ValueKey> {
+    typedef const clang::ValueDecl* ret_type;
+  };
+  
+  template<> struct cast_retty_impl<clang::Stmt,clang::ValueKey> {
+    typedef const clang::Stmt* ret_type;
+  };
+  
+  template<> struct simplify_type<clang::ValueKey> {
+    typedef void* SimpleType;
+    static inline SimpleType getSimplifiedValue(const clang::ValueKey &V) {
+      return V.getPtr();
+    }
+  };
+} // end llvm namespace
+
+#endif
