diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,8 @@
+0.5.0
+==========
+* [!12](https://gitlab.com/morley-framework/indigo/-/merge_requests/12)
+  Refactor some general documentation-related methods, see deprecation notes for migration instructions.
+
 0.4
 ==========
 * [!8](https://gitlab.com/morley-framework/indigo/-/merge_requests/8)
diff --git a/app/FileGen.hs b/app/FileGen.hs
--- a/app/FileGen.hs
+++ b/app/FileGen.hs
@@ -34,19 +34,21 @@
 generateFiles :: CustomSettings -> [TreeFs]
 generateFiles CustomSettings{..} =
   [ Dir "app"
-    [ File "Main.hs" F.main ]
+      [ File "Main.hs" F.main ]
   , Dir "src"
-    [ File "Basic.hs" F.basic ]
+      [ File "Basic.hs" F.basic ]
   , Dir "test"
-    [ Dir "Test"
-        [ File "Basic.hs" F.basicTest ]
-    , File "Main.hs" F.mainTest
-    ]
+      [ Dir "Test"
+          [ File "Basic.hs" F.basicTest ]
+      , File "Main.hs" F.mainTest
+      ]
   , File "ChangeLog.md" (F.changelog sProjectName)
   , File "README.md" (F.readme sProjectName)
   , File ".gitignore" F.gitignore
   , File "package.yaml" (F.packageYaml sProjectName)
   , File "stack.yaml" F.stackYaml
+  , File "indigo-snapshot.yaml" F.indigoSnapshotYaml
+  , File "indigo-dependence-snapshot.yaml" F.indigoDependenceSnapshotYaml
   ]
 
 data CustomSettings = CustomSettings
diff --git a/app/FileGen/Files.hs b/app/FileGen/Files.hs
--- a/app/FileGen/Files.hs
+++ b/app/FileGen/Files.hs
@@ -13,8 +13,11 @@
   , gitignore
   , packageYaml
   , stackYaml
+  , indigoSnapshotYaml
+  , indigoDependenceSnapshotYaml
   ) where
 
+import Data.FileEmbed (embedStringFile)
 import Data.String.Interpolate (i)
 
 import Helper
@@ -277,34 +280,18 @@
 |]
 
 stackYaml :: Text
-stackYaml = [i|resolver: lts-16.5
+stackYaml = [i|resolver: indigo-dependence-snapshot.yaml
 
 packages:
-  - .
-
-extra-deps:
-  - tasty-hunit-compat-0.2
-  - morley-prelude-0.3.0
-  - morley-1.7.0
-  - lorentz-0.6.1
-  - indigo-0.2.2
-  - git:
-      https://gitlab.com/morley-framework/morley.git
-    commit:
-      2d0506578493fec3851d711a5cc26c9dc5885001 # morley-1.7.0
-    subdirs:
-      - code/cleveland
-      - code/morley-client
-
-  - base58-bytestring-0.1.0
-  - hex-text-0.1.0.0
-  - show-type-0.1.1
-  - git: https://github.com/int-index/caps.git
-    commit: c5d61837eb358989b581ed82b1e79158c4823b1b
-  - named-0.3.0.1@sha256:69b9722301201f8ed8abc89c4595e22c746e944bf4cdfafa8b21b14d336b26d1,2233
-  - vinyl-0.12.1@sha256:43456d4b3009646eee63953cbe539f1f4d0caf8bc3c25e841117e712836508f3,3790
-  - cryptonite-0.27
+- .
 
 nix:
   packages: [zlib]
+
 |]
+
+indigoSnapshotYaml :: Text
+indigoSnapshotYaml = $(embedStringFile "./snapshots/indigo-snapshot.yaml")
+
+indigoDependenceSnapshotYaml :: Text
+indigoDependenceSnapshotYaml = $(embedStringFile "./snapshots/indigo-dependence-snapshot.yaml")
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -101,9 +101,13 @@
       result <- Utf8.readFile "package.yaml"
       S.shelly . S.escaping False $ case getExecName (words result) of
         Just execName ->
-          S.catch_sh @SomeException
+          -- If we don't catch the exception here, 2 errors message will be print
+          -- one by 'runStackWithArgs' and another by shelly itself.
+          -- We still treat it as a fail command when the exception occurs by
+          -- exit with error code 1.
+          S.catch_sh @(S.ReThrownException SomeException)
             (runStackWithArgs (["run", execName, "--"] <> (toText <$> input)))
-            (const pass)  -- Hide Exception error text from `optparse`
+            (\_ -> S.quietExit 1)
         Nothing ->
           die "Could not find executable name in package.yaml"
 
diff --git a/indigo.cabal b/indigo.cabal
--- a/indigo.cabal
+++ b/indigo.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           indigo
-version:        0.4
+version:        0.5.0
 synopsis:       Convenient imperative eDSL over Lorentz.
 description:    Syntax and implementation of Indigo eDSL.
 category:       Language
@@ -20,6 +20,8 @@
 extra-source-files:
     README.md
     CHANGES.md
+    snapshots/indigo-dependence-snapshot.yaml
+    snapshots/indigo-snapshot.yaml
 
 source-repository head
   type: git
@@ -107,6 +109,7 @@
   build-depends:
       base >=4.7 && <5
     , directory
+    , file-embed
     , megaparsec >=7.0.0
     , morley
     , morley-prelude
diff --git a/snapshots/indigo-dependence-snapshot.yaml b/snapshots/indigo-dependence-snapshot.yaml
new file mode 100644
--- /dev/null
+++ b/snapshots/indigo-dependence-snapshot.yaml
@@ -0,0 +1,11 @@
+# SPDX-FileCopyrightText: 2020 Tocqueville Group
+# SPDX-License-Identifier: LicenseRef-MIT-TQ
+
+name: indigo-dependence-snapshot
+
+# See more extra-deps in 'indigo-snapshot.yaml'.
+resolver: indigo-snapshot.yaml
+
+# The 'packages' here act as 'extra-deps'.
+packages:
+  - indigo-0.5.0
diff --git a/snapshots/indigo-snapshot.yaml b/snapshots/indigo-snapshot.yaml
new file mode 100644
--- /dev/null
+++ b/snapshots/indigo-snapshot.yaml
@@ -0,0 +1,37 @@
+# SPDX-FileCopyrightText: 2020 Tocqueville Group
+# SPDX-License-Identifier: LicenseRef-MIT-TQ
+
+name: indigo-snapshot
+
+# When 'resolver' or 'extra-deps' are updated, you might have to update
+# pinned stackage and hackage indexes used by CI, to make sure they
+# contain the latest snapshots and packages. To update them, you need
+# to have 'nix' and 'niv' installed and run the commands
+# 'niv update hackage.nix' and 'niv update stackage.nix'
+resolver: lts-16.5
+
+# You might have to update hackage index used by CI when you update
+# packages in this list, see the comment at the top of the file
+# The 'packages' here act as 'extra-deps'.
+packages:
+  - morley-1.11.0
+  - morley-prelude-0.3.0
+  - lorentz-0.9.0
+  - tasty-hunit-compat-0.2
+  - git:
+      https://gitlab.com/morley-framework/morley.git # CI can't use SSH
+    commit:
+      fd1f796e970ed370285b4ca184a5d63c04483d19 # morley-1.11.0
+    subdirs:
+      - code/cleveland
+      - code/morley-client
+
+  - base58-bytestring-0.1.0
+  - hex-text-0.1.0.0
+  - show-type-0.1.1
+  - git: https://github.com/int-index/caps.git
+    commit: c5d61837eb358989b581ed82b1e79158c4823b1b
+  - named-0.3.0.1@sha256:69b9722301201f8ed8abc89c4595e22c746e944bf4cdfafa8b21b14d336b26d1,2233
+  - vinyl-0.12.1@sha256:43456d4b3009646eee63953cbe539f1f4d0caf8bc3c25e841117e712836508f3,3790
+  - cryptonite-0.27
+  - uncaught-exception-0.1.0
diff --git a/src/Indigo/Backend.hs b/src/Indigo/Backend.hs
--- a/src/Indigo/Backend.hs
+++ b/src/Indigo/Backend.hs
@@ -133,24 +133,25 @@
 
 -- | Group documentation built in the given piece of code
 -- into a block dedicated to one thing, e.g. to one entrypoint.
-docGroup :: DocGrouping -> SomeIndigoState i -> SomeIndigoState i
+docGroup :: DocItem di => (SubDoc -> di) -> SomeIndigoState i -> SomeIndigoState i
 docGroup gr = overSIS $ \(GenCode md cd clr) -> SomeGenCode $
   GenCode md (L.docGroup gr cd) clr
 
 -- | Insert documentation of the contract storage type. The type
 -- should be passed using type applications.
+{-# DEPRECATED docStorage "Use `doc (dStorage @storage)` instead." #-}
 docStorage :: forall storage s. TypeHasDoc storage => IndigoState s s
-docStorage = IndigoState \md -> GenCode (mdStack md) (L.docStorage @storage) L.nop
+docStorage = doc (dStorage @storage)
 
 -- | Give a name to the given contract. Apply it to the whole contract code.
+{-# DEPRECATED contractName "Use `docGroup name` instead." #-}
 contractName :: Text -> SomeIndigoState i -> SomeIndigoState i
-contractName cName = overSIS $ \(GenCode mdb gc clr) ->
-  SomeGenCode $ GenCode mdb (L.contractName cName gc) clr
+contractName cName = docGroup (DName cName)
 
 -- | Attach general info to the given contract.
+{-# DEPRECATED contractGeneral "Use `docGroup DGeneralInfoSection` instead." #-}
 contractGeneral :: SomeIndigoState i -> SomeIndigoState i
-contractGeneral = overSIS $ \(GenCode mdb gc clr) ->
-  SomeGenCode $ GenCode mdb (L.contractGeneral gc) clr
+contractGeneral = docGroup DGeneralInfoSection
 
 -- | Attach default general info to the contract documentation.
 contractGeneralDefault :: IndigoState s s
diff --git a/src/Indigo/Compilation/Sequential.hs b/src/Indigo/Compilation/Sequential.hs
--- a/src/Indigo/Compilation/Sequential.hs
+++ b/src/Indigo/Compilation/Sequential.hs
@@ -270,7 +270,8 @@
     -> Block
     -> Instruction
   DocGroup
-    :: DocGrouping
+    :: forall di. DocItem di
+    => (SubDoc -> di)
     -> Block
     -> Instruction
   ContractGeneral
@@ -594,11 +595,11 @@
     toSIS $ forEach ex varIop (sequentialToSIS (block, nextRef))
 
   ContractName tx block ->
-    contractName tx (sequentialToSIS (block, nextRef))
+    docGroup (DName tx) (sequentialToSIS (block, nextRef))
   DocGroup dg block ->
     docGroup dg (sequentialToSIS (block, nextRef))
   ContractGeneral block ->
-    contractGeneral (sequentialToSIS (block, nextRef))
+    docGroup DGeneralInfoSection (sequentialToSIS (block, nextRef))
   FinalizeParamCallingDoc varCp block param ->
     finalizeParamCallingDoc varCp (sequentialToSIS (block, nextRef)) param
 
diff --git a/src/Indigo/Frontend/Language.hs b/src/Indigo/Frontend/Language.hs
--- a/src/Indigo/Frontend/Language.hs
+++ b/src/Indigo/Frontend/Language.hs
@@ -120,7 +120,6 @@
 import GHC.Stack (popCallStack)
 import GHC.Stack.Types (SrcLoc(..))
 
-import Prelude ((==))
 import qualified Indigo.Backend as B
 import Indigo.Backend.Case hiding (caseRec, entryCaseRec)
 import Indigo.Backend.Lambda
@@ -128,7 +127,7 @@
 import Indigo.Compilation (compileIndigoContract)
 import Indigo.Frontend.Program
 import Indigo.Frontend.Statement
-import Indigo.Internal hiding (SetField, (>>), (==))
+import Indigo.Internal hiding (SetField, (==), (>>))
 import Indigo.Lorentz
 import Indigo.Prelude
 import Lorentz.Entrypoints.Helpers (RequireSumType)
@@ -137,6 +136,7 @@
 import qualified Michelson.Typed as MT
 import qualified Michelson.Typed.Arith as M
 import Michelson.Typed.Haskell.Instr.Sum (CaseClauseParam(..), CtorField(..))
+import Prelude ((==))
 import Util.Markdown (toAnchor)
 import Util.TypeLits (AppendSymbol)
 import Util.TypeTuple.Class
@@ -681,21 +681,24 @@
 
 -- | Group documentation built in the given piece of code
 -- into a block dedicated to one thing, e.g. to one entrypoint.
-docGroup :: HasCallStack => DocGrouping -> IndigoM () -> IndigoM ()
+docGroup :: (DocItem di, HasCallStack) => (SubDoc -> di) -> IndigoM () -> IndigoM ()
 docGroup = calledFrom . oneIndigoM ... DocGroup
 
 -- | Insert documentation of the contract's storage type. The type
 -- should be passed using type applications.
+{-# DEPRECATED docStorage "Use `doc (dStorage @storage)` instead." #-}
 docStorage :: forall storage. (TypeHasDoc storage, HasCallStack) => IndigoM ()
-docStorage = calledFrom $ liftIndigoState $ toSIS $ B.docStorage @storage
+docStorage = doc $ dStorage @storage
 
 -- | Give a name to the given contract. Apply it to the whole contract code.
+{-# DEPRECATED contractName "Use `docGroup name` instead." #-}
 contractName :: HasCallStack => Text -> IndigoM () -> IndigoM ()
-contractName = calledFrom . oneIndigoM ... ContractName
+contractName = docGroup . DName
 
 -- | Attach general info to the given contract.
+{-# DEPRECATED contractGeneral "Use `docGroup DGeneralInfoSection` instead." #-}
 contractGeneral :: HasCallStack => IndigoM () -> IndigoM ()
-contractGeneral = calledFrom . oneIndigoM . ContractGeneral
+contractGeneral = docGroup DGeneralInfoSection
 
 -- | Attach default general info to the contract documentation.
 contractGeneralDefault :: HasCallStack => IndigoM ()
diff --git a/src/Indigo/Frontend/Statement.hs b/src/Indigo/Frontend/Statement.hs
--- a/src/Indigo/Frontend/Statement.hs
+++ b/src/Indigo/Frontend/Statement.hs
@@ -147,8 +147,11 @@
     -> (Var (IterOpElHs a) -> freer ())
     -> StatementF freer ()
 
-  ContractName :: Text        -> freer () -> StatementF freer ()
-  DocGroup     :: DocGrouping -> freer () -> StatementF freer ()
+  ContractName
+    :: Text -> freer () -> StatementF freer ()
+  DocGroup
+    :: DocItem di
+    => (SubDoc -> di) -> freer () -> StatementF freer ()
   ContractGeneral :: freer () -> StatementF freer ()
   FinalizeParamCallingDoc
     :: (NiceParameterFull cp, RequireSumType cp, HasCallStack)
diff --git a/src/Indigo/Print.hs b/src/Indigo/Print.hs
--- a/src/Indigo/Print.hs
+++ b/src/Indigo/Print.hs
@@ -17,8 +17,8 @@
 import Data.Text.Lazy.IO.Utf8 (writeFile)
 
 import Indigo.Compilation
-import Indigo.Internal.Object
 import Indigo.Frontend.Program (IndigoContract)
+import Indigo.Internal.Object
 import Indigo.Lorentz
 import Indigo.Prelude
 
@@ -46,7 +46,8 @@
   => IndigoContract param st
   -> LText
 renderIndigoDoc ctr =
-  renderLorentzDocWithGitRev DGitRevisionUnknown $ compileIndigoContract @param @st ctr
+  buildMarkdownDoc . attachDocCommons DGitRevisionUnknown $
+    compileIndigoContract @param @st ctr
 
 -- | Prints the pretty-printed Michelson code of an Indigo contract to
 -- the standard output.
diff --git a/test/Test/Code/Examples.hs b/test/Test/Code/Examples.hs
--- a/test/Test/Code/Examples.hs
+++ b/test/Test/Code/Examples.hs
@@ -25,7 +25,7 @@
 
 import Indigo
 import qualified Lorentz.Run as L
-import Michelson.Doc (DName(..))
+
 import Test.Util
 
 contractVarLorentz :: ContractCode Integer Integer
@@ -110,9 +110,9 @@
 contractDocLorentz :: ContractCode Integer Integer
 contractDocLorentz = compileIndigoContract $ \param -> do
   doc (DDescription "x")
-  contractName "aaa" (doc $ DDescription "a")
+  docGroup "aaa" (doc $ DDescription "a")
   i <- new$ 10 int
-  docGroup (SomeDocItem . DName "bbb") (doc $ DDescription "b")
+  docGroup "bbb" (doc $ DDescription "b")
   storageVar =: param + i
 
 contractOpsLorentz :: ContractCode (Maybe KeyHash) Address
diff --git a/test/Test/Examples.hs b/test/Test/Examples.hs
--- a/test/Test/Examples.hs
+++ b/test/Test/Examples.hs
@@ -34,18 +34,17 @@
   , pathComment
   ) where
 
+import Lorentz
 import Prelude hiding (drop, swap)
 
 import Hedgehog (Gen)
 import qualified Hedgehog.Gen as Gen
+import Hedgehog.Gen.Tezos.Address (genAddress)
+import Hedgehog.Gen.Tezos.Crypto (genKeyHash)
 import qualified Hedgehog.Range as Range
 import Test.Tasty (TestTree)
 
 import Cleveland.Util (genTuple2)
-import Hedgehog.Gen.Tezos.Address (genAddress)
-import Hedgehog.Gen.Tezos.Crypto (genKeyHash)
-import Lorentz
-import Michelson.Doc (DName(..))
 import Michelson.Interpret (MichelsonFailed(..))
 import Michelson.Runtime.GState
 import qualified Michelson.Typed as T
@@ -252,12 +251,12 @@
   dip nop #
   -- doc (DDescription "x")
   doc (DDescription "x") #
-  -- contractName "aaa" (doc $ DDescription "a")
-  contractName "aaa" (doc $ DDescription "a") #
+  -- docGroup "aaa" (doc $ DDescription "a")
+  docGroup "aaa" (doc $ DDescription "a") #
   -- i <- new$ 10 int
   push @Integer 10 #
-  -- docGroup (SomeDocItem . DName "bbb") (doc $ DDescription "b")
-  docGroup (SomeDocItem . DName "bbb") (doc $ DDescription "b") #
+  -- docGroup "bbb" (doc $ DDescription "b")
+  docGroup "bbb" (doc $ DDescription "b") #
   -- duplicate `i`
   duupX @1 #
   -- copy `param` to top of the stack
diff --git a/test/Test/Util.hs b/test/Test/Util.hs
--- a/test/Test/Util.hs
+++ b/test/Test/Util.hs
@@ -39,6 +39,7 @@
 import Indigo.Lorentz
 import Lorentz.Run (Contract(..))
 import Lorentz.Test (ContractPropValidator, contractProp, dummyContractEnv, failedTest)
+import Michelson.Doc.Test (buildMarkdownDocTest)
 import Michelson.Interpret (MichelsonFailed(..))
 import Michelson.Typed.Haskell.Value (IsoValuesStack)
 
@@ -93,7 +94,7 @@
     -> TestTree
 testIndigoDoc name iContract lContract =
   testCase (name <> " matches Lorentz docs content") $
-    renderLorentzDoc iContract @?= renderLorentzDoc lContract
+    buildMarkdownDocTest iContract @?= buildMarkdownDocTest lContract
 
 -- | Takes a validating function and an Indigo-generated Lorentz `Instr` to check
 -- the resulting stack content.
