diff --git a/Biobase/Fasta/Export.hs b/Biobase/Fasta/Export.hs
deleted file mode 100644
--- a/Biobase/Fasta/Export.hs
+++ /dev/null
@@ -1,38 +0,0 @@
--- | Fasta export
-
-module Biobase.Fasta.Export where
-import Biobase.Fasta.Types
-import qualified Data.ByteString.Lazy.Char8 as B
-import Data.List
-import GHC.Int
-
-instance Show Fasta where
-  show (Fasta _header _sequence) =
-    (B.unpack _header) ++ "\n" ++ (B.unpack _sequence) ++ "\n"
-
-prettyPrintFasta :: Int -> Fasta -> String
-prettyPrintFasta number (Fasta _header _sequence) = (B.unpack _header) ++ "\n" ++ (B.unpack sequenceLines) ++ "\n"
-  where sequenceSlices = breakByteString number _sequence
-        sequenceLines = B.intercalate (B.pack "\n") sequenceSlices
-
-prettyByteStringFasta :: Int -> Fasta -> B.ByteString
-prettyByteStringFasta number (Fasta _header _sequence) = _header `B.append` bslinebreak `B.append` sequenceLines `B.append` bslinebreak
-  where sequenceSlices = breakByteString number _sequence
-        sequenceLines = B.intercalate (B.pack "\n") sequenceSlices
-        bslinebreak = B.pack "\n"
-
-
-breakByteString :: Int -> B.ByteString -> [B.ByteString]
-breakByteString number bs
-  | B.empty == currentLine = []
-  | otherwise = currentLine:(breakByteString number rest)
-  where (currentLine,rest) = B.splitAt (fromIntToInt64 number) bs
-
-fromIntToInt64 :: Int -> Int64
-fromIntToInt64 = fromIntegral
-
-writeFastaFile :: FilePath -> [Fasta] -> IO ()
-writeFastaFile filePath fastas = do
-  let fastabs = map (prettyByteStringFasta 80) fastas
-  let outputbs= B.concat fastabs
-  B.writeFile filePath outputbs
diff --git a/Biobase/Fasta/Streaming.hs b/Biobase/Fasta/Streaming.hs
--- a/Biobase/Fasta/Streaming.hs
+++ b/Biobase/Fasta/Streaming.hs
@@ -1,20 +1,15 @@
+
 -- | Streaming Fasta handling via the @streaming@ library.
 --
 -- The functions in here should be streaming in constant memory.
 --
 -- TODO Check if this is actually true with some unit tests.
 
-{-# LANGUAGE UnicodeSyntax #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE PolyKinds #-}
-{-# LANGUAGE DataKinds #-}
-
-
 module Biobase.Fasta.Streaming
   ( module Biobase.Fasta.Streaming
   ) where
 
+import           Control.Lens hiding (Index,Empty, mapped)
 import           Control.Monad
 import           Control.Monad.Trans.Resource (runResourceT, ResourceT(..), MonadResource)
 import           Data.ByteString.Streaming as BSS
@@ -22,18 +17,20 @@
 import           Data.ByteString.Streaming.Internal (ByteString(..))
 import           Data.Semigroup as SG
 import           Debug.Trace
+import           GHC.Generics
 import           GHC.TypeLits
 import           Prelude as P
 import qualified Data.ByteString.Char8 as BS
-import qualified Data.ByteString.Lazy.Char8 as B
 import qualified Streaming.Internal as SI
 import           Streaming as S
 import           Streaming.Prelude as SP
-import qualified Data.List as L
+
+import           Biobase.Types.BioSequence
 import           Biobase.Types.Index.Type
-import           Biobase.Fasta.Types
+import           Biobase.Types.Strand
 
 
+
 newtype HeaderSize = HeaderSize Int
   deriving (Eq,Ord,Show)
 
@@ -43,16 +40,15 @@
 newtype CurrentSize = CurrentSize Int
   deriving (Eq,Ord,Show)
 
-newtype Header (which ∷ k) = Header { getHeader ∷ BS.ByteString }
-  deriving (Eq,Ord,Show)
+-- | lens into the unique id / first word of the header.
 
-newtype Overlap (which ∷ k) = Overlap { getOverlap ∷ BS.ByteString }
-  deriving (Eq,Ord,Show)
+fastaUid ∷ Lens' (SequenceIdentifier w) BS.ByteString
+fastaUid = lens getWord updateWord
+  where getWord ((BS.words . _sequenceIdentifier) → ws) = case ws of (x:_) → BS.drop 1 x; [] → BS.empty
+        updateWord (SequenceIdentifier hdr) w = SequenceIdentifier . BS.unwords $ BS.cons '>' w : tail (BS.words hdr)
+{-# Inlinable fastaUid #-}
 
--- | Current Fasta window, together with the start index (0-based).
 
-data Current (which ∷ k) = Current { currentFasta ∷ BS.ByteString, currentStart ∷ Index 0 }
-  deriving (Eq,Ord,Show)
 
 -- | Fully stream a fasta file, making sure to never exceed a constant amount
 -- of memory. The @go@ function yields values of type @a@ down the line for
@@ -64,7 +60,7 @@
 -- @
 
 streamingFasta
-  ∷ forall m w r a
+  ∷ forall m w ty k r a
   . ( Monad m )
   ⇒ HeaderSize
   -- ^ Maximal length of the header. Ok to set to @20 000@, only guards against
@@ -75,15 +71,12 @@
   -- todo at 'overlappedFasta')
   → CurrentSize
   -- ^ The size of each window to be processed.
-  → (Header w → Overlap w → Current w → Stream (Of a) m ())
-  -- ^ The processing function. Takes in the header, any overlap from the
-  -- previous window, the current window and produces a stream of @a@s.
   → ByteString m r
   -- ^ A streaming bytestring of Fasta files.
-  → Stream (Of a) m r
-  -- ^ The outgoing stream of @a@s being processed.
+  → Stream (Of (BioSequenceWindow w ty k)) m r
+  -- ^ The outgoing stream of @Current@ windows being processed.
 {-# Inlinable streamingFasta #-}
-streamingFasta (HeaderSize hSz) (OverlapSize oSz) (CurrentSize cSz) f = go (FindHeader [] 0) where
+streamingFasta (HeaderSize hSz) (OverlapSize oSz) (CurrentSize cSz) = go (FindHeader [] 0) where
   -- Find the next FASTA header
   go (FindHeader hdr cnt) = \case
     -- No more data to be had. If There is some part of a header, we will run
@@ -92,8 +85,8 @@
     Empty retVal → do
       -- handle case of last empty fasta
       unless (P.null hdr) $ do
-        let thisHeader = BS.take hSz $ BS.concat $ P.reverse hdr
-        f (Header thisHeader) (Overlap BS.empty) (Current BS.empty 0)
+        let thisHeader = BS.take hSz . BS.drop 1 . BS.concat $ P.reverse hdr
+        yield $ seqWindow thisHeader BS.empty BS.empty 0
       SI.Return retVal
     -- Effects are wrapped up into a 'Stream' effect.
     Go m → SI.Effect $ liftM (go (FindHeader hdr cnt)) m
@@ -112,7 +105,7 @@
       -- We have found a newline at @k@. Prepare the full header (up to @hSz@
       -- size) and hand over to @HasHeader@ which processes actual fasta
       -- payload.
-      | Just k  ← mk → let thisHeader = BS.take hSz $ BS.concat $ P.reverse $ BS.take k b:hdr
+      | Just k  ← mk → let thisHeader = BS.take hSz . BS.drop 1 . BS.concat . P.reverse $ BS.take k b:hdr
                        in  go (HasHeader thisHeader BS.empty [] 0 0)
                               (Chunk (BS.drop (k+1) b) bytestream)
       where b = if P.null hdr then BS.dropWhile (\c → c/='>' && c/=';') rawBS else rawBS
@@ -121,7 +114,7 @@
   go hasHeader@(HasHeader hdr overlap cs cnt entries) = \case
     -- No more data, process final input and return.
     Empty retVal → do
-      when (cnt>0 || entries==0) $ f (Header hdr) (Overlap BS.empty) (Current (BS.concat $ reverse cs) 0)
+      when (cnt>0 || entries==0) . yield $ seqWindow hdr BS.empty (BS.concat $ reverse cs) 0
       SI.Return retVal
     -- Effects to be dealt with.
     Go m → SI.Effect $ liftM (go hasHeader) m
@@ -135,7 +128,7 @@
       Nothing → let (this,next) = BS.splitAt (cSz-cnt) $ BS.filter (/= '\n') b
                 in  if BS.length this + cnt >= cSz
                     then do let thisFasta = BS.concat $ reverse $ this:cs
-                            f (Header hdr) (Overlap overlap) (Current thisFasta 0)
+                            yield $ seqWindow hdr overlap thisFasta entries
                             go (HasHeader hdr (BS.drop (BS.length thisFasta - oSz) thisFasta) [] 0 (entries+1))
                                (if BS.null next then bytestream else Chunk next bytestream)
                     else go (HasHeader hdr overlap (this:cs) (BS.length this + cnt) entries)
@@ -150,10 +143,19 @@
         | otherwise → do let thisFasta = BS.concat $ reverse cs
                          -- we only emit on empty @thisFasta@, if there is
                          -- data, or it is the only (then empty) entry.
-                         when (cnt>0 || entries==0) $ f (Header hdr) (Overlap overlap) (Current thisFasta 0)
+                         when (cnt>0 || entries==0) . yield $ seqWindow hdr overlap thisFasta entries
                          go (FindHeader [] 0) $ Chunk b bytestream
   -- Returns the first index (if any) of a new fasta entry symbol.
   newFastaIndex b = getMin <$> (Min <$> BS.elemIndex '>' b) SG.<> (Min <$> BS.elemIndex ';' b)
+  -- build up a seq-window
+  seqWindow hdr pfx seq entries = BioSequenceWindow
+    { _bswIdentifier = SequenceIdentifier hdr
+    , _bswPrefix = BioSequence pfx
+    , _bswSequence = BioSequence seq
+    , _bswSuffix = BioSequence BS.empty
+    , _bswStrand = PlusStrand
+    , _bswIndex = Index $ entries * cSz
+    }
 
 -- | Control structure for 'streamingFasta'.
 
@@ -165,7 +167,7 @@
       -- ^ accumulated header length
       }
   | HasHeader
-      { header ∷ !BS.ByteString
+      { fhHeader ∷ !BS.ByteString
       -- ^ the (size-truncated) header for this fasta file
       , dataOverlap ∷ !BS.ByteString
       -- ^ overlap (if any) from earlier parts of the fasta file
@@ -177,7 +179,6 @@
       -- ^ count how many entries we have seen
       }
 
-
 {-
 t0 = P.unlines
   [ ">Aaaa"
@@ -189,40 +190,30 @@
   ]
 
 
-r2 = splitFastaLines $ S8.lines $ S8.fromStrict $ BS.pack t0
-
-r3 = streamFastaLines $ S8.lines $ S8.fromStrict $ BS.pack t0
-
--- r3' ∷ Stream (Stream (Of BS.ByteString) Identity) Identity ()
-r3' = toList . mapped toList $ maps (mapped toStrict) r3
-
-r4 = toList . streamingFasta (HeaderSize 2) (OverlapSize 1) (CurrentSize 2) go . S8.fromStrict $ BS.pack t0
-  where go (Header h) (Overlap o) (Current c) = yield (h,o,c)
+r4 = toList . streamingFasta (HeaderSize 2) (OverlapSize 1) (CurrentSize 2) . S8.fromStrict $ BS.pack t0
 -}
 
---eachFasta :: forall (m0 :: * -> *).  Header Int -> Overlap Int -> Current Int -> Stream (Of (BS.ByteString, BS.ByteString, BS.ByteString)) (ResourceT IO) ()
-eachFasta (Header h) (Overlap o) (Current c p) = SP.yield (h,o,c)
-
---readFastaFile ∷ FilePath → IO () -- [(BS.ByteString,BS.ByteString,BS.ByteString)]
---readFastaFile f = do
---  let s = 1000000000000
---  r ← runResourceT
---          $ SP.mapM_ (liftIO . P.print)
---          $ streamingFasta (HeaderSize s) (OverlapSize 0) (CurrentSize s) eachFasta
---          $ S8.readFile f
---  return r
+{-
+--eachFasta (Header h) (Overlap o) (Current c p) = SP.yield (h,o,c)
+eachFasta (Header h) (Overlap o) (Current c p) = SP.yield (BS.length h, BS.length o, BS.length c)
 
-parseFastaFile ∷ FilePath → IO [Fasta]
-parseFastaFile f = do
+--readFastaFile ∷ FilePath → IO [(BS.ByteString,BS.ByteString,BS.ByteString)]
+readFastaFile f = do
   let s = 1000000000000
   r ← runResourceT
-          $ toList_
+          $ SP.mapM_ (liftIO . P.print)
           $ streamingFasta (HeaderSize s) (OverlapSize 0) (CurrentSize s) eachFasta
           $ S8.readFile f
-  let fastas = L.map (\(a,_,c) -> Fasta (B.fromStrict a) (B.fromStrict c)) r
-  return fastas
+  return r
+-}
 
-parseFasta ∷ B.ByteString → [Fasta]
-parseFasta input = L.map (\(a,_,c) -> Fasta (B.fromStrict a) (B.fromStrict c)) (L.head r)
-    where s = 1000000000000
-          r = toList_ $ streamingFasta (HeaderSize s) (OverlapSize 0) (CurrentSize s) eachFasta $ BSS.fromLazy input
+{-
+readFastaFile f = do
+  let s = 1000000000000
+  r ← runResourceT
+          $ SP.mapM_ (liftIO . P.print)
+          $ SP.mapped S8.toStrict
+          $ S8.split '>'
+          $ S8.readFile f
+  return r
+-}
diff --git a/Biobase/Fasta/Strict.hs b/Biobase/Fasta/Strict.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/Fasta/Strict.hs
@@ -0,0 +1,103 @@
+
+-- | A convenience module for *small* @Fasta@ entries, that are completely in
+-- memory and *not* to be streamed.
+--
+-- The @Data.ByteString.Strict.Lens@ module is very helpful for further
+-- handling of 'Fasta' entries.
+--
+-- For convenience, the 'convertString' function from @string-conversions@ is
+-- supplied.
+
+module Biobase.Fasta.Strict
+  ( module Biobase.Fasta.Strict
+  , convertString
+  ) where
+
+import           Control.Lens
+import           Data.Bifunctor (first)
+import           Data.ByteString (ByteString)
+import           Data.String.Conversions
+import           Data.Void
+import           GHC.Generics (Generic)
+import qualified Data.ByteString.Builder as BB
+import qualified Data.ByteString.Char8 as BS
+import qualified Data.ByteString.Lazy as BSL
+import qualified Data.ByteString.Streaming as BSS
+import qualified Streaming.Prelude as SP
+
+import           Biobase.Fasta.Streaming as FS
+import           Biobase.Types.BioSequence
+
+
+
+-- | A *strict* @Fasta@ entry.
+
+data Fasta which ty = Fasta
+  { _header ∷ !(SequenceIdentifier which)
+  , _fasta  ∷ !(BioSequence ty)
+  }
+  deriving (Eq,Ord,Read,Show,Generic)
+makeLenses ''Fasta
+
+-- | If you don't want to deal with the phantom types.
+
+type FastaUntyped = Fasta Void Void
+
+-- | Render a 'Fasta' entry to a 'ByteString'. Will end with a final @\n@ in
+-- any case.
+
+fastaToByteString ∷ Int → Fasta which ty → ByteString
+{-# Inlinable fastaToByteString #-}
+fastaToByteString k' Fasta{..} = BS.cons '>' (_header^._Wrapped) <> "\n" <> go (_fasta^._Wrapped)
+  where go (BS.splitAt k → (hd,tl))
+          | BS.null hd = mempty
+          | otherwise  = hd <> "\n" <> go tl
+        k = max 1 k'
+
+-- | Render a 'Fasta' entry to a 'Builder'. Will end with a final @\n@ in
+-- any case.
+
+fastaToBuilder ∷ Int → Fasta which ty → BB.Builder
+{-# Inlinable fastaToBuilder #-}
+fastaToBuilder k' Fasta{..} = BB.char8 '>' <> (BB.byteString $ _header^._Wrapped) <> BB.char8 '\n' <> go (_fasta^._Wrapped)
+  where go (BS.splitAt k → (hd,tl))
+          | BS.null hd = mempty
+          | otherwise  = BB.byteString hd <> BB.char8 '\n' <> go tl
+        k = max 1 k'
+
+-- | Try to parse a 'ByteString' as a 'Fasta', failing with 'Left', succees
+-- with 'Right'.
+
+byteStringToFasta ∷ ByteString → Either String (Fasta which ty)
+{-# Inlinable byteStringToFasta #-}
+byteStringToFasta (BS.lines → ls)
+  | null ls = Left "empty bytestring"
+  | Just (z, hdr) ← BS.uncons h, z `BS.elem` ">;" = Right $ Fasta { _header = SequenceIdentifier hdr, _fasta = BioSequence $ BS.concat ts }
+  | otherwise = Left "no '>'/';' first character"
+  where h:ts = ls
+
+-- | Try to parse a 'ByteString' as multiple 'Fasta' entries. Even though this
+-- is using the underlying streaming interface, this is not streaming.
+
+byteStringToMultiFasta
+  ∷ BSL.ByteString → [Fasta which ty]
+{-# Inlinable byteStringToMultiFasta #-}
+byteStringToMultiFasta bsl = map (view windowedFasta) $ runIdentity bss
+  where bss = SP.toList_ . streamingFasta (HeaderSize maxBound) (OverlapSize 0) (CurrentSize maxBound) $ BSS.fromLazy bsl
+
+-- | A lens that goes from a 'BioSequenceWindow' to a 'Fasta'.
+
+windowedFasta ∷ Lens' (BioSequenceWindow w ty k) (Fasta w ty)
+{-# Inline windowedFasta #-}
+windowedFasta = lens lr rl
+  where lr bsw = Fasta { _header = bsw^.bswIdentifier, _fasta = bsw^.bswSequence }
+        rl bsw f = set bswSequence (f^.fasta) $ set bswIdentifier (f^.header) bsw
+
+-- | A prism from a 'ByteString' to a 'Fasta'. Note that this will only be an
+-- identity if the underlying fasta file is rendered with @k@ characters per
+-- line.
+
+rawFasta ∷ Int → Prism' ByteString (Fasta which ty)
+{-# Inline rawFasta #-}
+rawFasta k = prism (fastaToByteString k) $ \bs → first (const bs) $ byteStringToFasta bs
+
diff --git a/Biobase/Fasta/Types.hs b/Biobase/Fasta/Types.hs
deleted file mode 100644
--- a/Biobase/Fasta/Types.hs
+++ /dev/null
@@ -1,56 +0,0 @@
-{-# Language DeriveGeneric #-}
-
-module Biobase.Fasta.Types where
-
-import Control.DeepSeq
-import Control.Lens
-import Data.ByteString.Char8 (ByteString)
-import qualified Data.ByteString.Lazy.Char8 as B
-import Data.Data
-import GHC.Generics
-import Biobase.Types.NucleotideSequence
-import Biobase.Types.AminoAcidSequence
-
--- |
-
-data Fasta = Fasta { fastaHeader :: B.ByteString, fastaSequence :: B.ByteString }
-  deriving (Eq)
-
-newtype RawFastaEntry = RawFastaEntry { _rawFastaEntry :: ByteString }
-  deriving (Show,Eq,Ord,Typeable)
-
---makeLenses ''RawFastaEntry
-
--- | 'StreamEvent's are chunked pieces of data, where the raw data is
--- a strict @ByteString@. Each element also retains information on the
--- first and last line and column (via 'streamLines') that are part of this
--- chunk.
-
-data StreamEvent
-  -- | A Header event, multiple header events signal that the header name
-  -- was longer than the chunk size.
-  = StreamHeader  { streamHeader  :: !ByteString, streamLines :: !LineInfo }
-  -- | A data event. We keep a pointer to the previous chunk (which is
-  -- useful for some algorithms). The chunk is free of newlines!
-  | StreamFasta   { streamFasta   :: !ByteString, prevStreamFasta :: !ByteString, streamLines :: !LineInfo, streamHeader :: !ByteString }
-  deriving (Show,Eq,Ord,Typeable,Generic)
-
-instance NFData StreamEvent
-
-
-
--- | Complete information on line and column start and end for a chunk.
---
--- TODO This is a 1-based format? Lets use the BiobaseTypes facilities!
-
-data LineInfo = LineInfo
-  { firstLine   :: !Int   -- ^ first line for this chunk @(lines in complete file!)@
-  , firstCol    :: !Int   -- ^ first column in first line for this chunk
-  , lastLine    :: !Int   -- ^ last line for this chunk @(lines in complete file!)@
-  , lastCol     :: !Int   -- ^ last column in last line for this chunk
-  , firstIndex  :: !Int   -- ^ first index in this fasta block. Counts just the number of symbols in the @Fasta@ payload.
-  }
-  deriving (Show,Eq,Ord,Typeable,Generic)
-
-instance NFData LineInfo
-
diff --git a/BiobaseFasta.cabal b/BiobaseFasta.cabal
--- a/BiobaseFasta.cabal
+++ b/BiobaseFasta.cabal
@@ -1,17 +1,17 @@
+cabal-version:  2.2
 name:           BiobaseFasta
-version:        0.2.0.0
-author:         Christian Hoener zu Siederdissen, Florian Eggenhofer
+version:        0.3.0.0
+author:         Christian Hoener zu Siederdissen
 maintainer:     choener@bioinf.uni-leipzig.de
 homepage:       https://github.com/choener/BiobaseFasta
 bug-reports:    https://github.com/choener/BiobaseFasta/issues
-copyright:      Christian Hoener zu Siederdissen, 2011-2018
+copyright:      Christian Hoener zu Siederdissen, 2011-2019
 category:       Bioinformatics
-license:        GPL-3
+license:        BSD-3-Clause
 license-file:   LICENSE
 build-type:     Simple
 stability:      experimental
-cabal-version:  >= 1.10.0
-tested-with:    GHC == 8.4.3
+tested-with:    GHC == 8.4.4
 synopsis:       streaming FASTA parser
 description:
                 Stream-based handling of FASTA files. The user selects a window
@@ -19,9 +19,6 @@
                 previous (past) window is available, in case some data sits on
                 the boundary between windows.
                 .
-                FastaTool is a simple tool providing information on FASTA
-                files, and allowing to extract sequences and subsequences.
-                .
                 Greg Schwartz' <http://hackage.haskell.org/package/fasta>
                 package is a lot more complete. This one is mostly tailored to
                 my usage requirements (and may at some point use his library).
@@ -37,20 +34,16 @@
 
 
 
-library
+common deps
   build-depends: base                 >= 4.7    && < 5.0
                , bytestring
+               , lens                 >= 4.0
                , resourcet            >= 1.0
                , streaming            >= 0.1
                , streaming-bytestring >= 0.1
-               , lens
-               , deepseq
+               , string-conversions   >= 0.4
                --
-               , BiobaseTypes         == 0.1.4.*
-  exposed-modules:
-    Biobase.Fasta.Streaming,
-    Biobase.Fasta.Types,
-    Biobase.Fasta.Export
+               , BiobaseTypes         == 0.2.0.*
   default-language:
     Haskell2010
   default-extensions: BangPatterns
@@ -58,24 +51,39 @@
                     , DeriveDataTypeable
                     , DeriveGeneric
                     , FlexibleContexts
+                    , FlexibleInstances
                     , GADTs
+                    , GeneralizedNewtypeDeriving
                     , KindSignatures
                     , LambdaCase
+                    , MultiParamTypeClasses
                     , MultiWayIf
                     , NoMonomorphismRestriction
+                    , OverloadedStrings
                     , PolyKinds
                     , RankNTypes
                     , RecordWildCards
                     , ScopedTypeVariables
                     , TemplateHaskell
+                    , TypeApplications
+                    , TypeFamilies
                     , UnicodeSyntax
                     , ViewPatterns
   ghc-options:
     -O2
 
+library
+  import:
+    deps
+  exposed-modules:
+    Biobase.Fasta.Streaming
+    Biobase.Fasta.Strict
 
 
+
 test-suite properties
+  import:
+    deps
   type:
     exitcode-stdio-1.0
   main-is:
@@ -84,19 +92,8 @@
     -threaded -rtsopts -with-rtsopts=-N
   hs-source-dirs:
     tests
-  default-language:
-    Haskell2010
-  default-extensions: TemplateHaskell
-                    , UnicodeSyntax
-                    , OverloadedStrings
-		    
-  build-depends: base
-               , QuickCheck
-               , bytestring
+  build-depends: QuickCheck
                , filepath
-               , resourcet              >= 1.0
-               , streaming              >= 0.1
-               , streaming-bytestring   >= 0.1
                , tasty                  >= 0.11
                , tasty-hunit            >= 0.9
                , tasty-golden           >= 2.3
diff --git a/tests/properties.hs b/tests/properties.hs
--- a/tests/properties.hs
+++ b/tests/properties.hs
@@ -1,63 +1,69 @@
 
 module Main where
 
-import           Prelude as P
-import           Data.Functor.Of
-import qualified Data.ByteString.Char8 as BS
+import           Control.Lens (view)
+import           Control.Monad.Trans.Resource (runResourceT, ResourceT(..), MonadResource)
 import           Data.ByteString.Streaming as BSS
 import           Data.ByteString.Streaming.Char8 as S8
 import           Data.ByteString.Streaming.Internal (ByteString(..))
+import           Data.Functor.Of
+import           Data.Void
+import           Prelude as P
+import qualified Data.ByteString.Char8 as BS
+import qualified Data.ByteString.Lazy.Char8 as BL8
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
+import qualified Test.Tasty.Golden as Golden
 import           Streaming as S
 import           Streaming.Prelude as SP
+import           System.FilePath (takeBaseName, replaceExtension)
 import           Test.Tasty
 import           Test.Tasty.HUnit
 import           Test.Tasty.QuickCheck as QC
---import           Test.Tasty.Silver as S
---import           Test.Tasty.Silver.Interactive as SI
 import           Test.Tasty.TH
-import           Control.Monad.Trans.Resource (runResourceT, ResourceT(..), MonadResource)
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as T
-import qualified Test.Tasty.Golden as Golden
-import           System.FilePath (takeBaseName, replaceExtension)
-import qualified Data.ByteString.Lazy.Char8 as BL8
 
+import           Biobase.Types.BioSequence
+import           Biobase.Types.Strand
+
 import           Biobase.Fasta.Streaming
+import           Biobase.Fasta.Strict
 
 
 
--- * golden tests
-
-readFastaFile ∷ FilePath → IO [(BS.ByteString,BS.ByteString,BS.ByteString)]
-readFastaFile f = do
-  let s = 1000000
-  xs :> r ← runResourceT
-          $ SP.toList
-          $ streamingFasta (HeaderSize s) (OverlapSize 0) (CurrentSize s) eachFasta
-          $ S8.readFile f
-  return xs
-
-lazyFastaOut = BL8.concat . P.map go
-  where go (h,o,c) = BL8.concat
-          [ BL8.fromStrict h
-          , BL8.pack "\n"
-          , BL8.fromStrict o
-          , BL8.pack "\n"
-          , BL8.fromStrict c
-          , BL8.pack "\n"
-          ]
-
-goldenTests ∷ IO TestTree
-goldenTests = do
-  fastaFiles ← Golden.findByExtension [".fa"] "./tests/"
-  return $ testGroup "readFastaFile golden tests"
-    [ Golden.goldenVsString
-        (takeBaseName fastaFile) -- test name
-        goldenFile -- golden file path
-        (lazyFastaOut <$> readFastaFile fastaFile) -- action whose result is tested
-    | fastaFile <- fastaFiles
-    , let goldenFile = replaceExtension fastaFile ".fa-golden"
-    ]
+-- -- * golden tests
+-- 
+-- eachFasta (HeaderSize h) (OverlapSize o) (CurrentSize c p) = SP.yield (h,o,c)
+-- 
+-- readFastaFile ∷ FilePath → IO [(BS.ByteString,BS.ByteString,BS.ByteString)]
+-- readFastaFile f = do
+--   let s = 1000000
+--   xs :> r ← runResourceT
+--           $ SP.toList
+--           $ streamingFasta (HeaderSize s) (OverlapSize 0) (CurrentSize s) eachFasta
+--           $ S8.readFile f
+--   return xs
+-- 
+-- lazyFastaOut = BL8.concat . P.map go
+--   where go (h,o,c) = BL8.concat
+--           [ BL8.fromStrict h
+--           , BL8.pack "\n"
+--           , BL8.fromStrict o
+--           , BL8.pack "\n"
+--           , BL8.fromStrict c
+--           , BL8.pack "\n"
+--           ]
+-- 
+-- goldenTests ∷ IO TestTree
+-- goldenTests = do
+--   fastaFiles ← Golden.findByExtension [".fa"] "./tests/"
+--   return $ testGroup "readFastaFile golden tests"
+--     [ Golden.goldenVsString
+--         (takeBaseName fastaFile) -- test name
+--         goldenFile -- golden file path
+--         (lazyFastaOut <$> readFastaFile fastaFile) -- action whose result is tested
+--     | fastaFile <- fastaFiles
+--     , let goldenFile = replaceExtension fastaFile ".fa-golden"
+--     ]
 
 -- * unit tests
 
@@ -70,28 +76,34 @@
   , "890"
   ]
 
-smallTest ∷ Int → Int → Int → Of [(BS.ByteString,BS.ByteString,BS.ByteString)] ()
+smallTest ∷ Int → Int → Int → Of [BioSequenceWindow Void Void 1] ()
 smallTest h o c = runIdentity
          . toList
-         . streamingFasta (HeaderSize h) (OverlapSize o) (CurrentSize c) go
+--         . SP.map (view windowedFasta)
+         . streamingFasta (HeaderSize h) (OverlapSize o) (CurrentSize c)
          . S8.fromStrict
          $ BS.pack smallInlineFasta
-  where go (Header h) (Overlap o) (Current c _) = yield (h,o,c)
+  where go (HeaderSize h) (OverlapSize o) (CurrentSize c) = yield (h,o,c)
 
 smallTest333 = testCase "3/3/3" $ do
   let res :> r = smallTest 3 3 3
   assertEqual "return is null" () r
   assertEqual "length is 4" 4 (P.length res)
-  assertEqual "!!0" (">Aa","","123") (res!!0)
-  assertEqual "!!1" (">Bb","","456") (res!!1)
-  assertEqual "!!2" (">Bb","456","7") (res!!2)
-  assertEqual "!!3" (">Cc","","890") (res!!3)
+  assertEqual "!!0" (BioSequenceWindow "Aaa" ""    "123" "" PlusStrand 1) (res!!0)
+  assertEqual "!!1" (BioSequenceWindow "Bbb" ""    "456" "" PlusStrand 1) (res!!1)
+  assertEqual "!!2" (BioSequenceWindow "Bbb" "456" "7"   "" PlusStrand 4) (res!!2)
+  assertEqual "!!3" (BioSequenceWindow "Ccc" ""    "890" "" PlusStrand 1) (res!!3)
+  --
+  assertEqual "!!0/Fasta" (Fasta "Aaa" "123") (view windowedFasta $ res!!0)
+  assertEqual "!!1/Fasta" (Fasta "Bbb" "456") (view windowedFasta $ res!!1)
+  assertEqual "!!2/Fasta" (Fasta "Bbb" "7"  ) (view windowedFasta $ res!!2)
+  assertEqual "!!3/Fasta" (Fasta "Ccc" "890") (view windowedFasta $ res!!3)
 
 main :: IO ()
 main = do
-  gs ← goldenTests
-  defaultMain $ testGroup "all tests"
-    [ testGroup "Golden" [gs]
-    , testGroup "unit tests" [smallTest333]
-    ]
+--   gs ← goldenTests
+   defaultMain $ testGroup "all tests"
+--     [ testGroup "Golden" [gs]
+     [ testGroup "unit tests" [smallTest333]
+     ]
 
