diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -24,7 +24,7 @@
 - Standard library of Scheme functions
 - Read-Eval-Print-Loop (REPL) interpreter, with input driven by Haskeline to provide a rich user experience
 - Full numeric tower: includes support for parsing/storing types (exact, inexact, etc), support for operations on these types as well as mixing types and other constraints from the R<sup>5</sup>RS specification.
-- Continuations: call/cc and first-class continuations.
+- Continuations: First-class continuations, call/cc, and call-with-values.
 - Hygienic Macros: High-level macros via define-syntax - *Note this is still somewhat of a work in progress* and while it works well enough that many derived forms are implemented in our standard library, you may still run into problems when defining your own macros.
 
 As well as the following approved extensions:
diff --git a/hs-src/Language/Scheme/Core.hs b/hs-src/Language/Scheme/Core.hs
--- a/hs-src/Language/Scheme/Core.hs
+++ b/hs-src/Language/Scheme/Core.hs
@@ -14,8 +14,13 @@
     , evalLisp
     , evalString
     , evalAndPrint
-    , primitiveBindings -- FUTURE: this may be a bad idea...
-                        -- but there should be an interface to inject custom functions written in Haskell
+    , primitiveBindings -- FUTURE: this is a bad idea.
+                        -- There should be an interface to inject custom functions written in Haskell.
+                        --
+                        -- Probably any new func should be added as an EvalFunc or IOFunc
+                        --
+                        -- If so, need to ensure that apply handles them properly, and that continuations are
+                        -- captured properly.
     ) where
 import Language.Scheme.Macro
 import Language.Scheme.Numerical
@@ -75,7 +80,13 @@
 -- Passing a higher-order function as the continuation; just evaluate it. This is 
 -- done to enable an 'eval' function to be broken up into multiple sub-functions,
 -- so that any of the sub-functions can be passed around as a continuation.
-continueEval _ (Continuation cEnv (Just (HaskellBody func funcArgs)) (Just cCont) _) val = func cEnv cCont val funcArgs
+--
+-- Carry extra args from the current continuation into the next, to support (call-with-values)
+continueEval _
+            (Continuation cEnv (Just (HaskellBody func funcArgs)) 
+                               (Just (Continuation cce cnc ccc _ cdynwind)) 
+                                xargs _) -- rather sloppy, should refactor code so this is not necessary
+             val = func cEnv (Continuation cce cnc ccc xargs cdynwind) val funcArgs
 
 -- No higher order function, so:
 --
@@ -83,22 +94,24 @@
 --
 -- Otherwise, if all code in the function has been executed, we 'unwind' to an outer
 -- continuation (if there is one), or we just return the result. Yes technically with
--- CPS you are supposed to keep calling into functions and never return, but eventually
+-- CPS you are supposed to keep calling into functions and never return, but in this case
 -- when the computation is complete, you have to return something.
-continueEval _ (Continuation cEnv (Just (SchemeBody cBody)) (Just cCont) _) val = do
+continueEval _ (Continuation cEnv (Just (SchemeBody cBody)) (Just cCont) extraArgs dynWind) val = do
     case cBody of
         [] -> do
           case cCont of
-            Continuation nEnv _ _ _ -> continueEval nEnv cCont val
+            Continuation nEnv ncCont nnCont _ nDynWind -> 
+              -- Pass extra args along if last expression of a function, to support (call-with-values)
+              continueEval nEnv (Continuation nEnv ncCont nnCont extraArgs nDynWind) val 
             _ -> return (val)
-        [lv] -> eval cEnv (Continuation cEnv (Just (SchemeBody [])) (Just cCont) False) (lv)
-        (lv : lvs) -> eval cEnv (Continuation cEnv (Just (SchemeBody lvs)) (Just cCont) False) (lv)
+        [lv] -> eval cEnv (Continuation cEnv (Just (SchemeBody [])) (Just cCont) Nothing dynWind) (lv)
+        (lv : lvs) -> eval cEnv (Continuation cEnv (Just (SchemeBody lvs)) (Just cCont) Nothing dynWind) (lv)
 
 -- No current continuation, but a next cont is available; call into it
-continueEval _ (Continuation cEnv Nothing (Just cCont) _) val = continueEval cEnv cCont val
+continueEval _ (Continuation cEnv Nothing (Just cCont) _ _) val = continueEval cEnv cCont val
 
 -- There is no continuation code, just return value
-continueEval _ (Continuation _ Nothing Nothing _) val = return val
+continueEval _ (Continuation _ Nothing Nothing _ _) val = return val
 continueEval _ _ _ = throwError $ Default "Internal error in continueEval"
 
 -- |Core eval function
@@ -136,21 +149,6 @@
 eval env cont val@(Vector _)    = continueEval env cont val
 eval env cont (Atom a)          = continueEval env cont =<< getVar env a
 
--- Evaluate an expression in the current environment
---
--- Calls into eval once to get raw expression, and a second time
--- to eval *that* expression.
---
--- Assumption is any macro transform is already performed
--- prior to this step.
---
--- FUTURE: consider allowing env to be specified, per R5RS
---
-eval env cont (List [Atom "eval", val]) = do
-  eval env (makeCPS env cont cps) val
-  where cps :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cps e c result _ = eval e c result
-
 -- Quote an expression by simply passing along the value
 eval env cont (List [Atom "quote", val])         = continueEval env cont val
 
@@ -305,17 +303,12 @@
             Just fArgs -> eval e c $ List (Atom "begin" : fArgs)
             Nothing -> throwError $ Default "Unexpected error in begin"
 
-
-eval env cont (List [Atom "load", String filename]) = do
-     result <- load filename >>= liftM last . mapM (evaluate env (makeNullContinuation env))
-     continueEval env cont result
-	 where evaluate env2 cont2 val2 = macroEval env2 val2 >>= eval env2 cont2
-
-
 eval env cont (List [Atom "set!", Atom var, form]) = do 
   eval env (makeCPS env cont cpsResult) form
  where cpsResult :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
        cpsResult e c result _ = setVar e var result >>= continueEval e c
+eval _ _ (List [Atom "set!", nonvar, _]) = throwError $ TypeMismatch "variable" nonvar 
+eval _ _ (List (Atom "set!" : args)) = throwError $ NumArgs 2 args
 
 eval env cont (List [Atom "define", Atom var, form]) = do 
   eval env (makeCPS env cont cpsResult) form
@@ -342,28 +335,6 @@
   result <- makeVarargs varargs env [] fbody
   continueEval env cont result
 
-eval env cont (List [Atom "string-fill!", Atom var, character]) = do 
-  eval env (makeCPS env cont cpsVar) =<< getVar env var
-  where cpsVar :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsVar e c result _ = eval e (makeCPSWArgs e c cpsChr $ [result]) $ character
-
-        cpsChr :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsChr e c result (Just [rVar]) = (fillStr(rVar, result) >>= setVar e var) >>= continueEval e c
-        cpsChr _ _ _ _ = throwError $ Default "Unexpected error in string-fill!"
-
-        fillStr (String str, Char achr) = doFillStr (String "", Char achr, length str)
-        fillStr (String _, c) = throwError $ TypeMismatch "character" c
-        fillStr (s, _) = throwError $ TypeMismatch "string" s
-
-        doFillStr (String str, Char achr, left) = do
-          if left == 0
-             then return $ String str
-             else doFillStr(String $ achr : str, Char achr, left - 1)
-        doFillStr (String _, c, _) = throwError $ TypeMismatch "character" c
-        doFillStr (s, Char _, _) = throwError $ TypeMismatch "string" s
-        doFillStr (_, _, _) = throwError $ BadSpecialForm "Unexpected error in string-fill!" $ List []
-
-
 eval env cont (List [Atom "string-set!", Atom var, i, character]) = do 
   eval env (makeCPS env cont cpsStr) i
   where 
@@ -382,9 +353,26 @@
         substr (String _, Char _, n) = throwError $ TypeMismatch "number" n
         substr (String _, c, _) = throwError $ TypeMismatch "character" c
         substr (s, _, _) = throwError $ TypeMismatch "string" s
+eval _ _ (List [Atom "string-set!" , nonvar , _ , _ ]) = throwError $ TypeMismatch "variable" nonvar 
+eval _ _ (List (Atom "string-set!" : args)) = throwError $ NumArgs 3 args
 
+eval env cont (List [Atom "set-car!", Atom var, argObj]) = do
+  continueEval env (makeCPS env cont cpsObj) =<< getVar env var
+  where 
+        cpsObj :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
+        cpsObj _ _ obj@(List []) _ = throwError $ TypeMismatch "pair" obj
+        cpsObj e c obj@(List (_:_)) _ = eval e (makeCPSWArgs e c cpsSet $ [obj]) argObj
+        cpsObj e c obj@(DottedList _ _) _ = eval e (makeCPSWArgs e c cpsSet $ [obj]) argObj
+        cpsObj _ _ obj _ = throwError $ TypeMismatch "pair" obj 
+
+        cpsSet :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
+        cpsSet e c obj (Just [List (_ : ls)]) = setVar e var (List (obj : ls)) >>= continueEval e c -- Wrong constructor? Should it be DottedList?
+        cpsSet e c obj (Just [DottedList (_ : ls) l]) = setVar e var (DottedList (obj : ls) l) >>= continueEval e c
+        cpsSet _ _ _ _ = throwError $ InternalError "Unexpected argument to cpsSet" 
+eval _ _ (List [Atom "set-car!" , nonvar , _ ]) = throwError $ TypeMismatch "variable" nonvar 
+eval _ _ (List (Atom "set-car!" : args)) = throwError $ NumArgs 2 args
+
 eval env cont (List [Atom "set-cdr!", Atom var, argObj]) = do
---  eval env (makeCPS env cont cpsObj) =<< getVar env var
   continueEval env (makeCPS env cont cpsObj) =<< getVar env var
   where 
         cpsObj :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
@@ -397,6 +385,8 @@
         cpsSet e c obj (Just [List (l : _)]) = setVar e var (DottedList [l] obj) >>= continueEval e c
         cpsSet e c obj (Just [DottedList (l : _) _]) = setVar e var (DottedList [l] obj) >>= continueEval e c
         cpsSet _ _ _ _ = throwError $ InternalError "Unexpected argument to cpsSet" 
+eval _ _ (List [Atom "set-cdr!" , nonvar , _ ]) = throwError $ TypeMismatch "variable" nonvar 
+eval _ _ (List (Atom "set-cdr!" : args)) = throwError $ NumArgs 2 args
 
 eval env cont (List [Atom "vector-set!", Atom var, i, object]) = do 
   eval env (makeCPS env cont cpsObj) i
@@ -416,24 +406,8 @@
         updateVector :: LispVal -> LispVal -> LispVal -> IOThrowsError LispVal
         updateVector (Vector vec) (Number idx) obj = return $ Vector $ vec//[(fromInteger idx, obj)]
         updateVector v _ _ = throwError $ TypeMismatch "vector" v
-
-eval env cont (List [Atom "vector-fill!", Atom var, object]) = do 
-  eval env (makeCPS env cont cpsVec) object
-  where
-        cpsVec :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsVec e c obj _ = eval e (makeCPSWArgs e c cpsFillVec $ [obj]) =<< getVar e var
-
-        cpsFillVec :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsFillVec e c vec (Just [obj]) = 
-            fillVector vec obj >>= setVar e var >>= continueEval e c 
-        cpsFillVec _ _ _ _ = throwError $ InternalError "Invalid argument to cpsFillVec" 
-
-        fillVector :: LispVal -> LispVal -> IOThrowsError LispVal
-        fillVector (Vector vec) obj = do
-          let l = replicate (lenVector vec) obj
-          return $ Vector $ (listArray (0, length l - 1)) l
-        fillVector v _ = throwError $ TypeMismatch "vector" v
-        lenVector v = length (elems v)
+eval _ _ (List [Atom "vector-set!" , nonvar , _ , _]) = throwError $ TypeMismatch "variable" nonvar 
+eval _ _ (List (Atom "vector-set!" : args)) = throwError $ NumArgs 3 args
 
 eval env cont (List [Atom "hash-table-set!", Atom var, rkey, rvalue]) = do 
   eval env (makeCPS env cont cpsValue) rkey
@@ -452,6 +426,8 @@
                   setVar env var (HashTable $ Data.Map.insert key value ht) >>= eval e c
                 other -> throwError $ TypeMismatch "hash-table" other
         cpsEvalH _ _ _ _ = throwError $ InternalError "Invalid argument to cpsEvalH"
+eval _ _ (List [Atom "hash-table-set!" , nonvar , _ , _]) = throwError $ TypeMismatch "variable" nonvar 
+eval _ _ (List (Atom "hash-table-set!" : args)) = throwError $ NumArgs 3 args
 
 eval env cont (List [Atom "hash-table-delete!", Atom var, rkey]) = do 
   eval env (makeCPS env cont cpsH) rkey
@@ -466,84 +442,12 @@
                   setVar env var (HashTable $ Data.Map.delete key ht) >>= eval e c
                 other -> throwError $ TypeMismatch "hash-table" other
         cpsEvalH _ _ _ _ = throwError $ InternalError "Invalid argument to cpsEvalH"
-
-
-eval _ _ (List [Atom "apply"]) = throwError $ BadSpecialForm "apply" $ String "Function not specified"
-eval _ _ (List [Atom "apply", _]) = throwError $ BadSpecialForm "apply" $ String "Arguments not specified"
-eval env cont (List (Atom "apply" : applyArgs)) = do
-  eval env (makeCPSWArgs env cont cpsLast $ [List applyArgs]) $ head applyArgs
-  where cpsLast :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsLast e c proc (Just [List args]) = 
-          eval e (makeCPSWArgs e c cpsArgs $ [proc, List $ tail $ reverse $ tail $ reverse args]) $ head $ reverse args 
-        cpsLast _ _ _ _ = throwError $ InternalError "Invalid arguments to cpsLast"
-
-        cpsArgs :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsArgs e c lst (Just [proc, List args]) =
-          case args of
-            [] -> cpsApply c (Just [proc, lst, List args])
-            _ -> eval e (makeCPSWArgs e c cpsEvalArgs $ [proc, lst, List $ tail args, List []]) $ head args
-        cpsArgs _ _ _ _ = throwError $ InternalError "Invalid arguments to cpsArgs"
-
-        cpsEvalArgs :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsEvalArgs e c result (Just [proc, lst, List args, List evaledArgs]) =
-          case args of
-            [] -> cpsApply c (Just [proc, lst, List (evaledArgs ++ [result])])
-            (x:xs) -> eval e (makeCPSWArgs e c cpsEvalArgs $ [proc, lst, List xs, List (evaledArgs ++ [result])]) x
-        cpsEvalArgs _ _ _ _ = throwError $ InternalError "Invalid arguments to cpsEvalArgs"
-
-        cpsApply :: LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-        cpsApply c (Just [proc, lst, List argVals]) = do 
-          case lst of
-            List l -> apply c proc (argVals ++ l)
-            other -> throwError $ TypeMismatch "list" other
-        cpsApply _ _ = throwError $ InternalError "Invalid arguments to cpsApply"
-
--- 
---
--- FUTURE: Issue #2: support for other continuation-related functions, such as
--- (dynamic-wind)
---
---
-
-eval env cont (List [Atom "call-with-values", producer, consumer]) = do
--- TODO: validate that producer and consumer are functions
-  eval env
-  -- TODO: problem is that this continuation will not be called into by (values), rather
-  --       one of the conts inside producer will be called instead...
-      (Continuation env (Just (HaskellBody cpsEval Nothing)) (Just cont) True) -- Multiple Values
-      (List [producer]) -- Call into prod to get values
- where
-   cpsEval :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-   cpsEval e c (List values) _ = do
-        -- should handle if multiple values are passed...
-        eval e c $ List $ [consumer] ++ values --List [consumer , value]
--- should not need the following case??
-   cpsEval e c value _ = eval e c $ List [consumer, value]
-    --throwError $ Default $ "Unexpected error in call-with-values, value = " ++ show value
-eval _ _ (List (Atom "call-with-values" : _)) = throwError $ Default "Procedures not specified"
+eval _ _ (List [Atom "hash-table-delete!" , nonvar , _]) = throwError $ TypeMismatch "variable" nonvar 
+eval _ _ (List (Atom "hash-table-delete!" : args)) = throwError $ NumArgs 2 args
 
-eval env cont (List (Atom "call-with-current-continuation" : args)) = 
-  eval env cont (List (Atom "call/cc" : args))
-eval _ _ (List [Atom "call/cc"]) = throwError $ Default "Procedure not specified"
-eval e c (List [Atom "call/cc", proc]) = eval e (makeCPS e c cpsEval) proc
- where
-   cpsEval :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
-   cpsEval _ cont func _ = 
-      case func of
-        PrimitiveFunc f -> do
-            result <- liftThrows $ f [cont]
-            case cont of 
-                Continuation cEnv _ _ _ -> continueEval cEnv cont result
-                _ -> return result
-        Func aparams _ _ _ ->
-          if (toInteger $ length aparams) == 1 
-            then apply cont func [cont] 
-            else throwError $ NumArgs (toInteger $ length aparams) [cont] 
-        other -> throwError $ TypeMismatch "procedure" other
-     
 -- Call a function by evaluating its arguments and then 
 -- executing it via 'apply'.
-eval env cont (List (function : functionArgs)) = do 
+eval env cont (List (function : functionArgs)) = do
   eval env (makeCPSWArgs env cont cpsPrepArgs $ functionArgs) function
  where cpsPrepArgs :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
        cpsPrepArgs e c func (Just args) = 
@@ -588,31 +492,34 @@
 
 -- Call into a Scheme function
 apply :: LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
-apply _ c@(Continuation env _ _ multipleValues) args = do
-  if multipleValues
-    then continueEval env c $ List args
-    else
-      if (toInteger $ length args) /= 1 
-        then throwError $ NumArgs 1 args
-        else continueEval env c $ head args
-
--- TODO: Think about wrapping the result into a new LispVal "multipleValues" that
--- will be returned in len(args) > 1. this var would then only be used by the call-with-values
--- continuation. otherwise it would eventually throw an error... is that feasible?
-
-{-        -- Hack: just pass all of the args along.
-        -- Assumption is that a multi-value continuation will eventually appear to accept this.
-        -- Really need a better solution, because this breaks other cont code...
-        continueEval env c $ List args -- TODO - testing: head args -}
+apply _ cont@(Continuation env ccont ncont _ ndynwind) args = do
+--  case (trace ("calling into continuation. dynWind = " ++ show ndynwind) ndynwind) of
+  case ndynwind of
+    -- Call into dynWind.before if it exists...
+    Just ([DynamicWinders beforeFunc _]) -> apply (makeCPS env cont cpsApply) beforeFunc []
+    _ ->  doApply env cont
+ where
+   cpsApply :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
+   cpsApply e c _ _ = doApply e c
+   doApply e c = 
+      case (toInteger $ length args) of 
+        0 -> throwError $ NumArgs 1 [] 
+        1 -> continueEval e c $ head args
+        _ ->  -- Pass along additional arguments, so they are available to (call-with-values)
+             continueEval e (Continuation env ccont ncont (Just $ tail args) ndynwind) $ head args 
 apply cont (IOFunc func) args = do
   result <- func args
   case cont of
-    Continuation cEnv _ _ _ -> continueEval cEnv cont result
+    Continuation cEnv _ _ _ _ -> continueEval cEnv cont result
     _ -> return result
+apply cont (EvalFunc func) args = do
+    -- An EvalFunc extends the evaluator so it needs access to the current continuation;
+    -- pass it as the first argument.
+    func (cont : args)
 apply cont (PrimitiveFunc func) args = do
   result <- liftThrows $ func args
   case cont of
-    Continuation cEnv _  _ _ -> continueEval cEnv cont result
+    Continuation cEnv _ _ _ _ -> continueEval cEnv cont result
     _ -> return result
 apply cont (Func aparams avarargs abody aclosure) args =
   if num aparams /= num args && avarargs == Nothing
@@ -633,14 +540,16 @@
         -- See: http://icem-www.folkwang-hochschule.de/~finnendahl/cm_kurse/doc/schintro/schintro_142.html#SEC294
         --
         evalBody evBody env = case cont of
-            Continuation _ (Just (SchemeBody cBody)) (Just cCont) _ -> if length cBody == 0
-                then continueWCont env (evBody) cCont
-                else continueWCont env (evBody) cont -- Might be a problem, not fully optimizing
-            _ -> continueWCont env (evBody) cont
+            Continuation _ (Just (SchemeBody cBody)) (Just cCont) _ cDynWind -> if length cBody == 0
+                then continueWCont env (evBody) cCont cDynWind
+--                else continueWCont env (evBody) cont (trace ("cDynWind = " ++ show cDynWind) cDynWind) -- Might be a problem, not fully optimizing
+                else continueWCont env (evBody) cont cDynWind -- Might be a problem, not fully optimizing
+            Continuation _ _ _ _ cDynWind -> continueWCont env (evBody) cont cDynWind
+            _ -> continueWCont env (evBody) cont Nothing 
 
         -- Shortcut for calling continueEval
-        continueWCont cwcEnv cwcBody cwcCont = 
-            continueEval cwcEnv (Continuation cwcEnv (Just (SchemeBody cwcBody)) (Just cwcCont) False) $ Nil ""
+        continueWCont cwcEnv cwcBody cwcCont cwcDynWind = 
+            continueEval cwcEnv (Continuation cwcEnv (Just (SchemeBody cwcBody)) (Just cwcCont) Nothing cwcDynWind) $ Nil ""
 
         bindVarArgs arg env = case arg of
           Just argName -> liftIO $ extendEnv env [((varNamespace, argName), List $ remainingArgs)]
@@ -652,9 +561,107 @@
 --  in the standard library which must be pulled into the environment using (load).
 primitiveBindings :: IO Env
 primitiveBindings = nullEnv >>= (flip extendEnv $ map (domakeFunc IOFunc) ioPrimitives
-                                              ++ map (domakeFunc PrimitiveFunc) primitives)
+                                               ++ map (domakeFunc EvalFunc) evalFunctions
+                                               ++ map (domakeFunc PrimitiveFunc) primitives)
   where domakeFunc constructor (var, func) = ((varNamespace, var), constructor func)
 
+-- Functions that extend the core evaluator, but that can be defined separately.
+--
+-- These functions have access to the current environment via the
+-- current continuation, which is passed as the first LispVal argument.
+--
+evalFunctions :: [(String, [LispVal] -> IOThrowsError LispVal)]
+evalFunctions = [
+                    ("apply", evalfuncApply)
+                  , ("call-with-current-continuation", evalfuncCallCC)
+                  , ("call-with-values", evalfuncCallWValues)
+                  , ("dynamic-wind", evalfuncDynamicWind)
+                  , ("eval", evalfuncEval)
+                  , ("load", evalfuncLoad)
+                ]
+evalfuncApply, evalfuncDynamicWind, evalfuncEval, evalfuncLoad, evalfuncCallCC, evalfuncCallWValues :: [LispVal] -> IOThrowsError LispVal
+
+-- A (somewhat) simplified implementation of dynamic-wind
+--
+-- The implementation must obey these 4 rules:
+--
+-- 1) The dynamic extent is entered when execution of the body of the called procedure begins.
+-- 2) The dynamic extent is also entered when execution is not within the dynamic extent and a continuation is invoked that was captured (using call-with-current-continuation) during the dynamic extent.
+-- 3) It is exited when the called procedure returns.
+-- 4) It is also exited when execution is within the dynamic extent and a continuation is invoked that was captured while not within the dynamic extent.
+--
+-- Basically (before) must be called either when thunk is called into, or when a continuation captured 
+-- during (thunk) is called into.
+-- And (after) must be called either when thunk returns *or* a continuation is called into during (thunk).
+--
+-- FUTURE:
+-- A this point dynamic-wind works well enough now to pass all tests, although I am not convinced the implementation
+-- is 100% correct since a stack is not directly used to hold the winders. I think there must still be edge
+-- cases that are not handled properly...
+--
+evalfuncDynamicWind [cont@(Continuation env _ _ _ _), beforeFunc, thunkFunc, afterFunc] = do 
+  apply (makeCPS env cont cpsThunk) beforeFunc []
+ where
+   cpsThunk, cpsAfter :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
+   cpsThunk e (Continuation ce cc cnc ca _ {- FUTURE: cwindrz -} ) _ _ = apply (Continuation e (Just (HaskellBody cpsAfter Nothing)) 
+                                            (Just (Continuation ce cc cnc ca
+                                                                Nothing)) 
+                                             Nothing 
+                                             (Just ([DynamicWinders beforeFunc afterFunc]))) -- FUTURE: append if existing winders
+                               thunkFunc []
+   cpsThunk _ _ _ _ = throwError $ Default "Unexpected error in cpsThunk during (dynamic-wind)" 
+   cpsAfter _ c _ _ = apply c afterFunc [] -- FUTURE: remove dynamicWinder from above from the list before calling after
+evalfuncDynamicWind (_ : args) = throwError $ NumArgs 3 args -- Skip over continuation argument
+evalfuncDynamicWind _ = throwError $ NumArgs 3 []
+
+evalfuncCallWValues [cont@(Continuation env _ _ _ _), producer, consumer] = do 
+  apply (makeCPS env cont cpsEval) producer [] -- Call into prod to get values
+ where
+   cpsEval :: Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal
+   cpsEval _ c@(Continuation _ _ _ (Just xargs) _) value _ = apply c consumer (value : xargs)
+   cpsEval _ c value _ = apply c consumer [value]
+evalfuncCallWValues (_ : args) = throwError $ NumArgs 2 args -- Skip over continuation argument
+evalfuncCallWValues _ = throwError $ NumArgs 2 []
+
+evalfuncApply [cont@(Continuation _ _ _ _ _), func, List args] = apply cont func args
+evalfuncApply (_ : args) = throwError $ NumArgs 2 args -- Skip over continuation argument
+evalfuncApply _ = throwError $ NumArgs 2 []
+
+evalfuncLoad [cont@(Continuation env _ _ _ _), String filename] = do
+     result <- load filename >>= liftM last . mapM (evaluate env (makeNullContinuation env))
+     continueEval env cont result
+	 where evaluate env2 cont2 val2 = macroEval env2 val2 >>= eval env2 cont2
+evalfuncLoad (_ : args) = throwError $ NumArgs 1 args -- Skip over continuation argument
+evalfuncLoad _ = throwError $ NumArgs 1 []
+
+-- Evaluate an expression in the current environment
+--
+-- Assumption is any macro transform is already performed
+-- prior to this step.
+--
+-- FUTURE: consider allowing env to be specified, per R5RS
+--
+evalfuncEval [cont@(Continuation env _ _ _ _), val] = eval env cont val
+evalfuncEval (_ : args) = throwError $ NumArgs 1 args -- Skip over continuation argument
+evalfuncEval _ = throwError $ NumArgs 1 []
+
+evalfuncCallCC [cont@(Continuation _ _ _ _ _), func] = do
+   case func of
+     PrimitiveFunc f -> do
+         result <- liftThrows $ f [cont]
+         case cont of 
+             Continuation cEnv _ _ _ _ -> continueEval cEnv cont result
+             _ -> return result
+     Func aparams _ _ _ ->
+       if (toInteger $ length aparams) == 1 
+         then apply cont func [cont] 
+         else throwError $ NumArgs (toInteger $ length aparams) [cont] 
+     other -> throwError $ TypeMismatch "procedure" other
+evalfuncCallCC (_ : args) = throwError $ NumArgs 1 args -- Skip over continuation argument
+evalfuncCallCC _ = throwError $ NumArgs 1 []
+
+-- I/O primitives
+-- Primitive functions that execute within the IO monad
 ioPrimitives :: [(String, [LispVal] -> IOThrowsError LispVal)]
 ioPrimitives = [("open-input-file", makePort ReadMode),
                 ("open-output-file", makePort WriteMode),
@@ -673,7 +680,7 @@
                --  Consideration may be given in a future release, but keep in mind
                --  the impact to the other I/O functions.
 
--- TODO: not currently supported: char-ready?
+-- FUTURE: not currently supported: char-ready?
 
                 ("current-input-port", currentInputPort),
                 ("current-output-port", currentOutputPort),
@@ -682,7 +689,9 @@
                 ("peek-char", readCharProc hLookAhead),
                 ("write", writeProc (\port obj -> hPrint port obj)),
                 ("write-char", writeCharProc),
-                ("display", writeProc (\port obj -> hPutStr port $ show obj)),
+                ("display", writeProc (\port obj -> case obj of
+                                                        String str -> hPutStr port str
+                                                        _ -> hPutStr port $ show obj)),
                 ("read-contents", readContents),
                 ("read-all", readAll)]
 
@@ -1159,10 +1168,11 @@
 isDottedList _ = return $  Bool False
 
 isProcedure :: [LispVal] -> ThrowsError LispVal
-isProcedure ([Continuation _ _ _ _]) = return $ Bool True
+isProcedure ([Continuation _ _ _ _ _]) = return $ Bool True
 isProcedure ([PrimitiveFunc _]) = return $ Bool True
 isProcedure ([Func _ _ _ _]) = return $ Bool True
 isProcedure ([IOFunc _]) = return $ Bool True
+isProcedure ([EvalFunc _]) = return $ Bool True
 isProcedure _ = return $ Bool False
 
 isVector, isList :: LispVal -> ThrowsError LispVal
diff --git a/hs-src/Language/Scheme/Numerical.hs b/hs-src/Language/Scheme/Numerical.hs
--- a/hs-src/Language/Scheme/Numerical.hs
+++ b/hs-src/Language/Scheme/Numerical.hs
@@ -71,11 +71,14 @@
 numDiv [Float n] = return $ Float $ 1.0 / n
 numDiv [Rational n] = return $ Rational $ 1 / n
 numDiv [Complex n] = return $ Complex $ 1 / n
-numDiv aparams = do -- FUTURE: for Number type, consider casting results to Rational, per R5RS spec 
+numDiv aparams = do 
   foldl1M (\a b -> doDiv =<< (numCast [a, b])) aparams
   where doDiv (List [(Number a), (Number b)]) = if b == 0 
                                                    then throwError $ DivideByZero 
-                                                   else return $ Number $ div a b
+                                                   else if (mod a b) == 0 
+                                                           then return $ Number $ div a b
+                                                           -- Convert to a rational if the result is not an integer
+                                                           else return $ Rational $ (fromInteger a) / (fromInteger b)
         doDiv (List [(Float a), (Float b)]) = if b == 0.0 
                                                    then throwError $ DivideByZero 
                                                    else return $ Float $ a / b
diff --git a/hs-src/Language/Scheme/Parser.hs b/hs-src/Language/Scheme/Parser.hs
--- a/hs-src/Language/Scheme/Parser.hs
+++ b/hs-src/Language/Scheme/Parser.hs
@@ -138,15 +138,17 @@
 
 parseComplexNumber :: Parser LispVal
 parseComplexNumber = do
-  lispreal <- (try(parseRealNumber) <|> parseDecimalNumber)
+  lispreal <- (try (parseRealNumber) <|> try(parseRationalNumber) <|> parseDecimalNumber)
   let real = case lispreal of
                   Number n -> fromInteger n
+                  Rational r -> fromRational r
                   Float f -> f
                   _ -> 0
   char '+'
-  lispimag <- (try(parseRealNumber) <|> parseDecimalNumber)
+  lispimag <- (try(parseRealNumber) <|> try(parseRationalNumber) <|> parseDecimalNumber)
   let imag = case lispimag of
                   Number n -> fromInteger n
+                  Rational r -> fromRational r
                   Float f -> f
                   _ -> 0 -- Case should never be reached
   char 'i'
@@ -222,8 +224,8 @@
 
 parseExpr :: Parser LispVal
 parseExpr = 
-      try(parseRationalNumber)
-  <|> try(parseComplexNumber)
+      try(parseComplexNumber)
+  <|> try(parseRationalNumber)
   <|> parseComment
   <|> try(parseRealNumber)
   <|> try(parseNumber)
diff --git a/hs-src/Language/Scheme/Types.hs b/hs-src/Language/Scheme/Types.hs
--- a/hs-src/Language/Scheme/Types.hs
+++ b/hs-src/Language/Scheme/Types.hs
@@ -122,7 +122,7 @@
 	| Bool Bool
           -- ^Boolean
 	| PrimitiveFunc ([LispVal] -> ThrowsError LispVal)
-          -- ^
+          -- ^Primitive function
 	| Func {params :: [String], 
  	        vararg :: (Maybe String),
 	        body :: [LispVal], 
@@ -130,14 +130,17 @@
  	       }
           -- ^Function
 	| IOFunc ([LispVal] -> IOThrowsError LispVal)
-         -- ^
+         -- ^Primitive function within the IO monad
+	| EvalFunc ([LispVal] -> IOThrowsError LispVal)
+         -- ^Function within the IO monad with access to 
+         --  the current environment and continuation.
 	| Port Handle
          -- ^I/O port
-	| Continuation {  closure :: Env                     -- Environment of the continuation
-                        , currentCont :: (Maybe DeferredCode)-- Code of current continuation
-                        , nextCont    :: (Maybe LispVal)     -- Code to resume after body of cont
-                        , multipleArgs :: Bool
-                        -- FUTURE: stack (for dynamic wind)
+	| Continuation {  closure :: Env                       -- Environment of the continuation
+                        , currentCont :: (Maybe DeferredCode)  -- Code of current continuation
+                        , nextCont    :: (Maybe LispVal)       -- Code to resume after body of cont
+                        , extraReturnArgs :: (Maybe [LispVal]) -- Extra return arguments, to support (values) and (call-with-values)
+                        , dynamicWind :: (Maybe [DynamicWinders]) -- Functions injected by (dynamic-wind) 
                        }
          -- ^Continuation
  	| EOF
@@ -152,17 +155,30 @@
      , contFunctionArgs :: (Maybe [LispVal]) -- Arguments to the higher-order function 
     } -- ^A Haskell function
 
+-- |Container to store information from a dynamic-wind
+data DynamicWinders = DynamicWinders {
+    before :: LispVal -- ^Function to execute when resuming continuation within extent of dynamic-wind
+  , after :: LispVal -- ^Function to execute when leaving extent of dynamic-wind
+}
+
+showDWVal :: DynamicWinders -> String
+showDWVal (DynamicWinders b a) = "(" ++ (show b) ++ " . " ++ (show a) ++ ")"
+
+instance Show DynamicWinders where show = showDWVal
+
 -- Make an "empty" continuation that does not contain any code
 makeNullContinuation :: Env -> LispVal
-makeNullContinuation env = Continuation env Nothing Nothing False
+makeNullContinuation env = Continuation env Nothing Nothing Nothing Nothing 
 
 -- Make a continuation that takes a higher-order function (written in Haskell)
 makeCPS :: Env -> LispVal -> (Env -> LispVal -> LispVal -> Maybe [LispVal]-> IOThrowsError LispVal) -> LispVal
-makeCPS env cont cps = Continuation env (Just (HaskellBody cps Nothing)) (Just cont) False
+makeCPS env cont@(Continuation _ _ _ _ dynWind) cps = Continuation env (Just (HaskellBody cps Nothing)) (Just cont) Nothing dynWind
+makeCPS env cont cps = Continuation env (Just (HaskellBody cps Nothing)) (Just cont) Nothing Nothing -- This overload just here for completeness; it should never be used 
 
 -- Make a continuation that stores a higher-order function and arguments to that function
 makeCPSWArgs :: Env -> LispVal -> (Env -> LispVal -> LispVal -> Maybe [LispVal] -> IOThrowsError LispVal) -> [LispVal] -> LispVal
-makeCPSWArgs env cont cps args = Continuation env (Just (HaskellBody cps (Just args))) (Just cont) False
+makeCPSWArgs env cont@(Continuation _ _ _ _ dynWind) cps args = Continuation env (Just (HaskellBody cps (Just args))) (Just cont) Nothing dynWind
+makeCPSWArgs env cont cps args = Continuation env (Just (HaskellBody cps (Just args))) (Just cont) Nothing Nothing -- This overload just here for completeness; it should never be used 
 
 instance Ord LispVal where
   compare (Bool a) (Bool b) = compare a b
@@ -237,7 +253,7 @@
 showVal (List contents) = "(" ++ unwordsList contents ++ ")"
 showVal (DottedList h t) = "(" ++ unwordsList h ++ " . " ++ showVal t ++ ")"
 showVal (PrimitiveFunc _) = "<primitive>"
-showVal (Continuation _ _ _ _) = "<continuation>"
+showVal (Continuation _ _ _ _ _) = "<continuation>"
 showVal (Func {params = args, vararg = varargs, body = _, closure = _}) = 
   "(lambda (" ++ unwords (map show args) ++
     (case varargs of
@@ -245,6 +261,7 @@
       Just arg -> " . " ++ arg) ++ ") ...)"
 showVal (Port _) = "<IO port>"
 showVal (IOFunc _) = "<IO primitive>"
+showVal (EvalFunc _) = "<procedure>"
 
 unwordsList :: [LispVal] -> String
 unwordsList = unwords . map showVal
diff --git a/hs-src/Language/Scheme/Variables.hs b/hs-src/Language/Scheme/Variables.hs
--- a/hs-src/Language/Scheme/Variables.hs
+++ b/hs-src/Language/Scheme/Variables.hs
@@ -14,12 +14,10 @@
 
 -- |Extend given environment by binding a series of values to a new environment.
 extendEnv :: Env -> [((String, String), LispVal)] -> IO Env
-extendEnv envRef bindings = do bindinglist <- mapM (\((namespace, name), val) ->
-                                                    do ref <- newIORef val
-                                                       return ((namespace, name), ref)) bindings
-                                              >>= newIORef
-                               return $ Environment (Just envRef) bindinglist
-
+extendEnv envRef abindings = do bindinglist <- mapM addBinding abindings >>= newIORef
+                                return $ Environment (Just envRef) bindinglist
+ where addBinding ((namespace, name), val) = do ref <- newIORef val
+                                                return ((namespace, name), ref)
 {-
 -- Old implementation, left for the moment for reference purposes only:
 --
diff --git a/hs-src/shell.hs b/hs-src/shell.hs
--- a/hs-src/shell.hs
+++ b/hs-src/shell.hs
@@ -41,14 +41,14 @@
   env <- primitiveBindings >>= flip extendEnv [((varNamespace, "args"), List $ map String $ drop 1 args)]
   evalString env $ "(load \"" ++ stdlib ++ "\")" -- Load standard library
   (runIOThrows $ liftM show $ evalLisp env (List [Atom "load", String (args !! 0)]))
-     >>= hPutStrLn nullIO
+     >>= hPutStr nullIO
 
   -- Call into (main) if it exists...
   alreadyDefined <- liftIO $ isBound env "main"
   let argv = List $ map String $ args
   if alreadyDefined
-     then (runIOThrows $ liftM show $ evalLisp env (List [Atom "main", List [Atom "quote", argv]])) >>= hPutStrLn stderr
-     else (runIOThrows $ liftM show $ evalLisp env (Nil "")) >>= hPutStrLn stderr
+     then (runIOThrows $ liftM show $ evalLisp env (List [Atom "main", List [Atom "quote", argv]])) >>= hPutStr stderr
+     else (runIOThrows $ liftM show $ evalLisp env (Nil "")) >>= hPutStr stderr
 
 showBanner :: IO ()
 showBanner = do
@@ -59,7 +59,7 @@
   putStrLn " | | | | |_| \\__ \\   <    /// \\\\\\   \\__ \\ (__| | | |  __/ | | | | |  __/ "
   putStrLn " |_| |_|\\__,_|___/_|\\_\\  ///   \\\\\\  |___/\\___|_| |_|\\___|_| |_| |_|\\___| "
   putStrLn "                                                                         "
-  putStrLn " husk Scheme Interpreter                                     Version 2.3 "
+  putStrLn " husk Scheme Interpreter                                     Version 2.4 "
   putStrLn " (c) 2010-2011 Justin Ethier         github.com/justinethier/husk-scheme "
   putStrLn "                                                                         "
 
diff --git a/husk-scheme.cabal b/husk-scheme.cabal
--- a/husk-scheme.cabal
+++ b/husk-scheme.cabal
@@ -1,23 +1,9 @@
 Name:                husk-scheme
-Version:             2.3
+Version:             2.4
 Synopsis:            R5RS Scheme interpreter program and library.
-Description:         Husk is a dialect of Scheme written in Haskell that implements 
-                     a subset of the R5RS standard. Advanced R5RS features are
-                     provided including continuations, hygenic macros, and the
+Description:         A dialect of R5RS Scheme written in Haskell. Provides advanced 
+                     features including continuations, hygienic macros, and the
                      full numeric tower.
-                     
-                     Husk is not intended to be a highly optimized version of Scheme. 
-                     Rather, the goal of the project is to provide a tight integration 
-                     between Haskell and Scheme while at the same time providing a 
-                     great opportunity for deeper understanding of both languages. 
-                     In addition, by closely following the R5RS standard, the intent is 
-                     to develop a Scheme that is as compatible as possible with other 
-                     R5RS Schemes.
-
-                     This package includes a stand-alone executable as well as
-                     a library that allows an interpreter to be embedded within an 
-                     existing Haskell application.
-
 License:             MIT
 License-file:        LICENSE
 Author:              Justin Ethier
diff --git a/stdlib.scm b/stdlib.scm
--- a/stdlib.scm
+++ b/stdlib.scm
@@ -6,6 +6,8 @@
 ;
 ; Standard library of scheme functions
 ;
+(define call/cc call-with-current-continuation)
+
 (define (caar pair) (car (car pair)))
 (define (cadr pair) (car (cdr pair)))
 (define (cdar pair) (cdr (car pair)))
@@ -219,6 +221,20 @@
                          result))))))))
 
 ; End delayed evaluation section
+
+; String Section
+(define-syntax string-fill!
+  (syntax-rules ()
+    ((_ _str _chr)
+     (set! _str
+           (make-string (string-length _str) _chr)))))
+
+; Vector Section
+(define-syntax vector-fill!
+  (syntax-rules ()
+    ((_ _vec _fill)
+     (set! _vec
+           (make-vector (vector-length _vec) _fill)))))
 
 ; Continuation Section
 (define (values . things)
