Index: include/clang/Checker/PathSensitive/GRState.h
===================================================================
--- include/clang/Checker/PathSensitive/GRState.h	(revision 116923)
+++ include/clang/Checker/PathSensitive/GRState.h	(working copy)
@@ -36,6 +36,7 @@
 typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&,
                                                        GRSubEngine&);
 typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
+typedef SValuator* (*SValuatorCreator)(StoreManager &storeMgr, ValueManager &valMgr);
 
 //===----------------------------------------------------------------------===//
 // GRStateTrait - Traits used by the Generic Data Map of a GRState.
@@ -414,6 +415,7 @@
   EnvironmentManager                   EnvMgr;
   llvm::OwningPtr<StoreManager>        StoreMgr;
   llvm::OwningPtr<ConstraintManager>   ConstraintMgr;
+  llvm::OwningPtr<SValuator>           SVator;
 
   GRState::GenericDataMap::Factory     GDMFactory;
 
@@ -439,14 +441,16 @@
                  StoreManagerCreator CreateStoreManager,
                  ConstraintManagerCreator CreateConstraintManager,
                  llvm::BumpPtrAllocator& alloc,
-                 GRSubEngine &subeng)
+                 GRSubEngine &subeng,
+                 SValuatorCreator CreateSValuator = CreateSimpleSValuator)
     : Eng(subeng),
       EnvMgr(alloc),
       GDMFactory(alloc),
-      ValueMgr(alloc, Ctx, *this),
+      ValueMgr(alloc, Ctx),
       Alloc(alloc) {
     StoreMgr.reset((*CreateStoreManager)(*this));
     ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
+    SVator.reset((*CreateSValuator)(*StoreMgr, ValueMgr));
   }
 
   ~GRStateManager();
@@ -484,6 +488,7 @@
 
   StoreManager& getStoreManager() { return *StoreMgr; }
   ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
+  SValuator& getSValuator() { return *SVator; }
   GRSubEngine& getOwningEngine() { return Eng; }
 
   const GRState* RemoveDeadBindings(const GRState* St,
Index: include/clang/Checker/PathSensitive/Store.h
===================================================================
--- include/clang/Checker/PathSensitive/Store.h	(revision 116923)
+++ include/clang/Checker/PathSensitive/Store.h	(working copy)
@@ -35,13 +35,12 @@
 class StoreManager {
 protected:
   ValueManager &ValMgr;
-  GRStateManager &StateMgr;
 
   /// MRMgr - Manages region objects associated with this StoreManager.
   MemRegionManager &MRMgr;
   ASTContext &Ctx;
 
-  StoreManager(GRStateManager &stateMgr);
+  StoreManager(ValueManager &valMgr);
 
 public:
   virtual ~StoreManager() {}
@@ -126,15 +125,6 @@
   ///  conversions between arrays and pointers.
   virtual SVal ArrayToPointer(Loc Array) = 0;
 
-  class CastResult {
-    const GRState *state;
-    const MemRegion *region;
-  public:
-    const GRState *getState() const { return state; }
-    const MemRegion* getRegion() const { return region; }
-    CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){}
-  };
-
   const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
 
   /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
Index: include/clang/Checker/PathSensitive/SValuator.h
===================================================================
--- include/clang/Checker/PathSensitive/SValuator.h	(revision 116923)
+++ include/clang/Checker/PathSensitive/SValuator.h	(working copy)
@@ -21,11 +21,13 @@
 namespace clang {
 
 class GRState;
+class StoreManager;
 class ValueManager;
 
 class SValuator {
-  friend class ValueManager;
+
 protected:
+  StoreManager &StoreMgr;
   ValueManager &ValMgr;
 
 public:
@@ -35,7 +37,7 @@
   virtual SVal EvalCastL(Loc val, QualType castTy) = 0;
 
 public:
-  SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
+  SValuator(StoreManager &storeMgr, ValueManager &valMgr) : StoreMgr(storeMgr), ValMgr(valMgr) {}
   virtual ~SValuator() {}
 
   SVal EvalCast(SVal V, QualType castTy, QualType originalType);
@@ -64,7 +66,7 @@
                               DefinedOrUnknownSVal R);
 };
 
-SValuator* CreateSimpleSValuator(ValueManager &valMgr);
+SValuator* CreateSimpleSValuator(StoreManager &storeMgr, ValueManager &valMgr);
 
 } // end clang namespace
 #endif
Index: include/clang/Checker/PathSensitive/ValueManager.h
===================================================================
--- include/clang/Checker/PathSensitive/ValueManager.h	(revision 116923)
+++ include/clang/Checker/PathSensitive/ValueManager.h	(working copy)
@@ -28,7 +28,7 @@
 
 namespace clang {
 
-class GRStateManager;
+class StoreManager;
 
 class ValueManager {
 
@@ -38,43 +38,31 @@
   /// SymMgr - Object that manages the symbol information.
   SymbolManager SymMgr;
 
-  /// SVator - SValuator object that creates SVals from expressions.
-  llvm::OwningPtr<SValuator> SVator;
-
   MemRegionManager MemMgr;
 
-  GRStateManager &StateMgr;
-
   const QualType ArrayIndexTy;
   const unsigned ArrayIndexWidth;
 
 public:
-  ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context,
-               GRStateManager &stateMgr)
+  ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context)
                : Context(context), BasicVals(context, alloc),
                  SymMgr(context, BasicVals, alloc),
-                 MemMgr(context, alloc), StateMgr(stateMgr),
+                 MemMgr(context, alloc), 
                  ArrayIndexTy(context.IntTy),
-                 ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {
-    // FIXME: Generalize later.
-    SVator.reset(clang::CreateSimpleSValuator(*this));
-  }
+                 ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) 
+  {}
 
   // Accessors to submanagers.
 
   ASTContext &getContext() { return Context; }
   const ASTContext &getContext() const { return Context; }
 
-  GRStateManager &getStateManager() { return StateMgr; }
-
   BasicValueFactory &getBasicValueFactory() { return BasicVals; }
   const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
 
   SymbolManager &getSymbolManager() { return SymMgr; }
   const SymbolManager &getSymbolManager() const { return SymMgr; }
 
-  SValuator &getSValuator() { return *SVator.get(); }
-
   MemRegionManager &getRegionManager() { return MemMgr; }
   const MemRegionManager &getRegionManager() const { return MemMgr; }
 
@@ -131,6 +119,8 @@
   }
 
   SVal convertToArrayIndex(SVal V);
+  SVal castNonLoc(NonLoc val, QualType castTy);
+  SVal castLoc(Loc val, QualType castTy);
 
   nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
     return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
Index: lib/Checker/BasicObjCFoundationChecks.cpp
===================================================================
--- lib/Checker/BasicObjCFoundationChecks.cpp	(revision 116923)
+++ lib/Checker/BasicObjCFoundationChecks.cpp	(working copy)
@@ -466,7 +466,7 @@
   DefinedSVal Zero = cast<DefinedSVal>(ValMgr.makeZeroVal(Arg->getType()));
 
   // Make an expression asserting that they're equal.
-  SValuator &SVator = ValMgr.getSValuator();
+  SValuator &SVator = state->getStateManager().getSValuator();
   DefinedOrUnknownSVal ArgIsNull = SVator.EvalEQ(state, Zero, *DefArgVal);
 
   // Are they equal?
Index: lib/Checker/BasicStore.cpp
===================================================================
--- lib/Checker/BasicStore.cpp	(revision 116923)
+++ lib/Checker/BasicStore.cpp	(working copy)
@@ -35,8 +35,8 @@
 class BasicStoreManager : public StoreManager {
   BindingsTy::Factory VBFactory;
 public:
-  BasicStoreManager(GRStateManager& mgr)
-    : StoreManager(mgr), VBFactory(mgr.getAllocator()) {}
+  BasicStoreManager(ValueManager &mgr, llvm::BumpPtrAllocator& alloc)
+    : StoreManager(mgr), VBFactory(alloc) {}
 
   ~BasicStoreManager() {}
 
@@ -103,7 +103,7 @@
 
 
 StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
-  return new BasicStoreManager(StMgr);
+  return new BasicStoreManager(StMgr.getValueManager(), StMgr.getAllocator());
 }
 
 static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
@@ -422,7 +422,7 @@
 Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR,
                                           SVal* InitVal) {
 
-  BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+  BasicValueFactory& BasicVals = ValMgr.getBasicValueFactory();
   const VarDecl *VD = VR->getDecl();
 
   // BasicStore does not model arrays and structs.
Index: lib/Checker/BuiltinFunctionChecker.cpp
===================================================================
--- lib/Checker/BuiltinFunctionChecker.cpp	(revision 116923)
+++ lib/Checker/BuiltinFunctionChecker.cpp	(working copy)
@@ -70,7 +70,7 @@
     ValueManager& ValMgr = C.getValueManager();
     DefinedOrUnknownSVal Extent = R->getExtent(ValMgr);
 
-    SValuator& SVator = ValMgr.getSValuator();
+    SValuator& SVator = state->getStateManager().getSValuator();
     DefinedOrUnknownSVal ExtentMatchesSizeArg =
       SVator.EvalEQ(state, Extent, Size);
     state = state->Assume(ExtentMatchesSizeArg, true);
Index: lib/Checker/CastSizeChecker.cpp
===================================================================
--- lib/Checker/CastSizeChecker.cpp	(revision 116923)
+++ lib/Checker/CastSizeChecker.cpp	(working copy)
@@ -60,7 +60,7 @@
   ValueManager &ValMgr = C.getValueManager();
   SVal Extent = SR->getExtent(ValMgr);
 
-  SValuator &SVator = ValMgr.getSValuator();
+  SValuator &SVator = state->getStateManager().getSValuator();
   const llvm::APSInt *ExtentInt = SVator.getKnownValue(state, Extent);
   if (!ExtentInt)
     return;
Index: lib/Checker/CStringChecker.cpp
===================================================================
--- lib/Checker/CStringChecker.cpp	(revision 116923)
+++ lib/Checker/CStringChecker.cpp	(working copy)
@@ -122,7 +122,7 @@
     return std::pair<const GRState*, const GRState *>(state, state);
 
   ValueManager &ValMgr = C.getValueManager();
-  SValuator &SV = ValMgr.getSValuator();
+  SValuator &SV = state->getStateManager().getSValuator();
 
   DefinedOrUnknownSVal Zero = ValMgr.makeZeroVal(Ty);
   DefinedOrUnknownSVal ValIsZero = SV.EvalEQ(state, *Val, Zero);
@@ -245,7 +245,7 @@
     return NULL;
 
   ValueManager &VM = C.getValueManager();
-  SValuator &SV = VM.getSValuator();
+  SValuator &SV = state->getStateManager().getSValuator();
   ASTContext &Ctx = C.getASTContext();
 
   QualType SizeTy = Size->getType();
@@ -313,7 +313,7 @@
     return NULL;
 
   ValueManager &VM = state->getStateManager().getValueManager();
-  SValuator &SV = VM.getSValuator();
+  SValuator &SV = state->getStateManager().getSValuator();
   ASTContext &Ctx = VM.getContext();
   const GRState *stateTrue, *stateFalse;
 
@@ -716,7 +716,7 @@
 
   const GRState *state = C.getState();
   ValueManager &ValMgr = C.getValueManager();
-  SValuator &SV = ValMgr.getSValuator();
+  SValuator &SV = state->getStateManager().getSValuator();
 
   // See if the size argument is zero.
   SVal SizeVal = state->getSVal(Size);
Index: lib/Checker/FlatStore.cpp
===================================================================
--- lib/Checker/FlatStore.cpp	(revision 116923)
+++ lib/Checker/FlatStore.cpp	(working copy)
@@ -25,7 +25,7 @@
 
 public:
   FlatStoreManager(GRStateManager &mgr) 
-    : StoreManager(mgr), 
+    : StoreManager(mgr.getValueManager()), 
       RBFactory(mgr.getAllocator()), 
       BVFactory(mgr.getAllocator()) {}
 
Index: lib/Checker/GRExprEngine.cpp
===================================================================
--- lib/Checker/GRExprEngine.cpp	(revision 116923)
+++ lib/Checker/GRExprEngine.cpp	(working copy)
@@ -393,7 +393,7 @@
              *this),
     SymMgr(StateMgr.getSymbolManager()),
     ValMgr(StateMgr.getValueManager()),
-    SVator(ValMgr.getSValuator()),
+    SVator(StateMgr.getSValuator()),
     CurrentStmt(NULL),
     NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
     RaiseSel(GetNullarySelector("raise", getContext())),
Index: lib/Checker/GRState.cpp
===================================================================
--- lib/Checker/GRState.cpp	(revision 116923)
+++ lib/Checker/GRState.cpp	(working copy)
@@ -241,7 +241,7 @@
   // FIXME: This should probably be part of SValuator.
   GRStateManager &SM = getStateManager();
   ValueManager &VM = SM.getValueManager();
-  SValuator &SV = VM.getSValuator();
+  SValuator &SV = SM.getSValuator();
   ASTContext &Ctx = VM.getContext();
 
   // Get the offset: the minimum value of the array index type.
Index: lib/Checker/MallocChecker.cpp
===================================================================
--- lib/Checker/MallocChecker.cpp	(revision 116923)
+++ lib/Checker/MallocChecker.cpp	(working copy)
@@ -241,7 +241,7 @@
   DefinedOrUnknownSVal Extent = R->getExtent(ValMgr);
   DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
 
-  SValuator &SVator = ValMgr.getSValuator();
+  SValuator &SVator = state->getStateManager().getSValuator();
   DefinedOrUnknownSVal ExtentMatchesSize =
     SVator.EvalEQ(state, Extent, DefinedSize);
   state = state->Assume(ExtentMatchesSize, true);
Index: lib/Checker/RegionStore.cpp
===================================================================
--- lib/Checker/RegionStore.cpp	(revision 116923)
+++ lib/Checker/RegionStore.cpp	(working copy)
@@ -193,12 +193,13 @@
 class RegionStoreManager : public StoreManager {
   const RegionStoreFeatures Features;
   RegionBindings::Factory RBFactory;
-
+  SValuator &SVator;
 public:
   RegionStoreManager(GRStateManager& mgr, const RegionStoreFeatures &f)
-    : StoreManager(mgr),
+    : StoreManager(mgr.getValueManager()),
       Features(f),
-      RBFactory(mgr.getAllocator()) {}
+      RBFactory(mgr.getAllocator()),
+      SVator(mgr.getSValuator()) {}
 
   SubRegionMap *getSubRegionMap(Store store) {
     return getRegionStoreSubRegionMap(store);
@@ -458,9 +459,9 @@
   RegionBindings B;
 
 public:
-  ClusterAnalysis(RegionStoreManager &rm, GRStateManager &StateMgr,
+  ClusterAnalysis(RegionStoreManager &rm, ValueManager &valMgr,
                   RegionBindings b)
-    : RM(rm), Ctx(StateMgr.getContext()), ValMgr(StateMgr.getValueManager()),
+    : RM(rm), Ctx(valMgr.getContext()), ValMgr(valMgr),
       B(b) {}
 
   RegionBindings getRegionBindings() const { return B; }
@@ -570,12 +571,12 @@
   StoreManager::InvalidatedRegions *Regions;
 public:
   InvalidateRegionsWorker(RegionStoreManager &rm,
-                          GRStateManager &stateMgr,
+                          ValueManager &valMgr,
                           RegionBindings b,
                           const Expr *ex, unsigned count,
                           StoreManager::InvalidatedSymbols *is,
                           StoreManager::InvalidatedRegions *r)
-    : ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr, b),
+    : ClusterAnalysis<InvalidateRegionsWorker>(rm, valMgr, b),
       Ex(ex), Count(count), IS(is), Regions(r) {}
 
   void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
@@ -696,7 +697,7 @@
                                             InvalidatedSymbols *IS,
                                             bool invalidateGlobals,
                                             InvalidatedRegions *Regions) {
-  InvalidateRegionsWorker W(*this, StateMgr,
+  InvalidateRegionsWorker W(*this, ValMgr,
                             RegionStoreManager::GetRegionBindings(store),
                             Ex, Count, IS, Regions);
 
@@ -739,7 +740,6 @@
                                                            const MemRegion *R,
                                                            QualType EleTy) {
   SVal Size = cast<SubRegion>(R)->getExtent(ValMgr);
-  SValuator &SVator = ValMgr.getSValuator();
   const llvm::APSInt *SizeInt = SVator.getKnownValue(state, Size);
   if (!SizeInt)
     return UnknownVal();
@@ -1276,8 +1276,7 @@
           if (const IntegerLiteral *IL =
               dyn_cast<IntegerLiteral>(Init->IgnoreParenCasts())) {
             const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL);
-            return ValMgr.getSValuator().EvalCast(V, Init->getType(),
-                                                  IL->getType());
+            return SVator.EvalCast(V, Init->getType(), IL->getType());
           }
       }
 
@@ -1609,10 +1608,10 @@
   const StackFrameContext *CurrentLCtx;
 
 public:
-  RemoveDeadBindingsWorker(RegionStoreManager &rm, GRStateManager &stateMgr,
+  RemoveDeadBindingsWorker(RegionStoreManager &rm, ValueManager &valMgr,
                            RegionBindings b, SymbolReaper &symReaper,
                            const StackFrameContext *LCtx)
-    : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr, b),
+    : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, valMgr, b),
       SymReaper(symReaper), CurrentLCtx(LCtx) {}
 
   // Called by ClusterAnalysis.
@@ -1747,7 +1746,7 @@
                            llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
 {
   RegionBindings B = GetRegionBindings(store);
-  RemoveDeadBindingsWorker W(*this, StateMgr, B, SymReaper, LCtx);
+  RemoveDeadBindingsWorker W(*this, ValMgr, B, SymReaper, LCtx);
   W.GenerateClusters();
 
   // Enqueue the region roots onto the worklist.
Index: lib/Checker/SimpleSValuator.cpp
===================================================================
--- lib/Checker/SimpleSValuator.cpp	(revision 116923)
+++ lib/Checker/SimpleSValuator.cpp	(working copy)
@@ -23,7 +23,7 @@
   virtual SVal EvalCastL(Loc val, QualType castTy);
 
 public:
-  SimpleSValuator(ValueManager &valMgr) : SValuator(valMgr) {}
+  SimpleSValuator(StoreManager &storeMgr, ValueManager &valMgr) : SValuator(storeMgr, valMgr) {}
   virtual ~SimpleSValuator() {}
 
   virtual SVal EvalMinus(NonLoc val);
@@ -44,8 +44,8 @@
 };
 } // end anonymous namespace
 
-SValuator *clang::CreateSimpleSValuator(ValueManager &valMgr) {
-  return new SimpleSValuator(valMgr);
+SValuator *clang::CreateSimpleSValuator(StoreManager &storeMgr, ValueManager &valMgr) {
+  return new SimpleSValuator(storeMgr, valMgr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -54,88 +54,12 @@
 
 SVal SimpleSValuator::EvalCastNL(NonLoc val, QualType castTy) {
 
-  bool isLocType = Loc::IsLocType(castTy);
-
-  if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
-    if (isLocType)
-      return LI->getLoc();
-
-    // FIXME: Correctly support promotions/truncations.
-    ASTContext &Ctx = ValMgr.getContext();
-    unsigned castSize = Ctx.getTypeSize(castTy);
-    if (castSize == LI->getNumBits())
-      return val;
-
-    return ValMgr.makeLocAsInteger(LI->getLoc(), castSize);
-  }
-
-  if (const SymExpr *se = val.getAsSymbolicExpression()) {
-    ASTContext &Ctx = ValMgr.getContext();
-    QualType T = Ctx.getCanonicalType(se->getType(Ctx));
-    if (T == Ctx.getCanonicalType(castTy))
-      return val;
-    
-    // FIXME: Remove this hack when we support symbolic truncation/extension.
-    // HACK: If both castTy and T are integers, ignore the cast.  This is
-    // not a permanent solution.  Eventually we want to precisely handle
-    // extension/truncation of symbolic integers.  This prevents us from losing
-    // precision when we assign 'x = y' and 'y' is symbolic and x and y are
-    // different integer types.
-    if (T->isIntegerType() && castTy->isIntegerType())
-      return val;
-
-    return UnknownVal();
-  }
-
-  if (!isa<nonloc::ConcreteInt>(val))
-    return UnknownVal();
-
-  // Only handle casts from integers to integers.
-  if (!isLocType && !castTy->isIntegerType())
-    return UnknownVal();
-
-  llvm::APSInt i = cast<nonloc::ConcreteInt>(val).getValue();
-  i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
-  i.extOrTrunc(ValMgr.getContext().getTypeSize(castTy));
-
-  if (isLocType)
-    return ValMgr.makeIntLocVal(i);
-  else
-    return ValMgr.makeIntVal(i);
+  return ValMgr.castNonLoc(val, castTy);
 }
 
 SVal SimpleSValuator::EvalCastL(Loc val, QualType castTy) {
 
-  // Casts from pointers -> pointers, just return the lval.
-  //
-  // Casts from pointers -> references, just return the lval.  These
-  //   can be introduced by the frontend for corner cases, e.g
-  //   casting from va_list* to __builtin_va_list&.
-  //
-  if (Loc::IsLocType(castTy) || castTy->isReferenceType())
-    return val;
-
-  // FIXME: Handle transparent unions where a value can be "transparently"
-  //  lifted into a union type.
-  if (castTy->isUnionType())
-    return UnknownVal();
-
-  if (castTy->isIntegerType()) {
-    unsigned BitWidth = ValMgr.getContext().getTypeSize(castTy);
-
-    if (!isa<loc::ConcreteInt>(val))
-      return ValMgr.makeLocAsInteger(val, BitWidth);
-
-    llvm::APSInt i = cast<loc::ConcreteInt>(val).getValue();
-    i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
-    i.extOrTrunc(BitWidth);
-    return ValMgr.makeIntVal(i);
-  }
-
-  // All other cases: return 'UnknownVal'.  This includes casting pointers
-  // to floats, which is probably badness it itself, but this is a good
-  // intermediate solution until we do something better.
-  return UnknownVal();
+  return ValMgr.castLoc(val, castTy);
 }
 
 //===----------------------------------------------------------------------===//
Index: lib/Checker/Store.cpp
===================================================================
--- lib/Checker/Store.cpp	(revision 116923)
+++ lib/Checker/Store.cpp	(working copy)
@@ -17,9 +17,9 @@
 
 using namespace clang;
 
-StoreManager::StoreManager(GRStateManager &stateMgr)
-  : ValMgr(stateMgr.getValueManager()), StateMgr(stateMgr),
-    MRMgr(ValMgr.getRegionManager()), Ctx(stateMgr.getContext()) {}
+StoreManager::StoreManager(ValueManager &valMgr)
+  : ValMgr(valMgr),
+    MRMgr(ValMgr.getRegionManager()), Ctx(ValMgr.getContext()) {}
 
 Store StoreManager::EnterStackFrame(const GRState *state,
                                     const StackFrameContext *frame) {
@@ -52,8 +52,6 @@
 
 const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy) {
 
-  ASTContext& Ctx = StateMgr.getContext();
-
   // Handle casts to Objective-C objects.
   if (CastToTy->isObjCObjectPointerType())
     return R->StripCasts();
@@ -224,9 +222,9 @@
   }
   
   if (const Loc *L = dyn_cast<Loc>(&V))
-    return ValMgr.getSValuator().EvalCastL(*L, castTy);
+    return ValMgr.castLoc(*L, castTy);
   else if (const NonLoc *NL = dyn_cast<NonLoc>(&V))
-    return ValMgr.getSValuator().EvalCastNL(*NL, castTy);
+    return ValMgr.castNonLoc(*NL, castTy);
   
   return V;
 }
Index: lib/Checker/SValuator.cpp
===================================================================
--- lib/Checker/SValuator.cpp	(revision 116923)
+++ lib/Checker/SValuator.cpp	(working copy)
@@ -49,19 +49,16 @@
 DefinedOrUnknownSVal SValuator::EvalEQ(const GRState *ST,
                                        DefinedOrUnknownSVal L,
                                        DefinedOrUnknownSVal R) {
-  return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BO_EQ, L, R,
-                                              ValMgr.getContext().IntTy));
+  return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BO_EQ, L, R, ValMgr.getContext().IntTy));
 }
 
 SVal SValuator::EvalCast(SVal val, QualType castTy, QualType originalTy) {
   if (val.isUnknownOrUndef() || castTy == originalTy)
     return val;
 
-  ASTContext &C = ValMgr.getContext();
-
   // For const casts, just propagate the value.
   if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
-    if (C.hasSameUnqualifiedType(castTy, originalTy))
+    if (ValMgr.getContext().hasSameUnqualifiedType(castTy, originalTy))
       return val;
 
   // Check for casts to real or complex numbers.  We don't handle these at all
@@ -81,8 +78,7 @@
   if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
     if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
       if (const MemRegion *R = LV->getLoc().getAsRegion()) {
-        StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
-        R = storeMgr.CastRegion(R, castTy);
+        R = StoreMgr.CastRegion(R, castTy);
         return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
       }
       return LV->getLoc();
@@ -99,7 +95,7 @@
   // Check for casts from array type to another type.
   if (originalTy->isArrayType()) {
     // We will always decay to a pointer.
-    val = ValMgr.getStateManager().ArrayToPointer(cast<Loc>(val));
+    val = StoreMgr.ArrayToPointer(cast<Loc>(val));
 
     // Are we casting from an array to a pointer?  If so just pass on
     // the decayed value.
@@ -141,12 +137,10 @@
     assert(Loc::IsLocType(originalTy) || originalTy->isFunctionType() ||
            originalTy->isBlockPointerType());
 
-    StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
-
     // Delegate to store manager to get the result of casting a region to a
     // different type.  If the MemRegion* returned is NULL, this expression
     // evaluates to UnknownVal.
-    R = storeMgr.CastRegion(R, castTy);
+    R = StoreMgr.CastRegion(R, castTy);
     return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
   }
 
Index: lib/Checker/ValueManager.cpp
===================================================================
--- lib/Checker/ValueManager.cpp	(revision 116923)
+++ lib/Checker/ValueManager.cpp	(working copy)
@@ -67,9 +67,96 @@
       return V;
   }
 
-  return SVator->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy);
+  return castNonLoc(cast<NonLoc>(V), ArrayIndexTy);
 }
 
+
+SVal ValueManager::castNonLoc(NonLoc val, QualType castTy) {
+
+  bool isLocType = Loc::IsLocType(castTy);
+
+  if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
+    if (isLocType)
+      return LI->getLoc();
+
+    // FIXME: Correctly support promotions/truncations.
+    unsigned castSize = Context.getTypeSize(castTy);
+    if (castSize == LI->getNumBits())
+      return val;
+
+    return makeLocAsInteger(LI->getLoc(), castSize);
+  }
+
+  if (const SymExpr *se = val.getAsSymbolicExpression()) {
+    QualType T = Context.getCanonicalType(se->getType(Context));
+    if (T == Context.getCanonicalType(castTy))
+      return val;
+    
+    // FIXME: Remove this hack when we support symbolic truncation/extension.
+    // HACK: If both castTy and T are integers, ignore the cast.  This is
+    // not a permanent solution.  Eventually we want to precisely handle
+    // extension/truncation of symbolic integers.  This prevents us from losing
+    // precision when we assign 'x = y' and 'y' is symbolic and x and y are
+    // different integer types.
+    if (T->isIntegerType() && castTy->isIntegerType())
+      return val;
+
+    return UnknownVal();
+  }
+
+  if (!isa<nonloc::ConcreteInt>(val))
+    return UnknownVal();
+
+  // Only handle casts from integers to integers.
+  if (!isLocType && !castTy->isIntegerType())
+    return UnknownVal();
+
+  llvm::APSInt i = cast<nonloc::ConcreteInt>(val).getValue();
+  i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
+  i.extOrTrunc(Context.getTypeSize(castTy));
+
+  if (isLocType)
+    return makeIntLocVal(i);
+  else
+    return makeIntVal(i);
+}
+
+
+SVal ValueManager::castLoc(Loc val, QualType castTy) {
+  // Casts from pointers -> pointers, just return the lval.
+  //
+  // Casts from pointers -> references, just return the lval.  These
+  //   can be introduced by the frontend for corner cases, e.g
+  //   casting from va_list* to __builtin_va_list&.
+  //
+  if (Loc::IsLocType(castTy) || castTy->isReferenceType())
+    return val;
+
+  // FIXME: Handle transparent unions where a value can be "transparently"
+  //  lifted into a union type.
+  if (castTy->isUnionType())
+    return UnknownVal();
+
+  if (castTy->isIntegerType()) {
+    unsigned BitWidth = Context.getTypeSize(castTy);
+
+    if (!isa<loc::ConcreteInt>(val))
+      return makeLocAsInteger(val, BitWidth);
+
+    llvm::APSInt i = cast<loc::ConcreteInt>(val).getValue();
+    i.setIsUnsigned(castTy->isUnsignedIntegerType() || Loc::IsLocType(castTy));
+    i.extOrTrunc(BitWidth);
+    return makeIntVal(i);
+  }
+
+  // All other cases: return 'UnknownVal'.  This includes casting pointers
+  // to floats, which is probably badness it itself, but this is a good
+  // intermediate solution until we do something better.
+  return UnknownVal();
+}
+
+
+
 DefinedOrUnknownSVal 
 ValueManager::getRegionValueSymbolVal(const TypedRegion* R) {
   QualType T = R->getValueType();
Index: lib/Checker/VLASizeChecker.cpp
===================================================================
--- lib/Checker/VLASizeChecker.cpp	(revision 116923)
+++ lib/Checker/VLASizeChecker.cpp	(working copy)
@@ -108,7 +108,7 @@
 
   // Convert the array length to size_t.
   ValueManager &ValMgr = C.getValueManager();
-  SValuator &SV = ValMgr.getSValuator();
+  SValuator &SV = state->getStateManager().getSValuator();
   QualType SizeTy = Ctx.getSizeType();
   NonLoc ArrayLength = cast<NonLoc>(SV.EvalCast(sizeD, SizeTy, SE->getType()));
 
