diff --git a/camfort.cabal b/camfort.cabal
--- a/camfort.cabal
+++ b/camfort.cabal
@@ -1,5 +1,5 @@
 name:                   camfort
-version:                0.903
+version:                0.904
 synopsis:               CamFort - Cambridge Fortran infrastructure
 description:            CamFort is a tool for the analysis, transformation, verification of Fortran code.
 homepage:               https://camfort.github.io
@@ -28,71 +28,10 @@
   location: https://github.com/camfort/camfort
 
 executable camfort
-  main-is: Main.hs
-  hs-source-dirs:       src
-  other-modules:        Camfort.Analysis.Annotations
-                        Camfort.Analysis.CommentAnnotator
-                        Camfort.Analysis.Simple
-                        Camfort.Specification.Parser
-                        Camfort.Specification.Stencils.Annotation
-                        Camfort.Specification.Stencils.CheckBackend
-                        Camfort.Specification.Stencils.CheckFrontend
-                        Camfort.Specification.Stencils.Consistency
-                        Camfort.Specification.Stencils.DenotationalSemantics
-                        Camfort.Specification.Stencils.Generate
-                        Camfort.Specification.Stencils.InferenceBackend
-                        Camfort.Specification.Stencils.InferenceFrontend
-                        Camfort.Specification.Stencils.Model
-                        Camfort.Specification.Stencils.Syntax
-                        Camfort.Specification.Stencils.Parser
-                        Camfort.Specification.Stencils.Parser.Types
-                        Camfort.Specification.Stencils.Synthesis
-                        Camfort.Specification.Stencils
-                        Camfort.Specification.Units
-                        Camfort.Specification.Units.InferenceFrontend
-                        Camfort.Specification.Units.InferenceBackend
-                        Camfort.Specification.Units.Environment
-                        Camfort.Specification.Units.Monad
-                        Camfort.Specification.Units.Parser
-                        Camfort.Specification.Units.Parser.Types
-                        Camfort.Specification.Units.Synthesis
-                        Camfort.Transformation.CommonBlockElim
-                        Camfort.Transformation.DeadCode
-                        Camfort.Transformation.EquivalenceElim
-                        Camfort.Helpers
-                        Camfort.Helpers.Syntax
-                        Camfort.Helpers.Vec
-                        Camfort.Functionality
-                        Camfort.Input
-                        Camfort.Output
-                        Camfort.Reprint
-                        Main
-
+  main-is: src/Main.hs
   build-depends:        base >= 4.6 && < 5,
-                        ghc-prim >= 0.3.1.0 && < 0.6,
-                        containers >= 0.5.0.0 && < 0.6,
-                        uniplate >= 1.6.10 && < 2,
-                        syz >= 0.2 && < 0.3,
-                        syb >= 0.4 && < 0.7,
-                        matrix >= 0.2.2 && < 0.4,
-                        vector >= 0.1 && < 0.12,
-                        hmatrix >= 0.15 && < 0.19,
-                        mtl >= 2.1 && < 3,
-                        text >= 0.11.2.3 && < 2,
-                        array >= 0.4 && < 0.6,
-                        directory >= 1.2 && < 2,
-                        transformers >= 0.4 && < 0.6,
-                        GenericPretty >= 1.2 && < 2,
-                        QuickCheck >= 2.8 && < 3,
-                        fortran-src >= 0.2.0.0 && < 0.3,
-                        filepath >= 1.4 && < 2,
-                        fgl >= 5.5 && < 6,
-                        bytestring >= 0.10 && < 0.11,
-                        binary >= 0.8.3.0 && < 0.9,
-                        lattices >= 1.5 && < 2,
-                        sbv >= 7.0 && < 8,
-                        partial-order >= 0.1.2,
-                        optparse-applicative >= 0.13.2.0 && < 0.14
+                        optparse-applicative >= 0.13.2.0 && < 0.14,
+                        camfort
   default-language: Haskell2010
 
 library
@@ -138,26 +77,26 @@
   build-depends:        base >= 4.6 && < 5,
                         ghc-prim >= 0.3.1.0 && < 0.6,
                         containers >= 0.5.0.0 && < 0.6,
-                        uniplate >= 1.6.10 && < 2,
+                        uniplate >= 1.6.10 && < 1.7,
                         syz >= 0.2 && < 0.3,
                         syb >= 0.4 && < 0.7,
                         matrix >= 0.2.2 && < 0.4,
                         hmatrix >= 0.15 && < 0.19,
-                        mtl >= 2.1 && < 3,
-                        text >= 0.11.2.3 && < 2,
+                        mtl >= 2.1 && < 2.3,
+                        text >= 0.11.2.3 && < 1.3,
                         array >= 0.4 && < 0.6,
-                        directory >= 1.2 && < 2,
+                        directory >= 1.2 && < 1.4,
                         transformers >= 0.4 && < 0.6,
                         vector >= 0.1 && < 0.12,
-                        GenericPretty >= 1.2 && < 2,
+                        GenericPretty >= 1.2 && < 1.3,
                         fortran-src >= 0.2.0.0 && < 0.3,
-                        filepath >= 1.4 && < 2,
+                        filepath >= 1.4 && < 1.5,
                         bytestring >= 0.10 && < 0.11,
-                        fgl >= 5.5 && < 6,
+                        fgl >= 5.5 && < 5.6,
                         binary >= 0.8.3.0 && < 0.9,
-                        lattices >= 1.5 && < 2,
+                        lattices == 1.5.*,
                         sbv >= 7.0 && < 8,
-                        partial-order >= 0.1.2 && < 0.2
+                        partial-order >= 0.1.2.1 && < 0.1.3
   default-language: Haskell2010
 
 test-suite spec
@@ -165,6 +104,7 @@
   main-is:              Spec.hs
   hs-source-dirs:       tests
   other-modules:        Camfort.Analysis.CommentAnnotatorSpec
+                        Camfort.ReprintSpec
                         Camfort.Specification.ParserSpec
                         Camfort.Specification.Stencils.CheckSpec
                         Camfort.Specification.Stencils.ConsistencySpec
@@ -181,20 +121,20 @@
                         Camfort.Transformation.EquivalenceElimSpec
   build-depends:        base >= 4.6 && < 5,
                         containers >= 0.5.0.0 && < 0.6,
-                        filepath >= 1.4 && < 2,
+                        filepath >= 1.4 && < 1.5,
                         directory >= 1.2 && < 2,
                         hspec >= 2.2 && < 3,
                         QuickCheck >= 2.8 && < 3,
                         fortran-src >= 0.2.0.0 && < 0.3,
-                        uniplate >= 1.6.10 && < 2,
-                        mtl >= 2.1 && < 3,
+                        uniplate >= 1.6.10 && < 1.7,
+                        mtl >= 2.1 && < 2.3,
                         bytestring >= 0.10 && < 0.11,
                         array >= 0.4 && < 0.6,
                         hmatrix >= 0.15 && < 0.19,
-                        text >= 0.11.2.3 && < 2,
+                        text >= 0.11.2.3 && < 1.3,
                         binary >= 0.8.3.0 && < 0.9,
-                        lattices >= 1.5 && < 2,
+                        lattices == 1.5.*,
                         sbv >= 7.0 && < 8,
-                        partial-order >= 0.1.2 && < 0.2,
+                        partial-order >= 0.1.2.1 && < 0.1.3,
                         camfort
   default-language: Haskell2010
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -369,7 +369,7 @@
 
 
 -- | Current CamFort version.
-version = "0.903"
+version = "0.904"
 
 
 -- | Full CamFort version string.
diff --git a/tests/Camfort/ReprintSpec.hs b/tests/Camfort/ReprintSpec.hs
new file mode 100644
--- /dev/null
+++ b/tests/Camfort/ReprintSpec.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+module Camfort.ReprintSpec (spec) where
+
+import Camfort.Functionality
+import Camfort.Reprint
+import Camfort.Specification.Units.Monad (LiteralsOpt(LitMixed))
+import qualified Data.ByteString.Char8 as B
+import qualified Language.Fortran.Util.Position as FU
+
+import System.FilePath
+
+import Test.Hspec
+import Test.QuickCheck
+
+
+spec :: Spec
+spec =
+  describe "subtext function tests" $ do
+    it "(unit test) first line of sample text" $
+      subtext (1, 1) (1, 1) (2, 1) btext `shouldBe`
+              (B.pack (text !! 0 ++ "\n"), B.pack (unlines . tail $ text))
+
+    it "(unit test) second line of sample text" $
+      subtext (1, 1) (2, 1) (3, 1) btext `shouldBe`
+              (B.pack (text !! 1 ++ "\n"), B.pack (unlines . tail . tail $ text))
+
+    it "(unit test) third line of sample text" $
+      subtext (1, 1) (4, 1) (5, 1) btext `shouldBe`
+              (B.pack (text !! 3 ++ "\n"), B.empty)
+
+    it "(unit test) fourth line, middle, of sample text" $
+      subtext (1, 1) (4, 2) (4, 5) btext `shouldBe`
+              (B.pack "G H", B.pack " I J K L\n")
+
+    it "(unit test) relative test (third line)" $
+      subtext (3, 1) (5, 1) (6, 1) btext `shouldBe`
+              (B.pack "  E F\n", B.pack " G H I J K L\n")
+
+    it "(unit test) relative test (third line fragment)" $
+      subtext (3, 1) (5, 1) (5, 4) btext `shouldBe`
+              (B.pack "  E", B.pack " F\n G H I J K L\n")
+
+    it "zero-length span at start yields empty string" $ property $
+      \s -> subtext (0, 0) (0, 0) (0, 0) s == (B.empty, s)
+
+    it "zero-length span yields empty substring" $ property $
+      \(l,c) -> \s -> (fst $ subtext (l,c) (l,c) (l,c) s) == B.empty
+
+{-
+    it "takeBounds is the same as old one" $ property $
+      \p   -> takeBoundsOld (FU.initPosition, p) btext
+           == takeBounds    (FU.initPosition, p) btext
+
+    it "takeBounds is the same as old one, with different start pos" $ property $
+      \p   -> takeBoundsOld (FU.Position 0 2 2, unwrapPO p) btext
+           == takeBounds    (FU.Position 0 2 2, unwrapPO p) btext
+-}
+
+    it "takeBounds test 1" $
+      (fst $ takeBounds (FU.Position 0 2 2, FU.Position 0 5 2) btext)
+        `shouldBe` (B.pack "A B")
+
+    it "takeBounds test 2" $
+      (fst $ takeBounds (FU.Position 0 2 2, FU.Position 0 1 3) btext)
+        `shouldBe` (B.pack "A B C D\n")
+
+    it "takeBound test 3" $
+      (fst $ takeBounds (FU.Position 1 1 1, FU.Position 1 5 3) btext2)
+        `shouldBe` (B.pack $ unlines $ take 3 text2)
+
+    context "Integration test with synthesising a spec" $ do
+       runIO $ unitsSynth ("tests" </> "fixtures" </> "simple.f90") []
+         LitMixed False Nothing
+         ("tests" </> "fixtures" </> "simple.f90.out") ATDefault
+       actual <- runIO $ readFile ("tests" </> "fixtures" </> "simple.f90.out")
+       expected <- runIO $ readFile ("tests" </> "fixtures" </> "simple.expected.f90")
+       it "Unit synth" $ actual `shouldBe` expected
+
+----
+
+data PlusOne a = PlusOne { _unwrapPO :: a } deriving Show
+
+instance Arbitrary (PlusOne FU.Position) where
+    arbitrary = do
+      FU.Position offset col line <- arbitrary
+      let col' = if line == 1 then col+1 else col
+      return $ PlusOne $ FU.Position offset col' (line + 1)
+
+instance Arbitrary FU.Position where
+    arbitrary = do
+      offset <- arbitrary `suchThat` (>0)
+      line   <- arbitrary `suchThat` (\x -> x >= 1 && x <= (length text))
+      col    <- choose (1, orOne $ length (text !! (line - 1)))
+      return $ FU.Position offset col line
+
+orOne x | x == 0    = 1
+        | otherwise = x
+
+-- Arbtirary ByteString
+instance Arbitrary B.ByteString where
+    arbitrary = do
+      numLines <- choose (0, 3)
+      return . B.pack . concat $ take numLines text
+
+btext = B.pack . unlines $ text
+text = ["A B C D"
+       ,""
+       ,"  E F"
+       ," G H I J K L"]
+
+btext2 = B.pack . unlines $ text2
+text2 = ["A B C D"
+       ,"E F"
+       ,"G H"
+       ,"I J K L"]
+
+{-
+-- Given a lower-bound and upper-bound pair of FU.Positions, split the
+-- incoming SourceText based on the distanceF between the FU.Position pairs
+takeBoundsOld :: (FU.Position, FU.Position) -> SourceText -> (SourceText, SourceText)
+takeBoundsOld (l, u) = takeBounds' ((ll, lc), (ul, uc)) B.empty
+  where (FU.Position _ lc ll) = l
+        (FU.Position _ uc ul) = u
+        takeBounds' ((ll, lc), (ul, uc)) tk inp  =
+          if (ll == ul && lc == uc) || (ll > ul) then (B.reverse tk, inp)
+          else
+            case B.uncons inp of
+              Nothing         -> (B.reverse tk, inp)
+              Just ('\n', ys) -> takeBounds' ((ll+1, 1), (ul, uc))  (B.cons '\n' tk) ys
+              Just (x, xs)    -> takeBounds' ((ll, lc+1), (ul, uc)) (B.cons x tk) xs
+-}
