parseTerm :: M.Map Text [(Term, Text)]
          -> X.Element
          -> ElementParser (M.Map Text [(Term, Text)])
parseTerm m node = do
  let attr = getAttributes node
  name <- case lookupAttribute "name" attr of
                Just n   -> return n
                Nothing  -> parseFailure "Text node has no name attribute"
  let single = mconcat $ map getTextContent $ getChildren "single" node
  let multiple = mconcat $ map getTextContent $ getChildren "multiple" node
  let txt = getTextContent node
  let form = case lookupAttribute "form" attr of
               Just "short"      -> Short
               Just "verb"       -> Verb
               Just "verb-short" -> VerbShort
               Just "symbol"     -> Symbol
               _                 -> Long
  let gender = case lookupAttribute "gender" attr of
                 Just "masculine"  -> Just Masculine
                 Just "feminine"   -> Just Feminine
                 _                 -> Nothing
  let genderForm = case lookupAttribute "gender-form" attr of
                     Just "masculine"  -> Just Masculine
                     Just "feminine"   -> Just Feminine
                     _                 -> Nothing
  let match = case lookupAttribute "match" attr of
                     Just "last-digit"      -> Just LastDigit
                     Just "last-two-digits" -> Just LastTwoDigits
                     Just "whole-number"    -> Just WholeNumber
                     _                      -> Nothing
  let term = Term
        { termName          = name
        , termForm          = form
        , termNumber        = Nothing
        , termGender        = gender
        , termGenderForm    = genderForm
        , termMatch         = match
        }
  let addToList x Nothing   = Just [x]
      addToList x (Just xs) = Just (x:xs)
  if T.null single
     then return $ M.alter (addToList (term, txt)) (termName term) m
     else do
       let term_single = term{ termNumber = Just Singular }
       let term_plural = term{ termNumber = Just Plural }
       return $ M.alter
          (addToList (term_single, single) .
           addToList (term_plural, multiple)) (termName term) m
parseTerm :: M.Map Text [(Term, Text)]
          -> X.Element
          -> ElementParser (M.Map Text [(Term, Text)])
parseTerm m node = do
  let attr = getAttributes node
  name <- case lookupAttribute "name" attr of
                Just n   -> return n
                Nothing  -> parseFailure "Text node has no name attribute"
  let single = mconcat $ map getTextContent $ getChildren "single" node
  let multiple = mconcat $ map getTextContent $ getChildren "multiple" node
  let txt = getTextContent node
  let form = case lookupAttribute "form" attr of
               Just "short"      -> Short
               Just "verb"       -> Verb
               Just "verb-short" -> VerbShort
               Just "symbol"     -> Symbol
               _                 -> Long
  let gender = case lookupAttribute "gender" attr of
                 Just "masculine"  -> Just Masculine
                 Just "feminine"   -> Just Feminine
                 _                 -> Nothing
  let genderForm = case lookupAttribute "gender-form" attr of
                     Just "masculine"  -> Just Masculine
                     Just "feminine"   -> Just Feminine
                     _                 -> Nothing
  let match = case lookupAttribute "match" attr of
                     Just "last-digit"      -> Just LastDigit
                     Just "last-two-digits" -> Just LastTwoDigits
                     Just "whole-number"    -> Just WholeNumber
                     _                      -> Nothing
  let term = Term
        { termName          = name
        , termForm          = form
        , termNumber        = Nothing
        , termGender        = gender
        , termGenderForm    = genderForm
        , termMatch         = match
        }
  let addToList x Nothing   = Just [x]
      addToList x (Just xs) = Just (x:xs)
  if T.null single
     then return $ M.alter (addToList (term, txt)) (termName term) m
     else do
       let term_single = term{ termNumber = Just Singular }
       let term_plural = term{ termNumber = Just Plural }
       return $ M.alter
          (addToList (term_single, single) .
           addToList (term_plural, multiple)) (termName term) m
parseTerm m node = do
  let attr = getAttributes node
  name <- case lookupAttribute "name" attr of
                Just n   -> return n
                Nothing  -> parseFailure "Text node has no name attribute"
  let single = mconcat $ map getTextContent $ getChildren "single" node
  let multiple = mconcat $ map getTextContent $ getChildren "multiple" node
  let txt = getTextContent node
  let form = case lookupAttribute "form" attr of
               Just "short"      -> Short
               Just "verb"       -> Verb
               Just "verb-short" -> VerbShort
               Just "symbol"     -> Symbol
               _                 -> Long
  let gender = case lookupAttribute "gender" attr of
                 Just "masculine"  -> Just Masculine
                 Just "feminine"   -> Just Feminine
                 _                 -> Nothing
  let genderForm = case lookupAttribute "gender-form" attr of
                     Just "masculine"  -> Just Masculine
                     Just "feminine"   -> Just Feminine
                     _                 -> Nothing
  let match = case lookupAttribute "match" attr of
                     Just "last-digit"      -> Just LastDigit
                     Just "last-two-digits" -> Just LastTwoDigits
                     Just "whole-number"    -> Just WholeNumber
                     _                      -> Nothing
  let term = Term
        { termName          = name
        , termForm          = form
        , termNumber        = Nothing
        , termGender        = gender
        , termGenderForm    = genderForm
        , termMatch         = match
        }
  let addToList x Nothing   = Just [x]
      addToList x (Just xs) = Just (x:xs)
  if T.null single
     then return $ M.alter (addToList (term, txt)) (termName term) m
     else do
       let term_single = term{ termNumber = Just Singular }
       let term_plural = term{ termNumber = Just Plural }
       return $ M.alter
          (addToList (term_single, single) .
           addToList (term_plural, multiple)) (termName term) m