diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp
index eba0619..4ae9077 100644
--- a/Analysis/GRConstants.cpp
+++ b/Analysis/GRConstants.cpp
@@ -348,43 +348,8 @@
 void GRConstants::ProcessBranch(Expr* Condition, Stmt* Term,
                                 BranchNodeBuilder& builder) {
 
-  StateTy PrevState = builder.getState();
-  
-  // Remove old bindings for subexpressions.  
-  for (StateTy::eb_iterator I=PrevState.eb_begin(), E=PrevState.eb_end(); I!=E; ++I)
-    if (I.getKey().isSubExpr())
-      PrevState = StateMgr.Remove(PrevState, I.getKey());
-  
-  // Remove terminator-specific bindings.
-  switch (Term->getStmtClass()) {
-    default: break;
-      
-    case Stmt::BinaryOperatorClass: { // '&&', '||'
-      BinaryOperator* B = cast<BinaryOperator>(Term);
-      // FIXME: Liveness analysis should probably remove these automatically.
-      //   Verify later when we converge to an 'optimization' stage.
-      PrevState = StateMgr.Remove(PrevState, B->getRHS());
-      break;
-    }
-      
-    case Stmt::ConditionalOperatorClass: { // '?' operator
-      ConditionalOperator* C = cast<ConditionalOperator>(Term);
-      // FIXME: Liveness analysis should probably remove these automatically.
-      //   Verify later when we converge to an 'optimization' stage.
-      if (Expr* L = C->getLHS()) PrevState = StateMgr.Remove(PrevState, L);
-      PrevState = StateMgr.Remove(PrevState, C->getRHS());
-      break;
-    }
-      
-    case Stmt::ChooseExprClass: { // __builtin_choose_expr
-      ChooseExpr* C = cast<ChooseExpr>(Term);
-      // FIXME: Liveness analysis should probably remove these automatically.
-      //   Verify later when we converge to an 'optimization' stage.
-      PrevState = StateMgr.Remove(PrevState, C->getRHS());
-      PrevState = StateMgr.Remove(PrevState, C->getRHS());
-      break;   
-    }
-  }
+  // Remove old bindings for subexpressions.
+  StateTy PrevState = StateMgr.RemoveSubExprBindings(builder.getState());
   
   RValue V = GetValue(PrevState, Condition);
   
@@ -1119,15 +1084,6 @@
 template<>
 struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
   public DefaultDOTGraphTraits {
-
-  static void PrintKindLabel(std::ostream& Out, ExprBindKey::Kind kind) {
-    switch (kind) {
-      case ExprBindKey::IsSubExpr:  Out << "Sub-Expressions:\\l"; break;
-      case ExprBindKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
-      default: assert (false && "Unknown ExprBindKey type.");
-    }
-  }
-    
     
   static void PrintVarBindings(std::ostream& Out, GRConstants::StateTy St) {
 
@@ -1149,26 +1105,43 @@
     
   }
     
-  static void PrintExprBindings(std::ostream& Out, GRConstants::StateTy St,
-                                ExprBindKey::Kind kind) {
+    
+  static void PrintSubExprBindings(std::ostream& Out, GRConstants::StateTy St) {
+    
+    bool isFirst = true;
+    
+    for (GRConstants::StateTy::seb_iterator I=St.seb_begin(), E=St.seb_end();
+                                            I != E;++I) {        
+      
+      if (isFirst) {
+        Out << "\\l\\lSub-Expressions:\\l";
+        isFirst = false;
+      }
+      else
+        Out << "\\l";
+      
+      Out << " (" << (void*) I.getKey() << ") ";
+      I.getKey()->printPretty(Out);
+      Out << " : ";
+      I.getData().print(Out);
+    }
+  }
+    
+  static void PrintBlkExprBindings(std::ostream& Out, GRConstants::StateTy St) {
+        
     bool isFirst = true;
 
-    for (GRConstants::StateTy::eb_iterator I=St.eb_begin(),
-                                           E=St.eb_end(); I!=E;++I) {        
-      
-      if (I.getKey().getKind() != kind)
-        continue;
-    
+    for (GRConstants::StateTy::beb_iterator I=St.beb_begin(), E=St.beb_end();
+                                            I != E; ++I) {      
       if (isFirst) {
-        Out << "\\l\\l";
-        PrintKindLabel(Out, kind);
+        Out << "\\l\\lBlock-level Expressions:\\l";
         isFirst = false;
       }
       else
         Out << "\\l";
 
-      Out << " (" << (void*) I.getKey().getExpr() << ") ";
-      I.getKey().getExpr()->printPretty(Out);
+      Out << " (" << (void*) I.getKey() << ") ";
+      I.getKey()->printPretty(Out);
       Out << " : ";
       I.getData().print(Out);
     }
@@ -1275,12 +1248,7 @@
     
     Out << "\\|StateID: " << (void*) N->getState().getImpl() << "\\|";
 
-    PrintVarBindings(Out, N->getState());
-    PrintExprBindings(Out, N->getState(), ExprBindKey::IsBlkExpr);
-    PrintExprBindings(Out, N->getState(), ExprBindKey::IsSubExpr);
-    
-    PrintEQ(Out, N->getState());
-    PrintNE(Out, N->getState());
+    N->getState().printDOT(Out);
       
     Out << "\\l";
     return Out.str();
diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp
index 6a9023a..724f64f 100644
--- a/Analysis/ValueState.cpp
+++ b/Analysis/ValueState.cpp
@@ -43,32 +43,31 @@
   // for optimum performance.
   
   llvm::SmallVector<ValueDecl*, 10> WList;
-
-  for (StateTy::eb_iterator I = St.eb_begin(), E = St.eb_end(); I!=E ; ++I) {
+  
+  ValueStateImpl NewSt = *St;
+  
+  // Drop bindings for subexpressions.
+  NewSt.SubExprBindings = EXFactory.GetEmptyMap();
+  
+  // Iterate over the block-expr bindings.
+  for (ValueState::beb_iterator I=St.beb_begin(), E=St.beb_end(); I!=E ; ++I) {
     
-    ExprBindKey K = I.getKey();
+    Expr* BlkExpr = I.getKey();
     
-    // Remove old bindings for subexpressions.
-    if (K.isSubExpr()) {
-      St = Remove(St, K);
-      continue;
-    }
-    
-    assert (I.getKey().isBlkExpr());
-    
-    if (Liveness.isLive(Loc, K.getExpr())) {
+    if (Liveness.isLive(Loc, BlkExpr)) {
       if (isa<lval::DeclVal>(I.getData())) {
         lval::DeclVal LV = cast<lval::DeclVal>(I.getData());
         WList.push_back(LV.getDecl());
       }
     }
     else
-      St = Remove(St, K);
+      NewSt.BlockExprBindings = Remove(NewSt, BlkExpr);
     
     continue;
   }
 
-  for (StateTy::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
+  // Iterate over the variable bindings.
+  for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
     if (Liveness.isLive(Loc, I.getKey()))
       WList.push_back(I.getKey());
   
@@ -94,24 +93,24 @@
     }    
   }
   
-  for (StateTy::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
+  for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
     if (!Marked.count(I.getKey()))
-      St = Remove(St, I.getKey());
+      NewSt.VarBindings = Remove(NewSt, I.getKey());
   
-  return St;
+  return getPersistentState(NewSt);
 }
 
 
-RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV,
+RValue ValueStateManager::GetValue(ValueState St, const LValue& LV,
                                    QualType* T) {
   if (isa<UnknownVal>(LV))
     return UnknownVal();
   
   switch (LV.getSubKind()) {
     case lval::DeclValKind: {
-      StateTy::VarBindingsTy::TreeTy* T =
+      ValueState::VarBindingsTy::TreeTy* T =
       // FIXME: We should make lval::DeclVal only contain VarDecl
-        St.getImpl()->VarBindings.SlimFind(
+        St->VarBindings.SlimFind(
               cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()));
       
       return T ? T->getValue().second : UnknownVal();
@@ -137,11 +136,10 @@
   return UnknownVal();
 }
 
-ValueStateManager::StateTy
-ValueStateManager::AddNE(StateTy St, SymbolID sym, const llvm::APSInt& V) {
+ValueState
+ValueStateManager::AddNE(ValueState St, SymbolID sym, const llvm::APSInt& V) {
   // First, retrieve the NE-set associated with the given symbol.
-  ValueState::ConstantNotEqTy::TreeTy* T =
-    St.getImpl()->ConstantNotEq.SlimFind(sym);    
+  ValueState::ConstantNotEqTy::TreeTy* T = St->ConstantNotEq.SlimFind(sym);    
   
   ValueState::IntSetTy S = T ? T->getValue().second : ISetFactory.GetEmptySet();
   
@@ -149,25 +147,25 @@
   S = ISetFactory.Add(S, &V);
   
   // Create a new state with the old binding replaced.
-  ValueStateImpl NewStateImpl = *St.getImpl();
-  NewStateImpl.ConstantNotEq = CNEFactory.Add(NewStateImpl.ConstantNotEq,
+  ValueStateImpl NewSt = *St;
+  NewSt.ConstantNotEq = CNEFactory.Add(NewSt.ConstantNotEq,
                                               sym, S);
     
   // Get the persistent copy.
-  return getPersistentState(NewStateImpl);
+  return getPersistentState(NewSt);
 }
 
-ValueStateManager::StateTy
-ValueStateManager::AddEQ(StateTy St, SymbolID sym, const llvm::APSInt& V) {
+ValueState
+ValueStateManager::AddEQ(ValueState St, SymbolID sym, const llvm::APSInt& V) {
   // Create a new state with the old binding replaced.
-  ValueStateImpl NewStateImpl = *St.getImpl();
-  NewStateImpl.ConstantEq = CEFactory.Add(NewStateImpl.ConstantEq, sym, &V);
+  ValueStateImpl NewSt = *St;
+  NewSt.ConstantEq = CEFactory.Add(NewSt.ConstantEq, sym, &V);
   
   // Get the persistent copy.
-  return getPersistentState(NewStateImpl);
+  return getPersistentState(NewSt);
 }
 
-RValue ValueStateManager::GetValue(const StateTy& St, Expr* S, bool* hasVal) {
+RValue ValueStateManager::GetValue(ValueState St, Expr* S, bool* hasVal) {
   for (;;) {
     switch (S->getStmtClass()) {
         
@@ -222,8 +220,14 @@
     break;
   }
   
-  StateTy::ExprBindingsTy::TreeTy* T =
-    St.getImpl()->ExprBindings.SlimFind(S);
+  ValueState::ExprBindingsTy::TreeTy* T = St->SubExprBindings.SlimFind(S);
+  
+  if (T) {
+    if (hasVal) *hasVal = true;
+    return T->getValue().second;
+  }
+  
+  T = St->BlockExprBindings.SlimFind(S);  
   
   if (T) {
     if (hasVal) *hasVal = true;
@@ -235,7 +239,7 @@
   }
 }
 
-LValue ValueStateManager::GetLValue(const StateTy& St, Expr* E) {
+LValue ValueStateManager::GetLValue(ValueState St, Expr* E) {
   
   while (ParenExpr* P = dyn_cast<ParenExpr>(E))
     E = P->getSubExpr();
@@ -251,22 +255,33 @@
 }
 
 
-ValueStateManager::StateTy 
-ValueStateManager::SetValue(StateTy St, Expr* E, bool isBlkExpr,
+ValueState 
+ValueStateManager::SetValue(ValueState St, Expr* E, bool isBlkExpr,
                             const RValue& V) {
   
   assert (E);
-  return V.isKnown() ? Add(St, ExprBindKey(E, isBlkExpr), V) : St;
+
+  if (V.isUnknown())
+    return St;
+  
+  ValueStateImpl NewSt = *St;
+  
+  if (isBlkExpr)
+    NewSt.BlockExprBindings = EXFactory.Add(NewSt.BlockExprBindings, E, V);
+  else
+    NewSt.SubExprBindings = EXFactory.Add(NewSt.SubExprBindings, E, V);
+
+  return getPersistentState(NewSt);
 }
 
-ValueStateManager::StateTy
-ValueStateManager::SetValue(StateTy St, const LValue& LV, const RValue& V) {
+ValueState
+ValueStateManager::SetValue(ValueState St, const LValue& LV, const RValue& V) {
   
   switch (LV.getSubKind()) {
     case lval::DeclValKind:        
       return V.isKnown()   // FIXME: Have DeclVal only contain VarDecl
-        ? Add(St, cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()), V)
-        : Remove(St, cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()));
+        ? BindVar(St, cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()), V)
+        : UnbindVar(St, cast<VarDecl>(cast<lval::DeclVal>(LV).getDecl()));
       
     default:
       assert ("SetValue for given LValue type not yet implemented.");
@@ -274,55 +289,29 @@
   }
 }
 
-ValueStateManager::StateTy
-ValueStateManager::Add(StateTy St, ExprBindKey K, const RValue& V) {
+ValueState
+ValueStateManager::BindVar(ValueState St, VarDecl* D, const RValue& V) {
   
   // Create a new state with the old binding removed.
-  ValueStateImpl NewStateImpl = *St.getImpl();
-  NewStateImpl.ExprBindings =
-    EXFactory.Add(NewStateImpl.ExprBindings, K, V);
+  ValueStateImpl NewSt = *St;
+  NewSt.VarBindings = VBFactory.Add(NewSt.VarBindings, D, V);
   
   // Get the persistent copy.
-  return getPersistentState(NewStateImpl);
+  return getPersistentState(NewSt);
 }
 
-ValueStateManager::StateTy
-ValueStateManager::Remove(StateTy St, ExprBindKey K) {
+ValueState
+ValueStateManager::UnbindVar(ValueState St, VarDecl* D) {
   
   // Create a new state with the old binding removed.
-  ValueStateImpl NewStateImpl = *St.getImpl();
-  NewStateImpl.ExprBindings =
-    EXFactory.Remove(NewStateImpl.ExprBindings, K);
+  ValueStateImpl NewSt = *St;
+  NewSt.VarBindings = VBFactory.Remove(NewSt.VarBindings, D);
   
   // Get the persistent copy.
-  return getPersistentState(NewStateImpl);
+  return getPersistentState(NewSt);
 }
 
-ValueStateManager::StateTy
-ValueStateManager::Add(StateTy St, VarDecl* D, const RValue& V) {
-  
-  // Create a new state with the old binding removed.
-  ValueStateImpl NewStateImpl = *St.getImpl();
-  NewStateImpl.VarBindings =
-    VBFactory.Add(NewStateImpl.VarBindings, D, V);
-  
-  // Get the persistent copy.
-  return getPersistentState(NewStateImpl);
-}
-
-ValueStateManager::StateTy
-ValueStateManager::Remove(StateTy St, VarDecl* D) {
-  
-  // Create a new state with the old binding removed.
-  ValueStateImpl NewStateImpl = *St.getImpl();
-  NewStateImpl.VarBindings =
-    VBFactory.Remove(NewStateImpl.VarBindings, D);
-  
-  // Get the persistent copy.
-  return getPersistentState(NewStateImpl);
-}
-
-ValueStateManager::StateTy
+ValueState
 ValueStateManager::getInitialState() {
 
   // Create a state with empty variable bindings.
@@ -334,12 +323,12 @@
   return getPersistentState(StateImpl);
 }
 
-ValueStateManager::StateTy
+ValueState
 ValueStateManager::getPersistentState(const ValueStateImpl &State) {
   
   llvm::FoldingSetNodeID ID;
   State.Profile(ID);  
-  void* InsertPos;  
+  void* InsertPos;
   
   if (ValueStateImpl* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
     return I;
@@ -349,3 +338,94 @@
   StateSet.InsertNode(I, InsertPos);
   return I;
 }
+
+void ValueState::printDOT(std::ostream& Out) const {
+  // Print Variable Bindings
+  Out << "Variables:\\l";
+  
+  bool isFirst = true;
+  
+  for (vb_iterator I=vb_begin(), E=vb_end(); I!=E; ++I) {        
+    
+    if (isFirst)
+      isFirst = false;
+    else
+      Out << "\\l";
+    
+    Out << ' ' << I.getKey()->getName() << " : ";
+    I.getData().print(Out);
+  }
+  
+  // Print Subexpression bindings.
+  
+  isFirst = true;
+  
+  for (seb_iterator I=seb_begin(), E=seb_end(); I != E;++I) {        
+    
+    if (isFirst) {
+      Out << "\\l\\lSub-Expressions:\\l";
+      isFirst = false;
+    }
+    else
+      Out << "\\l";
+    
+    Out << " (" << (void*) I.getKey() << ") ";
+    I.getKey()->printPretty(Out);
+    Out << " : ";
+    I.getData().print(Out);
+  }
+  
+  // Print block-expression bindings.
+  
+  isFirst = true;
+  
+  for (beb_iterator I=beb_begin(), E=beb_end(); I != E; ++I) {      
+
+    if (isFirst) {
+      Out << "\\l\\lBlock-level Expressions:\\l";
+      isFirst = false;
+    }
+    else
+      Out << "\\l";
+    
+    Out << " (" << (void*) I.getKey() << ") ";
+    I.getKey()->printPretty(Out);
+    Out << " : ";
+    I.getData().print(Out);
+  }
+  
+  // Print equality constraints.
+  
+  if (!Data->ConstantEq.isEmpty()) {
+  
+    Out << "\\l\\|'==' constraints:";
+  
+    for (ConstantEqTy::iterator I=Data->ConstantEq.begin(),
+                                E=Data->ConstantEq.end(); I!=E;++I)
+      Out << "\\l $" << I.getKey() << " : " << I.getData()->toString();
+  }
+  
+
+  // Print != constraints.
+    
+  if (!Data->ConstantNotEq.isEmpty()) {
+  
+    Out << "\\l\\|'!=' constraints:";
+  
+    for (ConstantNotEqTy::iterator I=Data->ConstantNotEq.begin(),
+                                   EI=Data->ConstantNotEq.end(); I != EI; ++I) {
+    
+      Out << "\\l $" << I.getKey() << " : ";
+      isFirst = true;
+    
+      IntSetTy::iterator J=I.getData().begin(), EJ=I.getData().end();      
+      
+      for ( ; J != EJ; ++J) {        
+        if (isFirst) isFirst = false;
+        else Out << ", ";
+      
+        Out << (*J)->toString();
+      }
+    }
+  }
+}
diff --git a/Analysis/ValueState.h b/Analysis/ValueState.h
index 3d7a2e6..5f2b58c 100644
--- a/Analysis/ValueState.h
+++ b/Analysis/ValueState.h
@@ -37,51 +37,7 @@
 
 #include <functional>
 
-namespace clang {  
-
-class ExprBindKey {
-  uintptr_t Raw;  
-  void operator=(const ExprBindKey& RHS); // Do not implement.
-  
-  inline void* getPtr() const { 
-    return reinterpret_cast<void*>(Raw & ~Mask);
-  }
-  
-public:
-  enum  Kind { IsSubExpr=0x0, IsBlkExpr=0x1, Mask=0x1 };
-  
-  inline Kind getKind() const {
-    return (Kind) (Raw & Mask);
-  }
-    
-  inline Expr* getExpr() const {
-    return (Expr*) getPtr();
-  }
-    
-  ExprBindKey(Expr* E, bool isBlkExpr = false) 
-  : Raw(reinterpret_cast<uintptr_t>(E) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
-    assert(E && "Tracked statement cannot be NULL.");
-  }
-  
-  bool isSubExpr() const { return getKind() == IsSubExpr; }
-  bool isBlkExpr() const { return getKind() == IsBlkExpr; }
-  
-  inline void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddPointer(getPtr());
-  }
-  
-  inline bool operator==(const ExprBindKey& X) const {
-    return getPtr() == X.getPtr();
-  }
-  
-  inline bool operator!=(const ExprBindKey& X) const {
-    return !operator==(X);
-  }
-  
-  inline bool operator<(const ExprBindKey& X) const { 
-    return getPtr() < X.getPtr();
-  }
-};
+namespace clang {
 
 //===----------------------------------------------------------------------===//
 // ValueState - An ImmutableMap type Stmt*/Decl*/Symbols to RValues.
@@ -90,7 +46,7 @@
 namespace vstate {
   typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
   
-  typedef llvm::ImmutableMap<ExprBindKey,RValue>           ExprBindingsTy;  
+  typedef llvm::ImmutableMap<Expr*,RValue>                 ExprBindingsTy;
   typedef llvm::ImmutableMap<VarDecl*,RValue>              VarBindingsTy;  
   typedef llvm::ImmutableMap<SymbolID,IntSetTy>            ConstantNotEqTy;
   typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstantEqTy;
@@ -105,7 +61,8 @@
   void operator=(const ValueStateImpl& R) const;
 
 public:
-  vstate::ExprBindingsTy     ExprBindings;
+  vstate::ExprBindingsTy     SubExprBindings;
+  vstate::ExprBindingsTy     BlockExprBindings;  
   vstate::VarBindingsTy      VarBindings;
   vstate::ConstantNotEqTy    ConstantNotEq;
   vstate::ConstantEqTy       ConstantEq;
@@ -115,13 +72,18 @@
                  vstate::VarBindingsTy VB,
                  vstate::ConstantNotEqTy CNE,
                  vstate::ConstantEqTy CE)
-    : ExprBindings(EB), VarBindings(VB), ConstantNotEq(CNE), ConstantEq(CE) {}
+    : SubExprBindings(EB), 
+      BlockExprBindings(EB),
+      VarBindings(VB),
+      ConstantNotEq(CNE),
+      ConstantEq(CE) {}
   
   /// Copy ctor - We must explicitly define this or else the "Next" ptr
   ///  in FoldingSetNode will also get copied.
   ValueStateImpl(const ValueStateImpl& RHS)
     : llvm::FoldingSetNode(),
-      ExprBindings(RHS.ExprBindings),
+      SubExprBindings(RHS.SubExprBindings),
+      BlockExprBindings(RHS.BlockExprBindings),
       VarBindings(RHS.VarBindings),
       ConstantNotEq(RHS.ConstantNotEq),
       ConstantEq(RHS.ConstantEq) {} 
@@ -131,7 +93,8 @@
   /// Profile - Profile the contents of a ValueStateImpl object for use
   ///  in a FoldingSet.
   static void Profile(llvm::FoldingSetNodeID& ID, const ValueStateImpl& V) {
-    V.ExprBindings.Profile(ID);
+    V.SubExprBindings.Profile(ID);
+    V.BlockExprBindings.Profile(ID);
     V.VarBindings.Profile(ID);
     V.ConstantNotEq.Profile(ID);
     V.ConstantEq.Profile(ID);
@@ -160,6 +123,8 @@
   
   // Accessors.  
   ValueStateImpl* getImpl() const { return Data; }
+  ValueStateImpl& operator*() { return *Data; }
+  ValueStateImpl* operator->() { return Data; }
 
   // Typedefs.
   typedef vstate::IntSetTy                 IntSetTy;
@@ -177,13 +142,17 @@
   
   // Iterators.
 
-  typedef VarBindingsTy::iterator vb_iterator;  
-  vb_iterator vb_begin() { return Data->VarBindings.begin(); }
-  vb_iterator vb_end() { return Data->VarBindings.end(); }
+  typedef VarBindingsTy::iterator vb_iterator;
+  vb_iterator vb_begin() const { return Data->VarBindings.begin(); }
+  vb_iterator vb_end() const { return Data->VarBindings.end(); }
+    
+  typedef ExprBindingsTy::iterator seb_iterator;
+  seb_iterator seb_begin() const { return Data->SubExprBindings.begin(); }
+  seb_iterator seb_end() const { return Data->SubExprBindings.end(); }
   
-  typedef ExprBindingsTy::iterator eb_iterator;
-  eb_iterator eb_begin() { return Data->ExprBindings.begin(); }
-  eb_iterator eb_end() { return Data->ExprBindings.end(); }
+  typedef ExprBindingsTy::iterator beb_iterator;
+  beb_iterator beb_begin() const { return Data->BlockExprBindings.begin(); }
+  beb_iterator beb_end() const { return Data->BlockExprBindings.end(); }
   
   // Profiling and equality testing.
   
@@ -198,6 +167,11 @@
   void Profile(llvm::FoldingSetNodeID& ID) const {
     Profile(ID, *this);
   }
+  
+  void printDOT(std::ostream& Out) const;
+  void print(std::ostream& Out) const;
+  void print() const { print(*llvm::cerr); }
+  
 };  
   
 template<> struct GRTrait<ValueState> {
@@ -233,38 +207,58 @@
 
   /// Alloc - A BumpPtrAllocator to allocate states.
   llvm::BumpPtrAllocator& Alloc;
+  
+private:
+  
+  ValueState::ExprBindingsTy Remove(ValueState::ExprBindingsTy B, Expr* E) {
+    return EXFactory.Remove(B, E);
+  }    
+    
+  ValueState::VarBindingsTy  Remove(ValueState::VarBindingsTy B, VarDecl* V) {
+    return VBFactory.Remove(B, V);
+  }
 
-  StateTy getPersistentState(const ValueState& St);
+  inline ValueState::ExprBindingsTy Remove(const ValueStateImpl& V, Expr* E) {
+    return Remove(V.BlockExprBindings, E);
+  }
+  
+  inline ValueState::VarBindingsTy Remove(const ValueStateImpl& V, VarDecl* D) {
+    return Remove(V.VarBindings, D);
+  }
+                  
+  ValueState BindVar(ValueState St, VarDecl* D, const RValue& V);
+  ValueState UnbindVar(ValueState St, VarDecl* D);  
   
 public:  
   ValueStateManager(ASTContext& Ctx, llvm::BumpPtrAllocator& alloc) 
     : ValMgr(Ctx, alloc), Alloc(alloc) {}
   
-  StateTy getInitialState();
+  ValueState getInitialState();
         
   ValueManager& getValueManager() { return ValMgr; }
   SymbolManager& getSymbolManager() { return SymMgr; }
   
-  StateTy RemoveDeadBindings(StateTy St, Stmt* Loc, 
-                             const LiveVariables& Liveness);
+  ValueState RemoveDeadBindings(ValueState St, Stmt* Loc, 
+                                const LiveVariables& Liveness);
   
-  StateTy SetValue(StateTy St, Expr* S, bool isBlkExpr, const RValue& V);
-  StateTy SetValue(StateTy St, const LValue& LV, const RValue& V);
+  ValueState RemoveSubExprBindings(ValueState St) {
+    ValueStateImpl NewSt = *St;
+    NewSt.SubExprBindings = EXFactory.GetEmptyMap();
+    return getPersistentState(NewSt);    
+  }
+    
+  
+  ValueState SetValue(ValueState St, Expr* S, bool isBlkExpr, const RValue& V);
+  ValueState SetValue(ValueState St, const LValue& LV, const RValue& V);
 
-  RValue GetValue(const StateTy& St, Expr* S, bool* hasVal = NULL);
-  RValue GetValue(const StateTy& St, const LValue& LV, QualType* T = NULL);    
-  LValue GetLValue(const StateTy& St, Expr* S);
+  RValue GetValue(ValueState St, Expr* S, bool* hasVal = NULL);
+  RValue GetValue(ValueState St, const LValue& LV, QualType* T = NULL);    
+  LValue GetLValue(ValueState St, Expr* S);
   
-  StateTy Add(StateTy St, ExprBindKey K, const RValue& V);
-  StateTy Remove(StateTy St, ExprBindKey K);
+  ValueState getPersistentState(const ValueStateImpl& Impl);
   
-  StateTy Add(StateTy St, VarDecl* D, const RValue& V);
-  StateTy Remove(StateTy St, VarDecl* D);
-  
-  StateTy getPersistentState(const ValueStateImpl& Impl);
-  
-  StateTy AddEQ(StateTy St, SymbolID sym, const llvm::APSInt& V);
-  StateTy AddNE(StateTy St, SymbolID sym, const llvm::APSInt& V);
+  ValueState AddEQ(ValueState St, SymbolID sym, const llvm::APSInt& V);
+  ValueState AddNE(ValueState St, SymbolID sym, const llvm::APSInt& V);
 };
   
 } // end clang namespace
