diff --git a/Bio/PDB.hs b/Bio/PDB.hs
--- a/Bio/PDB.hs
+++ b/Bio/PDB.hs
@@ -1,4 +1,4 @@
-module Bio.PDB(parse, write,
+module Bio.PDB(parse, write, PDBWritable,
                Structure(..), Model(..), Chain(..), Residue(..), Atom(..),
                Iterable(..),
                numAtoms, numResidues, numChains, numModels,
@@ -10,7 +10,7 @@
                atomicNumber, atomicMass, covalentRadius, vanDerWaalsRadius
               ) where
 
-import Bio.PDB.IO(parse, write)
+import Bio.PDB.IO(parse, write, PDBWritable)
 import Bio.PDB.Structure
 import Bio.PDB.Iterable
 import Bio.PDB.Fasta
diff --git a/Bio/PDB/IO.hs b/Bio/PDB/IO.hs
--- a/Bio/PDB/IO.hs
+++ b/Bio/PDB/IO.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings  #-}
 -- | Simple input/output wrappers taking filenames, and handling compression.
-module Bio.PDB.IO(parse, write) where
+module Bio.PDB.IO(parse, write, PDBWritable()) where
 
 import qualified Control.Exception(catch)
 import Control.Exception.Base(SomeException)
@@ -9,6 +9,7 @@
 import Bio.PDB.EventParser.PDBParsingAbstractions
 import Bio.PDB.Structure.List as L
 import qualified Bio.PDB.StructurePrinter as PDBSP
+import           Bio.PDB.StructurePrinter(PDBWritable())
 import Control.Monad(when)
 
 import Bio.PDB.EventParser.PDBEvents(PDBEvent(PDBParseError, PDBIgnoredLine))
@@ -51,6 +52,6 @@
   printError [BS.pack filename, ": IGNORED ", line]
 
 -- | Write structure to a .pdb file.
-write :: Bio.PDB.Structure.Structure -> FilePath -> IO ()
+write :: PDBWritable a => a -> FilePath -> IO ()
 write structure fname = writeFile fname $ \h -> PDBSP.write h structure
 
diff --git a/Bio/PDB/Structure/Neighbours.hs b/Bio/PDB/Structure/Neighbours.hs
--- a/Bio/PDB/Structure/Neighbours.hs
+++ b/Bio/PDB/Structure/Neighbours.hs
@@ -1,6 +1,8 @@
 {-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts #-}
 -- | Searching for neighbouring atoms in a 3D space using `Octree`.
-module Bio.PDB.Structure.Neighbours(makeOctree, findInRadius, findNearest)
+module Bio.PDB.Structure.Neighbours(makeOctree,
+                                    findInRadius, findNearest,
+                                    AtomOctree(..))
 where
 
 import qualified Data.Octree                as Oct
diff --git a/Bio/PDB/StructureBuilder/Parallel.hs b/Bio/PDB/StructureBuilder/Parallel.hs
--- a/Bio/PDB/StructureBuilder/Parallel.hs
+++ b/Bio/PDB/StructureBuilder/Parallel.hs
@@ -8,6 +8,7 @@
 import           Bio.PDB.EventParser.PDBEvents(PDBEvent(PDBParseError))
 import           GHC.Conc(numCapabilities)
 import           Control.Parallel.Strategies
+import           Bio.PDB.Util.ParFold(parFold1)
 import           Control.Arrow((&&&))
 import qualified Bio.PDB.Structure.List     as L
 import qualified Data.ByteString.Char8      as BS
@@ -101,7 +102,8 @@
     chunks = chunkString chunkLen input
     pList = map (partialParse fname) chunks
     partialResults  = pList `using` parList (evalTuple3 rdeepseq r0 r0)
-    (struct, errs, ln)  = foldl joinResult (head partialResults) (tail partialResults)
+    (struct, errs, ln)  = parFold1 joinResult partialResults
+    --(struct, errs, ln)  = foldl joinResult (head partialResults) (tail partialResults)
 -- TODO: correct line numbers! partial parse should return Structure + line number
 
 -- | Splits a ByteString into chunks of given size, and ending at end of line.
diff --git a/Bio/PDB/StructurePrinter.hs b/Bio/PDB/StructurePrinter.hs
--- a/Bio/PDB/StructurePrinter.hs
+++ b/Bio/PDB/StructurePrinter.hs
@@ -1,22 +1,66 @@
-{-# LANGUAGE NamedFieldPuns, DisambiguateRecordFields #-}
+{-# LANGUAGE NamedFieldPuns, DisambiguateRecordFields, OverloadedStrings #-}
 -- | High-level output routines for 'Structure'.
-module Bio.PDB.StructurePrinter(write) where
+module Bio.PDB.StructurePrinter(write, PDBWritable()) where
 
 import Prelude hiding(print)
+import Control.Monad(mapM_)
+import System.IO(Handle)
 import Data.ByteString.Char8 as BS
+
 import Bio.PDB.Structure
 import Bio.PDB.Iterable
 import Bio.PDB.Structure.List as L
 import Bio.PDB.EventParser.PDBEventPrinter as PR
-import Control.Monad(mapM_)
 import Bio.PDB.EventParser.PDBEvents 
 
 -- | ShowS like type for a list of `PDBEvent`s.
 type PDBEventS = [PDBEvent] -> [PDBEvent]
 
--- | Writes a structure in a PDB format to a filehandle.
-write handle structure = mapM_ (PR.print handle) (structureEvents structure)
-                            
+-- * Class-based interface for generating PDB events from structure fragments.
+-- | Writes a structure or its part in a PDB format to a filehandle.
+write :: PDBWritable a => Handle -> a -> IO ()
+write handle structure = mapM_ (PR.print handle) (pdbEvents structure)
+
+-- | Class generating events for PDB structure fragments.
+class PDBWritable a where
+    pdbEvents :: a -> [PDBEvent]
+    pdbEvents = flip pdbEventS []
+    pdbEventS :: a -> PDBEventS
+
+instance PDBWritable Structure
+  where
+    pdbEvents = structureEvents
+    pdbEventS = error "Structure is closed by definition cannot have continuation!"
+
+instance PDBWritable Model
+  where
+    pdbEventS = modelEvents
+
+instance PDBWritable Chain
+  where
+    pdbEventS = chainEvents
+
+instance PDBWritable Residue
+  where
+    pdbEventS = residueEvents blankChain
+
+instance PDBWritable Atom
+  where
+    pdbEventS = atomEvents blankChain blankResidue
+
+-- | Helper: blank chain in case we don't know which chain residue belongs to.
+blankChain   :: Chain
+blankChain   = Chain { chainId  = ' '
+                     , residues = L.empty }
+
+-- | Helper blank residue in case we don't know which residue the atom belongs to.
+blankResidue :: Residue
+blankResidue = Residue { resName = "UNK"
+                       , resSeq  = 0
+                       , insCode = ' '
+                       , atoms   = L.empty }
+
+-- * Routines for writing event list for fragments of the structure.
 -- | Generates list of `PDBEvent`s from a given Structure.
 structureEvents :: Structure -> [PDBEvent]
 structureEvents s = itfoldr modelEvents [END] s
@@ -79,3 +123,4 @@
                                  charge    = ch,
                                  hetatm    = isHet
                                } : c
+
diff --git a/Bio/PDB/Util/ParFold.hs b/Bio/PDB/Util/ParFold.hs
new file mode 100644
--- /dev/null
+++ b/Bio/PDB/Util/ParFold.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE TemplateHaskell #-}
+-- | Basic parallel folding utility.
+module Bio.PDB.Util.ParFold(parFold1) where
+
+import Data.Tree
+import Data.List
+import Test.QuickCheck.All(quickCheckAll)
+import Test.QuickCheck.Arbitrary
+import Control.Parallel.Strategies(parList, rseq, using)
+
+-- | Parallel folding like fold1, but assuming associativity and using O(n*lg)
+parFold1 f [ ] = error "parFold of empty list!"
+parFold1 f [a] = a
+parFold1 f l   = parFold1 f . (`using` parList rseq) $ aList
+  where
+    aList             = foldLevel l
+    -- | reduction by one level
+    foldLevel [ ]     = [ ]
+    foldLevel [a]     = [a]
+    foldLevel (a:b:l) = (a `f` b):foldLevel l
+    
+
+-- NOTE: join function must be associative
+-- | Checks parFold1 with a given associative function
+--check_join f l = foldBin f l == foldl1 f l
+
+--prop_join_plus l = check_join (+) l
+
+--main = $quickCheckAll
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -15,3 +15,5 @@
 It is aimed to not only deliver event-based interface, but also a high-level data structure for manipulating data in spirit of BioPython's PDB parser. 
 
 Details on official releases are on [Hackage](http://hackage.haskell.org/package/hPDB).
+
+This package is also a part of [Stackage](http://daniel-diaz.github.io/stackagelist/) - a stable subset of Hackage.
diff --git a/changelog b/changelog
new file mode 100644
--- /dev/null
+++ b/changelog
@@ -0,0 +1,19 @@
+-*-Changelog-*-
+
+1.1.1  Jan 2014
+	* Exposed PDBWritable class for all objects that can be written to PDB
+	file.
+
+1.1	Jan 2014
+	* Octree building with Bio.PDB.Structure.Neighbours.
+
+0.9999.1 Sep 2013
+	* Removed most compilation options and replaced them with conditionals
+	on library versions.
+
+0.9999  Sep 2013
+	* Parallel parsing.
+	* Change of Iterable interface from imap -> itmap etc.
+
+0.99   Sep 2013
+	* First public release.
diff --git a/hPDB.cabal b/hPDB.cabal
--- a/hPDB.cabal
+++ b/hPDB.cabal
@@ -1,5 +1,5 @@
 name:                hPDB
-version:             1.1
+version:             1.1.1
 synopsis:            Protein Databank file format library
 homepage:            https://github.com/BioHaskell/hPDB
 stability:           stable
@@ -32,12 +32,12 @@
 
 build-type:          Simple
 cabal-version:       >=1.8
-tested-with:         GHC==7.0.3, GHC==7.2.2, GHC==7.4.1, GHC==7.4.2, GHC==7.6.1, GHC==7.6.2
-extra-source-files:  README.md INSTALL AUTHORS
+tested-with:         GHC==7.0.3, GHC==7.2.2, GHC==7.4.1, GHC==7.4.2, GHC==7.6.1, GHC==7.6.2, GHC==7.6.3
+extra-source-files:  README.md INSTALL AUTHORS changelog
 
 source-repository head
   type:     git
-  location: https://github.com/BioHaskell/hPDB
+  location: https://github.com/BioHaskell/hPDB.git
 
 flag have-mmap
   description: Use mmap to read input faster.
@@ -55,26 +55,6 @@
                http://ghc.haskell.org/trac/ghc/ticket/5289
   default: True
 
--- TODO: Remove these old flags...
-flag old-bytestring
-  description: Use bytestring before version 0.10 (introduced in GHC 7.6), and define NFData for Data.ByteString yourself.
-               Disable for GHC 7.6.
-  default: False
-
-flag old-zlib
-  description: Use zlib before version 0.5.4 (introduced in GHC 7.6).
-               Disable for GHC 7.6.1
-  default: False
-
-flag old-vector
-  description: Use old vector library before version 0.10 (introduced along with GHC 7.6).
-               Disable for GHC 7.6.1 and latest 7.4.2.
-  default: False
-
-source-repository head
-  type:     git
-  location: git://github.com:mgajda/hpdb.git
-
 Library
   ghc-options:      -fspec-constr-count=4 -O3 
   build-depends:    base>=4.0, base <4.8, ghc-prim, directory, mtl, template-haskell, vector, AC-Vector, containers, deepseq, QuickCheck >= 2.5.0.0, text>=0.11.1.13, iterable >= 2.0, parallel >= 3.0.0.0, bytestring, zlib, Octree>= 0.5
@@ -89,7 +69,7 @@
     cpp-options: -DHAVE_TEXT_FORMAT
     build-depends: text-format >= 0.3.1.0
   other-extensions:       ScopedTypeVariables OverloadedStrings BangPatterns NoMonomorphismRestriction EmptyDataDecls MagicHash CPP PatternGuards NamedFieldPuns DisambiguateRecordFields TemplateHaskell MultiParamTypeClasses FlexibleInstances FlexibleContexts
-  other-modules:    Bio.PDB.EventParser.ParseATOM, Bio.PDB.EventParser.ParseCAVEAT, Bio.PDB.EventParser.ParseCISPEP, Bio.PDB.EventParser.ParseCONECT, Bio.PDB.EventParser.ParseCRYST1, Bio.PDB.EventParser.ParseDBREF, Bio.PDB.EventParser.ParseFORMUL, Bio.PDB.EventParser.ParseHEADER, Bio.PDB.EventParser.ParseHELIX, Bio.PDB.EventParser.ParseHET, Bio.PDB.EventParser.ParseHETNAM, Bio.PDB.EventParser.ParseHYDBND, Bio.PDB.EventParser.ParseIntRecord, Bio.PDB.EventParser.ParseJRNL, Bio.PDB.EventParser.ParseLINK, Bio.PDB.EventParser.ParseListRecord, Bio.PDB.EventParser.ParseMASTER, Bio.PDB.EventParser.ParseMatrixRecord, Bio.PDB.EventParser.ParseMODRES, Bio.PDB.EventParser.ParseObsoleting, Bio.PDB.EventParser.ParseREMARK, Bio.PDB.EventParser.ParseREVDAT, Bio.PDB.EventParser.ParseSEQADV, Bio.PDB.EventParser.ParseSEQRES, Bio.PDB.EventParser.ParseSHEET, Bio.PDB.EventParser.ParseSITE, Bio.PDB.EventParser.ParseSLTBRG, Bio.PDB.EventParser.ParseSpecListRecord, Bio.PDB.EventParser.ParseSPLIT, Bio.PDB.EventParser.ParseSSBOND, Bio.PDB.EventParser.ParseTER, Bio.PDB.EventParser.ParseTITLE, Bio.PDB.EventParser.ParseTVECT, Bio.PDB.EventParser.PDBParsingAbstractions, Bio.PDB.EventParser.FastParse, Bio.PDB.Util.MissingInstances, Bio.PDB.Common, Bio.PDB.Iterable.Utils, Bio.PDB.Iterable.Instances, Bio.PDB.StructureBuilder.Internals, Bio.PDB.StructureBuilder.Parallel
+  other-modules:    Bio.PDB.EventParser.ParseATOM, Bio.PDB.EventParser.ParseCAVEAT, Bio.PDB.EventParser.ParseCISPEP, Bio.PDB.EventParser.ParseCONECT, Bio.PDB.EventParser.ParseCRYST1, Bio.PDB.EventParser.ParseDBREF, Bio.PDB.EventParser.ParseFORMUL, Bio.PDB.EventParser.ParseHEADER, Bio.PDB.EventParser.ParseHELIX, Bio.PDB.EventParser.ParseHET, Bio.PDB.EventParser.ParseHETNAM, Bio.PDB.EventParser.ParseHYDBND, Bio.PDB.EventParser.ParseIntRecord, Bio.PDB.EventParser.ParseJRNL, Bio.PDB.EventParser.ParseLINK, Bio.PDB.EventParser.ParseListRecord, Bio.PDB.EventParser.ParseMASTER, Bio.PDB.EventParser.ParseMatrixRecord, Bio.PDB.EventParser.ParseMODRES, Bio.PDB.EventParser.ParseObsoleting, Bio.PDB.EventParser.ParseREMARK, Bio.PDB.EventParser.ParseREVDAT, Bio.PDB.EventParser.ParseSEQADV, Bio.PDB.EventParser.ParseSEQRES, Bio.PDB.EventParser.ParseSHEET, Bio.PDB.EventParser.ParseSITE, Bio.PDB.EventParser.ParseSLTBRG, Bio.PDB.EventParser.ParseSpecListRecord, Bio.PDB.EventParser.ParseSPLIT, Bio.PDB.EventParser.ParseSSBOND, Bio.PDB.EventParser.ParseTER, Bio.PDB.EventParser.ParseTITLE, Bio.PDB.EventParser.ParseTVECT, Bio.PDB.EventParser.PDBParsingAbstractions, Bio.PDB.EventParser.FastParse, Bio.PDB.Util.MissingInstances, Bio.PDB.Common, Bio.PDB.Iterable.Utils, Bio.PDB.Iterable.Instances, Bio.PDB.StructureBuilder.Internals, Bio.PDB.StructureBuilder.Parallel, Bio.PDB.Util.ParFold
   exposed-modules:  Bio.PDB.EventParser.PDBEvents, Bio.PDB.EventParser.PDBEventParser, Bio.PDB.EventParser.ExperimentalMethods, Bio.PDB.EventParser.HelixTypes, Bio.PDB.EventParser.StrandSense, Bio.PDB.Structure, Bio.PDB.StructureBuilder, Bio.PDB.Iterable, Bio.PDB.IO, Bio.PDB.Fasta, Bio.PDB, Bio.PDB.Structure.Vector, Bio.PDB.Structure.Elements, Bio.PDB.Structure.List, Bio.PDB.StructurePrinter, Bio.PDB.EventParser.PDBEventPrinter, Bio.PDB.IO.OpenAnyFile, Bio.PDB.Structure.Neighbours
   exposed:          True
 
