+getValEnv :: SimplM (IdSubst, InScopeEnv)
+getValEnv (SimplEnv {seSubst = (_, id_subst), seInScope = in_scope}) us sc
+ = ((id_subst, in_scope), us, sc)
+
+getInScope :: SimplM InScopeEnv
+getInScope env us sc = (seInScope env, us, sc)
+
+setInScope :: InScopeEnv -> SimplM a -> SimplM a
+setInScope in_scope m env us sc = m (env {seInScope = in_scope}) us sc
+
+extendInScope :: CoreBndr -> SimplM a -> SimplM a
+extendInScope v m env@(SimplEnv {seInScope = in_scope}) us sc
+ = m (env {seInScope = extendVarSet in_scope v}) us sc
+
+extendInScopes :: [CoreBndr] -> SimplM a -> SimplM a
+extendInScopes vs m env@(SimplEnv {seInScope = in_scope}) us sc
+ = m (env {seInScope = foldl extendVarSet in_scope vs}) us sc
+
+modifyInScope :: CoreBndr -> SimplM a -> SimplM a
+modifyInScope v m env us sc
+#ifdef DEBUG
+ | not (v `elemVarSet` seInScope env )
+ = pprTrace "modifyInScope: not in scope:" (ppr v)
+ m env us sc
+#endif
+ | otherwise
+ = extendInScope v m env us sc
+
+getSubstEnv :: SimplM SubstEnv
+getSubstEnv env us sc = (seSubst env, us, sc)
+
+setSubstEnv :: SubstEnv -> SimplM a -> SimplM a
+setSubstEnv subst_env m env us sc = m (env {seSubst = subst_env}) us sc
+
+extendIdSubst :: Id -> SubstCoreExpr -> SimplM a -> SimplM a
+extendIdSubst id expr m env@(SimplEnv {seSubst = (ty_subst, id_subst)}) us sc
+ = m (env { seSubst = (ty_subst, extendVarEnv id_subst id expr) }) us sc
+
+extendTySubst :: TyVar -> OutType -> SimplM a -> SimplM a
+extendTySubst tv ty m env@(SimplEnv {seSubst = (ty_subst, id_subst)}) us sc
+ = m (env { seSubst = (extendVarEnv ty_subst tv ty, id_subst) }) us sc
+
+zapSubstEnv :: SimplM a -> SimplM a
+zapSubstEnv m env us sc = m (env {seSubst = emptySubstEnv}) us sc
+
+getSimplBinderStuff :: SimplM (TyVarSubst, IdSubst, InScopeEnv, UniqSupply)
+getSimplBinderStuff (SimplEnv {seSubst = (ty_subst, id_subst), seInScope = in_scope}) us sc
+ = ((ty_subst, id_subst, in_scope, us), us, sc)
+
+setSimplBinderStuff :: (TyVarSubst, IdSubst, InScopeEnv, UniqSupply)
+ -> SimplM a -> SimplM a
+setSimplBinderStuff (ty_subst, id_subst, in_scope, us) m env _ sc
+ = m (env {seSubst = (ty_subst, id_subst), seInScope = in_scope}) us sc
+\end{code}
+
+
+\begin{code}
+newId :: Type -> (Id -> SimplM a) -> SimplM a
+ -- Extends the in-scope-env too
+newId ty m env@(SimplEnv {seInScope = in_scope}) us sc
+ = case splitUniqSupply us of
+ (us1, us2) -> m v (env {seInScope = extendVarSet in_scope v}) us2 sc
+ where
+ v = mkSysLocal (uniqFromSupply us1) ty
+
+newIds :: [Type] -> ([Id] -> SimplM a) -> SimplM a
+newIds tys m env@(SimplEnv {seInScope = in_scope}) us sc
+ = case splitUniqSupply us of
+ (us1, us2) -> m vs (env {seInScope = foldl extendVarSet in_scope vs}) us2 sc
+ where
+ vs = zipWithEqual "newIds" mkSysLocal (uniqsFromSupply (length tys) us1) tys