diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -2,6 +2,11 @@
 
 ## [Unreleased]
 
+## [0.1.4.4] - 2022-06-02
+### Changed
+- Update more dependencies;
+- Fix new warnings in GHC-9.
+
 ## [0.1.4.3] - 2022-03-23
 ### Changed
 - Support GHC-9.2 packages in dependencies.
diff --git a/cobot-io.cabal b/cobot-io.cabal
--- a/cobot-io.cabal
+++ b/cobot-io.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           cobot-io
-version:        0.1.4.3
+version:        0.1.4.4
 synopsis:       Biological data file formats and IO
 description:    Please see the README on GitHub at <https://github.com/biocad/cobot-io#readme>
 category:       Bio
@@ -192,8 +192,10 @@
     , mtl >=2.2.1 && <2.3.0
     , parser-combinators >=1.2.1
     , split
-    , text >=1.2.2.1 && <1.3
+    , text >=1.2.2.1 && <2.1
     , vector
+  if impl(ghc >= 9.0)
+    ghc-options: -haddock -Winvalid-haddock
   default-language: Haskell2010
 
 test-suite cobot-io-test
@@ -236,7 +238,7 @@
     , data-msgpack >=0.0.9 && <0.1
     , deepseq ==1.4.*
     , directory
-    , hspec >=2.4.1 && <2.9
+    , hspec >=2.4.1 && <2.11
     , http-conduit ==2.3.*
     , hyraxAbif >=0.2.3.27 && <0.2.4.0
     , lens >=4.16 && <5.2
@@ -246,6 +248,6 @@
     , neat-interpolation >=0.3
     , parser-combinators >=1.2.1
     , split
-    , text >=1.2.2.1 && <1.3
+    , text >=1.2.2.1 && <2.1
     , vector
   default-language: Haskell2010
diff --git a/src/Bio/GB/Writer.hs b/src/Bio/GB/Writer.hs
--- a/src/Bio/GB/Writer.hs
+++ b/src/Bio/GB/Writer.hs
@@ -108,8 +108,8 @@
     mainPart = processMany featuresIndent mempty ("/" <> nameF <> "=\"" <> textF <> "\"")
 
 featureRangeToText :: Range -> Text
-featureRangeToText (Point pos) = showText pos 
-featureRangeToText (Span (RangeBorder rbLo lo) (RangeBorder rbHi hi)) = borderToText True rbLo <> showText lo <> ".." <> borderToText False rbHi <> showText hi 
+featureRangeToText (Point pos) = showText pos
+featureRangeToText (Span (RangeBorder rbLo lo) (RangeBorder rbHi hi)) = borderToText True rbLo <> showText lo <> ".." <> borderToText False rbHi <> showText hi
   where
     borderToText :: Bool -> Border -> Text
     borderToText _ Precise      = ""
@@ -146,12 +146,12 @@
       where
         indText = showText startInd
 
-    -- | Number of nucleotides in one chunk.
+    -- Number of nucleotides in one chunk.
     --
     lengthOfChunk :: Int
     lengthOfChunk = 10
 
-    -- | Number of chunks per line of sequence in ORIGIN section.
+    -- Number of chunks per line of sequence in ORIGIN section.
     --
     lengthOfLineChunk :: Int
     lengthOfLineChunk = 6
@@ -166,13 +166,14 @@
 --------------------------------------------------------------------------------
 
 processMany :: Int -> Text -> Text -> Text
-processMany indent name ""   = toIndent indent name
-processMany indent name text = interNewLine resLines
-  where
-    (x : xs) = T.lines text
-
-    resLines = toIndent indent name <> x
-             : fmap (prependIndent indent) xs
+processMany indent name text =
+  case T.lines text of
+    [] -> toIndent indent name
+    (x:xs) ->
+      let
+        resLines = toIndent indent name <> x
+                 : fmap (prependIndent indent) xs
+      in interNewLine resLines
 
 interNewLine :: [Text] -> Text
 interNewLine = T.intercalate "\n" . filter (not . T.null)
@@ -181,7 +182,7 @@
 textFromMaybe = fromMaybe mempty
 
 toIndent :: Int -> Text -> Text
-toIndent indent name = name <> (spaces $ indent - (T.length name))
+toIndent indent name = name <> spaces (indent - T.length name)
 
 prependIndent :: Int -> Text -> Text
 prependIndent = T.append . spaces
diff --git a/src/Bio/MAE.hs b/src/Bio/MAE.hs
--- a/src/Bio/MAE.hs
+++ b/src/Bio/MAE.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE AllowAmbiguousTypes  #-}
-{-# LANGUAGE CPP                  #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE CPP                 #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 module Bio.MAE
@@ -14,35 +14,33 @@
   ) where
 
 import           Bio.MAE.Parser
-import           Bio.MAE.Type           (Block (..), FromMaeValue (..),
-                                         Mae (..), MaeValue (..), Table (..))
-import           Bio.Structure          (Atom (..), Bond (..), Chain (..), Model (..),
-                                         GlobalID (..), LocalID (..),
-                                         Model (..), Residue (..),
-                                         SecondaryStructure (..),
-                                         StructureModels (..))
+import           Bio.MAE.Type           (Block (..), FromMaeValue (..), Mae (..), MaeValue (..),
+                                         Table (..))
+import           Bio.Structure          (Atom (..), Bond (..), Chain (..), GlobalID (..),
+                                         LocalID (..), Model (..), Residue (..),
+                                         SecondaryStructure (..), StructureModels (..))
 import qualified Bio.Utils.Map          as M ((!?!))
 import           Control.Monad          (join)
 import           Control.Monad.IO.Class (MonadIO, liftIO)
 import           Data.Attoparsec.Text   (parseOnly)
 import           Data.Bifunctor         (bimap, first)
 import           Data.Function          (on)
-import qualified Data.List              as L (find, groupBy, sortOn)
+import qualified Data.List              as L (find, sortOn)
+import qualified Data.List.NonEmpty     as NE
 import           Data.Map.Strict        (Map)
 import qualified Data.Map.Strict        as M (fromList, lookup)
 import           Data.Maybe             (catMaybes, fromJust)
 import           Data.Text              (Text)
-import qualified Data.Text              as T (head, init, last, null, pack,
-                                              strip, tail)
+import qualified Data.Text              as T (head, init, last, null, pack, strip, tail)
 import qualified Data.Text.IO           as TIO (readFile)
 import           Data.Vector            (Vector)
 import qualified Data.Vector            as V (fromList)
 import           Linear.V3              (V3 (..))
-#if !MIN_VERSION_base(4,13,0)
-import           Control.Monad.Fail     (MonadFail (..))
-import           Prelude                hiding (fail)
-#endif
 
+
+
+
+
 -- | Reads 'Mae' from givem file.
 --
 fromFile :: (MonadFail m, MonadIO m) => FilePath -> m Mae
@@ -84,8 +82,8 @@
           stripQuotes t | not (T.null t) && T.head t == T.last t, T.last t == '\"' = T.strip $ T.init $ T.tail t
                         | otherwise                                                = T.strip t
 
-          toGroupsOn :: (Eq b, Ord b) => (a -> b) -> [a] -> [[a]]
-          toGroupsOn f = L.groupBy ((==) `on` f) . L.sortOn f
+          toGroupsOn :: (Eq b, Ord b) => (a -> b) -> [a] -> [NE.NonEmpty a]
+          toGroupsOn f = NE.groupBy ((==) `on` f) . L.sortOn f
 
           bondsTableToGlobalBonds :: Map Text [MaeValue] -> (Map Int [(Int, Int)], Vector (Bond GlobalID))
           bondsTableToGlobalBonds m = bimap toMap V.fromList bonds'
@@ -94,7 +92,7 @@
               bonds'        = unzip $ fmap indexToBond [0 .. numberOfBonds - 1]
 
               toMap :: [(Int, (Int, Int))] -> Map Int [(Int, Int)]
-              toMap = M.fromList . fmap (\l@((k, _) : _) -> (k, fmap snd l)) . toGroupsOn fst
+              toMap = M.fromList . fmap (\l@((k, _) NE.:| _) -> (k, snd <$> NE.toList l)) . toGroupsOn fst
 
               indexToBond :: Int -> ((Int, (Int, Int)), Bond GlobalID)
               indexToBond i = ((x, (y, o)), Bond (GlobalID x) (GlobalID y) o)
@@ -117,13 +115,12 @@
               unsafeGetFromContents :: FromMaeValue a => Text -> Int -> a
               unsafeGetFromContents = unsafeGetFromContentsMap m
 
-              groupToChain :: [Int] -> Chain
-              groupToChain []            = error "Group that is result of List.groupBy can't be empty."
-              groupToChain group@(h : _) = Chain name residues
+              groupToChain :: NE.NonEmpty Int -> Chain
+              groupToChain group@(h NE.:| _) = Chain name residues
                 where
                   name = stripQuotes $ getFromContents defaultChainName "s_m_chain_name" h
 
-                  groupedByResidues = toGroupsOn by group
+                  groupedByResidues = toGroupsOn by $ NE.toList group
                   residues          = V.fromList $ fmap groupToResidue groupedByResidues
 
                   by :: Int -> (Int, Char)
@@ -135,10 +132,10 @@
               defaultInsertionCode :: Char
               defaultInsertionCode = ' '
 
-              groupToResidue :: [Int] -> Residue
-              groupToResidue []            = error "Group that is result of List.groupBy can't be empty."
-              groupToResidue group@(h : _) = Residue name residueNumber insertionCode atoms (V.fromList localBonds) secondary chemCompType
+              groupToResidue :: NE.NonEmpty Int -> Residue
+              groupToResidue groupNE@(h NE.:| _) = Residue name residueNumber insertionCode atoms (V.fromList localBonds) secondary chemCompType
                 where
+                  group         = NE.toList groupNE
                   name          = stripQuotes $ unsafeGetFromContents "s_m_pdb_residue_name" h
                   residueNumber = unsafeGetFromContents "i_m_residue_number" h
                   insertionCode = getFromContents defaultInsertionCode "s_m_insertion_code" h
@@ -190,3 +187,4 @@
                                              , "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds"
                                              , "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og"
                                              ]
+
diff --git a/src/Bio/Uniprot/Parser.hs b/src/Bio/Uniprot/Parser.hs
--- a/src/Bio/Uniprot/Parser.hs
+++ b/src/Bio/Uniprot/Parser.hs
@@ -86,7 +86,7 @@
     flags    <- option [] (endOfLine *> parseFlagsDE)
     pure DE{..}
   where
-    -- | Parses name section like RecName, AltName or SubName.
+    -- Parses name section like RecName, AltName or SubName.
     parseNameDE :: Int -> NameType -> Parser Name
     parseNameDE indent nameType = do
         fullName <- parseDELine indent nameType "Full"
@@ -94,12 +94,12 @@
         ecNumber <- many' $ endOfLine *> parseDELine indent None "EC"
         pure Name{..}
 
-    -- | Parses flag line of DE section
+    -- Parses flag line of DE section
     parseFlagsDE :: Parser [Flag]
     parseFlagsDE = fmap (read . unpack) .
                        ("; " `splitOn`) <$> parseDELine 0 Flags ""
 
-    -- | Parses AltName lines of DE section
+    -- Parses AltName lines of DE section
     parseAltDE :: Int -> Parser AltName
     parseAltDE indent =
       (Simple <$> parseNameDE indent AltName) <|>
@@ -108,7 +108,7 @@
       (CDAntigen <$> parseDELine indent AltName "CD_antigen") <|>
       (INN <$> parseDELine indent AltName "INN")
 
-    -- | Parses any DE line
+    -- Parses any DE line
     parseDELine :: Int -> NameType -> Text -> Parser Text
     parseDELine indent nameType tpe = do
         string "DE   "
@@ -123,7 +123,7 @@
         result <- pack . P.init <$> many1 (satisfy (not . isEndOfLine))
         pure . head $ " {ECO" `splitOn` result
 
-    -- | Parses internal DE entities
+    -- Parses internal DE entities
     parseInternal :: Text -> Parser DE
     parseInternal name = do
         string "DE   " >> string name >> char ':'
@@ -148,7 +148,7 @@
     rest <- option [] $ string "and" *> endOfLine *> parseGN
     pure $ gn:rest
   where
-    -- | Parses any list item of GN line (like `Synonyms` or `ORFNames`)
+    -- Parses any list item of GN line (like `Synonyms` or `ORFNames`)
     parseGNList :: Text -> Parser [Text]
     parseGNList name = splitOn ", " <$> parseDefItem name
 
@@ -356,7 +356,7 @@
                       (hyphenConcat <$> parseMultiLine "FT" 32))
     pure FT{..}
   where
-    -- | Parse FT endpoint
+    -- Parse FT endpoint
     parseFTEndpoint :: Parser Endpoint
     parseFTEndpoint = (UncertainEP <$> (char '?' *> decimal)) <|>
                       (NTerminalEP <$> (char '<' *> decimal)) <|>
@@ -364,7 +364,7 @@
                       (ExactEP     <$> decimal) <|>
                       (char '?' $> UnknownEP)
 
-    -- | Split string to tokens by periods outside brackets.
+    -- Split string to tokens by periods outside brackets.
     splitByMagic :: String -> [Text]
     splitByMagic txt = pack <$> splitStr 0 [] txt
       where
diff --git a/test/ABISpec.hs b/test/ABISpec.hs
--- a/test/ABISpec.hs
+++ b/test/ABISpec.hs
@@ -66,7 +66,10 @@
         Right dat <- readData path
         S.length dat `shouldBe` lengthBefore
 
-        let Just cleaned = clean dat
+        let cleaned =
+              case clean dat of
+                Just c -> c
+                Nothing -> error "clean failed"
         S.length cleaned `shouldBe` lengthAfter
 
         S.toList cleaned `shouldStartWith` start
diff --git a/test/StructureSpec.hs b/test/StructureSpec.hs
--- a/test/StructureSpec.hs
+++ b/test/StructureSpec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecordWildCards   #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -fno-warn-orphans -Wno-incomplete-uni-patterns #-}
 
 module StructureSpec where
 
@@ -23,7 +23,7 @@
 
 structureSpec :: Spec
 structureSpec = describe "Structure spec." $ do
-    let mIO = V.toList . modelsOf <$> fromFile "test/MAE/Capri.mae" >>= \[x] -> pure x
+    let mIO = fromFile "test/MAE/Capri.mae" >>= (\[x] -> pure x) . V.toList . modelsOf
     beforeAll mIO $ do
         it "atoms filtering works correctly. only N, CA, C"  $ \m -> checkFiltering m $ (`elem` ["N", "CA", "C"]) . atomName
         it "atoms filtering works correctly. only CA"        $ \m -> checkFiltering m $ (== "CA") . atomName
