diff --git a/Biobase/BLAST.hs b/Biobase/BLAST.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/BLAST.hs
@@ -0,0 +1,11 @@
+-- | Types and functions for NCBI BLAST+
+--
+
+module Biobase.BLAST
+  ( module Biobase.BLAST.Types
+  , module Biobase.BLAST.Import
+  ) where
+
+import Biobase.BLAST.Import (blastFromFile)
+import Biobase.BLAST.Types
+
diff --git a/Biobase/BLAST/Import.hs b/Biobase/BLAST/Import.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/BLAST/Import.hs
@@ -0,0 +1,130 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE LambdaCase #-}
+
+-- | Parses NCBI BLAST+ tabular output
+
+module Biobase.BLAST.Import where
+
+import Prelude hiding (takeWhile)
+import Data.Attoparsec.ByteString.Char8 hiding (isSpace)
+import qualified Data.Attoparsec.ByteString.Lazy as L
+import qualified Data.ByteString.Char8 as C
+import qualified Data.ByteString.Builder as S
+import qualified Data.ByteString.Lazy.Char8 as B
+import qualified Data.Vector as V
+import System.Directory
+import Data.Char
+import Control.Monad
+import Debug.Trace
+import Text.Printf
+import Biobase.BLAST.Types
+
+-- | reads and parses tabular Blast result from provided filePath
+blastFromFile :: String -> IO [BlastTabularResult]
+blastFromFile filePath = do
+  printf "# reading tabular blast input from file %s\n" filePath
+  blastFileExists <- doesFileExist filePath
+  if blastFileExists
+     then parseTabularBlasts <$> B.readFile filePath
+     else fail "# tabular blast file \"%s\" does not exist\n" filePath
+
+-- | Read a lazy bytestring and stream out a lsit of @BlastTabularResult@'s.
+-- In case, there is a parse error "late" in the file, we might have
+-- already streamed out some (or many!) of these results.
+
+parseTabularBlasts :: B.ByteString -> [BlastTabularResult]
+parseTabularBlasts = go
+  where go xs = case L.parse genParseTabularBlast xs of
+          L.Fail remainingInput ctxts err  -> error $ "parseTabularBlasts failed! " ++ err ++ " ctxt: " ++ show ctxts ++ " head of remaining input: " ++ B.unpack (B.take 1000 remainingInput)
+          L.Done remainingInput btr
+            | B.null remainingInput  -> [btr]
+            | otherwise              -> btr : go remainingInput
+
+genParseBlastProgram :: Parser BlastProgram
+genParseBlastProgram = do
+  choice [string "# BLAST",string "# blast"]
+  (toLower <$> anyChar) >>= return . \case 
+    'x' -> BlastX
+    'p' -> BlastP
+    'n' -> BlastN
+
+genParseTabularBlast :: Parser BlastTabularResult
+genParseTabularBlast = do
+  --choice [string "# BLAST",string "# blast"]
+  --_blastProgram <- choice [string "p",string "P",string "x",string "X"] <?> "Program"
+  _blastProgram <- genParseBlastProgram <?> "Program"
+  many1 (notChar '\n')
+  endOfLine
+  string "# Query: " <?> "Query"
+  --_blastQueryId <- many1 (notChar ' ') <* skipWhile (not (string "\n")) <?> "QueryId"
+  _blastQueryId <- takeWhile (not . isSpace) <* manyTill anyChar endOfLine <?> "QueryId"
+  --_blastQueryName <- many' (notChar '\n')  <?> "QueryName"
+  string "# Database: " <?> "Database"
+  _blastDatabase <- many1 (notChar '\n') <?> "Db"
+  string "\n# " <?> "header linebreak"
+  --fields line
+  skipMany (try genParseFieldLine) <?> "Fields"
+  _blastHitNumber <- decimal  <?> "Hit number"
+  string " hits found\n" <?> "hits found"
+  _tabularHit <- count  _blastHitNumber (try genParseBlastTabularHit)  <?> "Tabular hit"
+  return $ BlastTabularResult _blastProgram (toLB _blastQueryId) (B.pack _blastDatabase) _blastHitNumber (V.fromList _tabularHit)
+
+genParseFieldLine :: Parser ()
+genParseFieldLine = do
+  string "Fields:"
+  skipMany (notChar '\n')
+  string "\n# "
+  return ()
+
+genParseBlastTabularHit :: Parser BlastTabularHit
+genParseBlastTabularHit = do
+  --start <- peekChar'
+  --when (start == '#') (fail "irgendwas")
+  --_queryId <- takeWhile (\c ->  c /= '#' || c /= '\t')  <?> "hit qid"
+  _queryId <- takeWhile1 ((/=9) . ord) <?> "hit qid"
+  char '\t'
+  _subjectId <- takeWhile1 ((/=9) . ord) <?> "hit sid"
+  char '\t'
+  _seqIdentity <- double <?> "hit seqid"
+  char '\t'
+  _alignmentLength <- decimal  <?> "hit sid"
+  char '\t'
+  _misMatches <- decimal <?> "hit mmatch"
+  char '\t'
+  _gapOpenScore <- decimal <?> "hit gopen"
+  char '\t'
+  _queryStart <- decimal <?> "hit qstart"
+  char '\t'
+  _queryEnd <- decimal  <?> "hit qend"
+  char '\t'
+  _hitSeqStart <- decimal  <?> "hit sstart"
+  char '\t'
+  _hitSeqEnd <- decimal <?> "hit send"
+  char '\t'
+  _eValue <- double <?> "hit eval"
+  char '\t'
+  _bitScore <- double <?> "hit bs"
+  char '\t'
+  _subjectFrame <- decimal <?> "hit sF"
+  char '\t'
+  _querySeq <- takeWhile1 ((/=9) . ord) <?> "hit qseq" -- 9 == '\t'
+  char '\t'
+  _subjectSeq <- takeWhile1 ((/=10) . ord) <?> "hit subSeq" -- 10 == '\n'
+  char '\n'
+  return $ BlastTabularHit (B.fromStrict _queryId) (B.fromStrict _subjectId) _seqIdentity _alignmentLength _misMatches _gapOpenScore _queryStart _queryEnd _hitSeqStart _hitSeqEnd _eValue _bitScore _subjectFrame (B.fromStrict _querySeq) (B.fromStrict _subjectSeq)
+  
+--IUPAC amino acid with gap
+--aminoacidLetters :: Char -> Bool
+aminoacidLetters = inClass "ARNDCQEGHILMFPSTWYVBZX-"
+
+--IUPAC nucleic acid characters with gap
+--nucleotideLetters :: Char -> Bool
+nucleotideLetters = inClass "AGTCURYSWKMBDHVN-."
+
+--IUPAC nucleic acid characters with gap
+--bioLetters :: Char -> Bool
+bioLetters = inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZ.-"
+
+
+toLB :: C.ByteString -> B.ByteString
+toLB = S.toLazyByteString . S.byteString
diff --git a/Biobase/BLAST/Types.hs b/Biobase/BLAST/Types.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/BLAST/Types.hs
@@ -0,0 +1,49 @@
+
+-- | Encoding of tabular NCBI BLAST+ output
+
+module Biobase.BLAST.Types where
+
+import Prelude hiding (takeWhile)
+import Data.Attoparsec.ByteString.Char8 hiding (isSpace)
+import qualified Data.Attoparsec.ByteString.Lazy as L
+import qualified Data.ByteString.Char8 as C
+import qualified Data.ByteString.Builder as S
+import qualified Data.ByteString.Lazy.Char8 as B
+import qualified Data.Vector as V
+import System.Directory
+import Data.Char
+import Control.Monad
+import Debug.Trace
+import Text.Printf
+
+data BlastTabularResult = BlastTabularResult
+  { blastProgram :: !BlastProgram,
+    blastQueryId :: !B.ByteString,
+--    blastQueryName :: !B.ByteString,
+    blastDatabase :: !B.ByteString,
+    blastHitNumber :: !Int,
+    hitLines :: !(V.Vector BlastTabularHit)
+  }
+  deriving (Show, Eq)
+
+data BlastProgram = BlastX | BlastP | BlastN
+  deriving (Show, Eq)
+
+data BlastTabularHit = BlastTabularHit
+  { queryId :: !B.ByteString,
+    subjectId ::  !B.ByteString,
+    seqIdentity :: !Double,
+    alignmentLength :: !Int,
+    misMatches :: !Int,
+    gapOpenScore :: !Int,
+    queryStart :: !Int,
+    queryEnd :: !Int,
+    hitSeqStart :: !Int,
+    hitSeqEnd :: !Int,
+    eValue :: !Double,
+    bitScore :: !Double,
+    subjectFrame :: !Int,
+    querySeq  :: !B.ByteString,
+    subjectSeq  :: !B.ByteString
+  }
+  deriving (Show, Eq)
diff --git a/Biobase/SubstMatrix.hs b/Biobase/SubstMatrix.hs
--- a/Biobase/SubstMatrix.hs
+++ b/Biobase/SubstMatrix.hs
@@ -1,58 +1,131 @@
 
 module Biobase.SubstMatrix where
 
-import qualified Data.Array.IArray  as A
-import qualified Data.Array.Unboxed as U
-import qualified Data.Map as M
-import Data.Char (toLower)
+import           Control.DeepSeq (NFData(..))
+import           Data.Aeson (FromJSON,ToJSON)
+import           Data.Binary (Binary)
+import           Data.Serialize (Serialize)
+import           Data.Vector.Unboxed.Deriving
+import           GHC.Generics (Generic)
+import qualified Data.Map.Strict as M
+import qualified Data.Vector.Unboxed as VU
 
-import Biobase.Primary
-import Biobase.Codon
+import           Biobase.Primary.AA (AA,aaRange)
+import           Biobase.Primary.Letter
+import           Biobase.Primary.Nuc.DNA (DNA)
+import           Biobase.Primary.Trans (dnaAAmap)
+import           Biobase.Types.Odds
+import           Data.PrimitiveArray
+import qualified Biobase.Primary.AA as AA
+import qualified Biobase.Primary.Nuc.DNA as D
 
 
 
--- | Substitution table for one amino acid with another
+-- | Denotes that we are dealing with a similarity score. Higher is more
+-- similar.
 
-type SubstMatrix = U.Array (Char,Char) Int
+data Similarity
 
--- | Substitution from three DNA nucleotides to an amino acid.
+-- | Denotes that we are dealing with a distance score. Lower is more
+-- similar.
 
-type Nuc3SubstMatrix = U.Array (Nuc,Nuc,Nuc,Char) Int
+data Distance
 
-type Nuc2SubstMatrix = U.Array (Nuc,Nuc,Char) Int
+-- An amino-acid substitution matrix. Tagged with the type of scoring used.
 
-type Nuc1SubstMatrix = U.Array (Nuc,Char) Int
+newtype AASubstMat t = AASubstMat { aaSubstMat :: Unboxed (Z:.Letter AA:.Letter AA) DLO }
+  deriving (Generic,Eq,Read,Show)
 
+instance Binary    (AASubstMat t)
+instance Serialize (AASubstMat t)
+--instance FromJSON  (AASubstMat t)
+--instance ToJSON    (AASubstMat t)
 
+instance NFData (AASubstMat t)
 
--- *
+-- | @PAM@ matrices are similarity matrices.
 
-mkNuc3SubstMatrix :: SubstMatrix -> Nuc3SubstMatrix
-mkNuc3SubstMatrix mat = A.accumArray (\_ z -> z) (-10) ((nN,nN,nN,'*'),(nT,nT,nT,'Z'))
-  [ ( (a,b,c,k), case l of Just l' -> mat A.! (l',k) ; Nothing -> -10 )
-  | a<-acgt, b<-acgt, c<-acgt
-  , k<-['*' .. 'Z']
-  , let abc = map (toLower . fromNuc) [a,b,c]
-  , let l = M.lookup abc codonTable
-  ]
+type SubstPAM = AASubstMat Similarity
 
-mkNuc2SubstMatrix :: (Int -> Int -> Int) -> (Int -> Int) -> SubstMatrix -> Nuc2SubstMatrix
-mkNuc2SubstMatrix f g mat = A.accumArray f (-10) ((nN,nN,'*'),(nT,nT,'Z'))
-  [ ( (x,y,k), case l of Just l' -> mat A.! (l',k) ; Nothing -> -10 )
-  | a<-acgt, b<-acgt, c<-acgt
-  , k<-['*' .. 'Z']
-  , (x,y) <- [ (a,b), (a,c), (b,c) ]
-  , let abc = map (toLower . fromNuc) [a,b,c]
-  , let l = M.lookup abc codonTable
-  ]
+-- | @BLOSUM@ matrices are distance matrices.
 
-mkNuc1SubstMatrix :: (Int -> Int -> Int) -> (Int -> Int) -> SubstMatrix -> Nuc1SubstMatrix
-mkNuc1SubstMatrix f g mat = A.accumArray f (-10) ((nN,'*'),(nT,'Z'))
-  [ ( (x,k), case l of Just l' -> mat A.! (l',k) ; Nothing -> -10 )
-  | a<-acgt, b<-acgt, c<-acgt
-  , k<-['*' .. 'Z']
-  , x <- [a,b,c]
-  , let abc = map (toLower . fromNuc) [a,b,c]
-  , let l = M.lookup abc codonTable
+type SubstBLOSUM = AASubstMat Distance
+
+-- | Substitution matrix from amino acids to nucleotide triplets.
+
+newtype ANuc3SubstMat t = ANuc3SubstMat { anuc3SubstMat :: Unboxed (Z:.Letter AA:.Letter DNA:.Letter DNA:.Letter DNA) DLO }
+  deriving (Generic,Eq,Read,Show)
+
+instance Binary    (ANuc3SubstMat t)
+instance Serialize (ANuc3SubstMat t)
+--instance FromJSON  (ANuc3SubstMat t)
+--instance ToJSON    (ANuc3SubstMat t)
+
+instance NFData (ANuc3SubstMat t)
+
+-- | Substitution matrix from amino acids to degenerate nucleotide
+-- 2-tuples. The third nucleotide letter is missing.
+
+newtype ANuc2SubstMat t = ANuc2SubstMat { anuc2SubstMat :: Unboxed (Z:.Letter AA:.Letter DNA:.Letter DNA) DLO }
+  deriving (Generic,Eq,Read,Show)
+
+instance Binary    (ANuc2SubstMat t)
+instance Serialize (ANuc2SubstMat t)
+--instance FromJSON  (ANuc2SubstMat t)
+--instance ToJSON    (ANuc2SubstMat t)
+
+instance NFData (ANuc2SubstMat t)
+
+-- | Substitution matrix from amino acids to degenerate nucleotide
+-- 1-tuples. Two out of three nucleotides in a triplet are missing.
+
+newtype ANuc1SubstMat t = ANuc1SubstMat { anuc1SubstMat :: Unboxed (Z:.Letter AA:.Letter DNA) DLO }
+  deriving (Generic,Eq,Read,Show)
+
+instance Binary    (ANuc1SubstMat t)
+instance Serialize (ANuc1SubstMat t)
+--instance FromJSON  (ANuc1SubstMat t)
+--instance ToJSON    (ANuc1SubstMat t)
+
+instance NFData (ANuc1SubstMat t)
+
+-- | The usual substitution matrix, but here with a codon and an amino acid
+-- to be compared.
+
+mkANuc3SubstMat :: AASubstMat t -> ANuc3SubstMat t
+mkANuc3SubstMat (AASubstMat m) = ANuc3SubstMat $ fromAssocs (Z:. AA.Stop :. D.A:.D.A:.D.A) (Z:. AA.Z :. D.N:.D.N:.D.N) (DLO $ -999)
+  [ ( (Z:.a:.u:.v:.w) , maybe (DLO $ -999) (\b -> m!(Z:.a:.b)) $ M.lookup uvw dnaAAmap)
+  | a <- aaRange
+  , u <- [D.A .. D.N], v <- [D.A .. D.N], w <- [D.A .. D.N]
+  , let uvw = VU.fromList [u,v,w]
   ]
+
+-- | Create a 2-tuple to amino acid substitution matrix. Here, @f@ combines
+-- all to entries that have the same 2-tuple index.
+
+mkANuc2SubstMat :: (DLO -> DLO -> DLO) -> AASubstMat t -> ANuc2SubstMat t
+mkANuc2SubstMat f (AASubstMat m) = ANuc2SubstMat $ fromAssocs (Z:. AA.Stop :. D.A:.D.A) (Z:. AA.Z :. D.N:.D.N) (DLO $ -999)
+  . M.assocs
+  . M.fromListWith f
+  $ [ ((Z:.a:.x:.y), maybe (DLO $ -999) (\k -> m!(Z:.a:.k)) $ M.lookup uvw dnaAAmap)
+    | a <- aaRange
+    , u <- [D.A .. D.N], v <- [D.A .. D.N], w <- [D.A .. D.N]
+    , (x,y) <- [ (u,v), (u,w), (v,w) ]
+    , let uvw = VU.fromList [u,v,w]
+    ]
+
+-- | The most degenerate case, where just a single nucleotide remains in
+-- the amino-acid / nucleotide substitution. Again, @f@ combines different
+-- entries.
+
+mkANuc1SubstMat :: (DLO -> DLO -> DLO) -> AASubstMat t -> ANuc1SubstMat t
+mkANuc1SubstMat f (AASubstMat m) = ANuc1SubstMat $ fromAssocs (Z:. AA.Stop :. D.A) (Z:. AA.Z :. D.N) (DLO $ -999)
+  . M.assocs
+  . M.fromListWith f
+  $ [ ((Z:.a:.x), maybe (DLO $ -999) (\k -> m!(Z:.a:.k)) $ M.lookup uvw dnaAAmap)
+    | a <- aaRange
+    , u <- [D.A .. D.N], v <- [D.A .. D.N], w <- [D.A .. D.N]
+    , x <- [u,v,w]
+    , let uvw = VU.fromList [u,v,w]
+    ]
 
diff --git a/Biobase/SubstMatrix/Import.hs b/Biobase/SubstMatrix/Import.hs
--- a/Biobase/SubstMatrix/Import.hs
+++ b/Biobase/SubstMatrix/Import.hs
@@ -1,17 +1,28 @@
 
 module Biobase.SubstMatrix.Import where
 
-import qualified Data.Array.IArray as A
-import Control.Applicative
 
-import Biobase.SubstMatrix
+import           Control.Applicative
+import           Data.Char (toLower)
+import qualified Data.Map as M
 
+import           Biobase.Primary.AA (charAA)
+import           Biobase.Types.Odds
+import           Data.PrimitiveArray hiding (map)
+import qualified Biobase.Primary.AA as AA
 
+import           Biobase.SubstMatrix
 
-fromFile :: FilePath -> IO SubstMatrix
+
+
+fromFile :: FilePath -> IO (AASubstMat t)
 fromFile fname = do
   (x:xs) <- dropWhile (("#"==).take 1) . lines <$> readFile fname
   let cs = map head . words $ x -- should give us the characters encoding an amino acid
-  let ss = map (map read . drop 1 . words) $ xs
-  return $ A.accumArray (\_ z -> z) (-10) (('*','*'),('Z','Z')) [ ((k1,k2),z) | (k1,s) <- zip cs ss, (k2,z) <- zip cs s ]
+  let ss = map (map DLO . map read . drop 1 . words) $ xs
+  let xs = [ ((Z:.charAA k1:.charAA k2),z)
+           | (k1,s) <- zip cs ss
+           , (k2,z) <- zip cs s
+           ]
+  return . AASubstMat $ fromAssocs (Z:.AA.Stop:.AA.Stop) (Z:.AA.Z:.AA.Z) (DLO $ -999) xs
 
diff --git a/BiobaseBlast.cabal b/BiobaseBlast.cabal
--- a/BiobaseBlast.cabal
+++ b/BiobaseBlast.cabal
@@ -1,50 +1,111 @@
 name:           BiobaseBlast
-version:        0.0.0.1
-author:         Christian Hoener zu Siederdissen
-maintainer:     choener@tbi.univie.ac.at
-homepage:       http://www.tbi.univie.ac.at/~choener/
-copyright:      Christian Hoener zu Siederdissen, 2013
+version:        0.2.0.0
+author:         Christian Hoener zu Siederdissen, Florian Eggenhofer
+maintainer:     choener@bioinf.uni-leipzig.de
+homepage:       https://github.com/choener/BiobaseBlast
+bug-reports:    https://github.com/choener/BiobaseBlast/issues
+copyright:      Christian Hoener zu Siederdissen, 2013 - 2017
 category:       Bioinformatics
-synopsis:       BLAST-related tools
 license:        GPL-3
 license-file:   LICENSE
 build-type:     Simple
 stability:      experimental
-cabal-version:  >= 1.6.0
+cabal-version:  >= 1.10.0
+tested-with:    GHC == 7.10.3, GHC == 8.0.1, GHC == 8.0.2
+synopsis:       BLAST-related tools
 description:
-                This library contains BLAST-related functionality. For now,
-                this library is very limited (and Ketil Malde provides other
-                BLAST functionality anyway).
+                This library contains BLAST-related functionality:
                 .
-                We do provide parsers for BLOSUM and PAM matrices.
+                - Parser for tabular NCBI BLAST+ output
+                - Parsers for BLOSUM and PAM matrices.
+                - Specialized substitution functions for (in)complete amino
+                  acid / nucleotide triplet substitution.
+                - Incomplete nucleotide patterns map one or two nucleotides to
+                  an amino acid (need for indel editing in the mitochondria of
+                  certain species like /p.polycephalum/).
                 .
-                The matrices can be found here:
+                The matrices are currently not provided but can be found here:
                 <ftp://ftp.ncbi.nih.gov/blast/matrices/>
 
 
 
 extra-source-files:
-  changelog
+  changelog.md
+  README.md
 
 
 
 library
-  build-depends:
-    base >3 && <5           ,
-    array                   ,
-    containers              ,
-    BiobaseXNA >= 0.7.0.2
+  build-depends: base             >= 4.7      && < 5.0
+               , aeson            >= 1.0
+               , attoparsec       >= 0.13
+               , binary           >= 0.7
+               , bytestring
+               , cereal           >= 0.4
+               , containers
+               , deepseq          >= 1.3
+               , directory
+               , vector           >= 0.10
+               , vector-th-unbox  >= 0.2
+               --
+               , BiobaseTypes     == 0.1.2.*
+               , BiobaseXNA       == 0.9.3.*
+               , PrimitiveArray   == 0.8.0.*
 
+  default-language:
+    Haskell2010
+  default-extensions: DeriveGeneric
+                    , MultiParamTypeClasses
+                    , TemplateHaskell
+                    , TypeFamilies
+                    , TypeOperators
   exposed-modules:
     Biobase.SubstMatrix
     Biobase.SubstMatrix.Import
+    Biobase.BLAST
+    Biobase.BLAST.Import
+    Biobase.BLAST.Types
 
   ghc-options:
     -O2
 
 
 
+test-suite properties
+  type:
+    exitcode-stdio-1.0
+  main-is:
+    properties.hs
+  ghc-options:
+    -O2 -threaded -rtsopts -with-rtsopts=-N
+  hs-source-dirs:
+    tests
+  default-language:
+    Haskell2010
+  default-extensions: BangPatterns
+                    , OverloadedStrings
+                    , ScopedTypeVariables
+                    , TemplateHaskell
+  build-depends: base
+               , bytestring
+               , containers
+               , filepath
+               , split                      >= 0.2.3
+               , tasty                      >= 0.11
+               , tasty-quickcheck           >= 0.8
+               , tasty-silver               >= 3.1.9
+               , tasty-th                   >= 0.1
+               --
+               , BiobaseBlast
+
+
+
 source-repository head
-  type: git
-  location: git://github.com/choener/BiobaseBlast
+  type:     git
+  location: https://github.com/choener/BiobaseBlast
+
+source-repository this
+  type:     git
+  location: https://github.com/choener/BiobaseBlast/tree/0.2.0.0
+  tag:      0.2.0.0
 
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+[![Build Status](https://travis-ci.org/choener/BiobaseBlast.svg?branch=master)](https://travis-ci.org/choener/BiobaseBlast)
+
+# BiobaseBlast
+
+This library contains BLAST-related functionality.
+
+
+
+#### Contact
+
+Christian Hoener zu Siederdissen  
+Leipzig University, Leipzig, Germany  
+choener@bioinf.uni-leipzig.de  
+http://www.bioinf.uni-leipzig.de/~choener/  
+
diff --git a/changelog b/changelog
deleted file mode 100644
--- a/changelog
+++ /dev/null
@@ -1,2 +0,0 @@
-0.0.0.1
-		* initial commit
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,16 @@
+0.2.0.0
+-------
+
+- Added parsing functionality for tabular NCBI BLAST+ output
+
+0.1.0.0
+-------
+
+- more efficient tables (using PrimitiveArray)
+- updated to newest PrimitiveArray & BiobaseXNA
+- travis.yml added
+
+0.0.0.1
+-------
+
+- initial commit
diff --git a/tests/properties.hs b/tests/properties.hs
new file mode 100644
--- /dev/null
+++ b/tests/properties.hs
@@ -0,0 +1,13 @@
+
+-- |
+--
+-- TODO some unit tests to check if assumed-known values are in the right
+-- table cells
+
+module Main where
+
+
+
+main :: IO ()
+main = return ()
+
