 newParser enc = do
   ptr <- parserCreate enc
   fptr <- newForeignPtr parserFree ptr
-  return $ Parser fptr
+  nullStartH <- newIORef nullCStartElementHandler
+  nullEndH <- newIORef nullCEndElementHandler
+  nullCharH <- newIORef nullCCharacterDataHandler
+  return $ Parser fptr nullStartH nullEndH nullCharH
 
 -- ByteString.useAsCStringLen is almost what we need, but C2HS wants a CInt
 -- instead of an Int.

    handler name (pairwise attrlist)
-- |Attach a StartElementHandler to a Parser.
setStartElementHandler :: Parser -> StartElementHandler -> IO ()
setStartElementHandler parser handler = do
  withParser parser $ \p -> do
  handler' <- wrapStartElementHandler handler
  {#call unsafe XML_SetStartElementHandler as ^#} p handler'


type CEndElementHandler = Ptr () -> CString -> IO ()
foreign import ccall "wrapper"
  mkCEndElementHandler :: CEndElementHandler
                       -> IO (FunPtr CEndElementHandler)
wrapEndElementHandler :: EndElementHandler
                      -> IO (FunPtr CEndElementHandler)
wrapEndElementHandler handler = mkCEndElementHandler h where
  h ptr cname = do
    name <- peekCString cname
    handler name
-- |Attach an EndElementHandler to a Parser.
setEndElementHandler :: Parser -> EndElementHandler -> IO ()
setEndElementHandler parser handler = do
  withParser parser $ \p -> do
  handler' <- wrapEndElementHandler handler
  {#call unsafe XML_SetEndElementHandler as ^#} p handler'

type CCharacterDataHandler = Ptr () -> CString -> CInt -> IO ()
foreign import ccall "wrapper"
  mkCCharacterDataHandler :: CCharacterDataHandler
                          -> IO (FunPtr CCharacterDataHandler)
wrapCharacterDataHandler :: CharacterDataHandler
                      -> IO (FunPtr CCharacterDataHandler)
wrapCharacterDataHandler handler = mkCCharacterDataHandler h where
  h ptr cdata len = do
    data_ <- peekCStringLen (cdata, fromIntegral len)
    handler data_
-- |Attach an CharacterDataHandler to a Parser.
setCharacterDataHandler :: Parser -> CharacterDataHandler -> IO ()
setCharacterDataHandler parser handler = do
  withParser parser $ \p -> do
  handler' <- wrapCharacterDataHandler handler
  {#call unsafe XML_SetCharacterDataHandler as ^#} p handler'

pairwise (x1:x2:xs) = (x1,x2) : pairwise xs
pairwise []         = []

-- |@parseChunk data False@ feeds /strict/ ByteString data into a
-- 'Parser'.  The end of the data is indicated by passing @True@ for the
-- final parameter.  @parse@ returns @False@ on a parse error.
parseChunk :: Parser
              -> BS.ByteString
              -> Bool
              -> IO Bool
parseChunk parser@(Parser fp startRef endRef charRef) xml final = do
    bracket
        (do
            cStartH <- mkCStartElementHandler =<< readIORef startRef
            cEndH   <- mkCEndElementHandler =<< readIORef endRef
            cCharH  <- mkCCharacterDataHandler =<< readIORef charRef
            withParser parser $ \p -> do
                {#call unsafe XML_SetStartElementHandler as ^#}  p cStartH
                {#call unsafe XML_SetEndElementHandler as ^#}    p cEndH
                {#call unsafe XML_SetCharacterDataHandler as ^#} p cCharH
            return (cStartH, cEndH, cCharH))
        (\(cStartH, cEndH, cCharH) -> do
            freeHaskellFunPtr cStartH
            freeHaskellFunPtr cEndH
            freeHaskellFunPtr cCharH)
        (\_ -> doParseChunk parser xml final)

{#fun XML_Parse as doParseChunk
    {withParser* `Parser', withBStringLen* `BS.ByteString' &, `Bool'}
    -> `Bool' unStatus#}

