diff --git a/backends/BackendPasses.hs b/backends/BackendPasses.hs
index d4ec94a..b6ed884 100644
--- a/backends/BackendPasses.hs
+++ b/backends/BackendPasses.hs
@@ -21,6 +21,7 @@ module BackendPasses (addSizesActualParameters, addSizesFormalParameters, declar
 
 import Control.Monad.State
 import Data.Generics
+import Data.List
 import qualified Data.Map as Map
 
 import qualified AST as A
@@ -47,6 +48,7 @@ backendPasses =
   , addSizesFormalParameters
   , addSizesActualParameters
   , fixMinInt
+  , mobileReturn
   ]
 
 prereq :: [Property]
@@ -410,3 +412,85 @@ simplifySlices = occamOnlyPass "Simplify array slices"
            return (A.SubscriptedVariable m (A.SubscriptFromFor m' check from (A.Dyadic m A.Subtr limit from)) v)
     doVariable v = return v
 
+-- | Finds all processes that have a MOBILE parameter passed in Abbrev mode, and
+-- add the communication back at the end of the process.
+mobileReturn :: Pass
+mobileReturn = cOnlyPass "Add MOBILE returns" [] [] recurse
+  where
+    ops = baseOp `extOpS` doStructured `extOp` doProcess
+
+    descend, recurse :: Data a => Transform a
+    descend = makeDescend ops
+    recurse = makeRecurse ops
+
+    ignoreProc :: A.Name -> PassM Bool
+    ignoreProc n
+      = do nd <- lookupName n
+           return $ "copy_" `isPrefixOf` A.ndOrigName nd -- Bit of a hard-hack
+
+    doProcess :: Transform A.Process
+    doProcess (A.ProcCall m n as)
+      = do sp <- specTypeOfName n
+           fs <- case sp of
+             A.Proc _ _ fs _ -> return fs
+             _ -> dieP m "PROC with unknown spec-type"
+           ig <- ignoreProc n
+           if ig
+             then return $ A.ProcCall m n as
+             else do (surr, as') <- addChansAct m $ zip fs as
+                     return $ surr $ A.ProcCall m n as'
+    doProcess p = descend p
+
+    chanT t = A.Chan (A.ChanAttributes False False) t
+
+    addChansAct :: Meta -> [(A.Formal, A.Actual)] -> PassM (A.Process -> A.Process, [A.Actual])
+    addChansAct _ [] = return (id, [])
+    addChansAct m ((A.Formal am t n, a):fas)
+      = do isMobile <- isMobileType t
+           (recF, recAS) <- addChansAct m fas
+           case (am, isMobile) of
+             (A.Abbrev, True)
+               -> do sp@(A.Specification _ c _) <- defineNonce m (A.nameName n)
+                       (A.Declaration m $ chanT t) A.Original
+                     let av = getV a
+                     return (\p -> A.Seq m $ A.Spec m sp $ A.Several m
+                               [A.Only m (recF p)
+                               ,A.Only m $ A.Input m (A.Variable m c) $
+                                 A.InputSimple m [A.InVariable m av]]
+                            , a : A.ActualVariable (A.Variable m c) : recAS)
+             _ -> return (recF, a : recAS)
+
+    getV (A.ActualVariable v) = v
+    getV (A.ActualExpression (A.ExprVariable _ v)) = v
+
+    addChansForm :: Meta -> [A.Formal] -> PassM ([A.Process], [A.Formal])
+    addChansForm _ [] = return ([], [])
+    addChansForm m (f@(A.Formal am t n):fs)
+      = do (ps, fs') <- addChansForm m fs
+           isMobile <- isMobileType t
+           case (am, isMobile) of
+             (A.Abbrev, True)
+               -> do A.Specification _ c _ <- defineNonce m (A.nameName n)
+                       (A.Declaration m $ chanT t) A.Abbrev
+                     modifyName n $ \nd -> nd {A.ndAbbrevMode = A.Original}
+                     return ( ps ++ [A.Output m (A.Variable m c)
+                                      [A.OutExpression m
+                                         $ A.ExprVariable m $ A.Variable m n]]
+                            , A.Formal A.Original t n : A.Formal A.Abbrev (chanT t) c : fs')
+             _ -> return (ps, f : fs')
+
+    doStructured :: Data a => Transform (A.Structured a)
+    doStructured s@(A.Spec msp (A.Specification m n (A.Proc m' sm fs pr)) scope)
+      = do pr' <- recurse pr
+           -- We do the scope first, so that all the callers are updated before
+           -- we fix our state:
+           scope' <- recurse scope
+           ig <- ignoreProc n
+           if ig
+             then return $ A.Spec msp (A.Specification m n (A.Proc m' sm fs pr')) scope'
+             else do (ps, fs') <- addChansForm m fs
+                     let newSpec = A.Proc m' sm fs' (A.Seq m' $ A.Several m' $
+                                            map (A.Only m') $ pr' : ps)
+                     modifyName n (\nd -> nd {A.ndSpecType = newSpec})
+                     return $ A.Spec msp (A.Specification m n newSpec) scope'
+    doStructured s = descend s
diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs
index 22a2da7..61151a6 100644
--- a/backends/GenerateC.hs
+++ b/backends/GenerateC.hs
@@ -280,11 +280,12 @@ cgenOverArray m var func
             Nothing -> return ()
 
 -- | Generate code for one of the Structured types.
-cgenStructured :: Data a => A.Structured a -> (Meta -> a -> CGen ()) -> CGen ()
+cgenStructured :: Data a => A.Structured a -> (Meta -> a -> CGen b) -> CGen [b]
 cgenStructured (A.Spec _ spec s) def = call genSpec spec (call genStructured s def)
 cgenStructured (A.ProcThen _ p s) def = call genProcess p >> call genStructured s def
-cgenStructured (A.Several _ ss) def = sequence_ [call genStructured s def | s <- ss]
-cgenStructured (A.Only m s) def = def m s
+cgenStructured (A.Several _ ss) def
+  = sequence [call genStructured s def | s <- ss] >>* concat
+cgenStructured (A.Only m s) def = def m s >>* singleton
 
 --}}}
 
@@ -630,7 +631,7 @@ cgenVariableWithAM checkValid v am fct
        t <- astTypeOf v
        ct <- call getCType m t am >>* fct
        -- Temporary, for debugging:
-       tell ["/* ", show (snd iv), " , ", show ct, " */"]
+       tell ["/* ", show (snd iv), " , trying to get: ", show ct, " */"]
        dressUp m iv ct
   where
     m = findMeta v
@@ -1037,7 +1038,7 @@ cgenInputItem c (A.InVariable m v)
               do call genClearMobile m v -- TODO insert this via a pass
                  tell ["MTChanIn(wptr,"]
                  genChan c
-                 tell [",(void*)"]
+                 tell [",(void**)"]
                  rhs
                  tell [");"]
             _ ->
@@ -1079,7 +1080,7 @@ cgenOutputItem innerT c (A.OutExpression m e)
               do tell ["MTChanOut(wptr,"]
                  genChan c
                  tell [",(void*)"]
-                 call genVariable v A.Abbrev
+                 call genVariable' v A.Original Pointer
                  tell [");"]
             (_, _, A.ExprVariable _ v) ->
               do tell ["ChanOut(wptr,"]
@@ -1160,11 +1161,12 @@ abbrevExpression am _ e = call genExpression e
 --}}}
 
 --{{{  specifications
-cgenSpec :: A.Specification -> CGen () -> CGen ()
+cgenSpec :: A.Specification -> CGen b -> CGen b
 cgenSpec spec body
     =  do call introduceSpec spec
-          body
+          x <- body
           call removeSpec spec
+          return x
 
 -- | Generate a declaration of a new variable.
 cgenDeclaration :: A.Type -> A.Name -> Bool -> CGen ()
@@ -1438,15 +1440,15 @@ cgenActuals :: [A.Formal] -> [A.Actual] -> CGen ()
 cgenActuals fs as = prefixComma [call genActual f a | (f, a) <- zip fs as]
 
 cgenActual :: A.Formal -> A.Actual -> CGen ()
-cgenActual f a = seqComma $ realActuals f a
+cgenActual f a = seqComma $ realActuals f a id
 
 -- | Return generators for all the real actuals corresponding to a single
 -- actual.
-realActuals :: A.Formal -> A.Actual -> [CGen ()]
-realActuals _ (A.ActualExpression e)
+realActuals :: A.Formal -> A.Actual -> (CType -> CType) -> [CGen ()]
+realActuals _ (A.ActualExpression e) _
     = [call genExpression e]
-realActuals (A.Formal am _ _) (A.ActualVariable v)
-    = [call genVariable v am]
+realActuals (A.Formal am _ _) (A.ActualVariable v) fct
+    = [call genVariable' v am fct]
 
 -- | Return (type, name) generator pairs for all the real formals corresponding
 -- to a single formal.
@@ -1508,17 +1510,24 @@ genProcSpec n (A.Proc _ (sm, _) fs p) forwardDecl
 -- workspace pointer and the name of the function to call.
 cgenProcAlloc :: A.Name -> [A.Formal] -> [A.Actual] -> CGen (String, CGen ())
 cgenProcAlloc n fs as
-    =  do let ras = concat [realActuals f a | (f, a) <- zip fs as]
+    =  do ras <- liftM concat $ sequence
+                [do isMobile <- isMobileType t
+                    let (s, fct) = case (am, isMobile) of
+                              (A.ValAbbrev, _) -> ("ProcParam", id)
+                              (_, True) -> ("ProcMTMove", Pointer)
+                              _ -> ("ProcParam", id)
+                    return $ zip (repeat s) $ realActuals f a fct
+                | (f@(A.Formal am t _), a) <- zip fs as]
 
           ws <- csmLift $ makeNonce "workspace"
           tell ["Workspace ", ws, " = ProcAlloc (wptr, ", show $ length ras, ", "]
           genName n
           tell ["_stack_size);\n"]
 
-          sequence_ [do tell ["ProcParam (wptr, ", ws, ", ", show num, ", "]
+          sequence_ [do tell [pc, " (wptr, ", ws, ", ", show num, ", "]
                         ra
                         tell [");\n"]
-                     | (num, ra) <- zip [(0 :: Int)..] ras]
+                     | (num, (pc, ra)) <- zip [(0 :: Int)..] ras]
 
           return (ws, genName n)
 --}}}
@@ -1663,7 +1672,7 @@ cgenStop m s
 --}}}
 --{{{  seq
 cgenSeq :: A.Structured A.Process -> CGen ()
-cgenSeq s = call genStructured s doP
+cgenSeq s = call genStructured s doP >> return ()
   where
     doP _ p = call genProcess p
 --}}}
@@ -1681,7 +1690,7 @@ cgenIf m s | justOnly s = do call genStructured s doCplain
           tell [label, ":;"]
   where
     genIfBody :: String -> A.Structured A.Choice -> CGen ()
-    genIfBody label s = call genStructured s doC
+    genIfBody label s = call genStructured s doC >> return ()
       where
         doC m (A.Choice m' e p)
             = do tell ["if("]
@@ -1757,18 +1766,26 @@ cgenPar pm s
           call genExpression count
           tell [");\n"]
 
-          call genStructured s (startP bar)
+          after <- call genStructured s (startP bar)
+          mapM_ (call genProcess) after
 
           tell ["LightProcBarrierWait (wptr, &", bar, ");\n"]
-
   where
-    startP :: String -> Meta -> A.Process -> CGen ()
+    startP :: String -> Meta -> A.Process -> CGen A.Process
     startP bar _ (A.ProcCall _ n as)
         =  do (A.Proc _ _ fs _) <- specTypeOfName n
               (ws, func) <- cgenProcAlloc n fs as
               tell ["LightProcStart (wptr, &", bar, ", ", ws, ", "]
               func
               tell [");\n"]
+              return (A.Skip emptyMeta)
+    -- When we need to receive mobiles back from the processes, we need to perform
+    -- some actions after all the processes have started, but before we wait on
+    -- the barrier, so this hack collects up all such receive operations and returns
+    -- them:
+    startP bar _ (A.Seq m s)
+      = call genStructured s (startP bar) >>* (A.Seq m . A.Several m . map (A.Only m))
+    startP _ _ p = return p
 --}}}
 --{{{  alt
 cgenAlt :: Bool -> A.Structured A.Alternative -> CGen ()
@@ -1809,7 +1826,7 @@ cgenAlt isPri s
     containsTimers (A.Several _ ss) = or $ map containsTimers ss
 
     genAltEnable :: String -> A.Structured A.Alternative -> CGen ()
-    genAltEnable id s = call genStructured s doA
+    genAltEnable id s = call genStructured s doA >> return ()
       where
         doA _ alt
             = case alt of
@@ -1829,7 +1846,7 @@ cgenAlt isPri s
                         tell [");\n"]
 
     genAltDisable :: String -> A.Structured A.Alternative -> CGen ()
-    genAltDisable id s = call genStructured s doA
+    genAltDisable id s = call genStructured s doA >> return ()
       where
         doA _ alt
             = case alt of
@@ -1849,7 +1866,7 @@ cgenAlt isPri s
                         tell [");\n"]
 
     genAltProcesses :: String -> String -> String -> A.Structured A.Alternative -> CGen ()
-    genAltProcesses id fired label s = call genStructured s doA
+    genAltProcesses id fired label s = call genStructured s doA >> return ()
       where
         doA _ alt
             = case alt of
diff --git a/backends/GenerateCBased.hs b/backends/GenerateCBased.hs
index 0a2c7a7..dd6bbea 100644
--- a/backends/GenerateCBased.hs
+++ b/backends/GenerateCBased.hs
@@ -167,11 +167,11 @@ data GenOps = GenOps {
     genSimpleDyadic :: String -> A.Expression -> A.Expression -> CGen (),
     genSimpleMonadic :: String -> A.Expression -> CGen (),
     genSizeSuffix :: String -> CGen (),
-    genSpec :: A.Specification -> CGen () -> CGen (),
+    genSpec :: forall b. A.Specification -> CGen b -> CGen b,
     genSpecMode :: A.SpecMode -> CGen (),
     -- | Generates a STOP process that uses the given Meta tag and message as its printed message.
     genStop :: Meta -> String -> CGen (),
-    genStructured :: forall a. Data a => A.Structured a -> (Meta -> a -> CGen ()) -> CGen (),
+    genStructured :: forall a b. Data a => A.Structured a -> (Meta -> a -> CGen b) -> CGen [b],
     genTimerRead :: A.Variable -> A.Variable -> CGen (),
     genTimerWait :: A.Expression -> CGen (),
     genTopLevel :: A.AST -> CGen (),
diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs
index c9cb2b7..a285a0e 100644
--- a/backends/GenerateCPPCSP.hs
+++ b/backends/GenerateCPPCSP.hs
@@ -421,7 +421,7 @@ cppgenAlt _ s
   where
     --This function is like the enable function in GenerateC, but this one merely builds a list of guards.  It does not do anything other than add to the guard list
     initAltGuards :: String -> A.Structured A.Alternative -> CGen ()
-    initAltGuards guardList s = call genStructured s doA
+    initAltGuards guardList s = call genStructured s doA >> return ()
       where
         doA  _ alt
             = case alt of
@@ -442,7 +442,7 @@ cppgenAlt _ s
     -- This is the same as GenerateC for now -- but it's not really reusable
     -- because it's so closely tied to how ALT is implemented in the backend.
     genAltProcesses :: String -> String -> String -> A.Structured A.Alternative -> CGen ()
-    genAltProcesses id fired label s = call genStructured s doA
+    genAltProcesses id fired label s = call genStructured s doA >> return ()
       where
         doA _ alt
             = case alt of
@@ -776,7 +776,7 @@ cppgenIf m s | justOnly s = do call genStructured s doCplain
           tell ["}catch(",ifExc,"){}"]
   where
     genIfBody :: String -> A.Structured A.Choice -> CGen ()
-    genIfBody ifExc s = call genStructured s doC
+    genIfBody ifExc s = call genStructured s doC >> return ()
       where
         doC m (A.Choice m' e p)
             = do tell ["if("]