diff --git a/Biobase/Infernal.hs b/Biobase/Infernal.hs
--- a/Biobase/Infernal.hs
+++ b/Biobase/Infernal.hs
@@ -10,7 +10,7 @@
   , eneeVerboseHit
   , vhEneeByteString
   , vhEneeByteStrings
-  , Species(..)
+  , SpeciesTaxonomy(..)
   , tFromFile
   , Clan(..)
   , cFromFile
diff --git a/Biobase/Infernal/Clan.hs b/Biobase/Infernal/Clan.hs
--- a/Biobase/Infernal/Clan.hs
+++ b/Biobase/Infernal/Clan.hs
@@ -1,25 +1,28 @@
 {-# LANGUAGE OverloadedStrings #-}
 
 -- | Rfam clans are a set of biologically related Rfam families. This module
--- provides simple abstraction methods and loaders.
---
--- TODO This has to go into biobase and needs to be made nice-looking.
+-- provides simple abstraction methods and loaders from file and ByteString.
 --
 -- TODO load and parse with enumerator
 
 module Biobase.Infernal.Clan where
 
-import qualified Data.ByteString.Char8 as BS
+import Data.ByteString.Char8 (ByteString)
 
+import Biobase.Infernal.Types
 
 
--- | Simple RfamClan data wrapper. Could Easily be just a list of bytestrings,
--- which it is using strings
 
+-- | Simple Rfam clan data.
+
 data Clan = Clan
-  { accession :: BS.ByteString
-  , identifier :: BS.ByteString
-  , members :: [BS.ByteString]
-  , strings :: [BS.ByteString]
+  -- | result of the "AC    CL00001" line, keeping "1" in this case.
+  { cAccession  :: !ClanAccession
+  -- | the "ID    tRNA" line, keeping "tRNA".
+  , cIdentifier :: !ClanIdentification
+  -- | all the "MB    RF00005;", "MB    RF00023;" lines, keeping "[5,23]".
+  , cMembers    :: ![ModelAccession]
+  -- | all lines of each clan, without any processing (except being in lines).
+  , cStrings    :: ![ByteString]
   } deriving (Read,Show,Eq)
 
diff --git a/Biobase/Infernal/Clan/Import.hs b/Biobase/Infernal/Clan/Import.hs
--- a/Biobase/Infernal/Clan/Import.hs
+++ b/Biobase/Infernal/Clan/Import.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE PatternGuards #-}
 {-# LANGUAGE OverloadedStrings #-}
 
 -- | Importing clan data is probably never time-critical as the total file size
@@ -10,23 +11,34 @@
 import Data.List
 
 import Biobase.Infernal.Clan
+import Biobase.Infernal.Types
 
 
 
--- | Import the complete data strictly.
+-- | Import the complete data from an uncompressed source file.
 
 fromFile :: FilePath -> IO [Clan]
-fromFile fp = do
-  (map mkClan . groupBy (\x y -> "AC"/=(head . BS.words $y)) . BS.lines) `fmap` BS.readFile fp
+fromFile fp = fromByteString `fmap` BS.readFile fp
 
+-- | Transform a bytestring into a list of 'Clan's.
+
+fromByteString :: BS.ByteString -> [Clan]
+fromByteString s = map mkClan
+                 . groupBy (\x y -> "AC"/=(head . BS.words $y))
+                 . BS.lines
+                 $ s
+
 -- | Given a list of bytestrings, create one Clan.
 --
--- TODO return Maybe, make crash-safe
+-- TODO return Maybe, make crash-safe (not really high on the list...)
 
 mkClan :: [BS.ByteString] -> Clan
 mkClan xs = Clan
-  { accession  = (!!1) . BS.words . head . filter ((=="AC") . BS.take 2) $ xs
-  , identifier = (!!1) . BS.words . head . filter ((=="ID") . BS.take 2) $ xs
-  , members    = map BS.init . map (!!1) . filter ((=="MB") . (!!0)) . map BS.words $ xs
-  , strings    = xs
-  }
+  { cAccession  = ClanAccession . f . BS.drop 2 . (!!1) . BS.words . head . filter ((=="AC") . BS.take 2) $ xs
+  , cIdentifier = ClanIdentification . (!!1) . BS.words . head . filter ((=="ID") . BS.take 2) $ xs
+  , cMembers    = map (ModelAccession . f . BS.drop 2 . BS.init . (!!1)) . filter ((=="MB") . (!!0)) . map BS.words $ xs
+  , cStrings    = xs
+  } where
+      f s
+        | Just (k, _) <- BS.readInt s = k
+        | otherwise = error $ "mkClan: " ++ BS.unpack s
diff --git a/Biobase/Infernal/Hit.hs b/Biobase/Infernal/Hit.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/Infernal/Hit.hs
@@ -0,0 +1,36 @@
+
+-- | Accessors for Infernal hits.
+--
+-- TODO modelStartStop pair? same for target?
+--
+-- TODO newtypes for these returns?
+
+module Biobase.Infernal.Hit where
+
+import Data.ByteString.Char8 (ByteString)
+
+import Biobase.Infernal.Types
+
+
+
+-- | Generalized accessors for VerboseHit's and TabularHit's.
+
+class Hit a where
+  -- | Model name (like 5S_rRNA).
+  model       :: a -> ModelIdentification
+  -- | Target name, typically the scaffold or chromosome where the hit occurs.
+  target      :: a -> Scaffold
+  -- | Start of submodel.
+  modelStart  :: a -> Int
+  -- | Stop of submodel.
+  modelStop   :: a -> Int
+  -- | Start of substring in target.
+  targetStart :: a -> Int
+  -- | Stop of substring in target.
+  targetStop  :: a -> Int
+  -- | Bit score of the hit of model in target.
+  bitScore    :: a -> BitScore
+  -- | Evalue, expectation of bit score of higher in target sequence of length.
+  evalue      :: a -> Double
+  -- | G/C content in target.
+  gcPercent   :: a -> Int
diff --git a/Biobase/Infernal/RfamFasta.hs b/Biobase/Infernal/RfamFasta.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/Infernal/RfamFasta.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+
+-- | The Rfam.fasta.gz file provides useful information: (1) conversion between
+-- Rfam accession and Rfam identifier, (2) species accession, (3) name of said
+-- species, and (4) the sequence fasta file.
+
+module Biobase.Infernal.RfamFasta where
+
+import Bio.Core.Sequence
+import Data.ByteString.Char8 as BS
+import Data.Map as M
+import qualified Data.ByteString.Lazy.Char8 as BSL
+import Text.Printf
+
+import Biobase.Infernal.Types
+
+
+
+-- | Rfam FASTA entry.
+
+data RfamFasta = RfamFasta
+  -- | Rfam accession number RFxxxxx (the xxxxx part).
+  { modelAccession    :: !ModelAccession
+  -- | Rfam identifier (like 5S_rRNA).
+  , modelIdentifier   :: !ModelIdentification
+  -- | EMBL sequence accession identifier and position.
+  , sequenceAccession :: !EmblAccession
+  -- | Rfam species accession.
+  , speciesAccession  :: !SpeciesAccession
+  -- | Species name.
+  , speciesName       :: !SpeciesName
+  -- | FASTA data
+  , fastaData         :: !StrictSeqData
+  } deriving (Show)
+
+-- | Since RfamFasta entries are just fasta entries...
+
+instance BioSeq RfamFasta where
+  seqlabel RfamFasta{..}  = SeqLabel . BSL.fromChunks $ [BS.concat
+    [ BS.pack . printf "RF%05d" . unModelAccession $ modelAccession
+    , ";"
+    , unModelIdentification modelIdentifier
+    , ";"
+    , let (a,b,c) = unEmblAccession sequenceAccession in BS.concat [a, "/", BS.pack $ show b, "-", BS.pack $ show c]
+    , "   "
+    , BS.pack . show . unSpeciesAccession $ speciesAccession
+    , ":"
+    , unSpeciesName speciesName
+    ] ]
+  seqdata RfamFasta{..}   = SeqData . BSL.fromChunks $ [unStrictSeqData fastaData]
+  seqlength RfamFasta{..} = Offset . fromInteger . toInteger . BS.length . unStrictSeqData $ fastaData
+
+
+
+-- * Some in-memory lookup systems.
+
+-- | Model accession to model identifier
+
+type ModelAC2ID = Map ModelAccession ModelIdentification
+
+-- | Model identifier to model accession
+
+type ModelID2AC = Map ModelIdentification ModelAccession
+
+-- | Model accession and sequence accession to 'RfamFasta' entry (and model
+-- accession to all entries for this accession).
+
+type ACAC2RfamFasta = Map ModelAccession (Map EmblAccession RfamFasta)
+
+-- | Model identifier and sequence accession to 'RfamFasta' entry.
+
+type IDAC2RfamFasta = Map ModelIdentification (Map EmblAccession RfamFasta)
+
diff --git a/Biobase/Infernal/RfamFasta/Import.hs b/Biobase/Infernal/RfamFasta/Import.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/Infernal/RfamFasta/Import.hs
@@ -0,0 +1,99 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE BangPatterns #-}
+
+-- | Imports an Rfam Fasta file and provides simultaneous export to four
+-- different data structures for lookups.
+
+module Biobase.Infernal.RfamFasta.Import where
+
+import Control.Arrow ((***))
+import Data.ByteString.Char8 as BS
+import Data.Iteratee as I
+import Data.Iteratee.Char as I
+import Data.Iteratee.IO as I
+import Data.Iteratee.ZLib as IZ
+import Data.Map as M
+import Prelude as P
+
+import Biobase.Infernal.RfamFasta
+import Biobase.Infernal.Types
+
+
+
+-- | Enumeratee for RfamFasta entries from a ByteString.
+
+eneeRfamFasta :: (Monad m) => Enumeratee ByteString [RfamFasta] m a
+eneeRfamFasta = enumLinesBS ><> convStream f where
+  f = do
+    th <- I.tryHead
+    case th of
+      Nothing -> error "huh?"
+      Just h  -> do
+                   let (ana,sps) = (BS.split ';' *** BS.split ':' . BS.dropWhile (==' ')) . BS.break (==' ') $ h
+                   fs <- I.takeWhile (\s -> ">" /= BS.take 1 s)
+                   return . (:[]) $ RfamFasta
+                     { modelAccession    = ModelAccession . read . P.drop 2 . unpack $ ana!!0
+                     , modelIdentifier   = ModelIdentification $ ana!!1
+                     , sequenceAccession = mkEmblAccession $ ana!!2
+                     -- , speciesAC = maybe (error $ "ERROR: " ++ show (unpack $ sps!!0,unpack s)) fst . readInt $ sps!!0
+                     , speciesAccession  = SpeciesAccession . maybe (-1) fst . readInt $ sps!!0
+                     , speciesName = SpeciesName $ sps!!1
+                     , fastaData = StrictSeqData . BS.copy . BS.concat $ fs
+                     }
+
+
+
+-- * In-memory lookup
+
+-- | Create a mapping between rfam family accession numbers and rfam family
+-- names.
+
+iModelAC2ID :: (Monad m) => Iteratee [RfamFasta] m ModelAC2ID
+iModelAC2ID = I.foldl' f M.empty where
+  f !m x = insertWith' const (modelAccession x) (modelIdentifier x) m
+
+-- | Create a mapping between rfam family names and rfam family accession
+-- numbers.
+
+iModelID2AC :: (Monad m) => Iteratee [RfamFasta] m ModelID2AC
+iModelID2AC = I.foldl' f M.empty where
+  f !m x = insertWith' const (modelIdentifier x) (modelAccession x) m
+
+-- | Provides a mapping between (Rfam accession, sequence accession) and the
+-- complete 'RfamFasta'.
+
+iACAC2RfamFasta :: (Monad m) => Iteratee [RfamFasta] m ACAC2RfamFasta
+iACAC2RfamFasta = I.foldl' f M.empty where
+  f !m x = insertWith' union (modelAccession x) (M.singleton (sequenceAccession x) x) m
+
+-- | Provides a mapping between (Rfam name, sequence accession) and the complete
+-- 'RfamFasta'.
+
+iIDAC2RfamFasta :: (Monad m) => Iteratee [RfamFasta] m IDAC2RfamFasta
+iIDAC2RfamFasta = I.foldl' f M.empty where
+  f !m x = insertWith' union (modelIdentifier x) (M.singleton (sequenceAccession x) x) m
+
+
+
+-- * File reading.
+
+-- | Convenience function creating all maps.
+
+fromFileZip :: FilePath -> IO (ModelAC2ID, ModelID2AC, ACAC2RfamFasta, IDAC2RfamFasta)
+fromFileZip fp = run =<< ( enumFile 8192 fp
+                         . joinI
+                         . enumInflate GZipOrZlib defaultDecompressParams
+                         . joinI
+                         . eneeRfamFasta
+                         $ I.zip4 iModelAC2ID iModelID2AC iACAC2RfamFasta iIDAC2RfamFasta
+                         )
+
+-- | Convenience function creating all maps.
+
+fromFile :: FilePath -> IO (ModelAC2ID, ModelID2AC, ACAC2RfamFasta, IDAC2RfamFasta)
+fromFile fp = run =<< ( enumFile 8192 fp
+                      . joinI
+                      . eneeRfamFasta
+                      $ I.zip4 iModelAC2ID iModelID2AC iACAC2RfamFasta iIDAC2RfamFasta
+                      )
+
diff --git a/Biobase/Infernal/TabularHit.hs b/Biobase/Infernal/TabularHit.hs
--- a/Biobase/Infernal/TabularHit.hs
+++ b/Biobase/Infernal/TabularHit.hs
@@ -5,15 +5,35 @@
 
 import Data.ByteString.Char8 as BS
 
+import Biobase.Infernal.Hit
+import Biobase.Infernal.Types
 
+
+
+-- | Tabular Infernal hits. See Biobase.Infernal.Hit for description of the
+-- individual fields.
+
 data TabularHit = TabularHit
-  { thModel :: ByteString
-  , thTarget :: ByteString
-  , thScaffoldStart :: Int
-  , thScaffoldStop :: Int
-  , thQueryStart :: Int
-  , thQueryStop :: Int
-  , thBitScore :: Double
-  , thEvalue :: Double
-  , thGCpercent :: Int
+  { thModel       :: !ModelIdentification
+  , thTarget      :: !Scaffold
+  , thTargetStart :: !Int
+  , thTargetStop  :: !Int
+  , thModelStart  :: !Int
+  , thModelStop   :: !Int
+  , thBitScore    :: !BitScore
+  , thEvalue      :: !Double
+  , thGCpercent   :: !Int
   } deriving (Read,Show)
+
+-- | Generalized accessors.
+
+instance Hit TabularHit where
+  model       = thModel
+  target      = thTarget
+  modelStart  = thModelStart
+  modelStop   = thModelStop
+  targetStart = thTargetStart
+  targetStop  = thTargetStop
+  bitScore    = thBitScore
+  evalue      = thEvalue
+  gcPercent   = thGCpercent
diff --git a/Biobase/Infernal/TabularHit/Import.hs b/Biobase/Infernal/TabularHit/Import.hs
--- a/Biobase/Infernal/TabularHit/Import.hs
+++ b/Biobase/Infernal/TabularHit/Import.hs
@@ -16,6 +16,7 @@
 import Data.Iteratee.IO as I
 
 import Biobase.Infernal.TabularHit
+import Biobase.Infernal.Types
 
 
 
@@ -24,18 +25,28 @@
 eneeTabularHit :: (Functor m, Monad m) => Enumeratee ByteString [TabularHit] m a
 eneeTabularHit = enumLinesBS ><> I.filter (\x -> not $ BS.null x || isPrefixOf "#" x) ><> mapStream f where
   f = fromRight . parseOnly p
-  p = TabularHit <$> pString -- model name
-                 <*> pString -- target name
-                 <*> pDecimal -- target start
-                 <*> pDecimal -- target stop
-                 <*> pDecimal -- query start
-                 <*> pDecimal -- query stop
-                 <*> pDouble -- bit score
-                 <*> pDouble -- evalue
-                 <*> pDecimal -- gc content
-  pString = A.skipSpace *> A.takeTill A.isSpace
+  mkTH mName tName tStart tStop qStart qStop bScore eValue gc = TabularHit
+    (ModelIdentification tName)
+    (Scaffold tName)
+    tStart
+    tStop
+    qStart
+    qStop
+    (BitScore bScore)
+    eValue
+    gc
+  p = mkTH <$> pString  -- model name
+           <*> pString  -- target name
+           <*> pDecimal -- target start
+           <*> pDecimal -- target stop
+           <*> pDecimal -- query start
+           <*> pDecimal -- query stop
+           <*> pDouble  -- bit score
+           <*> pDouble  -- evalue
+           <*> pDecimal -- gc content
+  pString  = A.skipSpace *> A.takeTill A.isSpace
   pDecimal = A.skipSpace *> A.decimal
-  pDouble = A.skipSpace *> A.double
+  pDouble  = A.skipSpace *> A.double
 
 -- | Convenience function to load from file and return a big list of tabular
 -- hits.
diff --git a/Biobase/Infernal/Taxonomy.hs b/Biobase/Infernal/Taxonomy.hs
--- a/Biobase/Infernal/Taxonomy.hs
+++ b/Biobase/Infernal/Taxonomy.hs
@@ -8,23 +8,25 @@
 import qualified Data.ByteString.Char8 as BS
 import Data.Char (toLower)
 
+import Biobase.Infernal.Types
 
 
+
 -- | For each species, we store the name and a classification list from most
 -- general (head) to most specific (last). The database comes with the NCBI
 -- taxon identifier (taxid).
 
-data Species = Species
-  { name :: BS.ByteString
-  , classification :: [BS.ByteString]
-  , taxid :: Int
+data SpeciesTaxonomy = SpeciesTaxonomy
+  { stAccession      :: !SpeciesAccession
+  , stName           :: !SpeciesName
+  , stClassification :: ![Classification]
   } deriving (Show)
 
 -- | Given a name such as "Drosophila Melanogaster", returns "d.melanogaster".
 
-shortenName :: BS.ByteString -> BS.ByteString
-shortenName xs
-  | null ws   = xs
-  | [w] <- ws = w
-  | otherwise = BS.map toLower $ BS.take 1 (ws!!0) `BS.append` (BS.cons '.' $ ws!!1)
+shortenName :: SpeciesName -> SpeciesName
+shortenName (SpeciesName xs)
+  | null ws   = SpeciesName xs
+  | [w] <- ws = SpeciesName w
+  | otherwise = SpeciesName . BS.map toLower $ BS.take 1 (ws!!0) `BS.append` (BS.cons '.' $ ws!!1)
   where ws = BS.words xs
diff --git a/Biobase/Infernal/Taxonomy/Import.hs b/Biobase/Infernal/Taxonomy/Import.hs
--- a/Biobase/Infernal/Taxonomy/Import.hs
+++ b/Biobase/Infernal/Taxonomy/Import.hs
@@ -19,6 +19,7 @@
 import Data.Map as M
 
 import Biobase.Infernal.Taxonomy
+import Biobase.Infernal.Types
 
 
 
@@ -27,19 +28,19 @@
 -- TODO there are 9 duplicates in the names, let's find them and see what is
 -- going on
 
-iSpeciesMap :: Monad m => Iteratee [Species] m (M.Map ByteString Species)
+iSpeciesMap :: Monad m => Iteratee [SpeciesTaxonomy] m (M.Map SpeciesName SpeciesTaxonomy)
 iSpeciesMap = I.foldl' f M.empty where
-  f !m x = M.insert (name x) x m
+  f !m x = M.insert (stName x) x m
 
 -- | And a map based on taxon id
 
-iTaxIdMap :: Monad m => Iteratee [Species] m (M.Map Int Species)
+iTaxIdMap :: Monad m => Iteratee [SpeciesTaxonomy] m (M.Map SpeciesAccession SpeciesTaxonomy)
 iTaxIdMap = I.foldl' f M.empty where
-  f !m x = M.insert (taxid x) x m
+  f !m x = M.insert (stAccession x) x m
 
 -- | Imports taxonomy data.
 
-eneeSpecies :: Monad m => Enumeratee ByteString [Either String Species] m a
+eneeSpecies :: Monad m => Enumeratee ByteString [Either String SpeciesTaxonomy] m a
 eneeSpecies = enumLinesBS ><> mapStream (parseOnly mkSpecies)
 
 -- | Given a 'ByteString', create a species entry.
@@ -48,18 +49,18 @@
 -- tab - species name - tab - semicolon separated list of classification names
 -- - dot - end of line.
 
-mkSpecies :: Parser Species
+mkSpecies :: Parser SpeciesTaxonomy
 mkSpecies = f <$> ptaxid <* tab <*> pname <* tab <*> takeByteString where
   f k n xs = let
-               cs = L.map (copy . BS.dropWhile (==' ')) . BS.split ';' . BS.init $ xs
-             in Species (copy n) cs k
+               cs = L.map (Classification . copy . BS.dropWhile (==' ')) . BS.split ';' . BS.init $ xs
+             in SpeciesTaxonomy (SpeciesAccession k) (SpeciesName $ copy n) cs
   ptaxid   = decimal
   pname    = A8.takeWhile (/='\t')
   tab      = char '\t'
 
 -- | Convenience function: given a taxonomy file, produce both maps simultanously.
 
-fromFile :: FilePath -> IO (M.Map ByteString Species, M.Map Int Species)
+fromFile :: FilePath -> IO (M.Map SpeciesName SpeciesTaxonomy, M.Map SpeciesAccession SpeciesTaxonomy)
 fromFile fp = do
   i <- enumFile 8192 fp
     . joinI
diff --git a/Biobase/Infernal/Types.hs b/Biobase/Infernal/Types.hs
new file mode 100644
--- /dev/null
+++ b/Biobase/Infernal/Types.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+-- | All these different accession numbers and identifiers are confusing,
+-- newtype's to the rescue.
+--
+-- TODO some of these names might have to change in the future...
+--
+-- TODO Use INT64 instead of Int...
+
+module Biobase.Infernal.Types where
+
+import Control.Arrow
+import Data.ByteString.Char8 as BS
+
+
+
+-- * Rfam Clans
+
+-- | Clan accession identifier
+
+newtype ClanAccession = ClanAccession {unClanAccession :: Int}
+  deriving (Eq,Ord,Read,Show)
+
+-- | Clan model name
+
+newtype ClanIdentification = ClanIdentification {unClanIdentification :: ByteString}
+  deriving (Eq,Ord,Read,Show)
+
+
+
+-- * Covariance models or Stockholm multiple alignments.
+
+-- | The numeric identifier of a covarience model or Stockholm multiple
+-- alignment as in RFxxxxx.
+
+newtype ModelAccession = ModelAccession {unModelAccession :: Int}
+  deriving (Eq,Ord,Read,Show)
+
+-- | String identifier of a covariance model or Stockholm multiple alignment as
+-- in "5S_rRNA".
+
+newtype ModelIdentification = ModelIdentification {unModelIdentification :: ByteString}
+  deriving (Eq,Ord,Read,Show)
+
+
+
+-- * Individual sequence information
+
+-- | EMBL sequence accession based on sequence accession and sequence start to
+-- stop. (Should this then be RfamSequenceAccession?)
+
+newtype EmblAccession = EmblAccession {unEmblAccession :: (ByteString,Int,Int)}
+  deriving (Eq,Ord,Read,Show)
+
+-- | Simple function to create 'EmblAccession' from a 'ByteString'.
+
+mkEmblAccession :: ByteString -> EmblAccession
+mkEmblAccession s = EmblAccession (sid,start,stop) where
+  (sid,(Just (start,_),Just (stop,_))) = second ((BS.readInt *** (BS.readInt . BS.drop 1)) . BS.span (/='-') . BS.drop 1) . BS.span (/='/') $ s
+
+-- | Numeric species accession number.
+
+newtype SpeciesAccession = SpeciesAccession {unSpeciesAccession :: Int}
+  deriving (Eq,Ord,Read,Show)
+
+-- | String name for species.
+
+newtype SpeciesName = SpeciesName {unSpeciesName :: ByteString}
+  deriving (Eq,Ord,Read,Show)
+
+-- | Strict FASTA data.
+
+newtype StrictSeqData = StrictSeqData {unStrictSeqData :: ByteString}
+  deriving (Eq,Ord,Read,Show)
+
+-- | Classification names (taxonomic classification)
+
+newtype Classification = Classification {unClassification :: ByteString}
+  deriving (Eq,Ord,Read,Show)
+
+
+
+-- * More generic newtypes, sequence identification, etc
+
+-- | Identifies a certain scaffold or chromosome where a hit occurs
+
+newtype Scaffold = Scaffold {unScaffold :: ByteString}
+  deriving (Eq,Ord,Read,Show)
+
+-- | Infernal bit score. Behaves like a double (deriving Num).
+
+newtype BitScore = BitScore {unBitScore :: Double}
+  deriving (Eq,Ord,Read,Show,Num)
diff --git a/Biobase/Infernal/VerboseHit.hs b/Biobase/Infernal/VerboseHit.hs
--- a/Biobase/Infernal/VerboseHit.hs
+++ b/Biobase/Infernal/VerboseHit.hs
@@ -4,32 +4,51 @@
 -- | Provides a datatype for cmsearch verbose output. The Import/Export system
 -- now allows for primitive annotations using "##" as the first two characters.
 -- Annotations are only accepted for individual hits.
+--
+-- TODE biocore / Strand for strand information?
 
 module Biobase.Infernal.VerboseHit where
 
 import Data.ByteString.Char8 as BS
 import Text.Printf
 
+import Biobase.Infernal.Hit
+import Biobase.Infernal.Types
 
 
+
 -- | Captures a complete alignment
 
 data VerboseHit = VerboseHit
-  { vhTarget      :: !(Int,Int)     -- ^ part of target sequence (start counting at 1)
-  , vhQuery       :: !(Int,Int)     -- ^ which part of the CM/stk do we align to
-  , vhCM          :: !ByteString    -- ^ the CM for this alignment
-  , vhStrand      :: !Strand        -- ^ should be either '+' or '-'
-  , vhScore       :: !Double        -- ^ bit score
-  , vhEvalue      :: !Double        -- ^ number of hits we expect to find with 'score' or higher for 'targetSequence' length
-  , vhPvalue      :: !Double        -- ^ ?
-  , vhGC          :: !Int           -- ^ ?
-  , vhScaffold    :: !ByteString    -- ^ scaffold, chromosome, ... (the name of the sequence, not the sequence data!)
-  , vhWuss        :: !ByteString    -- ^ fancy secondary structure annotation using wuss notation
-  , vhConsensus   :: !ByteString    -- ^ query consensus (upper: highly, lower: weak/no)
-  , vhScoring     :: !ByteString    -- ^ represents where positive and negative scores come from
-  , vhSequence    :: !ByteString    -- ^ the target sequence which aligns to the model
-  , vhAnnotation  :: ![ByteString]  -- ^ any annotations that could be associated (# lines)
+  { vhTargetStart :: !Int          -- ^ part of target sequence (start counting at 1)
+  , vhTargetStop  :: !Int
+  , vhModelStart  :: !Int          -- ^ which part of the CM/stk do we align to
+  , vhModelStop   :: !Int          -- ^ which part of the CM/stk do we align to
+  , vhModel       :: !ModelIdentification   -- ^ the CM for this alignment
+  , vhStrand      :: !Strand       -- ^ should be either '+' or '-'
+  , vhBitScore    :: !BitScore     -- ^ bit score
+  , vhEvalue      :: !Double       -- ^ number of hits we expect to find with 'score' or higher for 'targetSequence' length
+  , vhPvalue      :: !Double       -- ^ ?
+  , vhGCpercent   :: !Int          -- ^ ?
+  , vhTarget      :: !Scaffold     -- ^ scaffold, chromosome, ... (the name of the sequence, not the sequence data!)
+  , vhWuss        :: !ByteString   -- ^ fancy secondary structure annotation using wuss notation
+  , vhConsensus   :: !ByteString   -- ^ query consensus (upper: highly, lower: weak/no)
+  , vhScoring     :: !ByteString   -- ^ represents where positive and negative scores come from
+  , vhSequence    :: !ByteString   -- ^ the target sequence which aligns to the model
+  , vhAnnotation  :: ![ByteString] -- ^ any annotations that could be associated (# lines)
   } deriving (Show,Read)
 
 type Strand = Char
 
+-- | Generalized accessors.
+
+instance Hit VerboseHit where
+  model       = vhModel
+  target      = vhTarget
+  modelStart  = vhModelStart
+  modelStop   = vhModelStop
+  targetStart = vhTargetStart
+  targetStop  = vhTargetStop
+  bitScore    = vhBitScore
+  evalue      = vhEvalue
+  gcPercent   = vhGCpercent
diff --git a/Biobase/Infernal/VerboseHit/Export.hs b/Biobase/Infernal/VerboseHit/Export.hs
--- a/Biobase/Infernal/VerboseHit/Export.hs
+++ b/Biobase/Infernal/VerboseHit/Export.hs
@@ -18,6 +18,7 @@
 import Prelude as P
 import Text.Printf
 
+import Biobase.Infernal.Types
 import Biobase.Infernal.VerboseHit
 import Biobase.Infernal.VerboseHit.Internal
 
@@ -25,7 +26,7 @@
 
 -- | Transforms a list of verbose hits into a bytestring.
 --
--- TOOD How to append the last line "//" to the finished stream, if at least
+-- TODO How to append the last line "//" to the finished stream, if at least
 -- one element was printed?
 
 eneeByteString :: Monad m => Enumeratee [VerboseHit] ByteString m a
@@ -49,13 +50,13 @@
 -- switches have to be emitted.
 
 newAcc a@(AliGo{..}) h@VerboseHit{..}
-  | otherwise = ( AliGo vhCM vhScaffold vhStrand [], ls )
+  | otherwise = ( AliGo (unModelIdentification vhModel) (unScaffold vhTarget) vhStrand [], ls )
   where ls = [ "//" | aliCM /= BS.empty && bCM ] ++
-             [ "CM: " `BS.append` vhCM | bCM ] ++
-             [ ">" `BS.append` vhScaffold `BS.append` "\n" | bCM || bSc] ++
+             [ "CM: " `BS.append` unModelIdentification vhModel | bCM ] ++
+             [ ">" `BS.append` unScaffold vhTarget `BS.append` "\n" | bCM || bSc] ++
              [ str `BS.append` " strand results:\n" | bCM || bSc || bSt ]
-        bCM = aliCM /= vhCM
-        bSc = aliScaffold /= vhScaffold
+        bCM = aliCM /= unModelIdentification vhModel
+        bSc = aliScaffold /= unScaffold vhTarget
         bSt = aliStrand /= vhStrand
         str
           | vhStrand == '+' = "Plus"
@@ -70,18 +71,18 @@
 showVerboseHit :: VerboseHit -> BS.ByteString
 showVerboseHit VerboseHit{..} = BS.unlines
   [ BS.pack $ printf " Query = %d - %d, Target = %d - %d"
-                (fst vhQuery) (snd vhQuery) (fst vhTarget) (snd vhTarget)
+                vhModelStart vhModelStop vhTargetStart vhTargetStop
   , BS.pack $ printf " Score = %.2f, E = %f, P = %.4e, GC = %d"
-                vhScore vhEvalue vhPvalue vhGC
+                (unBitScore vhBitScore) vhEvalue vhPvalue vhGCpercent
   , ""
   , ws11 `BS.append` vhWuss
-  , (BS.pack $ printf "%10d " (fst vhQuery))
+  , (BS.pack $ printf "%10d " vhModelStart)
     `BS.append` vhConsensus
-    `BS.append` (BS.pack $ printf " %d" (snd vhQuery))
+    `BS.append` (BS.pack $ printf " %d" vhModelStop)
   , ws11 `BS.append` vhScoring
-  , (BS.pack $ printf "%10d " (fst vhTarget))
+  , (BS.pack $ printf "%10d " vhTargetStart)
     `BS.append` vhSequence
-    `BS.append` (BS.pack $ printf " %d" (snd vhTarget))
+    `BS.append` (BS.pack $ printf " %d" vhTargetStop)
   ] where
     ws11 = BS.pack $ P.replicate 11 ' '
 
@@ -102,5 +103,4 @@
   BS.putStrLn $ BS.take 1000 ys
   return ()
 -}
-
 
diff --git a/Biobase/Infernal/VerboseHit/Import.hs b/Biobase/Infernal/VerboseHit/Import.hs
--- a/Biobase/Infernal/VerboseHit/Import.hs
+++ b/Biobase/Infernal/VerboseHit/Import.hs
@@ -26,6 +26,7 @@
 import Data.Tuple.Select
 import Prelude as P
 
+import Biobase.Infernal.Types
 import Biobase.Infernal.VerboseHit
 import Biobase.Infernal.VerboseHit.Internal
 
@@ -59,15 +60,17 @@
   s <- I.head >>= return . fromRight . parseOnly sepg
   l <- fourLines $ sel4 q
   return . pure $ VerboseHit
-    { vhScaffold = scaf
-    , vhCM = cm
+    { vhTarget = Scaffold scaf
+    , vhModel = ModelIdentification cm
     , vhStrand = pm
-    , vhQuery = (sel1 q, sel2 q)
-    , vhTarget = (sel3 q, sel4 q)
-    , vhScore = sel1 s
+    , vhModelStart = sel1 q
+    , vhModelStop = sel2 q
+    , vhTargetStart = sel3 q
+    , vhTargetStop = sel4 q
+    , vhBitScore = BitScore $ sel1 s
     , vhEvalue = sel2 s
     , vhPvalue = sel3 s
-    , vhGC = sel4 s
+    , vhGCpercent = sel4 s
     , vhWuss = cpy $ l!!0
     , vhConsensus = cpy $ l!!1
     , vhScoring = cpy $ l!!2
diff --git a/BiobaseInfernal.cabal b/BiobaseInfernal.cabal
--- a/BiobaseInfernal.cabal
+++ b/BiobaseInfernal.cabal
@@ -1,5 +1,5 @@
 name:           BiobaseInfernal
-version:        0.5.4.1
+version:        0.6.0.0
 author:         Christian Hoener zu Siederdissen
 maintainer:     choener@tbi.univie.ac.at
 homepage:       http://www.tbi.univie.ac.at/~choener/
@@ -20,8 +20,21 @@
                 annotations. This extension should be backward-compatible with
                 standard-compliant parsers.
                 .
+                This package uses Int's to store sequence position information.
+                Don't compile for 32bit. (And yes, this is a TODO, to change to
+                Int64).
                 .
                 .
+                .
+                Changes in 0.6.0.0
+                .
+                * multiple changes to data representation (mostly newtypes) and
+                  documentation
+                .
+                * load the Rfam.fasta.gz file (and prepare lookup structures)
+                .
+                * partial biocore integration
+                .
                 Changes in 0.5.4.1
                 .
                 * fix-up for VH export
@@ -33,12 +46,14 @@
 library
   build-depends:
     base >3 && <5,
+    biocore,
     attoparsec,
     attoparsec-iteratee,
     bytestring,
     containers,
     either-unwrap,
     iteratee,
+    iteratee-compress,
     transformers,
     tuple,
     vector,
@@ -51,15 +66,19 @@
     Biobase.Infernal.CM
     Biobase.Infernal.CM.Export
     Biobase.Infernal.CM.Import
+    Biobase.Infernal.Hit
+    Biobase.Infernal.RfamFasta
+    Biobase.Infernal.RfamFasta.Import
     Biobase.Infernal.TabularHit
     Biobase.Infernal.TabularHit.Import
     Biobase.Infernal.Taxonomy
     Biobase.Infernal.Taxonomy.Import
+    Biobase.Infernal.Types
     Biobase.Infernal.VerboseHit
     Biobase.Infernal.VerboseHit.Export
     Biobase.Infernal.VerboseHit.Import
     Biobase.Infernal.VerboseHit.Internal
 
   ghc-options:
-    -O2
+    -O2 -funbox-strict-fields
 
