diff --git a/bird.cabal b/bird.cabal
--- a/bird.cabal
+++ b/bird.cabal
@@ -1,5 +1,5 @@
 Name:                 bird
-Version:              0.0.3
+Version:              0.0.6
 Build-type:           Simple
 Synopsis:             A simple, sinatra-inspired web framework.
 Description:          Bird is a hack-compatible framework for simple websites.
@@ -18,6 +18,6 @@
   hs-source-dirs: bin
   
 library
-  build-depends: haskell98, process, containers, bytestring, base >= 4.0 && < 5, hack >= 2009.10.30, hack-handler-happstack, data-default >= 0.2 
-  exposed-modules: Bird, Bird.Request, Bird.Reply, Bird.Reply.Codes
+  build-depends: haskell98, process, containers, parsec >= 2.1.0.1, bytestring, base >= 4.0 && < 5, hack >= 2009.10.30, hack-handler-happstack, data-default >= 0.2, rallod 
+  exposed-modules: Bird, Bird.Request, Bird.Reply, Bird.Reply.Codes, Bird.Request.QueryStringParser
   hs-source-dirs: src/
diff --git a/readme.markdown b/readme.markdown
--- a/readme.markdown
+++ b/readme.markdown
@@ -10,26 +10,26 @@
 
 ## Install
 
-    $ cabal update && cabal install bird
+    λ cabal update && cabal install bird
 
 Note: make sure $HOME/.cabal/bin is in your PATH.
 
 ## Create an app
 
-    $ bird MyApp 
+    λ bird MyApp 
 
 ## Compile your app
 
-    $ cd MyApp
-    $ bird nest 
+    λ cd MyApp
+    λ bird nest 
 
 ## Start your app (runs on port 3000)
 
-    $ bird fly
+    λ bird fly
 
 ## Try it out
     
-    $ curl http://localhost:3000
+    λ curl http://localhost:3000
       404 Not Found
 
 ## Improvise!
@@ -41,12 +41,17 @@
 
     get, post, put, delete :: Request -> IO Reply
     get Request { path = ("howdy":xs) } 
-      = ok $ ("Howdy " ++) $ join ", " xs
+      = ok $ "Howdy " ++ (join ", " xs) ++ "!"
 
     get _ = return notFound_
     post _ = return notFound_
     put _ = return notFound_
     delete _ = return notFound_
+
+now:
+
+    λ curl http://localhost:3000/howdy/there/pardna
+        Howdy there, pardna!
 
 ## Notes
 
diff --git a/src/Bird.hs b/src/Bird.hs
--- a/src/Bird.hs
+++ b/src/Bird.hs
@@ -1,9 +1,9 @@
 module Bird(
-  module Hack, 
-  module Data.Default, 
-  module Bird.Reply,
-  module Bird.Request, 
-  module Bird.Reply.Codes
+  module Hack 
+, module Data.Default 
+, module Bird.Reply
+, module Bird.Request 
+, module Bird.Reply.Codes
 ) where
 
 import Hack
diff --git a/src/Bird/Request.hs b/src/Bird/Request.hs
--- a/src/Bird/Request.hs
+++ b/src/Bird/Request.hs
@@ -6,13 +6,17 @@
 import Hack
 import Data.Default
 import Data.ByteString.Lazy.Char8 (pack)
+import Rallod
+import Text.ParserCombinators.Parsec
+import Numeric
+import Bird.Request.QueryStringParser
 import qualified Data.Map as Hash
 
 data Request = 
   Request { 
     verb      :: RequestMethod,
     path      :: [String],
-    params    :: Hash.Map String String,
+    params    :: Hash.Map String (Maybe String),
     protocol  :: Hack_UrlScheme,
     hackEnvironment :: Env
   } deriving (Show)
@@ -25,19 +29,11 @@
   Request {
     verb = requestMethod e,
     path = split '/' $ pathInfo e,
-    params = Hash.fromList $ buildParams (queryString e),
+    params = Hash.fromList $ parseQueryString $ queryString e,
     protocol = hackUrlScheme e,
     hackEnvironment = e
   }
 
-infixl 9 ==>
-f ==> g = g $ f
-
-buildParams ""          = []
-buildParams queryString = queryString ==> split '&' ==> map (split '=') ==> map tupleize
-
-tupleize (a:b:[]) = (a,b)
-
 split :: Char -> String -> [String]
 split d s
   | findSep == [] = []
@@ -45,3 +41,40 @@
     where
       (t, s'') = break (== d) findSep
       findSep = dropWhile (== d) s
+
+-----
+-- 
+-- parseQuery :: (String -> [(String, Maybe String)])
+-- parseQuery q =   
+--   case (parse (keyValuePair `sepBy` char '&') "Exception: Invalid Query String" q) of
+--     Left e -> error $ show e
+--     Right queryMap -> queryMap
+-- 
+-- keyValuePair = do
+--   k <- many1 keyCharacters
+--   v <- optionMaybe (char '=' >> many valueCharacters)
+--   return (k, v)
+-- 
+-- 
+-- keyCharacters :: CharParser () Char 
+-- keyCharacters = 
+--   oneOf urlBaseChars 
+--     <|> (char '+' >> return ' ') 
+--     <|> hexValue 
+--   
+--   where 
+--     urlBaseChars = 
+--       ['a'..'z'] ++
+--       ['A'..'Z'] ++
+--       ['0'..'9'] ++
+--       "$-_.!*'()," 
+-- 
+-- valueCharacters = keyCharacters
+-- 
+-- hexValue :: CharParser () Char 
+-- hexValue = do 
+--   char '%' 
+--   a <- hexDigit 
+--   b <- hexDigit 
+--   let ((d, _):_) = readHex [a,b] 
+--   return . toEnum $ d 
diff --git a/src/Bird/Request/QueryStringParser.hs b/src/Bird/Request/QueryStringParser.hs
new file mode 100644
--- /dev/null
+++ b/src/Bird/Request/QueryStringParser.hs
@@ -0,0 +1,41 @@
+module Bird.Request.QueryStringParser(
+  parseQueryString
+) where
+
+import Text.ParserCombinators.Parsec
+import Numeric
+
+parseQueryString :: String -> [(String, Maybe String)]
+parseQueryString q =   
+  case (parse (keyValuePair `sepBy` char '&') "Exception: Invalid Query String" q) of
+    Left e -> error $ show e
+    Right queryMap -> queryMap
+
+keyValuePair = do
+  k <- many1 keyCharacters
+  v <- optionMaybe (char '=' >> many valueCharacters)
+  return (k, v)
+
+
+keyCharacters :: CharParser () Char 
+keyCharacters = 
+  oneOf urlBaseChars 
+    <|> (char '+' >> return ' ') 
+    <|> hexValue 
+  
+  where 
+    urlBaseChars = 
+      ['a'..'z'] ++
+      ['A'..'Z'] ++
+      ['0'..'9'] ++
+      "$-_.!*'()," 
+
+valueCharacters = keyCharacters
+
+hexValue :: CharParser () Char 
+hexValue = do 
+  char '%' 
+  a <- hexDigit 
+  b <- hexDigit 
+  let ((d, _):_) = readHex [a,b] 
+  return . toEnum $ d 
