diff --git a/Text/Search/Sphinx.hs b/Text/Search/Sphinx.hs
--- a/Text/Search/Sphinx.hs
+++ b/Text/Search/Sphinx.hs
@@ -1,55 +1,205 @@
--- | This is the Haskell version of the Sphinx searchd client.
+-- The following functions are not yet implemented:
+-- setFilterFloatRange, setGeoAnchor
+-- resetFilters, resetGroupBy
+-- updateAttributes,
+-- buildKeyWords, escapeString, status, open, close
+module Text.Search.Sphinx ( module Text.Search.Sphinx
+  , Configuration(..), defaultConfig
+  ) where
 
-module Text.Search.Sphinx ( Configuration (..)
-                          , query
-                          , defaultConfig
-                          ) where
+import qualified Text.Search.Sphinx.Types as T (
+  VerCommand(VcSearch, VcExcerpt),
+  SearchdCommand(ScSearch, ScExcerpt),
+  Filter, Filter(..),
+  fromEnumFilter, Filter(..),
+  QueryStatus(..), toStatus, Status(..),
+  SearchResult, Result(..), QueryResult(..))
 
-import Network
-import IO hiding (bracket)
-import System
-import Control.Exception
-import Data.Binary.Get
-import Data.Binary.Put (runPut, Put)
-import Data.ByteString.Lazy hiding (pack, length, map, groupBy, head)
-import Data.ByteString.Lazy.Char8 (pack)
-import qualified Data.ByteString.Lazy as BS
-import Data.Char (ord, chr)
+import Text.Search.Sphinx.Configuration (Configuration(..), defaultConfig)
+import qualified Text.Search.Sphinx.ExcerptConfiguration as ExConf (ExcerptConfiguration(..))
+import Text.Search.Sphinx.Get (times, getResult, readHeader, getStr)
+import Text.Search.Sphinx.Put (num, num64, enum, list, numC, strC,
+                              numC64, stringIntList, str, cmd, verCmd)
+
+import Data.Binary.Put (Put, runPut)
+import Data.Binary.Get (runGet, getWord32be)
+import qualified Data.ByteString.Lazy as BS (ByteString, length, hGet, hPut, tail, append)
 import Data.Int (Int64)
-import Prelude hiding (readList)
-import Text.Search.Sphinx.Get
-import Text.Search.Sphinx.Put
-import Text.Search.Sphinx.Configuration
-import Text.Search.Sphinx.Types (SearchResult)
-import qualified Text.Search.Sphinx.Types as T
 
+import Network (connectTo, PortID(PortNumber))
+import IO (Handle, hFlush)
+import Data.Bits ((.|.))
 
-type Connection = (Handle, Configuration)
+import Prelude hiding (filter, tail)
 
+{- the funnest way to debug this is to run the same query with an existing working client and look at the difference
+ - sudo tcpflow -i lo dst port 9306 
+-}
+import Debug.Trace; debug a = trace (show a) a
 
-connect :: Configuration -> IO Connection
-connect cfg = do connection <- connectTo (host cfg) (PortNumber $ fromIntegral $ port cfg)
-                 bs         <- hGet connection 4
-                 let version   = runGet getWord32be bs
-                     myVersion = runPut (num 1)
-                 hPut connection myVersion
-                 return (connection, cfg)
+{- weren't working properly, should try out on latest version now
+setFilter :: Configuration -> String -> [Int64] -> Bool -> Configuration
+setFilter cfg attr values exclude =
+  let f = (T.FilterValues attr values)
+  in  addFilter cfg (if exclude then T.ExclusionFilter f else f)
 
+setFilterRange :: Configuration -> String -> Int64 -> Int64 -> Bool -> Configuration
+setFilterRange cfg attr min max exclude =
+  let f = (T.FilterRange attr min max)
+  in  addFilter cfg (if exclude then T.ExclusionFilter f else f)
 
+--setFilterFloatRange :: Configuration -> String -> Float -> Float -> Bool -> Configuration
+--setFilterFloatRange cfg attr min max exclude =
+  --let f = (T.FilterFloatRange attr min max)
+  --in  addFilter cfg (if exclude then T.ExclusionFilter f else f)
+
+-- | alternative interface to setFilter* using Filter constructors
+addFilter :: Configuration -> T.Filter -> Configuration
+addFilter cfg filter = cfg { filters = filter : (filters cfg) }
+  -}
+
+-- | The 'query' function runs a single query against the Sphinx daemon.
+query :: Configuration -- ^ The configuration
+      -> String        -- ^ The indexes, "*" means every index
+      -> String        -- ^ The query string
+      -> IO (T.Result T.SearchResult) -- ^ just one search result back
+query config indexes s = do
+    conn <- connect (host config) (port config)
+    let q = addQuery config s indexes ""
+    results <- runQueries conn [q] 1
+    return $ case results of
+      T.Ok rs -> case head rs of -- there is just 1 result
+                        T.QueryOk result        -> T.Ok result
+                        T.QueryWarning w result -> T.Warning w result
+                        T.QueryError code e     -> T.Error code e
+      T.Error   code error      -> T.Error code error
+      T.Retry   retry           -> T.Retry retry
+      T.Warning warning (result:results) -> case result of
+                        T.QueryOk result        -> T.Warning warning result
+                        T.QueryWarning w result -> T.Warning (BS.append warning w) result
+                        T.QueryError code e     -> T.Error code e
+         
+connect :: String -> Int -> IO Handle
+connect host port = do
+  connection <- connectTo host (PortNumber $ fromIntegral $ port)
+  bs         <- BS.hGet connection 4
+  let version   = runGet getWord32be bs
+      myVersion = runPut (num 1)
+  BS.hPut connection myVersion
+  return connection
+
+-- | TODO: add configuration options
+buildExcerpts :: ExConf.ExcerptConfiguration -- ^ Contains host and port for connection and optional configuration for buildExcerpts
+              -> [String]               -- ^ list of document contents to be highlighted
+              -> String                 -- ^ The indexes, "*" means every index
+              -> String                 -- ^ The query string to use for excerpts
+              -> IO (T.Result [BS.ByteString]) -- ^ the documents with excerpts highlighted
+buildExcerpts config docs indexes words = do
+  conn <- connect (ExConf.host config) (ExConf.port config)
+  let req = runPut $ makeBuildExcerpt addExcerpt
+  BS.hPut conn req
+  hFlush conn
+  (status, response) <- getResponse conn
+  case status of
+    T.OK      -> return $ T.Ok (getResults response)
+    T.WARNING -> return $ T.Warning (runGet getStr response) (getResults response)
+    T.RETRY   -> return $ T.Retry (errorMessage response)
+    T.ERROR n -> return $ T.Error n (errorMessage response)
+  where
+    getResults response = runGet ((length docs) `times` getStr) response
+    errorMessage response = BS.tail (BS.tail (BS.tail (BS.tail response)))
+
+    makeBuildExcerpt putExcerpt = do
+      cmd    T.ScExcerpt
+      verCmd T.VcExcerpt  
+      num $ fromEnum $ BS.length (runPut putExcerpt)
+      putExcerpt
+
+    addExcerpt :: Put
+    addExcerpt = do
+      num 0 -- mode
+      num $ excerptFlags config
+      str indexes
+      str words
+      strC config [ExConf.beforeMatch, ExConf.afterMatch, ExConf.chunkSeparator]
+      numC config [ExConf.limit, ExConf.around, ExConf.limitPassages, ExConf.limitWords, ExConf.startPassageId]
+      str $ ExConf.htmlStripMode config
+      list str docs
+
+    modeFlag :: ExConf.ExcerptConfiguration -> (ExConf.ExcerptConfiguration -> Bool) -> Int -> Int
+    modeFlag cfg setting value = if setting cfg then value else 0
+
+    excerptFlags :: ExConf.ExcerptConfiguration -> Int
+    excerptFlags cfg = foldl (.|.) 1 (map (\(s,v) -> modeFlag cfg s v) [
+        (ExConf.exactPhrase,      2 )
+      , (ExConf.singlePassage,    4 )
+      , (ExConf.useBoundaries,    8 )
+      , (ExConf.weightOrder,     16 )
+      , (ExConf.queryMode,       32 )
+      , (ExConf.forceAllWords,   64 )
+      , (ExConf.loadFiles,      128 )
+      , (ExConf.allowEmpty,     256 )
+      ])
+
+
+-- | right now this is just a lower leve method used by the query method
+-- | eventually it will be its own entry point that can run multiple queries by using addQuery
+-- | right now it just runs the first query and ignores the rest
+runQueries :: Handle -> [Put] -> Int -> IO (T.Result [T.QueryResult])
+runQueries conn qs numQueries = do
+    let nQueries = 1
+    let req = runPut $ makeRunQuery (head qs) nQueries
+    BS.hPut conn req
+    hFlush conn
+    getSearchResult conn nQueries
+  where 
+    makeRunQuery query n = do
+      cmd T.ScSearch
+      verCmd T.VcSearch
+      num $ fromEnum $ BS.length (runPut query) + 4
+      num n
+      query
+
+getSearchResult :: Handle -> Int -> IO (T.Result [T.QueryResult])
+getSearchResult conn numResults = do
+  (status, response) <- getResponse conn
+  case status of
+    T.OK      -> return $ T.Ok (getResults response)
+    T.WARNING -> return $ T.Warning (runGet getStr response) (getResults response)
+    T.RETRY   -> return $ T.Retry (errorMessage response)
+    T.ERROR n -> return $ T.Error n (errorMessage response)
+  where
+    getResults response = runGet (numResults `times` getResult) response
+    errorMessage response = BS.tail (BS.tail (BS.tail (BS.tail response)))
+
+getResponse :: Handle -> IO (T.Status, BS.ByteString)
+getResponse conn = do
+  header <- BS.hGet conn 8
+  let (status, version, len) = readHeader header
+  if len == 0
+    then error "received zero-sized searchd response (bad query?)"
+    else return ()
+  response <- BS.hGet conn (fromIntegral len)
+  return (status, response)
+
+-- | right now this is just a lower level method used by the query method
+-- | when runQueries works properly this is used to run batched queries
 addQuery :: Configuration -> String -> String -> String -> Put
-addQuery cfg query index comment = do
-    nums cfg [ offset
+addQuery cfg query indexes comment = do
+    numC cfg [ offset
              , limit
-             , T.matchMode . mode
-             , T.rank      . ranker
-             , T.sort      . sort]
+             , fromEnum . mode
+             , fromEnum . ranker
+             , fromEnum . sort]
     str (sortBy cfg)
     str query
-    numList (weights cfg)
-    str index
-    num 1
-    num64s cfg [minId, maxId]
-    num 0 -- todo: pack len filters + filters
+    list num (weights cfg)
+    str indexes
+    num 1                     -- id64 range marker
+    numC64 cfg [minId, maxId] -- id64 range
+
+    list putFilter (filters cfg)
+
     enum (groupByFunc   cfg)
     str  (groupBy       cfg)
     num  (maxMatches    cfg)
@@ -58,39 +208,24 @@
     num  (retryCount    cfg)
     num  (retryDelay    cfg)
     str  (groupDistinct cfg)
-    num 0 -- anchor point: todo
+    num 0 -- anchor point for setGeoAnchor
     stringIntList (indexWeights cfg)
     num (maxQueryTime cfg)
     stringIntList (fieldWeights cfg)
     str comment
-
--- | The 'query' function queries the Sphinx daemon.
-query :: Configuration -- ^ The configuration
-      -> String        -- ^ The indexes, "*" means every index
-      -> String        -- ^ The query string
-      -> IO SearchResult
-query config indexes s = do
-    conn <- connect config
-    let q = addQuery config s indexes ""
-    results <- runQueries (fst conn) q 1
-    return $ head results -- We only do one query, so we always have one SearchResult
-
-runQueries :: Handle -> Put -> Int -> IO [SearchResult]
-runQueries conn q numQueries = do
-    let req = runPut (makeRunQuery q numQueries)
-    hPut conn req
-    hFlush conn
-    getResponse conn numQueries
+    num 0 -- attribute overrides (none)
+    str (selectClause cfg) -- select-list
+    where
+      {- Not working properly -}
+      putFilter :: T.Filter -> Put
+      putFilter (T.ExclusionFilter filter) = putFilter_ filter True
+      putFilter filter                     = putFilter_ filter False
 
-makeRunQuery query numQueries =  do
-  cmd T.ScSearch
-  verCmd T.VcSearch
-  num $ fromEnum $ BS.length (runPut query) + 4
-  num numQueries
-  query
+      putFilter_ f@(T.FilterValues attr values)  ex = putFilter__ f attr (list num64) [values] ex
+      putFilter_ f@(T.FilterRange  attr min max) ex = putFilter__ f attr num64 [min, max] ex
 
-getResponse conn numResults = do
-  header <- hGet conn 8
-  let x@(status, version, len) = readHeader header
-  response <- hGet conn (fromIntegral len)
-  return $ runGet (numResults `times` getResult) response
+      putFilter__ filter attr puter values exclude = do
+        str (debug attr)
+        num $ (debug $ T.fromEnumFilter filter)
+        mapM_ puter (debug values)
+        num $ (debug $ fromEnum exclude)
diff --git a/Text/Search/Sphinx/Configuration.hs b/Text/Search/Sphinx/Configuration.hs
--- a/Text/Search/Sphinx/Configuration.hs
+++ b/Text/Search/Sphinx/Configuration.hs
@@ -26,6 +26,8 @@
   , minId :: Int
     -- | Maximum ID to match, 0 means no limit
   , maxId :: Int
+    -- | attribute filters
+  , filters :: [T.Filter]
     -- | Group-by sorting clause (to sort groups in result set with)
   , groupBy :: String
     -- | Group-by count-distinct attribute
@@ -48,7 +50,10 @@
   , maxQueryTime :: Int
     -- | Per-field-name weights
   , fieldWeights :: [(String, Int)]
+    -- | attributes to select, defaults to '*'
+  , selectClause :: String -- setSelect in regular API
 }
+ deriving (Show)
 
 -- | A basic, default configuration.
 defaultConfig = Configuration {
@@ -63,6 +68,7 @@
                 , sortBy        = ""
                 , minId         = 0
                 , maxId         = 0
+                , filters       = []
                 , groupSort     = "@group desc"
                 , groupBy       = ""
                 , groupByFunc   = T.Day
@@ -74,4 +80,5 @@
                 , indexWeights  = []
                 , maxQueryTime  = 0
                 , fieldWeights  = []
+                , selectClause  = "*"
               }
diff --git a/Text/Search/Sphinx/ExcerptConfiguration.hs b/Text/Search/Sphinx/ExcerptConfiguration.hs
new file mode 100644
--- /dev/null
+++ b/Text/Search/Sphinx/ExcerptConfiguration.hs
@@ -0,0 +1,61 @@
+module Text.Search.Sphinx.ExcerptConfiguration where
+
+-- import qualified Text.Search.Sphinx.Types as T
+
+data ExcerptConfiguration = ExcerptConfiguration {
+    -- | The hostname of the Sphinx daemon
+    host :: String
+    -- | The portnumber of the Sphinx daemon
+  , port :: Int
+  , beforeMatch :: String
+  , afterMatch :: String
+  , chunkSeparator :: String
+  , limit  :: Int
+  , around :: Int
+  , exactPhrase :: Bool
+  , singlePassage :: Bool
+  , useBoundaries :: Bool
+  , weightOrder :: Bool
+  -- | warning! broken on 1.10-beta (keep to default of false)
+  , queryMode :: Bool
+  , forceAllWords :: Bool
+  , limitPassages :: Int
+  , limitWords :: Int
+  , startPassageId :: Int
+  , loadFiles :: Bool
+  , htmlStripMode :: String
+  , allowEmpty :: Bool
+}
+ deriving (Show)
+
+-- this is true to the API
+defaultConfig = ExcerptConfiguration {
+    port          = 3312
+  , host          = "127.0.0.1"
+  , beforeMatch = "<b>"
+  , afterMatch = "</b>"
+  , chunkSeparator = "..."
+  , limit  = 256
+  , around = 5
+  , exactPhrase = False
+  , singlePassage = False
+  , weightOrder = False
+  , queryMode = False
+  , forceAllWords = False
+  , limitPassages = 0
+  , limitWords = 0
+  , useBoundaries = False
+  , startPassageId = 1
+  , loadFiles = False
+  , htmlStripMode = "index" -- ^ "none", "strip", "index", and "retain". 
+  , allowEmpty = False
+}
+
+-- this seems better to me
+altConfig = defaultConfig {
+    beforeMatch = "<span class='match'>"
+  , afterMatch = "</span>"
+  , chunkSeparator = " &#8230; "
+  -- , queryMode = True Buggy!
+  , forceAllWords = True
+}
diff --git a/Text/Search/Sphinx/Get.hs b/Text/Search/Sphinx/Get.hs
--- a/Text/Search/Sphinx/Get.hs
+++ b/Text/Search/Sphinx/Get.hs
@@ -1,62 +1,77 @@
 module Text.Search.Sphinx.Get where
 
 import Data.Binary.Get
+import Data.Binary.IEEE754
+
 import Data.Int (Int64)
 import Prelude hiding (readList)
 import Data.ByteString.Lazy hiding (pack, length, map, groupBy)
 import Control.Monad
-import Text.Search.Sphinx.Types
+import qualified Text.Search.Sphinx.Types as T
+import Data.Maybe (isJust, fromJust)
 
 -- Utility functions
 getNum :: Get Int
 getNum = getWord32be >>= return . fromEnum
 
+getFloat :: Get Float
+getFloat = getFloat32be
+
 getNum64 :: Get Int64
 getNum64 = getWord64be >>= return . fromIntegral
 
-getNums = readList getNum
 readList f = do num <- getNum
                 num `times` f
 times = replicateM
-readField = readStr
-readStr = do len <- getNum
-             getLazyByteString (fromIntegral len)
 
+getStr = do len <- getNum
+            getLazyByteString (fromIntegral len)
 
-getResult :: Get SearchResult
+getResult :: Get (T.QueryResult)
 getResult = do
-    status     <- getNum
-    -- todo: we suppose the status is OK
-    fields     <- readList readField
-    attrs      <- readList readAttr
-    matchCount <- getNum
-    id64       <- getNum
-    matches    <- matchCount `times` readMatch (id64 > 0) (map snd attrs)
-    [total, totalFound, time, numWords] <- 4 `times` getNum
-    wrds       <- numWords `times` readWord
-    return (SearchResult matches total totalFound wrds)
+  statusNum <- getNum
+  case T.toQueryStatus statusNum of
+    T.QueryERROR n -> do e <- getStr
+                         return $ T.QueryError statusNum e
+    T.QueryOK      -> getResultOk >>= return . T.QueryOk
+    T.QueryWARNING -> do w <- getStr
+                         getResultOk >>= return . (T.QueryWarning w)
+  where
+    getResultOk = do
+      fields     <- readList getStr
+      attrs      <- readList readAttrPair
+      matchCount <- getNum
+      id64       <- getNum
+      matches    <- matchCount `times` readMatch (id64 > 0) (map snd attrs)
+      [total, totalFound, time, numWords] <- 4 `times` getNum
+      wrds       <- numWords `times` readWord
+      return $ T.SearchResult matches total totalFound wrds (map fst attrs)
 
 
-readWord = do s <- readStr
+readWord = do s <- getStr
               [doc, hits] <- 2 `times` getNum
               return (s, doc, hits)
 
 readMatch isId64 attrs = do
     doc <- if isId64 then getNum64 else (getNum >>= return . fromIntegral)
     weight <- getNum
-    matchAttrs <- mapM readMatchAttr attrs
-    return $ Match doc weight matchAttrs
+    matchAttrs <- mapM readAttr attrs
+    return $ T.Match doc weight matchAttrs
+  where
+    readAttr (T.AttrTMulti attr)  = (readList (readAttr attr)) >>= return . T.AttrMulti
+    readAttr T.AttrTBigInt    = getNum64 >>= return . T.AttrBigInt
+    readAttr T.AttrTString    = getStr  >>= return . T.AttrString
+    readAttr T.AttrTUInt      = getNum >>= return . T.AttrUInt
+    readAttr T.AttrTFloat     = getFloat >>= return . T.AttrFloat
+    readAttr _                = getNum  >>= return . T.AttrUInt
 
-readMatchAttr AttrTFloat  = error "readMatchAttr for AttrFloat not implemented yet."
-readMatchAttr AttrTMulti  = getNums >>= return . AttrMulti
-readMatchAttr _           = getNum  >>= return . AttrNum
 
-readAttr = do
-    s <- readStr
+readAttrPair = do
+    s <- getStr
     t <- getNum
     return (s, toEnum t)
 
 readHeader = runGet $ do status  <- getWord16be
                          version <- getWord16be
                          length  <- getWord32be
-                         return (status, version, length)
+                         return (T.toStatus $ fromIntegral status, version, length)
diff --git a/Text/Search/Sphinx/Put.hs b/Text/Search/Sphinx/Put.hs
--- a/Text/Search/Sphinx/Put.hs
+++ b/Text/Search/Sphinx/Put.hs
@@ -1,22 +1,27 @@
 module Text.Search.Sphinx.Put where
 
+import Data.Int (Int64)
+import Data.Binary (Word64)
 import Data.Binary.Put
 import Data.ByteString.Lazy hiding (pack, length, map, groupBy)
 import Data.ByteString.Lazy.Char8 (pack)
 import qualified Data.ByteString.Lazy as BS
 import qualified Text.Search.Sphinx.Types as T
 
-num = putWord32be . toEnum
-num64 = putWord64be . toEnum
+num     = putWord32be . fromIntegral
+num64 i = putWord64be $ fromIntegral i
+
 enum :: Enum a => a -> Put
 enum = num . fromEnum
-numList ls = do num (length ls)
-                mapM_ num ls
-nums cfg   = mapM_ (\x -> num $ x cfg)
-num64s cfg = mapM_ (\x -> num64 $ x cfg)
 
+list f ls = num (length ls) >> mapM_ f ls
+
+numC   cfg = mapM_ (\x -> num   $ x cfg)
+numC64 cfg = mapM_ (\x -> num64 $ x cfg)
+strC   cfg = mapM_ (\x -> str   $ x cfg)
+
 stringIntList :: [(String, Int)] -> Put
-stringIntList xs = num (length xs) >> mapM_ strInt xs
+stringIntList xs = list strInt xs
  where strInt (s,i) = str s >> num i
 
 str :: String -> Put
diff --git a/Text/Search/Sphinx/Types.hs b/Text/Search/Sphinx/Types.hs
--- a/Text/Search/Sphinx/Types.hs
+++ b/Text/Search/Sphinx/Types.hs
@@ -1,7 +1,10 @@
-module Text.Search.Sphinx.Types where
+module Text.Search.Sphinx.Types (
+    module Text.Search.Sphinx.Types
+  , ByteString ) where
 
 import Data.ByteString.Lazy (ByteString)
 import Data.Int (Int64)
+import Data.Maybe (Maybe, isJust)
 
 -- | Search commands
 data SearchdCommand = ScSearch
@@ -20,21 +23,35 @@
                 | VcKeywords
                 deriving (Show)
 
-verCommand VcSearch   = 0x113
-verCommand VcExcerpt  = 0x100
+-- | Important! only 1.1 compatible
+verCommand VcSearch   = 0x117
+verCommand VcExcerpt  = 0x102
 verCommand VcUpdate   = 0x101
 verCommand VcKeywords = 0x100
 
 -- | Searchd status codes
-data Searchd = Ok
-             | Error
-             | Retry
-             | Warning
-             deriving (Show, Enum)
+data Status = OK
+            | RETRY
+            | WARNING
+            | ERROR Int
+            deriving (Show)
 
-searchd :: Searchd -> Int
-searchd = fromEnum
+-- | status from an individual query
+data QueryStatus = QueryOK
+                 | QueryWARNING
+                 | QueryERROR Int
+                 deriving (Show)
 
+toQueryStatus 0 = QueryOK
+toQueryStatus 3 = QueryWARNING
+toQueryStatus 2 = error "Didn't think retry was possible"
+toQueryStatus n = QueryERROR n
+
+toStatus 0 = OK
+toStatus 2 = RETRY
+toStatus 3 = WARNING
+toStatus n = ERROR n
+
 -- | Match modes
 data MatchMode = All
                | Any
@@ -45,19 +62,18 @@
                | Extended2  -- extended engine V2 (TEMPORARY, WILL BE REMOVED)
                deriving (Show, Enum)
 
-matchMode :: MatchMode -> Int
-matchMode = fromEnum
-
 -- | Ranking modes (ext2 only)
 data Rank = ProximityBm25  -- default mode, phrase proximity major factor and BM25 minor one
           | Bm25           -- statistical mode, BM25 ranking only (faster but worse quality)
           | None           -- no ranking, all matches get a weight of 1
           | WordCount      -- simple word-count weighting, rank is a weighted sum of per-field keyword occurence counts
+          | Proximity      -- internally used to emulate SPH_MATCH_ALL queries
+          | MatchAny       -- internaly used to emulate SPHINX_MATCH_ANY searching mode
+          | Fieldmask      -- ?
+          | Sph04          -- like ProximityBm25, but more weight given to matches at beginning or end of field
+          | Total
           deriving (Show, Enum)
 
-rank :: Rank -> Int
-rank = fromEnum
-
 -- | Sort modes
 data Sort = Relevance
           | AttrDesc
@@ -67,45 +83,58 @@
           | Expr
           deriving (Show, Enum)
 
-sort :: Sort -> Int
-sort = fromEnum
-
 -- | Filter types
-data Filter = Values
-            | Range
-            | FloatRange
-            deriving (Show, Enum)
+data Filter = ExclusionFilter Filter
+            | FilterValues String [Int64]
+            | FilterRange  String Int64 Int64
+            -- TODO | FilterFloatRange attr Float Float
+            deriving (Show)
 
-filter :: Filter -> Int
-filter = fromEnum
+-- | shortcut for creating an exclusion filter
+exclude filter = ExclusionFilter filter
 
+fromEnumFilter (FilterValues _ _)  = 0
+fromEnumFilter (FilterRange _ _ _) = 1
+-- fromEnumFilter (FilterFloatRange _ _ _) = 2
+
 -- | Attribute types
-data AttrT = AttrTInteger
-           | AttrTTimestamp
-           | AttrTOrdinal
-           | AttrTBool
-           | AttrTFloat
-           | AttrTMulti
+data AttrT = AttrTUInt          -- unsigned 32-bit integer
+           | AttrTTimestamp     -- timestamp
+           | AttrTStr2Ordinal   -- ordinal string number (integer at search time, specially handled at indexing time)
+           | AttrTBool          -- boolean bit field
+           | AttrTFloat         -- floating point number (IEEE 32-bit)
+           | AttrTBigInt        -- signed 64-bit integer
+           | AttrTString        -- string (binary; in-memory)
+           | AttrTWordCount     -- string word count (integer at search time,tokenized and counted at indexing time)
+           | AttrTMulti AttrT   -- multiple values (0 or more) 
            deriving (Show)
 
 instance Enum AttrT where
     toEnum = toAttrT
     fromEnum = attrT
 
-toAttrT 1          = AttrTInteger
+toAttrT 1          = AttrTUInt
 toAttrT 2          = AttrTTimestamp
-toAttrT 3          = AttrTOrdinal
+toAttrT 3          = AttrTStr2Ordinal
 toAttrT 4          = AttrTBool
 toAttrT 5          = AttrTFloat
-toAttrT 0x40000000 = AttrTMulti     
+toAttrT 6          = AttrTBigInt
+toAttrT 7          = AttrTString
+toAttrT 8          = AttrTWordCount
+toAttrT 0x40000001 = AttrTMulti AttrTUInt
 
-attrT AttrTInteger   = 1
-attrT AttrTTimestamp = 2
-attrT AttrTOrdinal   = 3
-attrT AttrTBool      = 4
-attrT AttrTFloat     = 5
-attrT AttrTMulti     = 0x40000000
+attrMultiMask = 0x40000000
 
+attrT AttrTUInt        = 1
+attrT AttrTTimestamp   = 2
+attrT AttrTStr2Ordinal = 3
+attrT AttrTBool        = 4
+attrT AttrTFloat       = 5
+attrT AttrTBigInt      = 6
+attrT AttrTString      = 7
+attrT AttrTWordCount   = 8
+attrT (AttrTMulti AttrTUInt) = 0x40000001
+
 -- | Grouping functions
 data GroupByFunction = Day
                      | Week
@@ -115,9 +144,6 @@
                      | AttrPair
                      deriving (Show, Enum)
 
-groupByFunction :: GroupByFunction -> Int
-groupByFunction = fromEnum
-
 -- | The result of a query
 data SearchResult = SearchResult {
       -- | The matches
@@ -126,11 +152,27 @@
     , total   :: Int
       -- | Total amount of matching documents in index.
     , totalFound :: Int
-      -- | List of processed words with the number of docs and the number of hits.
+      -- | processed words with the number of docs and the number of hits.
     , words :: [(ByteString, Int, Int)]
+      -- | List of attribute names returned in the result.
+      -- | The Match will contain just the attribute values in the same order.
+    , attributeNames :: [ByteString]
 }
  deriving Show
 
+-- | a single query result, runQueries returns a list of these
+data QueryResult = QueryOk SearchResult
+                 | QueryWarning ByteString SearchResult
+                 | QueryError Int ByteString
+                 deriving (Show)
+
+-- | a result returned from searchd
+data Result a = Ok a
+              | Warning ByteString a
+              | Error Int ByteString
+              | Retry ByteString
+              deriving (Show)
+
 data Match = Match {
              -- Document ID
                documentId :: Int64
@@ -141,6 +183,9 @@
              }
  deriving Show
 
-data Attr = AttrMulti [Int]
-          | AttrNum  Int
- deriving Show
+data Attr = AttrMulti [Attr]
+          | AttrUInt  Int
+          | AttrBigInt Int64
+          | AttrString ByteString
+          | AttrFloat Float
+          deriving (Show)
diff --git a/sphinx.cabal b/sphinx.cabal
--- a/sphinx.cabal
+++ b/sphinx.cabal
@@ -1,5 +1,5 @@
 Name:            sphinx
-Version:         0.2.1
+Version:         0.3.3
 Synopsis:        Haskell bindings to the Sphinx full-text searching deamon.
 Description:     Haskell bindings to the Sphinx full-text searching deamon. This
                  module is heavily inspired by the php and python client.
@@ -8,9 +8,16 @@
 License-file:    LICENSE
 Copyright:       (c) 2008 Tupil
 Author:          Tupil
-Maintainer:      Chris Eidhof <ce+sphinx@tupil.com>
-Exposed-Modules: Text.Search.Sphinx, Text.Search.Sphinx.Types,
-                 Text.Search.Sphinx.Configuration, Text.Search.Sphinx.Indexable
+Maintainer:      Greg Weber <greg@gregweber.info>
+
+Exposed-Modules: Text.Search.Sphinx,
+                 Text.Search.Sphinx.Types,
+                 Text.Search.Sphinx.Configuration, Text.Search.Sphinx.ExcerptConfiguration, 
+                 Text.Search.Sphinx.Indexable
+
 Other-Modules:   Text.Search.Sphinx.Get, Text.Search.Sphinx.Put
+
 Build-Type:      Simple
-Build-Depends:   base, binary, bytestring, network, haskell98, xml
+Build-Depends:   base >= 4 && < 5,
+                 binary, data-binary-ieee754,
+                 bytestring, network, haskell98, xml
