diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,67 +1,151 @@
 # README #
 
-Text.PrettyPrint.Tabulate : Print any list, vector or map as a well-formatted readable table.
+Textme.PrettyPrint.Tabulate : Print any list, vector or map of records as a well-formatted readable table. Nested record structures are printed with hierarchically arranged headers, thus clearly showing the nested structures.
 
 ### Text.PrettyPrint.Tabulate ###
 
 * This module provides simple functions used to print values in tabular format
-* Version 0.2.0.0
+* Version 0.3.0.0
 * Contributions and Bug Reports welcome. Please use the Github issue tracker.
 
+### Release Notes 0.3.0.0 (*This release has breaking changes*)
+
+* This release has some breaking changes which was required to extend
+  functionality. The extended functionality improves on previous
+  release by printing nested records with hierarchical column headers
+
+* All Records types need to update their `Tabulate` instances to provide a flag, namely `ExpandWhenNested` or `DoNotExpandWhenNested`.
+
+* `ppTable` function has been renamed to `printTable` to make the function name more descriptive.
+
+* New function called printTableWithFlds has been added.
+
 ### Example ###
 
 ``` haskell
 
-  -- ./Example.hs
-  :set -XDeriveGeneric
-  :set -XDeriveDataTypeable
+    {-# LANGUAGE MultiParamTypeClasses#-}
+    {-# LANGUAGE DeriveGeneric #-}
+    {-# LANGUAGE DeriveDataTypeable #-}
 
-  import qualified GHC.Generics as G
-  import Data.Data
+    import Text.PrettyPrint.Tabulate
+    import qualified GHC.Generics as G
+    import Data.Data
 
-  import qualified Text.PrettyPrint.Tabulate as T
-  import qualified Data.Map as Map
-  import qualified Data.List as List
-  import qualified Data.Vector as Vector
+    import qualified Text.PrettyPrint.Tabulate as T
 
+    import qualified Data.Map as Map
+    import qualified Data.List as List
+    import qualified Data.Vector as Vector
 
-  data Stock = Stock {ticker::String, price::Double, marketCap::Double} deriving (Data, G.Generic)
-  instance T.Tabulate Stock
+```
 
-  let yahoo =  Stock {ticker="YHOO", price=42.29101010, marketCap=40e9}
-  let google = Stock {ticker="GOOG", price=774.210101, marketCap=532.09e9}
-  let amazon = Stock {ticker="AMZN", price=799.161717, marketCap=378.86e9}
+#### Instance Declaration Requirements ####
 
+1. All records definitions should `derive` from `Data` and `Generic`
+2. All field types that are record attributes should have an instance of `CellValueFormatter`. Default instances for standard types are already provided.
+3. All records that need to be printed as a table need to be an instance of `Tabulate`.
+4. Depending on if the nested record's fields have to be expanded, the
+   Tabulate instance could either be
 
-  -- List of records
-  let tickers = [yahoo, google, amazon]
+   `instance Tabulate Price ExpandWhenNested` or
+   `instance Tabulate Price DoNotExpandWhenNested`.
 
-  -- The record type 'Stock' can also be in a Map
-  let tickers_map = Map.fromList [(10, yahoo), (100, google), (1000, amazon)]
+``` haskell
 
-  -- Or in a Vector
-  let tickers_vector = Vector.fromList tickers
+    data FxCode = USD | EUR | JPY deriving (Show, Data, G.Generic)
+    instance T.CellValueFormatter FxCode
 
-  -- Print table from List
-  T.ppTable tickers
-   ticker     price              marketCap
-   YHOO         42.291010100     4.000000000e10
-   GOOG        774.210101000     5.320900000e11
-   AMZN        799.161717000     3.788600000e11
+    -- This record type will be nested inside `Stock`
+    data Price = Price {price::Double, fx_code::FxCode} deriving (Data, G.Generic, Show)
 
-   -- Print table from Map
-   T.ppTable tickers_map
-   Key      ticker     price              marketCap
-   10       YHOO         42.291010100     4.000000000e10
-   100      GOOG        774.210101000     5.320900000e11
-   1000     AMZN        799.161717000     3.788600000e11
+    -- if we do not want the `Price` records to be expanded into their own fields
+    -- then choose `T.DoNotExpandWhenNested`
+    instance T.Tabulate Price T.ExpandWhenNested
+    instance T.CellValueFormatter Price
 
+    data Stock = Stock {ticker::String, local_price::Price, marketCap::Double} deriving (
+        Data, G.Generic, Show)
+    instance T.Tabulate Stock T.ExpandWhenNested
 
-   -- Print table from Vector
-   T.ppTable tickers_vector
-   ticker     price              marketCap
-   YHOO         42.291010100     4.000000000e10
-   GOOG        774.210101000     5.320900000e11
-   AMZN        799.161717000     3.788600000e11
+```
+Once we have the records and required instances created, we can see how
+the created records can be viewed in the tabular format.
+
+``` haskell
+
+    yahoo =  Stock {ticker="YHOO", local_price=Price 42.29101010 USD, marketCap=40e9}
+    google = Stock {ticker="GOOG", local_price=Price 774.210101 EUR, marketCap=532.09e9}
+    amazon = Stock {ticker="AMZN", local_price=Price 799.161717 JPY, marketCap=378.86e9}
+
+    tickers = [yahoo, google, amazon]
+    tickers_vector = Vector.fromList tickers
+    tickers_map:: Map.Map Integer Stock
+    tickers_map = Map.fromList [(10, yahoo), (100, google), (1000, amazon)]
+
+    printExamples:: IO ()
+    printExamples = do
+        putStrLn "Printing records in a list\n"
+        T.printTable tickers
+
+        putStrLn "\nPrinting records in a map with the index.\nNote the `key(s)` are printed as first columns"
+        T.printTable tickers_map
+
+        putStrLn "\nPrinting records in a vector\n"
+        T.printTable tickers_vector
+
+        -- Sometimes records may have too many fields. In those case, specific fields can
+        -- be chosen to be printed. Currently, support for this functionality is
+        -- minimal. The 'headers` are not printed. In the future, a function that
+        -- can take header labels as a list will be provided.
+
+        putStrLn "\nPrinting specific fields. Note, currently field names are not printed"
+        T.printTableWithFlds [T.DFld (price . local_price), T.DFld ticker] tickers_map
+
+        putStrLn "\nPrint nested record in a map, individually"
+        T.printTable $ fmap local_price tickers_map
+
+```
+
+### Print the examples ###
+
+``` haskell
+
+    main:: IO ()
+    main = do
+        printExamples
+```
+
+### Output ###
+
+``` haskell ignore
+    Printing records in a list
+
+    ticker     local_price        local_price     marketCap
+    -          price              fx_code         -
+    YHOO           42.2910101     USD               4.0000000e10
+    GOOG          774.2101010     EUR               5.3209000e11
+    AMZN          799.1617170     JPY               3.7886000e11
+
+    Printing records in a map with the index (Note the `key` is printed as the first column)
+
+    -        ticker     local_price        local_price     marketCap
+    -        -          price              fx_code         -
+    10       YHOO           42.2910101     USD               4.0000000e10
+    100      GOOG          774.2101010     EUR               5.3209000e11
+    1000     AMZN          799.1617170     JPY               3.7886000e11
+
+    Printing records in a vector
+
+    ticker     local_price        local_price     marketCap
+    -          price              fx_code         -
+    YHOO           42.2910101     USD               4.0000000e10
+    GOOG          774.2101010     EUR               5.3209000e11
+    AMZN          799.1617170     JPY               3.7886000e11
+
+    Printing specific fields. Note, currently field names are not printed
+    10           42.2910101     YHOO
+    100         774.2101010     GOOG
+    1000        799.1617170     AMZN
 
 ```
diff --git a/pptable.cabal b/pptable.cabal
--- a/pptable.cabal
+++ b/pptable.cabal
@@ -1,7 +1,7 @@
 name:                pptable
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            Pretty Print containers in a tabular format
-description:         Please see README.md
+description:         When you are faced with tens of records data types contained in a list or similar structure if becomes difficult to view all records during iterative development. This library provides a generic funciton to print any such record types in a tabular format that makes visualizing the data more pleasing. Please see README.md for examples of this.
 homepage:            https://github.com/gdevanla/pptable#readme
 license:             MIT
 license-file:        LICENSE
@@ -14,9 +14,9 @@
 cabal-version:       >=1.10
 
 library
-  hs-source-dirs:      src
-  exposed-modules:     Text.PrettyPrint.Tabulate, Text.PrettyPrint.Tabulate.Example
-  build-depends:       base >= 4.7 && < 5
+  hs-source-dirs:     src
+  exposed-modules:    Text.PrettyPrint.Tabulate
+  build-depends:      base >= 4.7 && < 5
                      , syb
                      , containers
                      , pretty
@@ -41,6 +41,24 @@
                      , boxes
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
   default-language:    Haskell2010
+
+test-suite readme
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             README.lhs
+  build-depends:       base
+                     , pptable
+                     , tasty
+                     , HUnit
+                     , QuickCheck
+                     , tasty-hunit
+                     , tasty-quickcheck
+                     , containers
+                     , vector
+                     , boxes
+                     , markdown-unlit
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -pgmL markdown-unlit
+  default-language:    Haskell2010  
 
 source-repository head
   type:     git
diff --git a/src/Text/PrettyPrint/Tabulate.hs b/src/Text/PrettyPrint/Tabulate.hs
--- a/src/Text/PrettyPrint/Tabulate.hs
+++ b/src/Text/PrettyPrint/Tabulate.hs
@@ -1,3 +1,9 @@
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE DeriveGeneric #-} -- Remove this
+{-# LANGUAGE DeriveDataTypeable #-} -- Remove this
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE Rank2Types #-}
@@ -6,18 +12,37 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE ConstrainedClassMethods #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
+{-#LANGUAGE ScopedTypeVariables #-}
 
+
 -- | Module implements the default methods for Tabulate
+-- All examples listed in the document need the following language pragmas
+-- and following modules imported
+--
+-- @
+-- {#- LANGUAGE MultiParamTypeClasses}
+-- {#- LANGUAGE DeriveGeneric}
+-- {#- LANGUAGE DeriveDataTypeable}
+--
+-- import qualified GHC.Generics as G
+-- import Data.Data
+-- @
+--
 
 module Text.PrettyPrint.Tabulate
-    (
-      Tabulate(..)
-    , Boxable(..)
-    , CellValueFormatter
-    
-    )where
+  (
+    Tabulate(..)
+  , Boxable(..)
+  , CellValueFormatter
+  , ExpandWhenNested
+  , DoNotExpandWhenNested
+  , DisplayFld(..)
+   )
+where
 
+import Data.Maybe
 import Data.Data
+import Data.Tree
 import Data.Typeable
 import Data.Generics.Aliases
 import GHC.Generics as G
@@ -25,6 +50,7 @@
 import qualified Data.Map as Map
 import qualified Text.PrettyPrint.Boxes as B
 import qualified Data.List as List
+import qualified Data.List as L
 import Text.Printf
 import qualified Data.Vector as V
 
@@ -42,48 +68,83 @@
                                    intValueFormat=Nothing,
                                    doubleValueFormat=Nothing}
 
+data Tag = Constr | Fields | Values deriving (Show)
 
--- | The Generalized class that implements the print feature
---   for any type that derives Generics and Data
-class GTabulate f where
-  -- | Print with default style
-  gprintTable :: f a -> [B.Box]
+class GRecordMeta f where
+  toTree:: f a -> [Tree String]
 
-  -- | For future, will be able to print with provided style
-  gprintTableWithStyle :: TablizeValueFormat -> f a -> [B.Box]
+instance GRecordMeta U1 where
+    toTree U1 = []
 
---- | The instance class for Unit type
-instance GTabulate U1 where
-  gprintTable _ = []
-  gprintTableWithStyle _ _ = []
+instance (GRecordMeta (a), GRecordMeta (b)) => GRecordMeta (a :*: b) where
+  toTree (x :*: y) = (toTree x)  ++ (toTree y)
 
--- | Any records or product types
--- | Nested algebraic types are printed using their respective Show methods
-instance (GTabulate a, GTabulate b) => GTabulate (a :*: b) where
-    gprintTable (a :*: b) = gprintTable a ++ gprintTable b
-    gprintTableWithStyle style (a :*: b) = gprintTableWithStyle style a ++ gprintTableWithStyle style b
+instance (GRecordMeta (a), GRecordMeta (b)) => GRecordMeta (a :+: b) where
+  toTree x = toTree x
 
--- | Sum types
-instance (GTabulate a, GTabulate b) => GTabulate (a :+: b) where
-    gprintTable (L1 x) = gprintTable x
-    gprintTable (R1 x) = gprintTable x
+instance (GRecordMeta a, Selector s) => GRecordMeta (M1 S s a) where
+  toTree a = [Node (selName a) $ toTree (unM1 a)] where
 
-    gprintTableWithStyle style (L1 x) = gprintTableWithStyle style x
-    gprintTableWithStyle style (R1 x) = gprintTableWithStyle style x
+instance (GRecordMeta a, Constructor c) => GRecordMeta (M1 C c a) where
+  -- we don't want to build node for constructor
+  --toTree a = [Node (conName a) $ toTree (unM1 a)]
+  toTree a = toTree (unM1 a)
 
--- | 
-instance (GTabulate a) => GTabulate (M1 i c a) where
-  gprintTable (M1 x) = gprintTable x
-  gprintTableWithStyle style (M1 x) = gprintTableWithStyle style x
+instance (GRecordMeta a) => GRecordMeta (M1 D c a) where
+  toTree (M1 x) = toTree x
 
+instance (CellValueFormatter a, Data a, RecordMeta a) => GRecordMeta (K1 i a) where
+  --toTree x = [Node (show (unK1 x)) (toTree' $ unK1 x)]
+  toTree x = toTree' $ unK1 x
 
--- | The leaf method that actually creates the Boxes that will
--- be used to render the boxes as a table.
-instance (CellValueFormatter a) => GTabulate (K1 i a) where
-  gprintTable (K1 x) = [B.text $ ppFormatter x]
-  gprintTableWithStyle style (K1 x) = [B.text $ ppFormatterWithStyle style x]
+-- | Use this flag to expand a Record Type as a table when
+-- nested inside another record.
+data ExpandWhenNested
 
+-- | Use this flag to not expand a Record type as a table when
+-- nested inside another record. The 'Show' instance of the nested record
+-- is used by default without expanding. This means that the fields of the
+-- nested record are not displayed as separate headers.
+data DoNotExpandWhenNested
 
+-- | Class instance that needs to be instantiated for each
+-- record that needs to be printed using printTable
+--
+-- @
+--
+-- data Stock = Stock {price:: Double, name:: String} derive (Show, G.Generic, Data)
+-- instance Tabulate S 'ExpandWhenNested'
+-- @
+--
+-- If 'S' is embedded inside another `Record` type and should be
+-- displayed in regular Record Syntax, then
+--
+-- @
+--
+-- instance Tabulate S 'DoNotExpandWhenNested'
+-- @
+--
+class Tabulate a flag | a->flag where {}
+
+--instance TypeCast flag HFalse => Tabulate a flag
+instance {-# OVERLAPPABLE #-} (flag ~ DoNotExpandWhenNested) => Tabulate a flag
+
+class RecordMeta a where
+  toTree':: a -> [Tree String]
+
+instance (Tabulate a flag, RecordMeta' flag a) => RecordMeta a where
+  toTree' = toTree'' (undefined::proxy flag)
+
+class RecordMeta' flag a where
+  toTree'':: proxy flag -> a -> [Tree String]
+
+instance (G.Generic a, GRecordMeta (Rep a)) => RecordMeta' ExpandWhenNested a where
+  toTree'' _ a = toTree (G.from a)
+
+instance (CellValueFormatter a) => RecordMeta' DoNotExpandWhenNested a where
+  toTree'' _ a = [Node (ppFormatter a) []]
+
+
 -- |  Class that implements formatting using printf.
 --    Default instances for String, Char, Int, Integer, Double and Float
 --    are provided. For types that are not an instance of this class
@@ -108,7 +169,7 @@
 
 instance CellValueFormatter Integer where
   ppFormatter x = printf "%d" x
-  
+
   ppFormatterWithStyle style x = case integerValueFormat style of
     Just f -> f x
     Nothing -> ppFormatter x
@@ -122,7 +183,7 @@
 
 
 instance CellValueFormatter Float where
-  ppFormatter x = printf "%14.9g" x
+  ppFormatter x = printf "%14.7g" x
 
   ppFormatterWithStyle style x = case floatValueFormat style of
     Just f -> f x
@@ -137,7 +198,7 @@
 
 
 instance CellValueFormatter Double where
-  ppFormatter x = printf "%14.9g" x
+  ppFormatter x = printf "%14.7g" x
 
   ppFormatterWithStyle style x = case doubleValueFormat style of
     Just f -> f x
@@ -145,78 +206,256 @@
 
 instance CellValueFormatter Bool
 
--- | Perform the final alignment of all
--- | generated [[B.Box]]
-alignBox :: [[B.Box]] -> B.Box
-alignBox b = B.hsep 5 B.left cols
-  where
-    cols = List.map (B.vcat B.left) $ List.transpose b
+instance (Show a, CellValueFormatter a) => CellValueFormatter (Maybe a)
 
--- | Helper method that detects an algebraic data type
-isAlgRepConstr t = case dataTypeRep . dataTypeOf $ t of
-  AlgRep [_] -> True
-  _ -> False
 
--- | Class that can be derived by a 'Traversable' to create
---   a list of 'Box' values and print as a Table.
---   Default instances for List, Map and Vector are already provided.
+gen_renderTableWithFlds :: [DisplayFld t] -> [t] -> B.Box
+gen_renderTableWithFlds flds recs = results where
+  col_wise_values = fmap (\(DFld f) -> fmap (ppFormatter .f) recs) flds
+  vertical_boxes = fmap (B.vsep 0 B.top) $ fmap (fmap B.text) col_wise_values
+  results = B.hsep 5 B.top vertical_boxes
+
+
 class Boxable b where
-  toBox :: (Data a, G.Generic a, GTabulate(Rep a)) => b a ->  [[B.Box]]
-  --toBoxWithStyle :: (Data a, G.Generic a, GTabulate(Rep a)) => TablizeValueFormat -> b a ->  [[B.Box]]
-  
-  printTable :: (Data a, G.Generic a, GTabulate(Rep a)) => b a -> IO ()
+  -- toBox :: (Data a, G.Generic a, GRecordMeta(Rep a)) => b a ->  [[B.Box]]
+  -- toBoxWithStyle :: (Data a, G.Generic a, GTabulate(Rep a)) => TablizeValueFormat -> b a ->  [[B.Box]]
+
+  -- | Used to print a container of Records in a tabular format.
+  --
+  -- @
+  --
+  -- data Stock = Stock {price:: Double, ticker:: String} deriving (Show, Data, G.Generic)
+  -- instance Tabulate Stock DoNotExpandWhenNested
+  -- -- this can be a Vector or Map
+  -- let s =  [Stock 10.0 "yahoo", Stock 12.0 "goog", Stock 10.0 "amz"]
+  -- T.printTable s
+  -- @
+  --
+  -- Nested records can also be printed in tabular format
+  --
+  -- @
+  --
+  -- data FxCode = USD | EUR deriving (Show, Data, G.Generic)
+  -- instance 'CellValueFormatter' FxCode
+  --
+  -- data Price = Price {px:: Double, fxCode:: FxCode} deriving (Show, Data, G.Generic)
+  -- instance 'Tabulate' Price 'ExpandWhenNested'
+  -- -- since Price will be nested, it also needs an instance of
+  -- -- CellValueFormatter
+  -- instance CellValueFormatter Price
+  --
+  -- data Stock = Stock {ticker:: String, price:: Price} deriving (Show, Data, G.Generic)
+  -- instance Tabulate Stock DoNotExpandWhenNested
+  --
+  -- -- this can be a Vector or Map
+  -- let s =  [Stock "yahoo" (Price 10.0 USD), Stock "ikea" (Price 11.0 EUR)]
+  -- printTable s
+  -- @
+  --
+  printTable :: (G.Generic a, GRecordMeta (Rep a)) => b a -> IO ()
   --printTableWithStyle :: (Data a, G.Generic a, GTabulate(Rep a)) => TablizeValueFormat -> b a -> IO ()
 
+  -- | Similar to 'printTable' but rather than return IO (), returns a
+  -- 'Box' object that can be printed later on, using 'printBox'
+  renderTable :: (G.Generic a, GRecordMeta (Rep a)) => b a -> B.Box
+
+  -- | Used for printing selected fields from Record types
+  -- This is useful when Records have a large number of fields
+  -- and only few fields need to be introspected at any time.
+  --
+  -- Using the example provided under 'printTables',
+  --
+  -- @
+  -- 'printTableWithFlds' [DFld (px . price), DFld ticker] s
+  --
+  -- @
+  printTableWithFlds :: [DisplayFld t] -> b t -> IO ()
+
+  -- | Same as printTableWithFlds but returns a `Box` object, rather than
+  -- returning an `IO ()`.
+  renderTableWithFlds :: [DisplayFld t] -> b t -> B.Box
+
+-- | Instance methods to render or print a list of records in a tabular format.
 instance Boxable [] where
-  toBox a = case a of
-    [] -> [[B.nullBox]]
-    x:xs -> gprintTable (from x):toBox xs
+  -- | Used to print a list of Records in a tabular format.
+  -- @
+  --
+  -- data Stock = Stock {price:: Double, ticker:: String}
+  -- instance Tabulate S DoNotExpandWhenNested
+  -- let s =  [Stock 10.0 "yahoo", Stock 12.0 "goog", Stock 10.0 "amz"]
+  -- T.printTable s
+  --
+  -- @
+  printTable m = B.printBox $ ppRecords m
 
-  -- | Prints a "List" as a table. Called by "ppTable"
-  -- | Need not be called directly
-  printTable m = do
-    let r = head $ m
-    let header = constrFields . toConstr $ r
-    let header_box = List.map (B.text) header
-    B.printBox $ alignBox $ header_box:toBox m
+  renderTable m = ppRecords m
 
-  
-instance Boxable V.Vector where
-  toBox v = V.toList $ fmap (\x -> (gprintTable (from x))) v
+  -- | Print a "List" of records as a table with just the given fields.
+  -- Called by "printTableWithFlds".
+  printTableWithFlds flds recs = B.printBox $ renderTableWithFlds flds recs
+  renderTableWithFlds = gen_renderTableWithFlds
 
-  -- | Prints a "Vector" as a table. Called by "ppTable"
+
+instance Boxable V.Vector where
+  -- | Prints a "Vector" as a table. Called by "printTable".
   -- | Need not be called directly
-  printTable m = do
-    let r = m V.! 0
-    let header = constrFields . toConstr $ r
-    let header_box = List.map (B.text) header
-    B.printBox $ alignBox $ header_box:toBox m
+  printTable m = B.printBox $ renderTable m  --TODO: switch this to Vector
+  renderTable m = ppRecords $ V.toList m
 
-instance (Show k) => Boxable (Map.Map k) where
-  -- | Returns a Map of Boxed values
-  toBox m =  Map.elems
-              (Map.mapWithKey
-               (\k v -> B.text (show k):gprintTable (from v))
-               m)
+  -- | Print a "Vector" of records as a table with the selected fields.
+  -- Called by "printTableWithFlds".
+  printTableWithFlds flds recs = B.printBox $ renderTableWithFlds flds $ V.toList recs
+  renderTableWithFlds flds recs = gen_renderTableWithFlds flds $ V.toList recs
+
+
+instance (CellValueFormatter k) => Boxable (Map.Map k) where
+
   -- | Prints a "Map" as a table. Called by "ppTable"
   -- | Need not be called directly
-  printTable m = do
-    let r = head . Map.elems $ m
-    let header = constrFields . toConstr $ r
-    let header_box = "Key":List.map (B.text) header
-    B.printBox $ alignBox $ header_box:toBox m
+  printTable m = B.printBox $ renderTable m
+  renderTable m = ppRecordsWithIndex m
 
-    
--- | The elements in a Traverserable should be an instance of Tabulate to be displayed in a tabular format
-class  (Data a) => Tabulate a where
+  -- | Prints a "Map" as a table with the selected fields. Called by "printTable"
+  -- | Need not be called directly
+  printTableWithFlds flds recs = B.printBox $ renderTableWithFlds flds recs
 
-  -- | Generic function that will be provided by the GTabulate class.
-  ppTable :: (Boxable f) => f a -> IO()
-  --ppTableWithStyle :: TablizeValueFormat -> f a -> IO()
+  renderTableWithFlds flds recs = results where
+    data_cols = renderTableWithFlds flds $ Map.elems recs
+    index_cols = B.vsep 0 B.top $ fmap (B.text . ppFormatter) $ Map.keys recs
+    vertical_cols = B.hsep 5 B.top [index_cols, data_cols]
+    results = vertical_cols
 
-  default ppTable :: (Boxable f, G.Generic a, GTabulate (Rep a)) => f a -> IO ()
-  ppTable x = printTable x
+-- Pretty Print the reords as a table. Handles both records inside
+-- Lists and Vectors
+ppRecords :: (GRecordMeta (Rep a), G.Generic a) => [a] -> B.Box
+ppRecords recs = result where
+  result = B.hsep 5 B.top $ createHeaderDataBoxes recs
 
-  --default ppTableWithStyle :: (Boxable f, G.Generic a, GTabulate (Rep a)) => TablizeValueFormat -> f a -> IO ()
-  --ppTableWithStyle x = printTableWithStyle x
+-- Pretty Print the records as a table. Handles records contained in a Map.
+-- Functions also prints the keys as the index of the table.
+ppRecordsWithIndex :: (CellValueFormatter k, GRecordMeta (Rep a), G.Generic a) => (Map.Map k a) -> B.Box
+ppRecordsWithIndex recs = result where
+  data_boxes = createHeaderDataBoxes $ Map.elems recs
+  index_box = createIndexBoxes recs
+  result = B.hsep 5 B.top $ index_box:data_boxes
 
+
+-- What follows are helper functions to build the B.Box structure to print as table.
+
+-- Internal helper functions for building the Tree.
+
+-- Build the list of paths from the root to every leaf.
+constructPath :: Tree a -> [[a]]
+constructPath (Node r []) = [[r]]
+constructPath (Node r f) = [r:x | x <- (L.concatMap constructPath f)]
+
+-- Fill paths with a "-" so that all paths have the
+-- same length.
+fillPath paths = stripped_paths where
+  depth = L.maximum $ L.map L.length paths
+  diff = L.map (\p -> depth - (L.length p)) paths
+  new_paths = L.map (\(p,d) ->  p ++ L.replicate d "-") $ L.zip paths diff
+  stripped_paths = [xs | x:xs <- new_paths]
+
+-- Count the number of fields in the passed structure.
+-- The no of leaves is the sum of all fields across all nested
+-- records in the passed structure.
+countLeaves :: Tree a -> Tree (Int, a)
+countLeaves (Node r f) = case f of
+  [] -> Node (1, r) []
+  x -> countLeaves' x where
+    countLeaves' x  = let
+      count_leaves = fmap countLeaves x
+      level_count = Prelude.foldr (\(Node (c, a) _) b -> c + b) 0 count_leaves
+      in
+      Node (level_count, r) count_leaves
+
+-- Trims a the tree of records and return just the
+-- leaves of the record
+trimTree (Node r f) = trimLeaves r f
+
+-- Helper function called by trimTree.
+trimLeaves r f = Node r (trimLeaves' f) where
+  trimLeaves' f =
+    let result = fmap trimLeaves'' f where
+          trimLeaves'' (Node r' f') = let
+            result' = case f' of
+              [] -> Nothing
+              _ -> Just $ trimLeaves r' f'
+            in
+            result'
+    in
+      catMaybes result
+
+-- Get  all the leaves from the record. Returns all leaves
+-- across the record structure.
+getLeaves :: (CellValueFormatter a) => Tree a -> [String]
+getLeaves (Node r f) = case f of
+  [] -> [(ppFormatter r)]
+  _ -> foldMap getLeaves f
+
+recsToTrees recs = fmap (\a -> Node "root" $ (toTree . G.from $ a)) $ recs
+
+getHeaderDepth rec_trees = header_depth where
+  header_depth = L.length . L.head . fillPath . constructPath . trimTree . L.head $ rec_trees
+
+createBoxedHeaders :: [[String]] -> [B.Box]
+createBoxedHeaders paths = boxes where
+  boxes = L.map wrapWithBox paths
+  wrapWithBox p = B.vsep 0 B.top $ L.map B.text p
+
+--createHeaderCols :: [Tree String] -> [B.Box]
+createHeaderCols rec_trees = header_boxes where
+  header_boxes =  createBoxedHeaders . fillPath . constructPath . trimTree . L.head $ rec_trees
+
+--createDataBoxes :: [Tree a] -> [B.Box]
+createDataBoxes rec_trees = vertical_boxes where
+  horizontal_boxes =  fmap (fmap  B.text) $ fmap getLeaves rec_trees
+  vertical_boxes = fmap (B.vsep 0 B.top) $ L.transpose horizontal_boxes
+
+--createIndexBoxes :: Map.Map a a -> B.Box
+createIndexBoxes recs = index_box where
+  rec_trees = recsToTrees $ Map.elems recs
+  header_depth = getHeaderDepth rec_trees
+  index_col = (L.replicate header_depth "-" ) ++  (L.map ppFormatter $ Map.keys recs)
+  index_box = B.vsep 0 B.top $ L.map B.text index_col
+
+createHeaderDataBoxes recs = vertical_boxes where
+  rec_trees = recsToTrees recs
+  header_boxes = createHeaderCols rec_trees
+  data_boxes = createDataBoxes rec_trees
+  vertical_boxes = fmap (\(a, b) -> B.vsep 0 B.top $ [a, b]) $ L.zip header_boxes data_boxes
+
+
+-- testing
+
+data T = C1 { aInt::Double, aString::String} deriving (Data, Typeable, Show,G.Generic)
+data T1 = C2 { t1:: T, bInt::Double, bString::String} deriving (Data, Typeable, Show, G.Generic)
+
+c1 = C1 1000 "record_c1fdsafaf"
+c2 = C2 c1 100.12121 "record_c2"
+c3 = C2 c1 1001.12111 "record_c2fdsafdsafsafdsafasfa"
+c4 = C2 c1 22222.12121 "r"
+
+instance Tabulate T ExpandWhenNested
+instance Tabulate T1 ExpandWhenNested
+instance CellValueFormatter T
+
+data R2 = R2 {a::Maybe Integer} deriving (G.Generic, Show)
+data R3 = R3 {r31::Maybe Integer, r32::String} deriving (G.Generic, Show)
+tr =  Node "root" (toTree . G.from $ c2)
+r2 = Node "root" (toTree . G.from $ (R2 (Just 10)))
+r3 = Node "root" (toTree . G.from $ (R3 (Just 10) "r3_string"))
+
+-- | Used with 'printTableWithFlds'
+data DisplayFld a = forall s. CellValueFormatter s => DFld (a->s)
+
+-- printTableWithFlds2 :: [DisplayFld t] -> V.Vector t -> IO ()
+-- printTableWithFlds2 flds recs = B.printBox $ printTableWithFlds flds $ V.toList recs
+
+-- printTableWithFlds3 :: (CellValueFormatter k) => [DisplayFld t] -> Map.Map k t -> IO ()
+-- printTableWithFlds3 flds recs = results where
+--   data_cols = printTableWithFlds flds $ Map.elems recs
+--   index_cols = B.vsep 0 B.top $ fmap (B.text . ppFormatter) $ Map.keys recs
+--   vertical_cols = B.hsep 5 B.top [index_cols, data_cols]
+--   results = B.printBox vertical_cols
diff --git a/src/Text/PrettyPrint/Tabulate/Example.hs b/src/Text/PrettyPrint/Tabulate/Example.hs
deleted file mode 100644
--- a/src/Text/PrettyPrint/Tabulate/Example.hs
+++ /dev/null
@@ -1,180 +0,0 @@
--- | Example usage of ppTable library
-
-
-module Text.PrettyPrint.Tabulate.Example
-  (
-
-    -- * Setup extensions
-    -- $setup_extensions
-    
-    -- * Required imports
-    -- $import_generics_and_data
-
-    -- * Import 'Tabulate'
-    -- $import_tabulate
-
-    -- * Use any 'Traversable' 
-    -- $import_containers
-
-    -- * Declare an instance of Tabulate
-    -- $declare_record
-
-    -- * Sample Data
-    -- $create_sample_data
-
-    -- * Printing the table
-    -- $print_table
-
-    -- * Complete Example
-    -- $complete_example
-
-    -- * Output
-    -- $output
-    
-    -- * Extending
-    -- ** Extending for any 'Traversable'
-    -- $boxable_instance
-    
-    -- ** Customizing formatting
-    -- $cell_value_formatter
-    
-
-
-  ) where
-
-import Text.PrettyPrint.Tabulate
-
--- $setup_extensions
--- > :set -XDeriveGeneric
--- > :set -XDeriveDataTypeable
-
--- $import_generics_and_data
--- Generics and Data need to be imported since
--- and type that will needs to be printed in tabular format
--- needs to derive from Generic and Data
---
--- > import qualified GHC.Generics as G
--- > import Data.Data
---
-
--- $import_tabulate
--- Tabulate class and ppTable function are the only declarations
--- to quickly using the library for printing in tabular format
---
--- > import qualified Text.PrettyPrint.Tabulate as T
-
--- $import_containers
--- The data type that we will print in tabular format will have
--- to be an element of a 'Traversable' instance. The ppTable library
--- provides default instances for 'Data.Map', 'Data.Vector' and 'Data.List'.
---
--- We import these modules here to provide examples of their use
--- 
--- > import qualified Data.Map as Map
--- > import qualified Data.List as List
--- > import qualified Data.Vector as Vector
---
-
--- $declare_record
---
--- A record structure  that will be an element in a 'Traversable' instance.
--- The data type has to derive from 'Generic' and 'Data'. 
--- Also an default instance of 'Tabulate' is declared
---
--- > data Stock = Stock {ticker::String, price::Double, marketCap::Double} deriving (Data, G.Generic)
--- > instance T.Tabulate Stock
---
-
--- $create_sample_data
--- 
--- > yahoo =  Stock {ticker="YHOO", price=42.29101010, marketCap=40e9}
--- > google = Stock {ticker="GOOG", price=774.210101, marketCap=532.09e9}
--- > amazon = Stock {ticker="AMZN", price=799.161717, marketCap=378.86e9}
--- > -- List of records
--- > tickers = [yahoo, google, amazon]
--- >
--- > -- The record type 'Stock' can also be in a Map
--- > tickers_map = Map.fromList [(10, yahoo), (100, google), (1000, amazon)]
--- >
--- > -- Or in a Vector
--- > tickers_vector = Vector.fromList tickers
-
--- $print_table
--- 
--- >  putStrLn "\nElements in a List, with records fields as column names\n"
--- >  T.ppTable tickers
--- >
--- >  putStrLn "\nElement in a map, with Key as first column\n"
--- >  T.ppTable tickers_map
--- >
--- >  putStrLn "\nElement in a Vector\n"
--- >  T.ppTable tickers_vector
--- 
-  
-
--- $complete_example
---
--- > -- ./Example.hs
--- > :set -XDeriveGeneric
--- > :set -XDeriveDataTypeable
--- >
--- > import qualified GHC.Generics as G
--- > import Data.Data
--- >
--- > import qualified Text.PrettyPrint.Tabulate as T
--- > import qualified Data.Map as Map
--- > import qualified Data.List as List
--- > import qualified Data.Vector as Vector
--- >
--- >
--- > data Stock = Stock {ticker::String, price::Double, marketCap::Double} deriving (Data, G.Generic)
--- > instance T.Tabulate Stock
--- >
--- > let yahoo =  Stock {ticker="YHOO", price=42.29101010, marketCap=40e9}
--- > let google = Stock {ticker="GOOG", price=774.210101, marketCap=532.09e9}
--- > let amazon = Stock {ticker="AMZN", price=799.161717, marketCap=378.86e9}
--- >
--- >
--- > -- List of records
--- > let tickers = [yahoo, google, amazon]
---
--- > -- The record type 'Stock' can also be in a Map
--- > let tickers_map = Map.fromList [(10, yahoo), (100, google), (1000, amazon)]
--- >
--- > -- Or in a Vector
--- > let tickers_vector = Vector.fromList tickers
-
--- $output
--- > -- Print table from List
--- > T.ppTable tickers
--- > ticker     price              marketCap
--- > YHOO         42.291010100     4.000000000e10
--- > GOOG        774.210101000     5.320900000e11
--- > AMZN        799.161717000     3.788600000e11
--- >
--- > -- Print table from Map
--- >T.ppTable tickers_map
--- > Key      ticker     price              marketCap
--- > 10       YHOO         42.291010100     4.000000000e10
--- > 100      GOOG        774.210101000     5.320900000e11
--- > 1000     AMZN        799.161717000     3.788600000e11
--- >
--- >
--- > -- Print table from Vector
--- > T.ppTable tickers_vector
--- > ticker     price              marketCap
--- > YHOO         42.291010100     4.000000000e10
--- > GOOG        774.210101000     5.320900000e11
--- > AMZN        799.161717000     3.788600000e11
--- >
-
-
-
--- $boxable_instance
--- Any 'Traversable' containers can be extended to work with ppTable by implementing
--- an instance of 'Tabulate'
-
--- $cell_value_formatter
--- Default instances of 'CellValueFormatter' for 'Int', 'Integer', 'String', 'Float' and 'Double' are provided.
--- To customize formatting of any types, an specific implementation of 'CellValueFormatter' can be provided.
-
diff --git a/test/README.lhs b/test/README.lhs
new file mode 100644
--- /dev/null
+++ b/test/README.lhs
@@ -0,0 +1,151 @@
+# README #
+
+Textme.PrettyPrint.Tabulate : Print any list, vector or map of records as a well-formatted readable table. Nested record structures are printed with hierarchically arranged headers, thus clearly showing the nested structures.
+
+### Text.PrettyPrint.Tabulate ###
+
+* This module provides simple functions used to print values in tabular format
+* Version 0.3.0.0
+* Contributions and Bug Reports welcome. Please use the Github issue tracker.
+
+### Release Notes 0.3.0.0 (*This release has breaking changes*)
+
+* This release has some breaking changes which was required to extend
+  functionality. The extended functionality improves on previous
+  release by printing nested records with hierarchical column headers
+
+* All Records types need to update their `Tabulate` instances to provide a flag, namely `ExpandWhenNested` or `DoNotExpandWhenNested`.
+
+* `ppTable` function has been renamed to `printTable` to make the function name more descriptive.
+
+* New function called printTableWithFlds has been added.
+
+### Example ###
+
+``` haskell
+
+    {-# LANGUAGE MultiParamTypeClasses#-}
+    {-# LANGUAGE DeriveGeneric #-}
+    {-# LANGUAGE DeriveDataTypeable #-}
+
+    import Text.PrettyPrint.Tabulate
+    import qualified GHC.Generics as G
+    import Data.Data
+
+    import qualified Text.PrettyPrint.Tabulate as T
+
+    import qualified Data.Map as Map
+    import qualified Data.List as List
+    import qualified Data.Vector as Vector
+
+```
+
+#### Instance Declaration Requirements ####
+
+1. All records definitions should `derive` from `Data` and `Generic`
+2. All field types that are record attributes should have an instance of `CellValueFormatter`. Default instances for standard types are already provided.
+3. All records that need to be printed as a table need to be an instance of `Tabulate`.
+4. Depending on if the nested record's fields have to be expanded, the
+   Tabulate instance could either be
+
+   `instance Tabulate Price ExpandWhenNested` or
+   `instance Tabulate Price DoNotExpandWhenNested`.
+
+``` haskell
+
+    data FxCode = USD | EUR | JPY deriving (Show, Data, G.Generic)
+    instance T.CellValueFormatter FxCode
+
+    -- This record type will be nested inside `Stock`
+    data Price = Price {price::Double, fx_code::FxCode} deriving (Data, G.Generic, Show)
+
+    -- if we do not want the `Price` records to be expanded into their own fields
+    -- then choose `T.DoNotExpandWhenNested`
+    instance T.Tabulate Price T.ExpandWhenNested
+    instance T.CellValueFormatter Price
+
+    data Stock = Stock {ticker::String, local_price::Price, marketCap::Double} deriving (
+        Data, G.Generic, Show)
+    instance T.Tabulate Stock T.ExpandWhenNested
+
+```
+Once we have the records and required instances created, we can see how
+the created records can be viewed in the tabular format.
+
+``` haskell
+
+    yahoo =  Stock {ticker="YHOO", local_price=Price 42.29101010 USD, marketCap=40e9}
+    google = Stock {ticker="GOOG", local_price=Price 774.210101 EUR, marketCap=532.09e9}
+    amazon = Stock {ticker="AMZN", local_price=Price 799.161717 JPY, marketCap=378.86e9}
+
+    tickers = [yahoo, google, amazon]
+    tickers_vector = Vector.fromList tickers
+    tickers_map:: Map.Map Integer Stock
+    tickers_map = Map.fromList [(10, yahoo), (100, google), (1000, amazon)]
+
+    printExamples:: IO ()
+    printExamples = do
+        putStrLn "Printing records in a list\n"
+        T.printTable tickers
+
+        putStrLn "\nPrinting records in a map with the index.\nNote the `key(s)` are printed as first columns"
+        T.printTable tickers_map
+
+        putStrLn "\nPrinting records in a vector\n"
+        T.printTable tickers_vector
+
+        -- Sometimes records may have too many fields. In those case, specific fields can
+        -- be chosen to be printed. Currently, support for this functionality is
+        -- minimal. The 'headers` are not printed. In the future, a function that
+        -- can take header labels as a list will be provided.
+
+        putStrLn "\nPrinting specific fields. Note, currently field names are not printed"
+        T.printTableWithFlds [T.DFld (price . local_price), T.DFld ticker] tickers_map
+
+        putStrLn "\nPrint nested record in a map, individually"
+        T.printTable $ fmap local_price tickers_map
+
+```
+
+### Print the examples ###
+
+``` haskell
+
+    main:: IO ()
+    main = do
+        printExamples
+```
+
+### Output ###
+
+``` haskell ignore
+    Printing records in a list
+
+    ticker     local_price        local_price     marketCap
+    -          price              fx_code         -
+    YHOO           42.2910101     USD               4.0000000e10
+    GOOG          774.2101010     EUR               5.3209000e11
+    AMZN          799.1617170     JPY               3.7886000e11
+
+    Printing records in a map with the index (Note the `key` is printed as the first column)
+
+    -        ticker     local_price        local_price     marketCap
+    -        -          price              fx_code         -
+    10       YHOO           42.2910101     USD               4.0000000e10
+    100      GOOG          774.2101010     EUR               5.3209000e11
+    1000     AMZN          799.1617170     JPY               3.7886000e11
+
+    Printing records in a vector
+
+    ticker     local_price        local_price     marketCap
+    -          price              fx_code         -
+    YHOO           42.2910101     USD               4.0000000e10
+    GOOG          774.2101010     EUR               5.3209000e11
+    AMZN          799.1617170     JPY               3.7886000e11
+
+    Printing specific fields. Note, currently field names are not printed
+    10           42.2910101     YHOO
+    100         774.2101010     GOOG
+    1000        799.1617170     AMZN
+
+```
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE ConstrainedClassMethods #-}
-
+{-# LANGUAGE MultiParamTypeClasses#-}
 
 import Data.Map as M
 import Data.List as L
@@ -17,44 +17,70 @@
 import Test.Tasty.HUnit
 
 -- R0 has to derive from Data, since
--- it will be nested 
-data R0 =  R0 {test_string::String,
+-- it will be nested
+data R01 =  R01 {test_string::String,
                test_integer::Integer,
                test_float::Float,
                test_double::Double}
   deriving (Data, Show, G.Generic)
--- data R01 =  R01 {r1_id::Int, nested_r::R0}
---   deriving (Show, G.Generic, Data)
--- data R3 =  R3 {r3_id::Int, nested_rlist::[R0]}
---   deriving (Show, G.Generic, Data)
--- data R4 = R4 {r4_id::Int, nested_rtuple::(R0,R0)}
---   deriving (Show, G.Generic, Data)
+instance T.CellValueFormatter R01
 
-instance T.Tabulate R0
--- instance T.Tabulate R01
--- instance T.Tabulate R3
--- instance T.Tabulate R4
+data R02 =  R02 {r2_id::Int, nested_r::R01}
+  deriving (Show, G.Generic, Data)
+instance T.CellValueFormatter R02
 
-getR0 = R0 {test_string="Jack-somone"
+data R03 =  R03 {r3_id::Int, nested_r02:: R02}
+          deriving (Show, G.Generic, Data)
+
+instance T.Tabulate R01 T.ExpandWhenNested
+instance T.Tabulate R02 T.ExpandWhenNested
+instance T.Tabulate R03 T.ExpandWhenNested
+
+getR01 = R01 {test_string="Jack-Jack"
            , test_integer=10
            , test_double=10.101
            , test_float=0.101021}
 
+getR02 = R02 {r2_id=10, nested_r=getR01}
+
+getR03 = R03 {r3_id=20, nested_r02=getR02}
+
 testList = testCase "testList"
   (
     do
-      let b = (L.head . L.head) $ T.toBox [getR0]
-      assertEqual "check rows" (B.rows b) 1
-      assertEqual "check cols" (B.cols b) 11
+      let records = Prelude.replicate 2 $ getR03
+          rows = B.rows $ T.renderTable records
+          cols = B.cols $ T.renderTable records
+      assertEqual "row count" rows 5
+      assertEqual "col count" cols 91
   )
 
-testLists = testGroup "test printing lists" [
-  testList
-  ]
 
+testMap = testCase "testMap"
+  (
+    do
+      let records = M.fromList [("key1", getR03), ("key2", getR03)]
+          rows = B.rows $ T.renderTable records
+          cols = B.cols $ T.renderTable records
+      assertEqual "row count" rows 5
+      assertEqual "col count" cols 100
+  )
+
+testVector = testCase "testVector"
+  (
+    do
+      let records = V.fromList [getR03, getR03]
+          rows = B.rows $ T.renderTable records
+          cols = B.cols $ T.renderTable records
+      assertEqual "row count" rows 5
+      assertEqual "col count" cols 91
+  )
+
 tests :: TestTree
 tests = testGroup "Tests" [
-  testLists
+  testList,
+  testMap,
+  testVector
   ]
 
 main = defaultMain tests
