diff --git a/HXQ-unstable.hs b/HXQ-unstable.hs
new file mode 100644
--- /dev/null
+++ b/HXQ-unstable.hs
@@ -0,0 +1,94 @@
+{--------------------------------------------------------------
+-
+- The main program of the XQuery Compiler
+- **** UNSTABLE *****
+- Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
+- Date: 05/02/2008
+-
+---------------------------------------------------------------}
+
+module Main where
+
+import GHC
+import DynFlags
+import Packages
+import PackageConfig
+import System.IO
+import XML.HXQ.XQuery
+import System.Environment
+import qualified Control.Exception
+import XML.HXQ.Compiler(functions)
+import XML.HXQ.Interpreter(evalInput)
+
+
+version = "0.8.3"
+default_system_path = "/usr/local/lib/ghc-6.8.2"
+default_hxq_path = "./"
+
+
+parseEnv :: [String] -> [(String,String)]
+parseEnv [] = [("hxq",default_hxq_path),("ghc",default_system_path),("o","Temp.hs")]
+parseEnv ("-help":xs) = ("help",""):(parseEnv xs)
+parseEnv ("-c":file:xs) = ("c",file):(parseEnv xs)
+parseEnv ("-o":file:xs) = ("o",file):(parseEnv xs)
+parseEnv ("-p":query:file:xs) = ("p","doc('"++file++"')"++query):(parseEnv xs)
+parseEnv ("-h":path:xs) = ("hxq",path):(parseEnv xs)
+parseEnv ("-l":path:xs) = ("ghc",path):(parseEnv xs)
+parseEnv (('-':x):_) = error ("Unrecognized option -"++x++". Use -help.")
+parseEnv (file:xs) = ("r",file):(parseEnv xs)
+
+
+main = do putStrLn ("HXQ: XQuery Compiler version "++version)
+          senv <- getArgs
+          let env = parseEnv senv
+              Just system_path = lookup "ghc" env
+              Just hxq_path = lookup "hxq" env
+          case lookup "help" env of
+            Just _ -> do putStrLn "Command line options and files:"
+                         putStrLn "xquery-file               compile and run the XQuery in xquery-file"
+                         putStrLn "-c xquery-file            compile the XQuery in xquery-file into Haskell code"
+                         putStrLn "-o haskell-file           set the Haskell file for -c (default is Temp.hs)"
+                         putStrLn "-p XPath-query xml-file   compile and run the XPath query against the xml-file"
+                         putStrLn ("-h path                   set the HXQ installation directory (default is "++default_hxq_path++")")
+                         putStrLn ("-l path                   set the GHC installation directory (default is "++default_system_path++")")
+                         putStrLn ("Functions:  "++(foldr (\(f,_,_) r -> f++" "++r) "" functions))
+            _ -> case lookup "c" env of
+                   Just file -> do query <- readFile file
+                                   let qf = map (\c -> if c=='\"' then '\'' else c)
+                                                (foldr1 (\a r -> a++" "++r) (lines query))
+                                       pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport XML.HXQ.XQuery\n\nmain = do res <- $(xq \""
+                                            ++ qf ++ "\")\n          putXSeq res\n"
+                                       Just ofile = lookup "o" env
+                                   writeFile ofile pr
+                   _ -> do session <- newSession (Just system_path)
+                           dflags0 <- getSessionDynFlags session
+                           (dflags1,b) <- parseDynamicFlags dflags0 ["-fglasgow-exts", "-O2", "-fth", "-fobject-code",
+                                                                     --"-package HXQ", "-package ghc"]
+                                                                     "-i"++hxq_path++"XML/HXQ/:"++hxq_path++"hxml-0.2"]
+                           (dflags2, _) <- initPackages dflags1
+                           setSessionDynFlags session dflags2
+                           --load session LoadAllTargets
+                           let preludeModule = mkModule (stringToPackageId "base") (mkModuleName "Prelude")
+                           --xqueryModule = mkModule (stringToPackageId "HXQ") (mkModuleName "XQuery")
+                           setContext session [] [preludeModule]
+                           t <- guessTarget (hxq_path++"Main.hs") Nothing
+                           addTarget session t
+                           f <- getSessionDynFlags session
+                           sf <- defaultCleanupHandler f (load session LoadAllTargets)
+                           --ff <- load session (LoadDependenciesOf (mkModuleName "XQuery"))
+                           case lookup "r" env of
+                             Just file -> do q <- readFile file
+                                             let qf = map (\c -> if c=='\"' then '\'' else c)
+                                                          (foldr1 (\a r -> a++" "++r) (lines q))
+                                                 query = "do result <- $(XQuery.xq \""++qf++"\"); XQuery.putXSeq result"
+                                             _ <- runStmt session query SingleStep
+                                             return ()
+                             _ -> case lookup "p" env of
+                                    Just query -> do _ <- runStmt session ("do result <- $(XML.HXQ.XQuery.xq \""++query
+                                                                           ++"\"); XML.HXQ.XQuery.putXSeq result") SingleStep
+                                                     return ()
+                                    _ -> do putStrLn "To write an XQuery in multiple lines, wrap it in {}"
+                                            evalInput (\s vs fs -> let query = "do result <- $(XML.HXQ.XQuery.xq \""++s++"\");"
+                                                                               ++"XML.HXQ.XQuery.putXSeq result"
+                                                                   in Control.Exception.catch (do runStmt session query SingleStep; return (vs,fs))
+                                                                              (\e -> do putStrLn (show e); return (vs,fs))) [] []
diff --git a/HXQ.cabal b/HXQ.cabal
--- a/HXQ.cabal
+++ b/HXQ.cabal
@@ -1,12 +1,12 @@
 Cabal-Version:       >= 1.2
 Name:                HXQ
-Version:             0.8
+Version:             0.8.3
 Synopsis:            A Compiler from XQuery to Haskell
 Description:         
         HXQ is a fast and space-efficient compiler from XQuery (the standard
         query language for XML) to embedded Haskell code. The translation is
         based on Haskell templates. It also provides an interpreter for
-        evaluating ad-hoc XQueries read from input or from files.
+        evaluating XQueries from input and database connectivity using HDBC.
 Category:            XML
 Build-type:          Simple
 License-file:        LICENSE
@@ -18,20 +18,18 @@
 Homepage:            http://lambda.uta.edu/HXQ/
 Extra-Source-Files:
   Makefile
-  HXQ.hs
-  XML/HXQ/DB.hs
-  XML/HXQ/XQueryDB.hs
+  HXQ-unstable.hs
   XQueryParser.y
   Test1.hs
   Test2.hs
   TestDB.hs
-  profile.hs
   compile
 data-files:
   index.html
   data/cs.xml
   data/q1.xq
   data/q2.xq
+  data/q3.xq
   data/dblp.xq
   data/dblp2.xq
   data/company.sql
@@ -40,13 +38,14 @@
 
 Library
   Exposed-Modules:     XML.HXQ.XQuery
-  Other-Modules:       XML.HXQ.XTree, XML.HXQ.Compiler, XML.HXQ.Interpreter, XML.HXQ.Parser, XML.HXQ.Optimizer,
+  Other-Modules:       XML.HXQ.XTree, XML.HXQ.Compiler, XML.HXQ.Interpreter, XML.HXQ.Parser,
+                       XML.HXQ.Optimizer, XML.HXQ.DB, XML.HXQ.DBConnect,
                        HXML, DTD, LLParsing, TreeBuild, XMLParse, ETree, Misc, Tree,
                        XMLScanner, AssocList, PrintXML, XML
   hs-source-dirs:      . hxml-0.2
-  Build-Depends:       base, haskell98, array, readline, template-haskell
+  Build-Depends:       base, haskell98, array, readline, template-haskell, mtl, HDBC, HDBC-sqlite3
 
 Executable xquery
   Main-is:             Main.hs
   hs-source-dirs:      . hxml-0.2
-  Build-Depends:       base, haskell98, array, readline, template-haskell
+  Build-Depends:       base, haskell98, array, readline, template-haskell, mtl, HDBC, HDBC-sqlite3
diff --git a/HXQ.hs b/HXQ.hs
deleted file mode 100644
--- a/HXQ.hs
+++ /dev/null
@@ -1,94 +0,0 @@
-{--------------------------------------------------------------
--
-- The main program of the XQuery Compiler
-- **** UNSTABLE *****
-- Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 05/02/2008
--
----------------------------------------------------------------}
-
-module Main where
-
-import GHC
-import DynFlags
-import Packages
-import PackageConfig
-import System.IO
-import XML.HXQ.XQuery
-import System.Environment
-import qualified Control.Exception
-import XML.HXQ.Compiler(functions)
-import XML.HXQ.Interpreter(evalInput)
-
-
-version = "0.8"
-default_system_path = "/usr/local/lib/ghc-6.8.2"
-default_hxq_path = "./"
-
-
-parseEnv :: [String] -> [(String,String)]
-parseEnv [] = [("hxq",default_hxq_path),("ghc",default_system_path),("o","Temp.hs")]
-parseEnv ("-help":xs) = ("help",""):(parseEnv xs)
-parseEnv ("-c":file:xs) = ("c",file):(parseEnv xs)
-parseEnv ("-o":file:xs) = ("o",file):(parseEnv xs)
-parseEnv ("-p":query:file:xs) = ("p","doc('"++file++"')"++query):(parseEnv xs)
-parseEnv ("-h":path:xs) = ("hxq",path):(parseEnv xs)
-parseEnv ("-l":path:xs) = ("ghc",path):(parseEnv xs)
-parseEnv (('-':x):_) = error ("Unrecognized option -"++x++". Use -help.")
-parseEnv (file:xs) = ("r",file):(parseEnv xs)
-
-
-main = do putStrLn ("HXQ: XQuery Compiler version "++version)
-          senv <- getArgs
-          let env = parseEnv senv
-              Just system_path = lookup "ghc" env
-              Just hxq_path = lookup "hxq" env
-          case lookup "help" env of
-            Just _ -> do putStrLn "Command line options and files:"
-                         putStrLn "xquery-file               compile and run the XQuery in xquery-file"
-                         putStrLn "-c xquery-file            compile the XQuery in xquery-file into Haskell code"
-                         putStrLn "-o haskell-file           set the Haskell file for -c (default is Temp.hs)"
-                         putStrLn "-p XPath-query xml-file   compile and run the XPath query against the xml-file"
-                         putStrLn ("-h path                   set the HXQ installation directory (default is "++default_hxq_path++")")
-                         putStrLn ("-l path                   set the GHC installation directory (default is "++default_system_path++")")
-                         putStrLn ("Functions:  "++(foldr (\(f,_,_) r -> f++" "++r) "" functions))
-            _ -> case lookup "c" env of
-                   Just file -> do query <- readFile file
-                                   let qf = map (\c -> if c=='\"' then '\'' else c)
-                                                (foldr1 (\a r -> a++" "++r) (lines query))
-                                       pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport XML.HXQ.XQuery\n\nmain = do res <- $(xq \""
-                                            ++ qf ++ "\")\n          putXSeq res\n"
-                                       Just ofile = lookup "o" env
-                                   writeFile ofile pr
-                   _ -> do session <- newSession (Just system_path)
-                           dflags0 <- getSessionDynFlags session
-                           (dflags1,b) <- parseDynamicFlags dflags0 ["-fglasgow-exts", "-O2", "-fth", "-fobject-code",
-                                                                     --"-package HXQ", "-package ghc"]
-                                                                     "-i"++hxq_path++"XML/HXQ/:"++hxq_path++"hxml-0.2"]
-                           (dflags2, _) <- initPackages dflags1
-                           setSessionDynFlags session dflags2
-                           --load session LoadAllTargets
-                           let preludeModule = mkModule (stringToPackageId "base") (mkModuleName "Prelude")
-                           --xqueryModule = mkModule (stringToPackageId "HXQ") (mkModuleName "XQuery")
-                           setContext session [] [preludeModule]
-                           t <- guessTarget (hxq_path++"Main.hs") Nothing
-                           addTarget session t
-                           f <- getSessionDynFlags session
-                           sf <- defaultCleanupHandler f (load session LoadAllTargets)
-                           --ff <- load session (LoadDependenciesOf (mkModuleName "XQuery"))
-                           case lookup "r" env of
-                             Just file -> do q <- readFile file
-                                             let qf = map (\c -> if c=='\"' then '\'' else c)
-                                                          (foldr1 (\a r -> a++" "++r) (lines q))
-                                                 query = "do result <- $(XQuery.xq \""++qf++"\"); XQuery.putXSeq result"
-                                             _ <- runStmt session query SingleStep
-                                             return ()
-                             _ -> case lookup "p" env of
-                                    Just query -> do _ <- runStmt session ("do result <- $(XML.HXQ.XQuery.xq \""++query
-                                                                           ++"\"); XML.HXQ.XQuery.putXSeq result") SingleStep
-                                                     return ()
-                                    _ -> do putStrLn "To write an XQuery in multiple lines, wrap it in {}"
-                                            evalInput (\s vs fs -> let query = "do result <- $(XML.HXQ.XQuery.xq \""++s++"\");"
-                                                                               ++"XML.HXQ.XQuery.putXSeq result"
-                                                                   in Control.Exception.catch (do runStmt session query SingleStep; return (vs,fs))
-                                                                              (\e -> do putStrLn (show e); return (vs,fs))) [] []
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -2,11 +2,10 @@
 -
 - The main program of the XQuery interpreter
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 05/02/2008
+- Date: 06/10/2008
 -
 ---------------------------------------------------------------}
 
-{-# OPTIONS_GHC -fth #-}
 
 module Main where
 
@@ -16,7 +15,7 @@
 import XML.HXQ.Interpreter(evalInput,xqueryE)
 import XML.HXQ.XQuery
 
-version = "0.8"
+version = "0.8.3"
 
 
 parseEnv :: [String] -> [(String,String)]
@@ -24,24 +23,29 @@
 parseEnv ("-help":xs) = ("help",""):(parseEnv xs)
 parseEnv ("-c":file:xs) = ("c",file):(parseEnv xs)
 parseEnv ("-o":file:xs) = ("o",file):(parseEnv xs)
+parseEnv ("-db":file:xs) = ("db",file):(parseEnv xs)
+parseEnv ("-v":xs) = ("v",""):(parseEnv xs)
 parseEnv ("-p":query:file:xs) = ("p","doc('"++file++"')"++query):(parseEnv xs)
 parseEnv (('-':x):_) = error ("Unrecognized option -"++x++". Use -help.")
 parseEnv (file:xs) = ("r",file):(parseEnv xs)
 
 
-main = do putStrLn ("HXQ: XQuery Interpreter version "++version++". Use -help for help.")
-          senv <- getArgs
+main = do senv <- getArgs
           let env = parseEnv senv
               Just system_path = lookup "ghc" env
               Just hxq_path = lookup "hxq" env
+              Just dbname = lookup "db" env
+              verbose = case lookup "v" env of Nothing -> False; _ -> True
           case lookup "help" env of
             Just _ -> do putStrLn "Command line options and files:"
                          putStrLn "   xquery-file               interpret the XQuery in xquery-file"
+                         putStrLn "   -db file-path             use the relational database in file-path during querying"
                          putStrLn "   -c xquery-file            compile the XQuery in xquery-file into Haskell code"
                          putStrLn "   -o haskell-file           set the Haskell file for -c (default is Temp.hs)"
                          putStrLn "   -p XPath-query xml-file   interpret the XPath query against the xml-file"
-                         putStrLn "Without options, it reads and interprets the input:"
-                         putStrLn "   The input may be an XQuery or a declare variable or function"
+                         putStrLn "   -v                        verbose information"
+                         putStrLn "Without an xquery-file, it reads and interprets the input"
+                         putStrLn "   The input may be an XQuery or a declare variable/function"
                          putStrLn "   To write an XQuery in multiple lines, wrap it in {}"
                          putStrLn ("Functions:  "++(foldr (\(f,_,_) r -> f++" "++r) "" functions))
             _ -> case lookup "c" env of
@@ -53,12 +57,32 @@
                                        Just ofile = lookup "o" env
                                    writeFile ofile pr
                    _ -> case lookup "r" env of
-                          Just file -> do result <- xfile file
-                                          putXSeq result
+                          Just file -> case lookup "db" env of
+                                         Just filepath -> do db <- connect filepath
+                                                             result <- xfileDB file db
+                                                             disconnect db
+                                                             putXSeq result
+                                         _ -> do query <- readFile file
+                                                 (result,_,_) <- xqueryE query [] [] (\sql -> return []) verbose
+                                                 putXSeq result
                           _ -> case lookup "p" env of
-                                 Just query -> do result <- xquery query
+                                 Just query -> do (result,_,_) <- xqueryE query [] [] (\sql -> return []) verbose
                                                   putXSeq result
-                                 _ -> evalInput (\s vs fs-> Control.Exception.catch (do (result,nvs,nfs) <- xqueryE s vs fs
-                                                                                        putXSeq result
-                                                                                        return (nvs,nfs))
-                                                                              (\e -> do putStrLn (show e); return (vs,fs))) [] []
+                                 _ -> do putStrLn ("HXQ: XQuery Interpreter version "++version++". Use -help for help.")
+                                         case lookup "db" env of
+                                           Just filepath
+                                               -> do db <- connect filepath
+                                                     evalInput (\s vs fs-> Control.Exception.catch
+                                                                          (do (result,nvs,nfs) <- xqueryE s vs fs
+                                                                                                  (\sql -> do stmt <- prepareSQL db sql
+                                                                                                              return [XStmt stmt]) verbose
+                                                                              putXSeq result
+                                                                              return (nvs,nfs))
+                                                                          (\e -> do putStrLn (show e); return (vs,fs))) [] []
+                                                     disconnect db
+                                           _ -> evalInput (\s vs fs-> Control.Exception.catch
+                                                                      (do (result,nvs,nfs) <- xqueryE s vs fs
+                                                                                                 (\_ -> error "Missing Database Connection") verbose
+                                                                          putXSeq result
+                                                                          return (nvs,nfs))
+                                                                      (\e -> do putStrLn (show e); return (vs,fs))) [] []
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 hxml = hxml-0.2
 hxq = XML/HXQ
-options = -O2 -fvia-C
+options = -O2
 parser = $(hxq)/Parser.hs
 
 # xquery interpreter
@@ -8,8 +8,8 @@
 	ghc $(options) -i$(hxml) --make Main.hs -o xquery
 
 # on-the-fly compiler: unstable; use xquery instead
-hxqc:   $(parser) HXQ.hs
-	ghc $(options) -i$(hxml) -optl-s -package ghc --make HXQ.hs -o hxqc
+hxqc:   $(parser) HXQ-unstable.hs
+	ghc $(options) -i$(hxml) -optl-s -package ghc --make HXQ-unstable.hs -o hxqc
 
 # generate the XQuery parser using happy
 $(parser): XQueryParser.y
@@ -23,25 +23,23 @@
 	ghc $(options) -i$(hxml) --make Test2.hs -o a.out
 	time ./a.out +RTS -H20m
 
-testdb: $(parser) TestDB.hs
+test3:  $(parser) TestDB.hs
 	ghc $(options) -i$(hxml) --make TestDB.hs -o a.out
 	./a.out
 
-# get in the ghci interpreter and load HXQ
+test4:  $(parser) TestDB2.hs
+	ghc $(options) -i$(hxml) --make TestDB2.hs -o a.out
+	./a.out
+
+# run in the ghci interpreter and load HXQ
 ghci:   $(parser)
 	ghci -fth -i$(hxml) Main.hs
 
-# heap profile of a simple XQuery against dblp.xml
-profile: $(parser) profile.hs
-	ghc -O2 -i$(hxml) -prof -auto-all --make profile.hs -o a
-	./a +RTS -hy -p -H20m
-	hp2ps -color a.hp
-
 # create the cabal distribution
-cabal:	clean $(parser)
+cabal:	$(parser)
 	runhaskell Setup.lhs configure --ghc --user --prefix=$(HOME)
 	runhaskell Setup.lhs build
 	runhaskell Setup.lhs sdist
 
 clean:
-	/bin/rm -f *~ data/*~ $(hxq)/*~ *.o *.hi $(hxq)/*.o $(hxq)/*.hi $(hxml)/*.o $(hxml)/*.hi $(parser) *.stat *.prof *.ps *.aux *.hp xquery hxqc Temp.hs a.out a
+	/bin/rm -f *~ data/*~ $(hxq)/*~ *.o *.hi $(hxq)/*.o $(hxq)/*.hi $(hxml)/*.o $(hxml)/*.hi $(parser) xquery hxqc Temp.hs a.out
diff --git a/Test1.hs b/Test1.hs
--- a/Test1.hs
+++ b/Test1.hs
@@ -13,12 +13,12 @@
 import XML.HXQ.XQuery
 
 
-f(d,s) = $(xe "<student dept='{$d/text()}'>{$s//firstname/text(),' ',$s//lastname/text()}</student>")
+f(d,s) = $(xe "<student dept='{$d/text()}'>{$s//firstname/text(),$s//lastname/text()}</student>")
 
 main = do a <- $(xq ("  for $s in doc('data/cs.xml')//gradstudent          "
                 ++"     order by $s/gpa descending, $s//lastname           "
-                ++"     return <student>{$s//firstname/text(),' ',         "
-                ++"                      $s//lastname/text(),' ',          "
+                ++"     return <student>{$s//firstname/text(),             "
+                ++"                      $s//lastname/text(),              "
                 ++"                      $s/gpa/text()}</student>          "))
           putXSeq a
           let query name = $(xq " doc('data/cs.xml')//gradstudent[.//lastname = $name]//firstname ")
@@ -31,9 +31,8 @@
                   ++"       return f($d//deptname,$s)                      "
                   ++"   }</good-students>                                  "))
           putXSeq c
-          let q file = $(xq ("  let $d := doc($file)//gradstudent          "
-                         ++"    return ($d/../deptname,count($d))          "))
-          d <- q $(xe " 'data/cs.xml' ")
+          d <- $(xq ("    let $d := doc('data/cs.xml')//gradstudent  "
+                   ++"    return ($d/../deptname,count($d))          "))
           putXSeq d
           putStrLn "Type an XQuery:"
           iquery <- getLine        -- read an XQuery from input
diff --git a/Test2.hs b/Test2.hs
--- a/Test2.hs
+++ b/Test2.hs
@@ -14,14 +14,14 @@
 import XML.HXQ.XQuery
 
 
-f(x,y) = $(xe "<a>{$x,', ',$y}</a>")
+f(x,y) = $(xe "<a>{$x,$y}</a>")
 
 main = do a <- $(xq ("<result>{                                                               "
                  ++"     for $x at $i in doc('data/dblp.xml')//inproceedings                  "
                  ++"     where $x/author = 'Leonidas Fegaras'                                 "
                  ++"     order by $x/year descending                                          "
-                 ++"     return <paper>{ $i, ') ', $x/booktitle/text(),                       "
-                 ++"                     ': ', $x/title/text()                                "
+                 ++"     return <paper>{ $i, $x/booktitle/text(),                             "
+                 ++"                     ':', $x/title/text()                                 "
                  ++"            }</paper>                                                     "
                  ++"  }</result>                                                              "))
           putXSeq a
diff --git a/TestDB.hs b/TestDB.hs
--- a/TestDB.hs
+++ b/TestDB.hs
@@ -1,10 +1,10 @@
 {--------------------------------------------------------------
 -
-- A main program to test XQuery with Sqlite database connectivity
+- A main program to test XQuery connected to a Sqlite database
 - To create the database load the file data/company.sql in sqlite3
 -
 - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)
-- Date: 05/12/2008
+- Date: 05/21/2008
 -
 ---------------------------------------------------------------}
 
@@ -12,17 +12,15 @@
 
 module Main where
 
-import XML.HXQ.XQueryDB
-import Database.HDBC.Sqlite3
+import XML.HXQ.XQuery
 
 
-main = do db <- connectSqlite3 "myDB"
-          e <- $(xqdb ("  let $ln := 'English'                              "
-                     ++"  for $r in sql('  select e.fname, d.dname          "
+main = do db <- connect "myDB"
+          e <- $(xqdb ("  for $r in sql('  select e.fname, d.dname          "
                      ++"                   from employee e, department d    "
                      ++"                   where e.dno = d.dnumber          "
                      ++"                     and e.lname = ?           ',   "
-                     ++"                $ln)                                "
+                     ++"                'English')                          "
                      ++"  return <result>{$r/fname,$r/dname}</result>       ")) db
           putXSeq e
           disconnect db
diff --git a/XML/HXQ/Compiler.hs b/XML/HXQ/Compiler.hs
--- a/XML/HXQ/Compiler.hs
+++ b/XML/HXQ/Compiler.hs
@@ -4,7 +4,7 @@
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 02/15/08, last update: 05/12/08
+- Creation: 02/15/08, last update: 06/02/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -20,26 +20,36 @@
 
 import Data.List
 import Control.Monad
-import Char(isDigit)
+import Char(isDigit,toLower)
 import List(sortBy)
 import Language.Haskell.TH
+import Database.HDBC
 import XMLParse(parseDocument)
 import HXML(AttList)
 import XML.HXQ.Parser
 import XML.HXQ.XTree
 import XML.HXQ.Optimizer
+import XML.HXQ.DB
+import XML.HXQ.DBConnect
 
 
 {--------------- XPath Steps ---------------------------------------------------------}
 
 
+current_step :: Tag -> XTree -> XSeq
+current_step m x
+    = case x of
+        XElem k _ _ _ | (k==m || m=="*") -> [x]
+        _ -> []
+
+
 -- XPath step /tag or /*
 child_step :: Tag -> XTree -> XSeq
 child_step m x
     = case x of
-        (XElem _ _ _ bs)
+        XElem _ _ _ bs
             -> foldr (\b s -> case b of
-                                (XElem k _ _ _) | (k==m || m=="*") -> b:s
+                                XElem k _ _ _ | (k==m || m=="*") -> b:s
                                 _ -> s) [] bs
         _ -> []
 
@@ -108,8 +118,11 @@
 foldir c n [] i = n
 foldir c n (x:xs) i = c x i (foldir c n xs (i+1))
 
+
 trueXT = XBool True
+falseXT = XBool False
 
+
 readNum :: String -> Maybe XTree
 readNum cs = case span isDigit cs of
                (n,[]) -> Just (XInt (read n))
@@ -118,18 +131,18 @@
                                  _ -> Nothing
                _ -> Nothing
 
+
 text :: XSeq -> XSeq
 text xs = foldr (\x r -> case x of
-                           XElem _ _ _ [z@(XText _)] -> z:r
-                           XElem _ _ _ [z@(XInt _)] -> z:r
-                           XElem _ _ _ [z@(XFloat _)] -> z:r
-                           XElem _ _ _ [z@(XBool _)] -> z:r
+                           XElem _ _ _ zs -> (filter (\a -> case a of XText _ -> True; XInt _ -> True;
+                                                                      XFloat _ -> True; XBool _ -> True; _ -> False) zs)++r
                            XText _ -> x:r
                            XInt _ -> x:r
                            XFloat _ -> x:r
                            XBool _ -> x:r
                            _ -> r) [] xs
 
+
 toString :: XSeq -> [String]
 toString xs = map (\x -> case x of 
                            XText t -> t
@@ -138,6 +151,14 @@
                            XBool n -> show n)
                   (text xs)
 
+
+-- concatenate text with no padding (for element content)
+appendText :: [XSeq] -> XSeq
+appendText [] = []
+appendText [x] = x
+appendText (x:xs) = x++[XNoPad]++appendText xs
+
+
 toNum :: XSeq -> XSeq
 toNum xs = foldr (\x r -> case x of
                             XInt n -> x:r
@@ -147,6 +168,7 @@
                                          _ -> r
                             _ -> r) [] (text xs)
 
+
 toFloat :: XTree -> Float
 toFloat (XText s) = case readNum s of
                       Just (XInt n) -> fromIntegral n
@@ -156,23 +178,31 @@
 toFloat (XFloat n) = n
 toFloat x = error("Cannot convert to a float: "++(show x))
 
+
 mean :: (Fractional t) => [t] -> t
 mean = uncurry (/) . foldl' (\(!s, !n) x -> (s+x, n+1)) (0,0.0)
 
+
 contains :: String -> String -> Bool
-contains xs ys | ((take (length ys) xs) == ys) = True
-contains (_:xs) ys = contains xs ys
-contains [] ys = False
+contains text word
+    = let len = length word
+          c xs | ((take len xs) == word) = True
+          c (_:xs) = c xs
+          c _ = False
+      in c text
 
+
 distinct :: Eq a => [a] -> [a]
 distinct = foldl (\r a -> if elem a r then r else r++[a]) []
 
+
 arithmetic :: (Float -> Float -> Float) -> XTree -> XTree -> XTree
 arithmetic op (XInt n) (XInt m) = XInt (round (op (fromIntegral n) (fromIntegral m)))
 arithmetic op (XFloat n) (XFloat m) = XFloat (op n m)
 arithmetic op (XFloat n) (XInt m) = XFloat (op n (fromIntegral m))
 arithmetic op (XInt n) (XFloat m) = XFloat (op (fromIntegral n) m)
 
+
 compareXTrees :: XTree -> XTree -> Ordering
 compareXTrees (XElem _ _ _ _) _ = EQ
 compareXTrees _ (XElem _ _ _ _) = EQ
@@ -183,6 +213,7 @@
 compareXTrees (XText n) (XText m) = compare n m
 compareXTrees x y = compare (toFloat x) (toFloat y)
 
+
 strictCompareOne [XInt n] [XInt m] = compare n m
 strictCompareOne [XFloat n] [XFloat m] = compare n m
 strictCompareOne [XFloat n] [XInt m] = compare n (fromIntegral m)
@@ -211,6 +242,7 @@
                  then LT
               else EQ
 
+
 conditionTest :: XSeq -> Bool
 conditionTest [] = False
 conditionTest [XText ""] = False
@@ -221,7 +253,8 @@
 
 -- XPath steps
 paths :: [(Tag,Q Exp)]
-paths = [ ( "child_step", [| child_step |] ),
+paths = [ ( "current_step", [| current_step |] ),
+          ( "child_step", [| child_step |] ),
           ( "descendant_step", [| descendant_step |] ),
           ( "attribute_step", [| attribute_step |] ),
           ( "attribute_descendant_step", [| attribute_descendant_step |] )
@@ -234,17 +267,19 @@
 -- but here we make sure they are unfolded and fused with the rest of the query
 functions :: [(Tag,Int,Function)]
 functions = [ ( "=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ] |] ),
-              ( "!=", 2, \[xs,ys] -> [| if null [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ] then [trueXT] else [] |] ),
+              ( "!=", 2, \[xs,ys] -> [| if null [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ]
+                                        then [trueXT]
+                                        else [falseXT] |] ),
               ( ">", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == GT ] |] ),
               ( "<", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == LT ] |] ),
               ( ">=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [GT,EQ] ] |] ),
               ( "<=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [LT,EQ] ] |] ),
-              ( "eq", 2, \[xs,ys] -> [| if strictCompare $xs $ys == EQ then [trueXT] else [] |] ),
-              ( "neq", 2, \[xs,ys] -> [| if strictCompare $xs $ys /= EQ then [trueXT] else [] |] ),
-              ( "lt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == LT then [trueXT] else [] |] ),
-              ( "gt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == GT then [trueXT] else [] |] ),
-              ( "le", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [LT,EQ] then [trueXT] else [] |] ),
-              ( "ge", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [GT,EQ] then [trueXT] else [] |] ),
+              ( "eq", 2, \[xs,ys] -> [| if strictCompare $xs $ys == EQ then [trueXT] else [falseXT] |] ),
+              ( "neq", 2, \[xs,ys] -> [| if strictCompare $xs $ys /= EQ then [trueXT] else [falseXT] |] ),
+              ( "lt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == LT then [trueXT] else [falseXT] |] ),
+              ( "gt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == GT then [trueXT] else [falseXT] |] ),
+              ( "le", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [LT,EQ] then [trueXT] else [falseXT] |] ),
+              ( "ge", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [GT,EQ] then [trueXT] else [falseXT] |] ),
               ( "<<", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ <- $xs, XElem _ _ oy _  <- $ys, ox < oy ] |] ),
               ( ">>", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ <- $xs, XElem _ _ oy _  <- $ys, ox > oy ] |] ),
               ( "is", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ <- $xs, XElem _ _ oy _  <- $ys, ox == oy ] |] ),
@@ -256,10 +291,10 @@
               ( "mod", 2, \[xs,ys] -> [| [ XInt (mod x y) | (XInt x) <- toNum $xs, (XInt y) <- toNum $ys ] |] ),
               ( "uplus", 1, \[xs] -> [| [ x | x <- toNum $xs ] |] ),
               ( "uminus", 1, \[xs] -> [| [ case x of XInt n -> XInt (-n); XFloat n -> XFloat (-n) | x <- toNum $xs ] |] ),
-              ( "and", 2, \[xs,ys] -> [| if (conditionTest $xs) && (conditionTest $ys) then [trueXT] else [] |] ),
-              ( "or", 2, \[xs,ys] -> [| if (conditionTest $xs) || (conditionTest $ys) then [trueXT] else [] |] ),
-              ( "not", 1, \[xs] -> [| if (conditionTest $xs) then [] else [trueXT] |] ),
-              ( "some", 1, \[xs] -> [| if (conditionTest $xs) then [trueXT] else [] |] ),
+              ( "and", 2, \[xs,ys] -> [| if (conditionTest $xs) && (conditionTest $ys) then [trueXT] else [falseXT] |] ),
+              ( "or", 2, \[xs,ys] -> [| if (conditionTest $xs) || (conditionTest $ys) then [trueXT] else [falseXT] |] ),
+              ( "not", 1, \[xs] -> [| if (conditionTest $xs) then [falseXT] else [trueXT] |] ),
+              ( "some", 1, \[xs] -> [| if (conditionTest $xs) then [trueXT] else [falseXT] |] ),
               ( "count", 1, \[xs] -> [| [ XInt (length $xs) ] |] ),
               ( "sum", 1, \[xs] -> [| [ XFloat (sum [ toFloat x | x <- toNum $xs ]) ] |] ),
               ( "avg", 1, \[xs] -> [| [ XFloat (mean [ toFloat x | x <- toNum $xs ]) ] |] ),
@@ -269,7 +304,8 @@
               ( "text", 1, \[xs] -> [| text $xs |] ),
               ( "string", 1, \[xs] -> [| text $xs |] ),
               ( "data", 1, \[xs] -> [| text $xs |] ),
-              ( "node", 1, \[xs] -> [| $xs |] ),
+              ( "node", 1, \[xs] -> [| [ w | w@(XElem _ _ _ _) <- $xs ] |] ),
+              ( "exists", 1, \[xs] -> [| [ XBool (not (null $xs)) ] |] ),
               ( "empty", 0, \[] -> [| [] |] ),
               ( "true", 0, \[] -> [| [trueXT] |] ),
               ( "false", 0, \[] -> [| [] |] ),
@@ -278,8 +314,9 @@
               ( "attribute", 2, \[tags,xs] -> [| [ z | tag <- toString $tags, x <- $xs, z <- attribute_step tag x ] |] ),
               ( "name", 1, \[xs] -> [| [ XText tag | XElem tag _ _ _ <- $xs ] |] ),
               ( "contains", 2, \[xs,text] -> [| [ trueXT | x <- toString $xs, t <- toString $text, contains x t ] |] ),
+              ( "substring", 3, \[xs,n1,n2] -> [| [ XText (take m2 (drop (m1-1) x)) | x <- toString $xs,
+                                                    XInt m1 <- toNum $n1, XInt m2 <- toNum $n2 ] |] ),
               ( "concatenate", 2, \[xs,ys] -> [| $xs ++ $ys |] ),
-              ( "concat", 2, \[xs,ys] -> [| [ XText (showXS ($xs ++ $ys)) ] |] ),
               ( "distinct-values", 1, \[xs] -> [| distinct $xs |] ),
               ( "union", 2, \[xs,ys] -> [| distinct ($xs ++ $ys) |] ),
               ( "intersect", 2, \[xs,ys] -> [| filter (\x -> elem x $ys) $xs |] ),
@@ -291,10 +328,11 @@
 -- functions to be used by the interpreter
 -- when evaluated, it gives [(String,Int,[XSeq]->XSeq)]
 iFunctions :: Q Exp
-iFunctions = foldr (\(fname,len,f) r -> let vars = map (\i -> mkName ("v_"++(show i))) [1..len]
-                                            entry = tupE [litE (StringL fname),litE (IntegerL (toInteger len)),
-                                                          lamE [listP (map varP vars)] (f (map varE vars))]
-                                        in [| $entry : $r |]) [| [] |] functions
+iFunctions = foldr (\(fname,len,f) r
+                        -> let vars = map (\i -> mkName ("v_"++(show i))) [1..len]
+                               entry = tupE [litE (StringL fname),litE (IntegerL (toInteger len)),
+                                             lamE [listP (map varP vars)] (f (map varE vars))]
+                           in [| $entry : $r |]) [| [] |] functions
 
 
 -- XPath steps to be used by the interpreter
@@ -424,9 +462,9 @@
           -> position
       Ast "call" [Avar "last"]
           -> last
-      Ast "step" [Ast "child_step" [tag, Avar "."]]
+      Ast "child_step" [tag, Avar "."]
           | effective_axis /= ""
-          -> compile (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last ""
+          -> compile (Ast effective_axis [tag, Avar "."]) context position last ""
       Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
           -> let bc = compile body context position last effective_axis
                  ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
@@ -438,12 +476,23 @@
                  tc = litE (stringL tag)
              in [| foldr (\x r -> $(compilePredicates predicates [| $(findV path_step paths) $tc x |] True)++r)
                          [] $bc |]
+      Ast "descendant_any" (body:tags)
+          -> let bc = compile body context position last effective_axis
+                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
+             in [| foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] $bc |]
+      Ast path_step [Astring tag,body]
+          |  memV path_step paths
+          -> let bc = compile body context position last effective_axis
+                 tc = litE (stringL tag)
+             in [| foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] $bc |]
       Ast "step" [exp]
           -> compile exp context position last effective_axis
       Ast "step" (exp:predicates)
           -> compilePredicates predicates (compile exp context position last effective_axis) True
       Ast "predicate" [condition,body]
           -> compilePredicates [condition] (compile body context position last effective_axis) True
+      Ast "append" args
+          -> [| appendText $(listE (map (\x -> compile x context position last effective_axis) args)) |]
       Ast "call" ((Avar f):args)
           -> callF f (map (\x -> compile x context position last effective_axis) args)
       Ast "construction" [Astring tag,Ast "attributes" [],body]
@@ -454,7 +503,7 @@
           -> let alc = foldr (\(Ast "pair" [a,v]) r
                                   -> let ac = compile a context position last effective_axis
                                          vc = compile v context position last effective_axis
-                                     in [| (qName $ac,showXS (text $vc)) : $r |]) [| [] |] al
+                                     in [| (qName $ac,showXS $vc) : $r |]) [| [] |] al
                  ct = compile tag context position last effective_axis
                  bc = compile body context position last effective_axis
              in [| [ XElem (qName $ct) $alc 0 $bc ] |]
@@ -473,7 +522,7 @@
                  f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| \r -> $b ++ r |])
                  p = maxPosition (Avar ivar) body
                  ns = if p > 0              -- there is a top-k like restriction
-                      then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]
+                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
                       else source
                  s = compile ns context position last effective_axis
              in [| foldir (\x i -> $f [x] [XInt i]) [] $s 1 |]
@@ -553,9 +602,9 @@
           -> [| return $position |]
       Ast "call" [Avar "last"]
           -> [| return $last |]
-      Ast "step" [Ast "child_step" [tag, Avar "."]]
+      Ast "child_step" [tag, Avar "."]
           | effective_axis /= ""
-          -> compileM (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last ""
+          -> compileM (Ast effective_axis [tag, Avar "."]) context position last ""
       Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
           -> let bc = compileM body context position last effective_axis
                  ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
@@ -571,6 +620,17 @@
                       foldr (\x r -> (liftM2 (++)) $(compilePredicatesM predicates
                                                            [| $(findV path_step paths) $tc x |] True) r)
                             (return []) vs |]
+      Ast "descendant_any" (body:tags)
+          -> let bc = compileM body context position last effective_axis
+                 ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)
+             in [| do vs <- $bc
+                      return (foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] vs) |]
+      Ast path_step [Astring tag,body]
+          |  memV path_step paths
+          -> let bc = compileM body context position last effective_axis
+                 tc = litE (stringL tag)
+             in [| do vs <- $bc
+                      return (foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] vs) |]
       Ast "step" [exp]
           -> compileM exp context position last effective_axis
       Ast "step" (exp:predicates)
@@ -582,6 +642,10 @@
       Ast "executeSQL" [Avar stmt,args]
           -> [| do as <- $(compileM args context position last effective_axis)
                    $(varE (mkName "executeSQL")) $(varE (mkName stmt)) as |]
+      Ast "append" args
+          -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args
+             in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])
+                      [| return (appendText $(listE (map (\(n,_) -> varE n) binds))) |] binds
       Ast "call" ((Avar f):args)
           -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args
              in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])
@@ -596,7 +660,7 @@
                                   -> [| do ac <- $(compileM a context position last effective_axis)
                                            vc <- $(compileM v context position last effective_axis)
                                            s <- $r
-                                           return ((qName ac,showXS (text vc)):s) |]) [| return [] |] al
+                                           return ((qName ac,showXS vc):s) |]) [| return [] |] al
                  ct = compileM tag context position last effective_axis
                  bc = compileM body context position last effective_axis
              in [| do a <- $alc
@@ -618,7 +682,7 @@
                  f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| (liftM2 (++)) $b |])
                  p = maxPosition (Avar ivar) body
                  ns = if p > 0              -- there is a top-k like restriction
-                      then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]
+                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
                       else source
                  s = compileM ns context position last effective_axis
              in [| do vs <- $s
@@ -647,7 +711,7 @@
 
 -- functions that need IO interaction (document reader, DB access, etc)
 ioSources :: [ String ]
-ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql"]
+ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql","publish","fn:publish"]
 
 
 -- collect all input documents and assign them a unique number
@@ -657,6 +721,10 @@
              Ast "call" [Avar nm,file]
                  | elem nm ["doc","fn:doc"]
                  -> (Avar ("_doc"++(show count)), count+1, [("_doc"++(show count),file)])
+             Ast "call" [Avar nm,sql]
+                 | elem nm ["sql","fn:sql"]
+                 -> (Ast "executeSQL" [Avar ("_sql"++(show count)),Ast "call" [Avar "empty"]], count+1,
+                     [("_sql"++(show count),Ast "prepareSQL" [sql])])
              Ast "call" [Avar nm,sql,args]
                  | elem nm ["sql","fn:sql"]
                  -> (Ast "executeSQL" [Avar ("_sql"++(show count)),args], count+1,
@@ -683,6 +751,7 @@
 liftIOSources query
     = let (ast,_,ns) = pullIOSources query 0
           f x = case x of
+                  Ast nm _ | elem nm ["attributes"] -> x
                   Ast _ _ | noIO x -> Ast "nonIO" [x]
                   _ -> case x of
                          Ast "call" ((Avar nm):args)
@@ -714,8 +783,8 @@
     = letE [valD (varP (mkName v)) (normalB (compileAst u)) []]
            (compileQuery xs)
 compileQuery [query]
-    = let (ast,ns) = liftIOSources query
-          code = compileAstM ast
+    = let (ast,ns) = liftIOSources (optimize query)
+          code = compileM ast undef1 undef2 undef3 ""
       in foldl (\r (n,e) -> let d = lamE [varP (mkName n)] r
                             in case e of
                                  Avar m -> [| $d $(varE (mkName m)) |]
@@ -729,7 +798,7 @@
                [| $code |] ns
 
 
--- | Debugging: display the AST and the Haskell code of an input XQuery
+-- Debugging: display the AST and the Haskell code of an input XQuery
 cq :: String -> IO ()
 cq query = do putStrLn "Abstract Syntax Tree:"
               let ast = parse (scan query)
@@ -737,9 +806,9 @@
               let opt = optimize (last ast)
               putStrLn "Optimized AST:"
               putStrLn (show opt)
-              putStrLn "Haskell Code:"
-              let code = compileQuery ast
-              runQ code >>= putStrLn.pprint
+              --putStrLn "Haskell Code:"
+              --let code = compileQuery ast
+              --runQ code >>= putStrLn.pprint
 
 
 -- | Run an XQuery expression that does not read XML documents.
@@ -757,4 +826,4 @@
 -- | Run an XQuery that reads XML documents and queries databases.
 -- When evaluated, it returns (IConnection conn) => conn -> IO XSeq.
 xqdb :: String -> Q Exp
-xqdb query = (lamE [varP (mkName "_db")] (xq query))
+xqdb query = lamE [varP (mkName "_db")] (compileQuery (parse (scan query)))
diff --git a/XML/HXQ/DB.hs b/XML/HXQ/DB.hs
--- a/XML/HXQ/DB.hs
+++ b/XML/HXQ/DB.hs
@@ -1,10 +1,10 @@
 {-------------------------------------------------------------------------------------
 -
-- HDBC connectivity
+- Database connectivity using HDBC
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 05/12/08, last update: 05/12/08
+- Creation: 05/12/08, last update: 06/12/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -16,8 +16,13 @@
 
 module XML.HXQ.DB where
 
+import Char(isSpace,toLower)
+import Control.Monad.State
 import Database.HDBC
 import XML.HXQ.XTree
+import XMLParse(XMLEvent(..),parseDocument)
+import HXML(AttList)
+import XML.HXQ.Parser
 
 
 sql2xml :: SqlValue -> XTree
@@ -46,6 +51,8 @@
       XInt n -> SqlInteger (toInteger n)
       XFloat n -> SqlString (show n)
       XBool n -> SqlBool n
+      XElem n _ _ [x] -> xml2sql x
+      _ -> error ("Cannot convert "++show e++" into sql")
 
 
 executeSQL :: Statement -> XSeq -> IO XSeq
@@ -57,3 +64,363 @@
 
 prepareSQL :: (IConnection conn) => conn -> String -> IO Statement
 prepareSQL db sql = handleSqlError (prepare db sql)
+
+
+{---------------------------------------------------------------------------------------
+-- extract the structural summary of an XML file that contains statistics
+----------------------------------------------------------------------------------------}
+
+
+-- structural summary: tag   id  max#      hasText children
+data SSnode = SSnode String !Int !Int !Int !Bool   [SSnode]
+            deriving (Eq,Show)
+
+
+insertSS :: String -> [SSnode] -> State Int (Int,SSnode,[SSnode])
+insertSS tag ((SSnode n i j l b ts):s)
+    | n == tag
+    = return (i,SSnode n i j (l+1) b ts,s)
+insertSS tag (x:xs)
+    = do (i,t,ts) <- insertSS tag xs
+         return (i,t,x:ts)
+insertSS tag []
+    = do count <- get
+         put (count+1)
+         return (count+1,SSnode tag (count+1) 1 1 False [],[])
+
+
+insSS :: String -> [SSnode] -> State Int [SSnode]
+insSS tag ns = do (k,t,s) <- insertSS tag ns
+                  return (t:s)
+
+
+getSS :: [XMLEvent] -> [SSnode] -> State Int [SSnode]
+getSS ((EmptyEvent n atts):xs) rs
+    = getSS ((StartEvent n atts):(EndEvent n):xs) rs
+getSS ((StartEvent n atts):xs) ((SSnode m i j l b ns):rs)
+    = do (k,SSnode m' i' j' l' b' ks,ts) <- insertSS n ns
+         as <- foldM (\r (a,_) -> insSS ('@':a) r) ks atts
+         getSS xs (reset(SSnode m' i' j' l' b' as):(SSnode m i j l b ts):rs)
+    where r (SSnode m i j _ b ts) = SSnode m i j 0 b ts
+          reset (SSnode m i j l b ts) = SSnode m i j l b (map r ts)
+getSS ((EndEvent n):xs) (t:(SSnode m i j l b ns):rs)
+    = getSS xs ((SSnode m i j l b (set t:ns):rs))
+    where s (SSnode m i j l b ts) = SSnode m i (max j l) 0 b ts
+          set (SSnode m i j l b ts) = SSnode m i j l b (map s ts)
+getSS ((TextEvent t):xs) ((SSnode m i j l False ns):rs)
+    | any (not . isSpace) t
+    = getSS xs ((SSnode m i j l True ns):rs)
+getSS (_:xs) rs = getSS xs rs
+getSS [] rs = return rs
+
+
+{---------------------------------------------------------------------------------------
+-- Derive a good relational schema based on the structural summary (using hybrid inlining)
+----------------------------------------------------------------------------------------}
+
+
+type Path = [Tag]
+
+
+data Table = Table String Path Bool [Table]
+           | Column String Path
+           deriving (Show,Read)
+
+
+printPath :: Path -> String
+printPath [] = ""
+printPath [p] = p
+printPath (p:ps) = printPath ps++"/"++p
+
+
+pathCons p ps = if p=="root" then ps else p:ps
+
+
+schema :: SSnode -> String -> [String] -> [Table]
+schema (SSnode n i _ (-1) _ ts) prefix path
+    = [ Table (prefix++show i) (pathCons n path) True
+              ((reverse (concatMap (\t -> schema t prefix []) ts))
+               ++[ Column "value" [] ]) ]
+schema (SSnode n i j _ _ []) prefix path
+    | j == 1 || head n == '@'
+    = [ Column (prefix++show i) (pathCons n path) ]
+schema (SSnode n i 1 _ _ ts) prefix path
+    = concatMap (\t -> schema t prefix (pathCons n path)) ts
+schema (SSnode n i _ _ b ts) prefix path
+    = [ Table (prefix++show i) (pathCons n path) False
+              ((reverse (concatMap (\t -> schema t prefix []) ts))
+              ++(if b && all (\(SSnode x _ _ _ _ _)-> head x == '@') ts
+                 then [ Column "value" [] ] else [])) ]
+
+
+fixSS :: SSnode -> SSnode
+fixSS (SSnode n i j l True ts)
+    | any (\(SSnode x _ _ _ _ _)-> head x /= '@') ts
+    = SSnode n i j (-1) True (filter (\(SSnode x _ _ _ _ _)-> head x == '@') ts)
+fixSS (SSnode n i j l b ts)
+    = SSnode n i j l b (map fixSS ts)
+
+
+deriveSchema :: String -> String -> IO Table
+deriveSchema file prefix
+    = do doc <- readFile file
+         let ts = parseDocument doc
+             d = getSS ts [SSnode "root" 1 1 1 False []]
+             [SSnode _ _ _ _ _ [t]] = evalState d 1
+             nt@(SSnode m i j l b s) = fixSS t
+         return (Table prefix [] False (reverse (schema (SSnode m i 2 l b s) prefix [])))
+
+
+relationalSchema :: Table -> String -> [String]
+relationalSchema (Table n path b ts) parent
+    = ("create table "++n++" (      /* "++printPath path
+       ++(if b then " (mixed content)" else "")++" */\n"
+       ++n++"_id int,\n"
+       ++(if parent /= "" then (n++"_parent int references "++parent++"("++parent++"_id),\n") else "")
+       ++(concat [ m++" varchar,    /* "++printPath p++" */\n" | Column m p <- ts ])
+       ++"primary key ("++n++"_id))\n")
+      :[ s | t@(Table _ _ _ _) <- ts, s <- relationalSchema t n ]
+
+
+getTableNames :: Table -> [String]
+getTableNames (Table n _ _ ts) = n:(concatMap getTableNames ts)
+getTableNames _ = []
+
+
+initializeDB :: (IConnection conn) => conn -> IO ()
+initializeDB db
+    = do tables <- getTables db
+         if elem "HXQCatalog" tables
+            then return ()
+            else do let s = "create table HXQCatalog ( name varchar primary key, path varchar, summary varchar )"
+                    handleSqlError (run db s [])
+                    commit db
+
+
+createSchema :: (IConnection conn) => conn -> String -> String -> IO Table
+createSchema db file name
+    = do initializeDB db
+         stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")
+         _ <- handleSqlError (execute stmt  [SqlString name])
+         result <- handleSqlError (fetchAllRowsAL stmt)
+         if length result > 0
+            then do let [[(_,SqlString s)]] = result
+                        summary = (read s)::Table
+                        tables = getTableNames summary
+                    _ <- mapM (\t -> handleSqlError (run db ("drop table if exists "++t) [])) tables
+                    _ <- handleSqlError (run db "delete from HXQCatalog where name = ?" [SqlString name])
+                    commit db
+            else return ()
+         t <- deriveSchema file name
+         let schema = relationalSchema t ""
+         -- mapM putStrLn schema
+         _ <- handleSqlError (run db "insert into HXQCatalog values (?,?,?)"
+                                      [SqlString name, SqlString file, SqlString (show t)])
+         _ <- mapM (\s -> handleSqlError (run db s [])) schema
+         commit db
+         return t
+
+
+findSchema :: (IConnection conn) => conn -> String -> IO Table
+findSchema db name
+    = do initializeDB db
+         stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")
+         _ <- handleSqlError (execute stmt  [SqlString name])
+         result <- handleSqlError (fetchAllRowsAL stmt)
+         if length result == 1
+            then let [[(_,SqlString s)]] = result
+                 in return ((read s)::Table)
+            else error ("Schema "++name++" doesn't exist")
+
+
+{---------------------------------------------------------------------------------------
+-- Populate the database from the XML file and its derived structural summary
+----------------------------------------------------------------------------------------}
+
+
+findPath :: [Table] -> [String] -> Int -> Maybe (Int,Table)
+findPath (t@(Table _ p _ s):ts) path _ | p == path = Just ((length s)-1,t)
+findPath (t@(Column _ p):ts) path n | p == path = Just (n,t)
+findPath ((Table _ _ _ _):ts) path n = findPath ts path n
+findPath (_:ts) path n = findPath ts path (n+1)
+findPath [] _ _ = Nothing
+
+
+populate :: [XMLEvent] -> [Table] -> Int -> [[String]] -> [(Int,String)]
+populate ((EmptyEvent tag atts):xs) ts n ps
+    = populate ((StartEvent tag atts):(EndEvent tag):xs) ts n ps
+populate (x@(StartEvent tag atts):xs) ((t@(Table n path _ s)):ts) _ (p:ps)
+    = case findPath s (tag:p) 0 of
+        Just (n,nt@(Table m _ True as))
+            -> (-1,m):(popAtts atts as ++ showXTree xs 1 "")
+               where showXTree ((EmptyEvent tag atts):xs) i s
+                         = showXTree xs i (s++"<"++tag++showAL atts++"/>")
+                     showXTree ((StartEvent tag atts):xs) i s
+                         = showXTree xs (i+1) (s++"<"++tag++showAL atts++">")
+                     showXTree ((EndEvent tag):xs) i s
+                         = if i==1 then (n,s):(-2,m):(populate xs (t:ts) n (p:ps))
+                           else showXTree xs (i-1) (s++"</"++tag++">")
+                     showXTree ((TextEvent text):xs) i s = showXTree xs i (s++text)
+                     showXTree (_:xs) i s = showXTree xs i s
+        Just (n,nt@(Table m _ _ as))
+            -> (-1,m):((popAtts atts as)++(populate xs (nt:t:ts) n ([]:p:ps)))
+        Just (n,nt)
+            -> populate xs (nt:t:ts) n ((tag:p):ps)
+        Nothing -> populate xs (t:ts) 0 ((tag:p):ps)
+      where popAtts ((a,v):as) ks
+                = let Just(m,_) = findPath ks ['@':a] 0
+                  in (m,v):(popAtts as ks)
+            popAtts [] _ = []
+populate ((EndEvent tag):xs) ((t@(Table n path _ s)):ts) _ ([]:ps)
+    = (-2,n):populate xs ts 0 ps
+populate ((EndEvent tag):xs) ((Column m path):ts) n (p:ps)
+    = populate xs ts 0 (tail p:ps)
+populate ((EndEvent text):xs) ts _ (p:ps)
+    = populate xs ts 0 (tail p:ps)
+populate ((TextEvent text):xs) ts n ps
+    | any (not . isSpace) text
+    = (n,text):populate xs ts n ps
+populate (x:xs) ts n ps
+    = populate xs ts n ps
+populate [] ts n ps = []
+
+
+insert :: (IConnection conn) => conn -> [(Int,String)] -> [(String,Int,Statement)] -> IO ()
+insert db xs stmts = let (s,_,_,_) = m xs 0 0 in s
+    where m ((-1,m):xs) i p = let (s,el,xs',i') = ml xs (i+1) i
+                              in (s >> insertTuple m el i p,[],xs',i')
+          m ((k,m):xs) i p = (return (),[(k,m)],xs,i)
+          ml [] i p = (return (),[],[],i)
+          ml ((-2,m):xs) i p = (return (),[],xs,i)
+          ml xs i p = let (s,el,xs',i') = m xs i p
+                          (s',el',xs'',i'') = ml xs' i' p
+                      in (s >> s',el++el',xs'',i'')
+          find x xs = foldr (\(a,v) r -> if x==a then v else r) "\NUL" xs
+          insertTuple m e i p
+              = let (len,stmt) = foldr (\(a,l,s) r -> if m==a then (l,s) else r) (error "") stmts
+                    tuple = map (\c -> find c e) [0..len]
+                    lift x = if x=="\NUL" then SqlNull else SqlString x
+                in do _ <- handleSqlError (execute stmt
+                                           (if i==0
+                                            then SqlInteger i:(map lift tuple)
+                                            else SqlInteger i:SqlInteger p:(map lift tuple)))
+                      if mod i 100 == 99 then commit db else return ()
+                      return ()
+
+
+-- | Store an XML document into the database under the given name.
+shred :: (IConnection conn) => conn -> String -> String -> IO ()
+shred db file name
+    = do let prefix = map toLower name
+         let tableStmt (Table n _ _ ts)
+                 = do let len = length[ 1 | Column _ _ <- ts]-1
+                      stmt <- handleSqlError (prepare db ("insert into "++n++" values ("
+                                                          ++(if n==prefix then "" else "?,")++"?"
+                                                          ++(concatMap (\_ -> ",?") [0..len])++")"))
+                      l <- mapM tableStmt ts
+                      return ((n,len,stmt):(concat l))
+             tableStmt _ = return []
+         t <- createSchema db file prefix
+         stmts <- tableStmt t
+         doc <- readFile file
+         let ts = parseDocument doc
+         let ic = (-1,prefix):(populate ts [t] 0 [[]] ++ [(-2,prefix)])
+         insert db ic stmts
+         commit db
+         return ()
+
+
+-- | Create a secondary index on tagname for the shredded document under the given name..
+createIndex :: (IConnection conn) => conn -> String -> String -> IO ()
+createIndex db name tagname
+    = do let prefix = map toLower name
+         table <- findSchema db name
+         let indexes = getIndexes "" table
+         _ <- if null indexes
+              then error ("there is no tagname: "++tagname)
+              else mapM (\(t,c) -> do stmt <- handleSqlError (prepare db ("create index "++t++"_"++c++" on "++t++" ("++c++")"))
+                                      handleSqlError (execute stmt [])) indexes
+         commit db
+         return ()
+    where getIndexes _ (Table n _ _ ts) = concatMap (getIndexes n) ts
+          getIndexes table (Column n path) | (head path)==tagname = [(table,n)]
+          getIndexes _ _ = []
+
+
+{----------------------------------------------------------------------------------------------------
+--  Convert XQuery to SQL
+----------------------------------------------------------------------------------------------------}
+
+
+publishES :: [String] -> [String] -> String
+publishES (p:ps) xs
+    | head p == '@'
+    = "attribute "++(tail p)++" {"++publishES ps xs++"}"
+publishES (p:ps) xs
+    = "<"++p++">{"++publishES ps xs++"}</"++p++">"
+publishES [] [x] = x
+publishES [] (x:xs) = x++","++publishES [] xs
+
+
+publishS :: Table -> String -> String
+publishS (Table n path b ts) "error"
+    = "for $"++n++" in SQL(select(),from($"++n++"),true()) return "
+      ++publishES (reverse path) (map (\t -> publishS t n) ts)
+publishS (Table n path b ts) parent
+    = "for $"++n++" in SQL(select(),from($"++n++"),$"++n++"/"++n++"_parent eq $"
+      ++parent++"/"++parent++"_id) return "
+      ++publishES (reverse path) (map (\t -> publishS t n) ts)
+publishS (Column n path) parent
+    = publishES (reverse path) ["$"++parent++"/"++n++"/text()"]
+
+
+publishTable :: Table -> String
+publishTable table = "<root>{" ++ publishS table "error" ++ "}</root>"
+
+
+sqlFunctions = [("=","="),("eq","="),("<=","<="),(">=",">="),("!=","!="),(">",">"),
+                ("<","<"),("ne","!="),("gt",">"),("lt","<"),("ge",">="),("le","<="),
+                ("and","and"),("or","or")]
+
+-- Convert a predicate AST to an SQL predicate that uses the tables
+toSQL :: [String] -> Ast -> (String,[Ast])
+toSQL tables e
+    = case e of
+        Astring s -> ("\'"++s++"\'",[])
+        Aint n -> (show n,[])
+        Ast "child_step" [Astring c,Avar v]
+            -> if elem v tables
+               then (v++"."++c,[])
+               else ("?",[e])
+        Ast "construction" [_,_,Ast "append" [x]]
+            -> toSQL tables x
+        Ast "call" [Avar "text",x]
+            -> toSQL tables x
+        Ast "call" [Avar cmp,x,y]
+            | any (\(f,_) -> f==cmp) sqlFunctions
+            -> let (nx,vx) = toSQL tables x
+                   (ny,vy) = toSQL tables y
+               in (nx ++ " " ++ snd (head (filter (\(f,_) -> f==cmp) sqlFunctions)) ++ " " ++ ny,vx++vy)
+        _ -> error ("Cannot convert to SQL: "++show e)
+
+
+-- Convert an AST to an SQL
+makeSQL :: [Ast] -> Ast -> [Ast] -> (String,[Ast])
+makeSQL tables pred cols
+    = let tnames = [ x | Avar x <- tables ]
+          ts = combine tnames
+          cs = combine [ x | Avar x <- cols ]
+          vars (Ast n args) = concatMap vars args
+          vars (Avar v) | not (elem v tnames) = [v]
+          vars _ = []
+          combine [] = ""
+          combine [x] = x
+          combine (x:xs) = x++", "++combine xs
+      in if pred == Ast "call" [Avar "true"]
+         then (if null cs
+               then "select * from "++ts
+               else "select "++cs++" from "++ts,[])
+         else let (p,args) = toSQL tnames pred
+              in (if null cs
+                  then "select * from "++ts++" where "++p
+                  else "select "++cs++" from "++ts++" where "++p,args)
diff --git a/XML/HXQ/DBConnect.hs b/XML/HXQ/DBConnect.hs
new file mode 100644
--- /dev/null
+++ b/XML/HXQ/DBConnect.hs
@@ -0,0 +1,26 @@
+{-------------------------------------------------------------------------------------
+-
+- HDBC driver. Currently, Sqlite3.
+- Programmer: Leonidas Fegaras
+- Email: fegaras@cse.uta.edu
+- Web: http://lambda.uta.edu/
+- Creation: 05/30/08, last update: 05/30/08
+- 
+- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
+- This material is provided as is, with absolutely no warranty expressed or implied.
+- Any use is at your own risk. Permission is hereby granted to use or copy this program
+- for any purpose, provided the above notices are retained on all copies.
+-
+--------------------------------------------------------------------------------------}
+
+
+module XML.HXQ.DBConnect where
+
+
+import Database.HDBC.Sqlite3
+
+
+
+-- | Connect to the relational database in filepath using the HDBC Sqlite3 driver
+connect :: FilePath -> IO Connection
+connect filepath = connectSqlite3 filepath
diff --git a/XML/HXQ/Interpreter.hs b/XML/HXQ/Interpreter.hs
--- a/XML/HXQ/Interpreter.hs
+++ b/XML/HXQ/Interpreter.hs
@@ -4,7 +4,7 @@
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 03/22/08, last update: 05/02/08
+- Creation: 03/22/08, last update: 05/30/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -14,7 +14,7 @@
 --------------------------------------------------------------------------------------}
 
 
-{-# OPTIONS_GHC -fth #-}
+{-# OPTIONS_GHC -fth -fglasgow-exts #-}
 
 
 module XML.HXQ.Interpreter where
@@ -27,19 +27,25 @@
 import XML.HXQ.XTree
 import XML.HXQ.Optimizer
 import XML.HXQ.Compiler
+import Database.HDBC
+import XML.HXQ.DB
+import XML.HXQ.DBConnect
 
 
 -- system functions (=, concat, etc)
 systemFunctions :: [(String,Int,[XSeq]->XSeq)]
 systemFunctions = $(iFunctions)
 
+
 -- XPath step functions (child, descendant, etc)
 pathFunctions :: [(String,Tag->XTree->XSeq)]
 pathFunctions = $(pFunctions)
 
+
 -- run-time bindings of FLOWR variables
 type Environment = [(String,XSeq)]
 
+
 -- a user-defined function is (fname,parameters,body)
 type Functions = [(String,[String],Ast)]
 
@@ -49,6 +55,7 @@
 undefv3 = error "Undefined last()"
 
 
+
 -- Each XPath predicate must calculate position() and last() from its input XSeq
 -- if last() is used, then the evaluation is blocking (need to store the whole input XSeq)
 applyPredicates :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> XSeq
@@ -62,16 +69,14 @@
     | containsLast pred         -- blocking: use only when last() is used in the predicate
     = let last = length xs
       in applyPredicates preds
-             (foldir (\x i r -> if case eval pred x i last "" env fncs of
-                                     [XInt k] -> k == i               -- indexing
-                                     b -> conditionTest b
-                                then x:r else r) [] xs 1) True env fncs
+             (foldir (\x i r -> case eval pred x i last "" env fncs of
+                                  [XInt k] -> if k == i then x:r else r               -- indexing
+                                  b -> if conditionTest b then x:r else r) [] xs 1) True env fncs
 applyPredicates (pred:preds) xs _ env fncs
     = applyPredicates preds
-          (foldir (\x i r -> if case eval pred x i undefv3 "" env fncs of
-                                  [XInt k] -> k == i               -- indexing
-                                  b -> conditionTest b
-                             then x:r else r) [] xs 1) True env fncs
+          (foldir (\x i r -> case eval pred x i undefv3 "" env fncs of
+                               [XInt k] -> if k == i then x:r else r               -- indexing
+                               b -> if conditionTest b then x:r else r) [] xs 1) True env fncs
 
 
 -- The XQuery interpreter
@@ -95,9 +100,9 @@
                    [] (eval v context position last effective_axis env fncs)
       Ast "call" [Avar "position"] -> [XInt position]
       Ast "call" [Avar "last"] -> [XInt last]
-      Ast "step" [Ast "child_step" [tag, Avar "."]]
+      Ast "child_step" [tag, Avar "."]
           |  effective_axis /= ""
-          -> eval (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last "" env fncs
+          -> eval (Ast effective_axis [tag, Avar "."]) context position last "" env fncs
       Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
           -> let ts = map (\(Avar tag) -> tag) tags
              in foldr (\x r -> (applyPredicates predicates (descendant_any_with_tagged_children ts x) True env fncs)++r)
@@ -106,12 +111,22 @@
           |  memV path_step pathFunctions
           -> foldr (\x r -> (applyPredicates predicates ((findV path_step pathFunctions) tag x) True env fncs)++r)
                    [] (eval body context position last effective_axis env fncs)
+      Ast "descendant_any" (body:tags)
+          -> let ts = map (\(Avar tag) -> tag) tags
+             in foldr (\x r -> (descendant_any_with_tagged_children ts x)++r)
+                      [] (eval body context position last effective_axis env fncs)
+      Ast path_step [Astring tag,body]
+          |  memV path_step pathFunctions
+          -> foldr (\x r -> ((findV path_step pathFunctions) tag x)++r)
+                   [] (eval body context position last effective_axis env fncs)
       Ast "step" [exp]
           -> eval exp context position last effective_axis env fncs
       Ast "step" (exp:predicates)
           -> applyPredicates predicates (eval exp context position last effective_axis env fncs) True env fncs
       Ast "predicate" [condition,body]
           -> applyPredicates [condition] (eval body context position last effective_axis env fncs) True env fncs
+      Ast "append" args
+          -> appendText (map (\x -> eval x context position last effective_axis env fncs) args)
       Ast "call" ((Avar fname):args)
           -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of
                [(_,len,f)] -> if (length args) == len
@@ -130,7 +145,7 @@
              -> let alc = map (\(Ast "pair" [a,v])
                                      -> let ac = eval a context position last effective_axis env fncs
                                             vc = eval v context position last effective_axis env fncs
-                                        in (qName ac,showXS (text vc))) al
+                                        in (qName ac,showXS vc)) al
                     ct = eval tag context position last effective_axis env fncs
                     bc = eval body context position last effective_axis env fncs
                 in [ XElem (qName ct) alc 0 bc ]
@@ -143,7 +158,7 @@
       Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
           -> let p = maxPosition (Avar ivar) body
                  ns = if p > 0              -- there is a top-k like restriction
-                      then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]
+                      then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
                       else source 
              in foldir (\a i r -> (eval body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs)++r)
                        [] (eval ns context position last effective_axis env fncs) 1
@@ -209,9 +224,9 @@
                       (return []) vs
       Ast "call" [Avar "position"] -> return [XInt position]
       Ast "call" [Avar "last"] -> return [XInt last]
-      Ast "step" [Ast "child_step" [tag, Avar "."]]
+      Ast "child_step" [tag, Avar "."]
           |  effective_axis /= ""
-          -> evalM (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last "" env fncs
+          -> evalM (Ast effective_axis [tag, Avar "."]) context position last "" env fncs
       Ast "step" ((Ast "descendant_any" (body:tags)):predicates)
           -> do vs <- evalM body context position last effective_axis env fncs
                 let ts = map (\(Avar tag) -> tag) tags
@@ -222,6 +237,14 @@
           -> do vs <- evalM body context position last effective_axis env fncs
                 foldr (\x r -> (liftM2 (++)) (applyPredicatesM predicates ((findV path_step pathFunctions) tag x) True env fncs) r)
                       (return []) vs
+      Ast "descendant_any" (body:tags)
+          -> do vs <- evalM body context position last effective_axis env fncs
+                let ts = map (\(Avar tag) -> tag) tags
+                return (foldr (\x r -> (descendant_any_with_tagged_children ts x)++r) [] vs)
+      Ast path_step [Astring tag,body]
+          |  memV path_step pathFunctions
+          -> do vs <- evalM body context position last effective_axis env fncs
+                return (foldr (\x r -> ((findV path_step pathFunctions) tag x)++r) [] vs)
       Ast "step" [exp]
           -> evalM exp context position last effective_axis env fncs
       Ast "step" (exp:predicates)
@@ -230,10 +253,16 @@
       Ast "predicate" [condition,body]
           -> do vs <- evalM body context position last effective_axis env fncs
                 applyPredicatesM [condition] vs True env fncs
+      Ast "executeSQL" [Avar var,args]
+          -> do as <- evalM args context position last effective_axis env fncs
+                let [XStmt stmt] = findV var env
+                executeSQL stmt as
       Ast "call" [Avar nm,c,t,e]     -- this is the only lazy function
           | elem nm ["if","fn:if"]
           -> do ce <- evalM c context position last effective_axis env fncs
                 evalM (if conditionTest ce then t else e) context position last effective_axis env fncs
+      Ast "append" args
+          -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs) args)
       Ast "call" ((Avar fname):args)        -- Note: strict function application
           -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of
                [(_,len,f)] -> if (length args) == len
@@ -253,7 +282,7 @@
              -> do alc <- mapM (\(Ast "pair" [a,v])
                                      -> do ac <- evalM a context position last effective_axis env fncs
                                            vc <- evalM v context position last effective_axis env fncs
-                                           return (qName ac,showXS (text vc))) al
+                                           return (qName ac,showXS vc)) al
                    ct <- evalM tag context position last effective_axis env fncs
                    bc <- evalM body context position last effective_axis env fncs
                    return [ XElem (qName ct) alc 0 bc ]
@@ -267,7 +296,7 @@
       Ast "for" [Avar var,Avar ivar,source,body]     -- a for-loop with an index
           -> do let p = maxPosition (Avar ivar) body
                     ns = if p > 0              -- there is a top-k like restriction
-                            then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]
+                            then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]]
                             else source 
                 vs <- evalM ns context position last effective_axis env fncs
                 foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs) r)
@@ -316,8 +345,8 @@
                     evalInput eval nvs nfs
 
 
-xqueryE :: String -> Environment -> Functions -> IO (XSeq,Environment,Functions)
-xqueryE query variables functions
+xqueryE :: String -> Environment -> Functions -> (String -> IO XSeq) -> Bool -> IO (XSeq,Environment,Functions)
+xqueryE query variables functions dbmapper verbose
     = do let asts = parse (scan query)
              fncs = foldr (\e r -> case e of
                                      Ast "function" ((Avar f):b:args) -> (f,map (\(Avar v) -> v) args,optimize b):r
@@ -329,24 +358,52 @@
                                             return ((v,uv):s)
                                   _ -> r) (return variables) asts
          let exprp e = case e of Ast f _ | elem f ["function","variable"] -> True; _ -> False
-             (ast,ns) = liftIOSources (concatenateAll (dropWhile exprp asts))
+             exps = concatenateAll (dropWhile exprp asts)
+             opt_exps = optimize exps
+             (ast,ns) = liftIOSources opt_exps
+         if verbose
+            then do putStrLn "Abstract Syntax Tree (AST):"
+                    putStrLn (ppAst exps)
+                    putStrLn "Optimized AST:"
+                    putStrLn (ppAst opt_exps)
+                    putStrLn "Result:"
+            else return ()
          env <- foldr (\(n,s) r -> case s of
+                                     Avar m -> do env <- r
+                                                  return ((n,findV m env):env)
+                                     Ast "prepareSQL" [Astring sql]
+                                         -> do env <- r
+                                               t <- dbmapper sql
+                                               return ((n,t):env)
                                      Astring file -> do doc <- readFile file
                                                         env <- r
-                                                        return ((n,[materialize (parseDocument doc)]):env)
-                                     Avar m -> do env <- r
-                                                  return ((n,findV m env):env))
+                                                        return ((n,[materialize (parseDocument doc)]):env))
                       (return []) ns
-         e <- evalM (optimize ast) undefv1 undefv2 undefv3 "" (env++vars) fncs
+         e <- evalM ast undefv1 undefv2 undefv3 "" (env++vars) fncs
          return (e,vars,fncs)
 
 
--- | Evaluate the XQuery using interpreter.
+-- | Evaluate the XQuery using the interpreter.
 xquery :: String -> IO XSeq
-xquery query = do (u,_,_) <- xqueryE query [] []; return u
+xquery query = do (u,_,_) <- xqueryE query [] [] (\sql -> return []) False
+                  return u
 
 
--- | Read an XQuery fom a file and run it using the interpreter.
+-- | Read an XQuery from a file and run it using the interpreter.
 xfile :: String -> IO XSeq
 xfile file = do query <- readFile file
                 xquery query
+
+
+-- | Evaluate the XQuery with database connectivity using the interpreter.
+xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq
+xqueryDB query db = do (u,_,_) <- xqueryE query [] []
+                                  (\sql -> do stmt <- prepareSQL db sql
+                                              return [XStmt stmt]) False
+                       return u
+
+
+-- | Read an XQuery with database connectivity from a file and run it using the interpreter.
+xfileDB :: (IConnection conn) => String -> conn -> IO XSeq
+xfileDB file db = do query <- readFile file
+                     xqueryDB query db
diff --git a/XML/HXQ/Optimizer.hs b/XML/HXQ/Optimizer.hs
--- a/XML/HXQ/Optimizer.hs
+++ b/XML/HXQ/Optimizer.hs
@@ -4,7 +4,7 @@
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 05/01/08, last update: 05/01/08
+- Creation: 05/01/08, last update: 06/10/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -16,17 +16,42 @@
 
 module XML.HXQ.Optimizer(optimize) where
 
-import XML.HXQ.Parser(Ast(..))
+import System.IO.Unsafe
+import Control.Monad
+import Char(toLower)
+import List(sortBy)
+import Database.HDBC
+import HXML(AttList)
+import XML.HXQ.Parser
 import XML.HXQ.XTree
+import XML.HXQ.DB
+import XML.HXQ.DBConnect
 
 
-paths = [ "child_step", "descendant_step", "attribute_step", "attribute_descendant_step" ]
 
+paths = [ "current_step", "child_step", "descendant_step", "attribute_step", "attribute_descendant_step" ]
 
+
 distinct :: Eq a => [a] -> [a]
 distinct = foldl (\r a -> if elem a r then r else r++[a]) []
 
 
+{-# NOINLINE publishXmlDoc #-}
+-- get an XML document stored in a relational database
+publishXmlDoc :: FilePath -> String -> Ast
+publishXmlDoc filepath name
+    = let query = unsafePerformIO (publishWrapper filepath name)
+          [ast] = parse (scan query)
+      in ast
+    where publishWrapper filepath name
+              = do let prefix = map toLower name
+                   db <- connect filepath
+                   table <- findSchema db prefix
+                   let query = publishTable table
+                   disconnect db
+                   return query
+
+
 -- collect attribute constructions inside element constructions
 collect_attributes :: Ast -> (Ast,[Ast])
 collect_attributes (Ast "attribute_construction" [attr,value])
@@ -35,6 +60,9 @@
     = let (cx,ax) = collect_attributes x
           (cy,ay) = collect_attributes y
       in (Ast "call" [Avar "concatenate",cx,cy],ax++ay)
+collect_attributes (Ast "append" es)
+    = let (s,a) = foldr (\e (r,ar) -> let (cx,ax) = collect_attributes e in (cx:r,ax++ar)) ([],[]) es
+      in (Ast "append" s,a)
 collect_attributes (Ast "step" (e:es))
     = let (ce,ae) = collect_attributes e
       in (Ast "step" (ce:es),ae)
@@ -95,26 +123,30 @@
 tagged_children context (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Avar v):_)]):_))
     | v == context
     = [tag]
+tagged_children _ (Ast "step" ((Ast "descendant_any" _):_)) = []
 tagged_children _ (Ast "step" ((Ast step _):_))
     | elem step paths = []
 tagged_children context (Ast _ xs) = concatMap (tagged_children context) xs
 tagged_children _ _ = []
 
 
-optimize :: Ast -> Ast
+empty = Ast "call" [Avar "empty"]
+
+
+simplify :: Ast -> Ast
 -- must be done bottom-up:    /../..
-optimize (Ast "step" [Ast "parent_step" [Ast "step" [Ast "parent_step" x]]])
-    = let nx = optimize (Ast "step" [Ast "parent_step" x])
-      in optimize (Ast "step" [Ast "parent_step" [nx]])
+simplify (Ast "step" [Ast "parent_step" [Ast "step" [Ast "parent_step" x]]])
+    = let nx = simplify (Ast "step" [Ast "parent_step" x])
+      in simplify (Ast "step" [Ast "parent_step" [nx]])
 -- get rid of a parent step
-optimize (Ast "step" [Ast "parent_step" [x]])
-    = let (nx,cond,_,_) = removeParent x
-      in Ast "predicate" [optimize nx,optimize cond]
+simplify (Ast "step" [Ast "parent_step" [x]])
+    = let (cond,nx,_,_) = removeParent x
+      in Ast "predicate" [simplify cond,simplify nx]
 -- remove $var/.. in a let-FLWOR
-optimize (Ast "let" [Avar var,source,body])
+simplify (Ast "let" [Avar var,source,body])
     | parentOfVar body var
-    = let (nx,cond,childp,tag) = removeParent source
-      in optimize (Ast "let" [Avar (var++"_parent"),Ast "predicate" [nx,cond],
+    = let (cond,nx,childp,tag) = removeParent source
+      in simplify (Ast "let" [Avar (var++"_parent"),Ast "predicate" [cond,nx],
                               Ast "let" [Avar var,
                                          Ast "step" [ Ast (if childp
                                                            then "child_step"
@@ -122,10 +154,10 @@
                                                       [tag,Avar (var++"_parent")] ],
                                          replaceParentOfVar body var (var++"_parent")]])
 -- remove $var/.. from a for-FLWOR
-optimize (Ast "for" [Avar var,Avar "$",source,body])
+simplify (Ast "for" [Avar var,Avar "$",source,body])
     | parentOfVar body var
-    = let (nx,cond,childp,tag) = removeParent source
-      in optimize (Ast "for" [Avar (var++"_parent"),Avar "$",Ast "predicate" [nx,cond],
+    = let (cond,nx,childp,tag) = removeParent source
+      in simplify (Ast "for" [Avar (var++"_parent"),Avar "$",Ast "predicate" [cond,nx],
                               Ast "for" [Avar var,Avar "$",
                                          Ast "step" [ Ast (if childp
                                                            then "child_step"
@@ -133,24 +165,288 @@
                                                       [tag,Avar (var++"_parent")] ],
                                          replaceParentOfVar body var (var++"_parent")]])
 -- pull out attributes from a general element construction
-optimize (Ast "element_construction" [tag,content])
+simplify (Ast "element_construction" [tag,Ast "attributes" as,content])
     = let (nc,attrs) = collect_attributes content
-      in optimize (Ast "construction" [tag,Ast "attributes" attrs,nc])
+      in simplify (Ast "construction" [tag,Ast "attributes" (as++attrs),nc])
 -- if //* collect all children tagnames to use descendant_any_with_tagged_children
-optimize (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)],body])
+simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)],body])
     | not (null ((tagged_children var body))) || any (not . null . (tagged_children ".")) preds
     = let ctags = distinct ((tagged_children var body)++(concatMap (tagged_children ".") preds))
           tags = map Avar ctags
-      in optimize (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_any" (path:tags)):preds)],body])
-optimize (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)]):preds2))
+      in simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_any" (path:tags)):preds)],body])
+simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)]):preds2))
     = let ctags = distinct(tag:(concatMap (tagged_children ".") preds))
           tags = map Avar ctags
-      in optimize (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_any" (path:tags)):preds)]):preds2))
-optimize (Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds))
+      in simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_any" (path:tags)):preds)]):preds2))
+simplify (Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds))
     | any (not . null . (tagged_children ".")) preds
     = let ctags = distinct (concatMap (tagged_children ".") preds)
           tags = map Avar ctags
-      in optimize (Ast "step" ((Ast "descendant_any" (path:tags)):preds))
--- needs more rules
-optimize (Ast n args) = Ast n (map optimize args)
-optimize e = e
+      in simplify (Ast "step" ((Ast "descendant_any" (path:tags)):preds))
+-- expand the wrapper of a stored document
+simplify (Ast "call" [Avar "publish",Astring dbpath,Astring name])
+    = simplify (publishXmlDoc dbpath name)
+-- default
+simplify (Ast n args) = Ast n (map simplify args)
+simplify e = e
+
+
+taggedElement :: [Ast] -> String -> Maybe [Ast]
+taggedElement (e@(Ast "construction" [Astring ctag,_,x]):xs) tag
+    | ctag == tag || tag == "*"
+    = case taggedElement xs tag of
+        Nothing -> Nothing
+        Just s -> Just (e:s)
+taggedElement ((Ast "construction" [_,_,_]):xs) tag
+    = taggedElement xs tag
+taggedElement ((Ast "call" [Avar "concatenate",x,y]):xs) tag
+    = case (taggedElement (x:xs) tag,taggedElement (y:xs) tag) of
+        (Just tx,Just ty) -> Just (tx++ty)
+        _ -> Nothing
+taggedElement ((Astring _):xs) tag
+    = taggedElement xs tag
+taggedElement ((Aint _):xs) tag
+    = taggedElement xs tag
+taggedElement (e:xs) tag = Nothing
+taggedElement [] _ = Just []
+
+
+findAttr :: String -> [Ast] -> Ast
+findAttr tag ((Ast "pair" [Astring a,v]):_) | a==tag || tag=="*" = v
+findAttr tag (_:xs) = findAttr tag xs
+findAttr _ [] = empty
+
+
+andAll :: [Ast] -> Ast
+andAll [x] = x
+andAll (x:xs) = foldl (\a r -> call "and" [a,r]) x xs
+
+
+substContext :: Ast -> Ast -> Maybe Ast
+substContext context e
+    = case e of
+        Ast "call" ((Avar f):xs)
+            -> do ys <- mapM (substContext context) xs
+                  return (Ast "call" ((Avar f):ys))
+        Ast "descendant_any" (x:tags)
+            -> do nx <- substContext context x
+                  return (Ast "descendant_any" (nx:tags))
+        Ast step [tag,x]
+            | elem step paths
+            -> do nx <- substContext context x
+                  return (Ast step [tag,nx])
+        Avar "." -> Just context
+        Astring _ -> Just e
+        Aint _ -> Just e
+        Afloat _ -> Just e
+        Avar _ -> Just e
+        _ -> Nothing
+
+
+occurs :: String -> Ast -> Int
+occurs v e
+    = case e of
+        Avar w | v==w -> 1
+        Ast "let" [Avar w,_,_] | v==w -> 0
+        Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> 0
+        Ast n xs -> sum (map (occurs v) xs)
+        _ -> 0
+
+
+subst :: String -> Ast -> Ast -> Ast
+subst v e b
+    = case b of
+        Avar w | v==w -> e
+        Ast "let" [Avar w,_,_] | v==w -> b
+        Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> b
+        Ast n xs -> Ast n (map (subst v e) xs)
+        _ -> b
+
+
+sqlPredicate :: Ast -> Bool
+sqlPredicate e
+    = case e of
+        Astring s -> True
+        Aint n -> True
+        Ast "child_step" [Astring c,Avar v] -> True
+        Ast "construction" [_,_,Ast "append" [x]]
+            -> sqlPredicate x
+        Ast "call" [Avar "text",x]
+            -> sqlPredicate x
+        Ast "call" [Avar cmp,x,y]
+            | any (\(f,_) -> f==cmp) sqlFunctions
+            -> (sqlPredicate x) && (sqlPredicate y)
+        _ -> False
+
+
+usesCurrentContext :: Ast -> Bool
+usesCurrentContext (Ast _ xs) = any usesCurrentContext xs
+usesCurrentContext (Avar ".") = True
+usesCurrentContext _ = False
+
+
+-- Normalization
+normalize :: Ast -> Bool -> (Ast,Bool)
+normalize exp changed
+    = case exp of
+        Ast "step" [x]
+            -> normalize x True
+        Ast "step" (x:(Ast "call" [Avar "true"]):xs)
+            -> normalize (Ast "step" (x:xs)) True
+        Ast "step" (x:(Ast "call" [Avar "false"]):xs)
+            -> (empty,True)
+        Ast "for" [v,i,Ast "call" [Avar "empty"],b]
+            -> (empty,True)
+        Ast "for" [v,i,s,Ast "call" [Avar "empty"]]
+            -> (empty,True)
+        Ast "descendant_any" ((Astring _):_)
+            -> (empty,True)
+        Ast "descendant_any" ((Aint _):_)
+            -> (empty,True)
+        Ast "descendant_any" ((Afloat _):_)
+            -> (empty,True)
+        Ast "descendant_any" ((Ast "call" [Avar "text",_]):_)
+            -> (empty,True)
+        Ast "descendant_any" ((Ast "call" [Avar "empty"]):_)
+            -> (empty,True)
+        Ast step [_,Astring _]
+            | elem step paths
+            -> (empty,True)
+        Ast step [_,Aint _]
+            | elem step paths
+            -> (empty,True)
+        Ast step [_,Afloat _]
+            | elem step paths
+            -> (empty,True)
+        Ast step [_,Ast "call" [Avar "text",_]]
+            | elem step paths
+            -> (empty,True)
+        Ast step [_,Ast "call" [Avar "empty"]]
+            | elem step paths
+            -> (empty,True)
+        Ast "call" [Avar "and",Ast "call" [Avar "true"],x]
+            -> normalize x True
+        Ast "call" [Avar "and",x,Ast "call" [Avar "true"]]
+            -> normalize x True
+        -- (x,())  ->  x
+        Ast "call" [Avar "concatenate",x,Ast "call" [Avar "empty"]]
+            -> normalize x True
+        -- ((),x)  ->  x
+        Ast "call" [Avar "concatenate",Ast "call" [Avar "empty"],x]
+            -> normalize x True
+        -- for $v1 in (for $v2 in s2 return b2) return b1  -->  for $v2 in s2, for $v1 in b2 return b1
+        Ast "for" [v1,i1,Ast "for" [v2,i2,s2,b2],b1]
+            -> normalize (Ast "for" [v2,i2,s2,Ast "for" [v1,i1,b2,b1]]) True
+        -- (for $v in s return b)/tag  -->  for $v in s return b/tag  -->  
+        Ast "descendant_any" ((Ast "for" [v,i,s,b]):tags)
+            -> normalize (Ast "for" [v,i,s,Ast "descendant_any" (b:tags)]) True
+        Ast step [tag,Ast "for" [v,i,s,b]]
+            | elem step paths
+            -> normalize (Ast "for" [v,i,s,Ast step [tag,b]]) True
+        -- (x,y)/tag  -->  (x/tag,y/tag)
+        Ast "descendant_any" ((Ast "call" [Avar "concatenate",x,y]):tags)
+            -> normalize (Ast "call" [Avar "concatenate",Ast "descendant_any" (x:tags),Ast "descendant_any" (y:tags)]) True
+        Ast step [tag,Ast "call" [Avar "concatenate",x,y]]
+            | elem step paths
+            -> normalize (Ast "call" [Avar "concatenate",Ast step [tag,x],Ast step [tag,y]]) True
+        -- for $v in (x,y) return b  -->  (for $v in x return b,for $v in y return b)
+        Ast "for" [v,i,Ast "call" [Avar "concatenate",x,y],b]
+            -> normalize (Ast "call" [Avar "concatenate",Ast "for" [v,i,x,b],Ast "for" [v,i,y,b]]) True
+        Ast "for" [Avar v,Avar i,e,b]
+            | case e of Ast "construction" _ -> True; Ast _ _ -> False; _ -> True
+            -> normalize (if i == "$"
+                          then subst v e b
+                          else subst v e (subst i (Aint 1) b)) True
+        -- unfold linear let
+        Ast "let" [Avar v,e,b]
+            | occurs v b < 2
+            -> normalize (subst v e b) True
+        -- (if c then t else e)/A  -->  if c then t/A else e/A
+        Ast "descendant_any" ((Ast "predicate" [c,e]):tags)
+            | not (usesCurrentContext c)
+            -> normalize (Ast "predicate" [c,Ast "descendant_any" (e:tags)]) True
+        Ast step [tag,Ast "predicate" [c,e]]
+            | elem step paths && not (usesCurrentContext c)
+            -> normalize (Ast "predicate" [c,Ast step [tag,e]]) True
+        -- normalize predicate
+        Ast "predicate" [Ast "call"[Avar "true"],x]
+            -> (empty,True)
+        Ast "predicate" [x,Ast "call"[Avar "empty"]]
+            -> (empty,True)
+        Ast "step" ((Ast "call" [Avar "empty"]):xs)
+            -> (empty,True)
+        Ast "step" ((Ast "call" [Avar "concatenate",x,y]):xs)
+            -> normalize (Ast "call" [Avar "concatenate",Ast "step" (x:xs),Ast "step" (y:xs)]) True
+        Ast "step" ((Ast "for" [v,i,s,b]):xs)
+            -> normalize (Ast "for" [v,i,s,Ast "step" (b:xs)]) True
+        Ast "step" (e@(Ast "construction" [_,_,_]):xs)
+            -> case mapM (substContext e) xs of
+                 Just es -> normalize (Ast "predicate" [andAll es,e]) True
+                 Nothing -> let (r,b) = foldr (\a (r,b) -> let (c,s) = normalize a b in (c:r,s))
+                                              ([],changed) (e:xs)
+                            in (Ast "step" r,b)
+        Ast "call" [Avar "=",x,y]
+            | x == empty || y == empty
+            -> (Ast "call"[Avar "true"],True)
+        -- (<ctag>...<tag>...</tag>...</ctag>)/tag  -->  ...<tag>...</tag>...
+        Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]
+            | taggedElement x tag /= Nothing
+            -> case taggedElement x tag of
+                 Just [] -> (empty,True)
+                 Just s -> normalize (concatenateAll s) True
+        Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]
+            -> normalize (Ast "current_step" [Astring tag,concatenateAll x]) True
+        Ast "current_step" [Astring tag1,e@(Ast "construction" [Astring tag2,_,Ast "append" x])]
+            -> if tag1 == tag2 || tag1 == "*"
+               then normalize e True
+               else (empty,True)
+        -- (<tag>x</tag>)//tag  --> (x,x//tag)
+        Ast "descendant_any" (z@(Ast "construction" [Astring ctag,_,Ast "append" x]):tags)
+            -> normalize (Ast "call" [Avar "concatenate",z,Ast "descendant_any" ((concatenateAll x):tags)]) True
+        Ast "descendant_step" [Astring tag,z@(Ast "construction" [Astring ctag,_,Ast "append" x])]
+            -> normalize (if tag == ctag || tag == "*"
+                          then Ast "call" [Avar "concatenate",z,Ast "descendant_step" [Astring tag,concatenateAll x]]
+                          else Ast "descendant_step" [Astring tag,concatenateAll x]) True
+        -- (<tag A=s>x</tag>)/@A  --> s
+        Ast "attribute_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,x]]
+            -> (findAttr tag as,True)
+        -- (<tag A=s>x</tag>)//@A  --> (s,x//@A)
+        Ast "attribute_descendant_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,Ast "append" x]]
+            -> normalize (Ast "call" [Avar "concatenate",findAttr tag as,
+                                      Ast "attribute_descendant_step" [Astring tag,concatenateAll x]]) True
+        -- SQL folding
+        Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],
+                   Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],b]]
+            -> normalize (Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):(s1++s2)),
+                                                                  Ast "call" ((Avar "from"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]],b])
+                         True
+        Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):f),pred1],
+                   Ast "predicate" [pred2,x]]
+            | sqlPredicate pred2
+            -> normalize (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),
+                                                                 Ast "call" ((Avar "from"):f),Ast "call" [Avar "and",pred1,pred2]],x]) True
+        -- default
+        Ast n args
+            -> let (r,b) = foldr (\a (r,b) -> let (c,s) = normalize a b in (c:r,s)) ([],changed) args
+               in (Ast n r,b)
+        _ -> (exp,changed)
+
+
+foldSQL :: Ast -> Ast
+foldSQL e
+    = case e of
+        Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "from"):tables),pred]
+            -> let (sql,args) = makeSQL tables pred cols
+               in Ast "call" [Avar "sql",Astring sql,concatenateAll args]
+        Ast n args -> Ast n (map foldSQL args)
+        _ -> e
+
+
+optimizeLoop :: Ast -> Ast
+optimizeLoop e = let (ne,b) = normalize e False
+                 in if b
+                    then optimizeLoop ne
+                    else ne
+
+optimize :: Ast -> Ast
+optimize e = foldSQL (optimizeLoop (simplify e))
diff --git a/XML/HXQ/Parser.hs b/XML/HXQ/Parser.hs
--- a/XML/HXQ/Parser.hs
+++ b/XML/HXQ/Parser.hs
@@ -122,48 +122,60 @@
 happyOut20 :: (HappyAbsSyn ) -> ([ Ast ])
 happyOut20 x = unsafeCoerce# x
 {-# INLINE happyOut20 #-}
-happyIn21 :: ([ Ast ]) -> (HappyAbsSyn )
+happyIn21 :: (Ast) -> (HappyAbsSyn )
 happyIn21 x = unsafeCoerce# x
 {-# INLINE happyIn21 #-}
-happyOut21 :: (HappyAbsSyn ) -> ([ Ast ])
+happyOut21 :: (HappyAbsSyn ) -> (Ast)
 happyOut21 x = unsafeCoerce# x
 {-# INLINE happyOut21 #-}
-happyIn22 :: (Ast) -> (HappyAbsSyn )
+happyIn22 :: ([Ast]) -> (HappyAbsSyn )
 happyIn22 x = unsafeCoerce# x
 {-# INLINE happyIn22 #-}
-happyOut22 :: (HappyAbsSyn ) -> (Ast)
+happyOut22 :: (HappyAbsSyn ) -> ([Ast])
 happyOut22 x = unsafeCoerce# x
 {-# INLINE happyOut22 #-}
-happyIn23 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn23 :: ([ Ast ]) -> (HappyAbsSyn )
 happyIn23 x = unsafeCoerce# x
 {-# INLINE happyIn23 #-}
-happyOut23 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut23 :: (HappyAbsSyn ) -> ([ Ast ])
 happyOut23 x = unsafeCoerce# x
 {-# INLINE happyOut23 #-}
-happyIn24 :: (Ast -> Ast) -> (HappyAbsSyn )
+happyIn24 :: (Ast) -> (HappyAbsSyn )
 happyIn24 x = unsafeCoerce# x
 {-# INLINE happyIn24 #-}
-happyOut24 :: (HappyAbsSyn ) -> (Ast -> Ast)
+happyOut24 :: (HappyAbsSyn ) -> (Ast)
 happyOut24 x = unsafeCoerce# x
 {-# INLINE happyOut24 #-}
-happyIn25 :: (String -> Ast -> [ Ast ]) -> (HappyAbsSyn )
+happyIn25 :: (Ast -> Ast) -> (HappyAbsSyn )
 happyIn25 x = unsafeCoerce# x
 {-# INLINE happyIn25 #-}
-happyOut25 :: (HappyAbsSyn ) -> (String -> Ast -> [ Ast ])
+happyOut25 :: (HappyAbsSyn ) -> (Ast -> Ast)
 happyOut25 x = unsafeCoerce# x
 {-# INLINE happyOut25 #-}
-happyIn26 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
+happyIn26 :: (Ast -> Ast) -> (HappyAbsSyn )
 happyIn26 x = unsafeCoerce# x
 {-# INLINE happyIn26 #-}
-happyOut26 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
+happyOut26 :: (HappyAbsSyn ) -> (Ast -> Ast)
 happyOut26 x = unsafeCoerce# x
 {-# INLINE happyOut26 #-}
-happyIn27 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
+happyIn27 :: (String -> Ast -> [ Ast ]) -> (HappyAbsSyn )
 happyIn27 x = unsafeCoerce# x
 {-# INLINE happyIn27 #-}
-happyOut27 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
+happyOut27 :: (HappyAbsSyn ) -> (String -> Ast -> [ Ast ])
 happyOut27 x = unsafeCoerce# x
 {-# INLINE happyOut27 #-}
+happyIn28 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
+happyIn28 x = unsafeCoerce# x
+{-# INLINE happyIn28 #-}
+happyOut28 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
+happyOut28 x = unsafeCoerce# x
+{-# INLINE happyOut28 #-}
+happyIn29 :: (String -> Ast -> Ast) -> (HappyAbsSyn )
+happyIn29 x = unsafeCoerce# x
+{-# INLINE happyIn29 #-}
+happyOut29 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)
+happyOut29 x = unsafeCoerce# x
+{-# INLINE happyOut29 #-}
 happyInTok :: Token -> (HappyAbsSyn )
 happyInTok x = unsafeCoerce# x
 {-# INLINE happyInTok #-}
@@ -173,21 +185,21 @@
 
 
 happyActOffsets :: HappyAddr
-happyActOffsets = HappyA# "\xbe\x00\xbe\x00\x00\x00\x00\x00\x74\x02\x70\x00\x00\x00\x00\x00\xeb\xff\x00\x00\xfd\xff\x00\x00\x00\x00\x69\x01\x69\x01\xfa\x00\x82\x00\xfa\x00\xfa\x00\x00\x00\x70\x01\xfa\x00\x67\x01\x67\x01\x1c\x00\x16\x00\x37\x00\x84\x01\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\x47\x01\x00\x00\x3b\x00\x4f\x01\x46\x01\xff\xff\xfd\xff\x4d\x01\xfa\x00\x7d\x01\x4b\x01\xfa\x00\x7b\x01\x0c\x01\x11\x01\xe0\xff\x0f\x01\x00\x00\xf9\x00\x00\x00\x00\x00\x74\x02\x29\x00\x00\x00\x5a\x01\xf4\xff\xef\xff\x2b\x01\x00\x00\xfa\x00\x4d\x00\x24\x00\x00\x00\x02\x01\xed\x00\xed\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\x90\x02\x90\x02\x90\x02\xc2\x02\x90\x02\xa9\x02\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x00\x00\x00\x00\x00\x00\x00\x00\x25\x01\x25\x01\xda\x02\x74\x02\x04\x01\x00\x01\x2c\x01\xee\x00\x00\x00\x19\x00\xfa\x00\x0e\x00\xfb\xff\xe2\x00\x00\x00\x00\x00\x16\x01\x37\x00\x5b\x00\x00\x00\xa2\x01\x00\x00\xd5\x00\xfa\x00\xfa\x00\xfa\x00\x00\x00\xfa\x00\xdb\x00\xfe\x00\xfa\x00\xd2\x00\xd2\x00\xfa\x00\xfa\x00\x1e\x02\x05\x01\xfa\x00\xff\x01\x03\x01\xc6\x00\x08\x00\x00\x00\xd0\x00\xf0\x00\xb2\x00\x00\x00\x04\x00\xfa\x00\x00\x00\x00\x00\xeb\x00\x5f\x00\x00\x00\xe7\x00\x5c\x00\x74\x02\xc2\x00\xb7\x00\x74\x02\x09\x00\xcc\x00\x74\x02\x7f\x01\x74\x02\x74\x02\xde\xff\x00\x00\xda\x00\x37\x00\xda\x00\xc3\x00\x50\x00\x00\x00\xfa\x00\x9f\x00\x00\x00\x00\x00\xfa\x00\xfa\x00\x74\x02\x34\x01\xaa\x00\xc0\x00\x26\x00\x00\x00\x00\x00\xca\x00\xfa\x00\x8f\x00\xfa\x00\xfa\xff\xfa\x00\x00\x00\xfa\x00\xfa\x00\x00\x00\xfa\x00\x00\x00\xfa\x00\x74\x02\x02\x00\x00\x00\xba\x00\xfa\x00\xb8\x00\x7b\x00\x0c\x00\xfe\xff\x74\x02\x74\x02\x58\x02\xfa\x00\x00\x00\x74\x02\x90\x00\x74\x02\x00\x00\x00\x00\xfa\x00\x00\x00\x00\x00\x00\x00\x34\x01\xfa\x00\x3b\x02\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x00\xe0\x01\x00\x00\xc1\x01\x00\x00\x74\x02\x00\x00\x00\x00\x00\x00"#
+happyActOffsets = HappyA# "\xce\x00\xce\x00\x00\x00\x00\x00\x47\x02\x9c\x00\x00\x00\x00\x00\x40\x00\x00\x00\x06\x00\x00\x00\xfd\xff\x00\x00\x00\x00\x7e\x01\x7e\x01\x13\x01\x89\x00\x13\x01\x13\x01\x13\x01\x00\x00\x68\x01\x13\x01\x5f\x01\x5f\x01\x1c\x00\x17\x00\x63\x00\x97\x01\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xff\x5c\x01\x00\x00\x44\x00\x64\x01\x5b\x01\xff\xff\xfd\xff\x43\x01\x13\x01\x71\x01\x41\x01\x13\x01\x6f\x01\x4c\x01\x4b\x01\xec\xff\x2a\x01\x00\x00\x3c\x01\x00\x00\x00\x00\x47\x02\x64\x00\x10\x00\x00\x00\x73\x01\x3a\x00\x38\x00\x1b\x01\x00\x00\x13\x01\x28\x00\x13\x01\x00\x00\x16\x00\x00\x00\x23\x01\x0f\x01\x0f\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x63\x02\x63\x02\x63\x02\x95\x02\x63\x02\x7c\x02\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01\x08\x01\x56\x08\x47\x02\x24\x01\x22\x01\x4e\x01\x14\x01\x00\x00\xfa\xff\x13\x01\x01\x00\xfb\xff\x12\x01\x00\x00\x00\x00\x59\x00\x3a\x01\x63\x00\x62\x00\x00\x00\xb7\x01\x00\x00\xf9\x00\x13\x01\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x00\x01\x25\x01\x13\x01\xf4\x00\xf4\x00\x13\x01\x13\x01\x2b\x02\x29\x01\x13\x01\x0e\x02\x27\x01\xef\x00\x0e\x00\x00\x00\x03\x01\x1e\x01\xe3\x00\x00\x00\x0c\x00\x13\x01\x00\x00\x00\x00\x1a\x01\x57\x00\x00\x00\x19\x01\x51\x00\x47\x02\xf0\x00\xe6\x00\x47\x02\xfc\xff\xfb\x00\x47\x02\x96\x01\x47\x02\x47\x02\xe8\xff\x00\x00\xf8\x00\x63\x00\xf8\x00\x00\x00\xf5\x00\x4f\x00\x00\x00\x13\x01\xc2\x00\x00\x00\x00\x00\x13\x01\x13\x01\x47\x02\x4d\x01\xdb\x00\xd9\x00\x49\x00\x00\x00\x00\x00\xe7\x00\x13\x01\xa1\x00\x13\x01\xfc\xff\x00\x00\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x13\x01\x47\x02\x08\x00\x00\x00\xcf\x00\x13\x01\xca\x00\x85\x00\x24\x00\x12\x00\x47\x02\x47\x02\x00\x00\x47\x02\x97\x00\x47\x02\x00\x00\x00\x00\x13\x01\x00\x00\x00\x00\x00\x00\x4d\x01\x13\x01\x00\x00\x00\x00\x00\x00\x13\x01\xf1\x01\x00\x00\xd4\x01\x47\x02\x00\x00\x00\x00\x00\x00"#
 
 happyGotoOffsets :: HappyAddr
-happyGotoOffsets = HappyA# "\xa4\x00\x0d\x01\x00\x00\x00\x00\x00\x00\x9d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x9b\x00\x79\x00\x5a\x06\x9c\x03\x4d\x06\x40\x06\x00\x00\x00\x00\x33\x06\x73\x00\x67\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x00\x00\x00\xa0\x00\x87\x03\x98\x00\x00\x00\x26\x06\x00\x00\x00\x00\x19\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x0c\x06\x12\x01\xbd\x00\x00\x00\x86\x00\x6b\x00\x5d\x00\xff\x05\xf2\x05\xe5\x05\xd8\x05\xcb\x05\xbe\x05\xb1\x05\xa4\x05\x97\x05\x8a\x05\x7d\x05\x70\x05\x63\x05\x56\x05\x49\x05\x3c\x05\x2f\x05\x22\x05\x15\x05\x08\x05\xfb\x04\xee\x04\xe1\x04\xd4\x04\xc7\x04\xba\x04\xad\x04\xa0\x04\x93\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x72\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x00\xd9\x00\x00\x00\x00\x00\x00\x00\x71\x00\x86\x04\x79\x04\x6c\x04\x00\x00\x5f\x04\x00\x00\x00\x00\x52\x04\x60\x00\x5a\x00\x45\x04\x5d\x03\x00\x00\x00\x00\x48\x03\x00\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\x00\x38\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x03\x00\x00\x00\x00\x00\x00\x1e\x03\x2b\x04\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x04\x2b\x00\x11\x04\x00\x00\x04\x04\x00\x00\xf7\x03\xea\x03\x00\x00\x11\x03\x00\x00\xfc\x02\x00\x00\x00\x00\x00\x00\x00\x00\xdd\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\x03\x00\x00\x00\x00\x00\x00\x07\x00\xb6\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+happyGotoOffsets = HappyA# "\xa7\x00\x31\x01\x00\x00\x00\x00\x00\x00\xb1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x01\x00\x00\x00\x00\xd8\x00\xd1\x00\x4a\x08\x9e\x03\x87\x03\x33\x08\x1c\x08\x00\x00\x00\x00\x05\x08\xc1\x00\x7f\x00\x00\x00\x00\x00\xf3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\xb4\x00\x70\x03\xdf\x00\x00\x00\xee\x07\x00\x00\x00\x00\xd7\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\xc0\x07\xd3\x00\x59\x03\x00\x00\x0d\x00\x00\x00\x9f\x00\x8e\x00\x71\x00\xa9\x07\x92\x07\x7b\x07\x64\x07\x4d\x07\x36\x07\x1f\x07\x08\x07\xf1\x06\xda\x06\xc3\x06\xac\x06\x95\x06\x7e\x06\x67\x06\x50\x06\x39\x06\x22\x06\x0b\x06\xf4\x05\xdd\x05\xc6\x05\xaf\x05\x98\x05\x81\x05\x6a\x05\x53\x05\x3c\x05\x25\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x42\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x9b\x00\x0e\x05\xf7\x04\xe0\x04\x00\x00\xc9\x04\x00\x00\x00\x00\x00\x00\xb2\x04\x93\x00\x77\x00\x9b\x04\x2b\x03\x00\x00\x00\x00\x14\x03\x00\x00\x00\x00\xf5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x84\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x02\x00\x00\x00\x00\x00\x00\xe6\x02\x6d\x04\x00\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x04\x20\x00\x3f\x04\x4d\x00\x00\x00\x28\x04\x11\x04\x00\x00\xcf\x02\x00\x00\xb8\x02\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\x03\x00\x00\x00\x00\x00\x00\x1f\x00\xcc\x03\x00\x00\x00\x00\x00\x00\xb5\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
 
 happyDefActions :: HappyAddr
-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8e\xff\xfa\xff\xbd\xff\xed\xff\xee\xff\x00\x00\xef\xff\x9e\xff\x93\xff\x91\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\xff\x00\x00\x8d\xff\xf4\xff\xcc\xff\xcb\xff\xcd\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xc8\xff\xce\xff\xac\xff\xcf\xff\xd0\xff\xca\xff\x00\x00\x8b\xff\x00\x00\x00\x00\x00\x00\x9c\xff\x9a\xff\x00\x00\x00\x00\x00\x00\xb1\xff\xbb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xbe\xff\xc5\xff\xc6\xff\x00\x00\x00\x00\xa7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xff\xa9\xff\x98\xff\x00\x00\x00\x00\x94\xff\x00\x00\x99\xff\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xff\x00\x00\xab\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xff\x00\x00\x89\xff\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x8a\xff\xb4\xff\x00\x00\x00\x00\xb5\xff\x00\x00\x00\x00\xc0\xff\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\xc9\xff\x00\x00\xf1\xff\xf2\xff\x00\x00\x92\xff\x96\xff\x00\x00\x97\xff\x00\x00\x00\x00\xa3\xff\x00\x00\x00\x00\xa4\xff\xa5\xff\x00\x00\x00\x00\xf3\xff\xb6\xff\xbc\xff\x00\x00\x00\x00\xaa\xff\xb2\xff\x95\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\xff\x00\x00\x00\x00\xae\xff\x00\x00\xad\xff\x00\x00\xf9\xff\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xff\xc3\xff\x00\x00\x00\x00\xa0\xff\xf0\xff\x00\x00\xc2\xff\xa6\xff\xb3\xff\x00\x00\xba\xff\xb8\xff\xb7\xff\xb6\xff\x00\x00\x00\x00\xa1\xff\xb0\xff\xaf\xff\xf5\xff\x00\x00\x00\x00\xf7\xff\x00\x00\x9f\xff\xc1\xff\xb9\xff\xf8\xff"#
+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8b\xff\xfa\xff\xbd\xff\xed\xff\xee\xff\x00\x00\xcd\xff\xa2\xff\xef\xff\x9b\xff\x90\xff\x8e\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xff\x00\x00\x8a\xff\xf4\xff\xcc\xff\xcb\xff\xa1\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xc8\xff\xce\xff\xac\xff\xcf\xff\xd0\xff\xca\xff\x00\x00\x00\x00\x88\xff\x00\x00\x00\x00\x00\x00\x99\xff\x97\xff\x00\x00\x00\x00\x00\x00\x9f\xff\x00\x00\xb1\xff\xbb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xbe\xff\xc5\xff\xc6\xff\x00\x00\x00\x00\xa7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xff\xa9\xff\x00\x00\x95\xff\x00\x00\x00\x00\x91\xff\x00\x00\x96\xff\x00\x00\x00\x00\x00\x00\x00\x00\x89\xff\x00\x00\xa0\xff\xab\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\x00\x00\x86\xff\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x87\xff\xb4\xff\x00\x00\x00\x00\xb5\xff\x00\x00\x00\x00\xc0\xff\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\xc9\xff\x00\x00\xf1\xff\xf2\xff\x00\x00\x8f\xff\x93\xff\x00\x00\x94\xff\x9e\xff\x00\x00\x00\x00\xa3\xff\x00\x00\x00\x00\xa4\xff\xa5\xff\x00\x00\x00\x00\xf3\xff\xb6\xff\xbc\xff\x00\x00\x00\x00\xaa\xff\xb2\xff\x92\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xff\x00\x00\x00\x00\xae\xff\x00\x00\xad\xff\x00\x00\xf9\xff\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xff\xc3\xff\x9c\xff\xf0\xff\x00\x00\xc2\xff\xa6\xff\xb3\xff\x00\x00\xba\xff\xb8\xff\xb7\xff\xb6\xff\x00\x00\xb0\xff\xaf\xff\xf5\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xc1\xff\xb9\xff\xf8\xff"#
 
 happyCheck :: HappyAddr
-happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x1a\x00\x0b\x00\x0d\x00\x09\x00\x0a\x00\x0c\x00\x2d\x00\x0a\x00\x2d\x00\x0a\x00\x10\x00\x11\x00\x12\x00\x0a\x00\x0c\x00\x43\x00\x03\x00\x0d\x00\x18\x00\x0c\x00\x0b\x00\x49\x00\x0e\x00\x0f\x00\x2e\x00\x40\x00\x09\x00\x40\x00\x0b\x00\x2e\x00\x38\x00\x0b\x00\x09\x00\x27\x00\x0b\x00\x39\x00\x0c\x00\x2b\x00\x2c\x00\x2e\x00\x39\x00\x03\x00\x0b\x00\x2e\x00\x18\x00\x0c\x00\x0a\x00\x35\x00\x36\x00\x2e\x00\x3c\x00\x3b\x00\x3a\x00\x2e\x00\x3c\x00\x18\x00\x02\x00\x03\x00\x04\x00\x09\x00\x42\x00\x48\x00\x44\x00\x09\x00\x46\x00\x47\x00\x48\x00\x44\x00\x12\x00\x3c\x00\x10\x00\x11\x00\x12\x00\x35\x00\x36\x00\x37\x00\x48\x00\x3c\x00\x18\x00\x2e\x00\x14\x00\x09\x00\x2e\x00\x3c\x00\x35\x00\x36\x00\x37\x00\x0c\x00\x03\x00\x45\x00\x12\x00\x03\x00\x48\x00\x27\x00\x03\x00\x09\x00\x08\x00\x2b\x00\x2c\x00\x0c\x00\x45\x00\x03\x00\x0c\x00\x48\x00\x12\x00\x03\x00\x08\x00\x35\x00\x36\x00\x07\x00\x3c\x00\x03\x00\x3a\x00\x03\x00\x3c\x00\x3d\x00\x42\x00\x07\x00\x44\x00\x03\x00\x42\x00\x2e\x00\x44\x00\x07\x00\x46\x00\x47\x00\x48\x00\x02\x00\x03\x00\x04\x00\x3a\x00\x3b\x00\x3c\x00\x2e\x00\x09\x00\x0a\x00\x2e\x00\x41\x00\x42\x00\x0a\x00\x44\x00\x10\x00\x11\x00\x12\x00\x3a\x00\x11\x00\x3c\x00\x02\x00\x03\x00\x18\x00\x2b\x00\x2c\x00\x42\x00\x03\x00\x44\x00\x30\x00\x14\x00\x07\x00\x03\x00\x00\x00\x01\x00\x09\x00\x03\x00\x04\x00\x27\x00\x06\x00\x13\x00\x14\x00\x2b\x00\x2c\x00\x13\x00\x14\x00\x0d\x00\x0e\x00\x0f\x00\x3e\x00\x3f\x00\x12\x00\x35\x00\x36\x00\x15\x00\x16\x00\x17\x00\x3a\x00\x2d\x00\x3c\x00\x44\x00\x02\x00\x03\x00\x04\x00\x0b\x00\x42\x00\x0b\x00\x44\x00\x09\x00\x46\x00\x47\x00\x48\x00\x0e\x00\x0f\x00\x10\x00\x10\x00\x11\x00\x12\x00\x07\x00\x01\x00\x44\x00\x03\x00\x04\x00\x18\x00\x06\x00\x2e\x00\x03\x00\x1a\x00\x3c\x00\x03\x00\x1a\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x16\x00\x12\x00\x2d\x00\x27\x00\x15\x00\x16\x00\x17\x00\x2b\x00\x2c\x00\x15\x00\x16\x00\x17\x00\x15\x00\x16\x00\x17\x00\x2f\x00\x0b\x00\x35\x00\x36\x00\x03\x00\x0b\x00\x45\x00\x3a\x00\x09\x00\x3c\x00\x3d\x00\x02\x00\x03\x00\x04\x00\x2f\x00\x42\x00\x3b\x00\x44\x00\x09\x00\x46\x00\x47\x00\x48\x00\x15\x00\x16\x00\x17\x00\x10\x00\x11\x00\x12\x00\x0a\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x18\x00\x06\x00\x16\x00\x03\x00\x44\x00\x3c\x00\x03\x00\x44\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x3c\x00\x12\x00\x32\x00\x27\x00\x15\x00\x16\x00\x17\x00\x2b\x00\x2c\x00\x15\x00\x16\x00\x17\x00\x15\x00\x16\x00\x17\x00\x01\x00\x2e\x00\x35\x00\x36\x00\x44\x00\x2e\x00\x31\x00\x3a\x00\x3c\x00\x3c\x00\x12\x00\x13\x00\x14\x00\x15\x00\x2f\x00\x42\x00\x2e\x00\x44\x00\x2e\x00\x46\x00\x47\x00\x48\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x05\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x3b\x00\x33\x00\x34\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x06\x00\x0b\x00\x3c\x00\x0b\x00\x3c\x00\x44\x00\x3c\x00\x45\x00\x09\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x08\x00\x44\x00\x3c\x00\x44\x00\xff\xff\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\xff\xff\x27\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\xff\xff\xff\xff\x27\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\x0b\x00\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
+happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x0b\x00\x0b\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x16\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x16\x00\x0b\x00\x0a\x00\x2b\x00\x03\x00\x16\x00\x0a\x00\x2b\x00\x0a\x00\x41\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x47\x00\x09\x00\x0b\x00\x0b\x00\x03\x00\x25\x00\x09\x00\x3e\x00\x0b\x00\x29\x00\x2a\x00\x3e\x00\x0c\x00\x16\x00\x33\x00\x34\x00\x35\x00\x0c\x00\x09\x00\x33\x00\x34\x00\x2c\x00\x3a\x00\x39\x00\x38\x00\x10\x00\x3a\x00\x2c\x00\x3a\x00\x2c\x00\x43\x00\x2c\x00\x40\x00\x46\x00\x42\x00\x46\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x35\x00\x46\x00\x09\x00\x42\x00\x0b\x00\x2c\x00\x3a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x3a\x00\x0c\x00\x18\x00\x43\x00\x16\x00\x0c\x00\x46\x00\x0c\x00\x11\x00\x12\x00\x38\x00\x39\x00\x3a\x00\x0c\x00\x2c\x00\x0c\x00\x2c\x00\x3f\x00\x40\x00\x25\x00\x42\x00\x09\x00\x09\x00\x29\x00\x2a\x00\x37\x00\x0c\x00\x37\x00\x10\x00\x10\x00\x03\x00\x2c\x00\x36\x00\x33\x00\x34\x00\x08\x00\x03\x00\x2c\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x11\x00\x12\x00\x03\x00\x2c\x00\x40\x00\x2c\x00\x42\x00\x08\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x02\x00\x03\x00\x2c\x00\x03\x00\x09\x00\x0a\x00\x0b\x00\x07\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x38\x00\x03\x00\x3a\x00\x3a\x00\x03\x00\x16\x00\x0e\x00\x0f\x00\x40\x00\x40\x00\x42\x00\x42\x00\x16\x00\x00\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x13\x00\x06\x00\x25\x00\x17\x00\x18\x00\x19\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x03\x00\x11\x00\x12\x00\x09\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2b\x00\x3a\x00\x03\x00\x29\x00\x2a\x00\x42\x00\x07\x00\x40\x00\x2e\x00\x42\x00\x03\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x03\x00\x03\x00\x0b\x00\x03\x00\x09\x00\x07\x00\x0b\x00\x0b\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x07\x00\x17\x00\x18\x00\x19\x00\x42\x00\x16\x00\x3c\x00\x3d\x00\x17\x00\x18\x00\x19\x00\x17\x00\x18\x00\x19\x00\x01\x00\x07\x00\x03\x00\x04\x00\x18\x00\x06\x00\x25\x00\x15\x00\x16\x00\x03\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x3a\x00\x11\x00\x12\x00\x07\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x17\x00\x18\x00\x19\x00\x18\x00\x40\x00\x14\x00\x42\x00\x2b\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x10\x00\x11\x00\x12\x00\x13\x00\x09\x00\x2d\x00\x0b\x00\x15\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x0b\x00\x43\x00\x09\x00\x39\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x2d\x00\x0a\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x42\x00\x06\x00\x25\x00\x14\x00\x3a\x00\x42\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x11\x00\x12\x00\x30\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x3a\x00\x3a\x00\x2c\x00\x01\x00\x2c\x00\x42\x00\x2f\x00\x40\x00\x39\x00\x42\x00\x2c\x00\x44\x00\x45\x00\x46\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x3a\x00\x2c\x00\x05\x00\x2d\x00\x0b\x00\x3a\x00\x0b\x00\x3a\x00\x31\x00\x32\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x06\x00\x42\x00\x3a\x00\x43\x00\x09\x00\x42\x00\x3a\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x08\x00\x42\x00\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\x25\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
 
 happyTable :: HappyAddr
-happyTable = HappyA# "\x00\x00\x0e\x00\x0f\x00\x10\x00\x41\x00\x43\x00\x2c\x00\xee\x00\x11\x00\xa8\x00\xfd\x00\xd6\x00\xe7\x00\x9c\x00\xe5\x00\x12\x00\x13\x00\x14\x00\xaf\x00\x05\x01\x26\x00\xfe\x00\xda\x00\x15\x00\xfe\x00\x2f\x00\xff\xff\xc6\x00\x08\x00\x94\x00\xd7\x00\x2b\x00\x9d\x00\x2c\x00\x94\x00\x44\x00\xc8\x00\x2e\x00\x16\x00\x2f\x00\x95\x00\xf5\x00\x17\x00\x18\x00\x99\x00\x96\x00\xf0\x00\x88\x00\xe8\x00\x15\x00\xf3\x00\x98\x00\x19\x00\x1a\x00\x99\x00\x2d\x00\x42\x00\x1b\x00\x99\x00\x1c\x00\x15\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1e\x00\xef\x00\x1f\x00\x11\x00\x20\x00\x21\x00\x22\x00\x1f\x00\x14\x00\x30\x00\x12\x00\x13\x00\x14\x00\x89\x00\x8a\x00\xc9\x00\xdb\x00\x2d\x00\x15\x00\x99\x00\x92\x00\x11\x00\x99\x00\x30\x00\x89\x00\x8a\x00\x8b\x00\xd3\x00\xb6\x00\xca\x00\x14\x00\x30\x00\xcb\x00\x16\x00\xb7\x00\x11\x00\x81\x00\x17\x00\x18\x00\xde\x00\x8c\x00\x30\x00\xe0\x00\x8d\x00\x14\x00\x32\x00\x31\x00\x19\x00\x1a\x00\x82\x00\x1c\x00\xbf\x00\x1b\x00\x32\x00\x1c\x00\x1d\x00\x1e\x00\x33\x00\x1f\x00\x32\x00\x1e\x00\x99\x00\x1f\x00\x3c\x00\x20\x00\x21\x00\x22\x00\x0e\x00\x0f\x00\x10\x00\x8f\x00\x90\x00\x1c\x00\x99\x00\x11\x00\x3b\x00\x99\x00\x91\x00\x1e\x00\x83\x00\x1f\x00\x12\x00\x13\x00\x14\x00\xc3\x00\x99\x00\x1c\x00\xe2\x00\xe3\x00\x15\x00\x46\x00\x47\x00\x1e\x00\x32\x00\x1f\x00\x48\x00\x92\x00\x3d\x00\xa8\x00\x22\x00\x23\x00\x44\x00\x03\x00\x04\x00\x16\x00\x05\x00\xa5\x00\x3f\x00\x17\x00\x18\x00\x3e\x00\x3f\x00\x06\x00\x07\x00\x08\x00\x27\x00\x28\x00\x09\x00\x19\x00\x1a\x00\x0a\x00\x0b\x00\x0c\x00\x1b\x00\xfa\x00\x1c\x00\x1f\x00\x0e\x00\x0f\x00\x10\x00\x00\x01\x1e\x00\xe6\x00\x1f\x00\x11\x00\x20\x00\x21\x00\x22\x00\x85\x00\x08\x00\x86\x00\x12\x00\x13\x00\x14\x00\x41\x00\xaa\x00\x1f\x00\x03\x00\x04\x00\x15\x00\x05\x00\xf5\x00\x03\x00\xf4\x00\xd1\x00\x03\x00\xd4\x00\x06\x00\x07\x00\x08\x00\x41\x00\xd9\x00\x09\x00\xdc\x00\x16\x00\x0a\x00\x0b\x00\x0c\x00\x17\x00\x18\x00\xd4\x00\x0b\x00\x0c\x00\xc1\x00\x0b\x00\x0c\x00\xdd\x00\xdf\x00\x19\x00\x1a\x00\x03\x00\xe1\x00\xac\x00\x1b\x00\xad\x00\x1c\x00\x1d\x00\x0e\x00\x0f\x00\x10\x00\xae\x00\x1e\x00\x42\x00\x1f\x00\x11\x00\x20\x00\x21\x00\x22\x00\xc3\x00\x0b\x00\x0c\x00\x12\x00\x13\x00\x14\x00\xb0\x00\x02\x00\xb3\x00\x03\x00\x04\x00\x15\x00\x05\x00\xba\x00\x03\x00\x1f\x00\xbb\x00\x03\x00\x1f\x00\x06\x00\x07\x00\x08\x00\x41\x00\xc5\x00\x09\x00\xcc\x00\x16\x00\x0a\x00\x0b\x00\x0c\x00\x17\x00\x18\x00\x8d\x00\x0b\x00\x0c\x00\x29\x00\x0b\x00\x0c\x00\xcd\x00\x94\x00\x19\x00\x1a\x00\x1f\x00\x9e\x00\x85\x00\x1b\x00\x9b\x00\x1c\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x9f\x00\x1e\x00\x94\x00\x1f\x00\x9e\x00\x20\x00\x21\x00\x22\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x97\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x42\x00\xf7\x00\xf8\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xd8\x00\xa0\x00\xa2\x00\xa3\x00\xa5\x00\x1f\x00\xaa\x00\x25\x00\x29\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xc1\x00\x1f\x00\x36\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x07\x01\x00\x00\x00\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x02\x01\x00\x00\x00\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xb1\x00\x00\x00\x00\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xb4\x00\x00\x00\x00\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x04\x01\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xfc\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x00\x00\x61\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x03\x00\x38\x00\xe8\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xe9\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xce\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\xcf\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xd1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xb1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xb4\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xc5\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xa6\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\x39\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x02\x01\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x04\x01\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xf8\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xfa\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x00\x01\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xea\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xeb\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xec\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xef\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xf1\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xcd\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xe1\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xb5\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xb8\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbb\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbc\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbd\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbe\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x64\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x65\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x66\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x67\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x68\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x69\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6a\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6b\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6c\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6d\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6e\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6f\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x70\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x71\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x72\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x73\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x74\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x75\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x76\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x77\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x78\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x79\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7a\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7b\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7c\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7d\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7e\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7f\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x80\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x91\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xa0\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xa3\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x34\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x36\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x37\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x3b\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x45\x00\xd1\x00\x2f\x00\x14\x00\x13\x00\xb0\x00\x14\x00\x99\x00\x32\x00\x15\x00\x16\x00\x17\x00\x18\x00\x47\x00\xef\x00\xdf\x00\x02\x01\x18\x00\xed\x00\xa4\x00\xb7\x00\x29\x00\x9f\x00\x8b\x00\x08\x00\x8c\x00\x01\x01\xff\xff\x2e\x00\x8e\x00\x2f\x00\xf6\x00\x19\x00\x31\x00\xe0\x00\x32\x00\x1a\x00\x1b\x00\xa5\x00\x08\x01\x18\x00\x8f\x00\x90\x00\xd2\x00\x02\x01\x13\x00\x1c\x00\x1d\x00\xf0\x00\x30\x00\x46\x00\x1e\x00\x17\x00\x1f\x00\xa0\x00\x33\x00\xa0\x00\xd3\x00\xa0\x00\x21\x00\xd4\x00\x22\x00\x25\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x8f\x00\x90\x00\x91\x00\x48\x00\x13\x00\x22\x00\x14\x00\xa0\x00\x30\x00\x15\x00\x16\x00\x17\x00\xf9\x00\x33\x00\xfb\x00\x49\x00\x92\x00\x18\x00\xdc\x00\x93\x00\xe6\x00\xf4\x00\x0a\x00\x96\x00\x97\x00\x1f\x00\xe8\x00\x9b\x00\xcd\x00\x9b\x00\x98\x00\x21\x00\x19\x00\x22\x00\x13\x00\x13\x00\x1a\x00\x1b\x00\x9c\x00\xa1\x00\x9d\x00\x17\x00\x17\x00\x33\x00\xa0\x00\x4a\x00\x1c\x00\x1d\x00\x87\x00\xbe\x00\xa0\x00\x1e\x00\xa0\x00\x1f\x00\x20\x00\xe2\x00\x0a\x00\x33\x00\xa0\x00\x21\x00\xa0\x00\x22\x00\x34\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\xea\x00\xeb\x00\xa0\x00\x35\x00\x13\x00\x3f\x00\x14\x00\x88\x00\xbf\x00\x15\x00\x16\x00\x17\x00\xcb\x00\x03\x00\x1f\x00\x1f\x00\xc7\x00\x18\x00\xcf\x00\x08\x00\x21\x00\x21\x00\x22\x00\x22\x00\x99\x00\x25\x00\x26\x00\x89\x00\x03\x00\x04\x00\xa1\x00\x05\x00\x19\x00\xdd\x00\x0d\x00\x0e\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xb0\x00\x09\x00\x0a\x00\x4a\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\x00\x01\x1f\x00\x35\x00\x4c\x00\x4d\x00\x22\x00\x36\x00\x21\x00\x4e\x00\x22\x00\x03\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x03\x00\x35\x00\x04\x01\x03\x00\x13\x00\x40\x00\x14\x00\xee\x00\x35\x00\x15\x00\x16\x00\x17\x00\x41\x00\xc9\x00\x0d\x00\x0e\x00\x22\x00\x18\x00\x2a\x00\x2b\x00\xcb\x00\x0d\x00\x0e\x00\x94\x00\x0d\x00\x0e\x00\xb2\x00\x45\x00\x03\x00\x04\x00\xfa\x00\x05\x00\x19\x00\xad\x00\x43\x00\x03\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xda\x00\x09\x00\x0a\x00\x45\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xfb\x00\x1f\x00\x20\x00\x2c\x00\x0d\x00\x0e\x00\xdd\x00\x21\x00\xe2\x00\x22\x00\xe4\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x52\x00\x53\x00\x54\x00\x55\x00\x13\x00\xe5\x00\x14\x00\x42\x00\x43\x00\x15\x00\x16\x00\x17\x00\xe7\x00\xe9\x00\xb4\x00\xb5\x00\x46\x00\x18\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xb6\x00\xb8\x00\x02\x00\xbb\x00\x03\x00\x04\x00\x22\x00\x05\x00\x19\x00\xc2\x00\xc3\x00\x22\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\x45\x00\x09\x00\x0a\x00\xd5\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xce\x00\x1f\x00\x9b\x00\xd6\x00\xa6\x00\x22\x00\x8b\x00\x21\x00\x46\x00\x22\x00\x9b\x00\x23\x00\x24\x00\x25\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xa3\x00\xa6\x00\x9e\x00\xa7\x00\xa8\x00\xaa\x00\xab\x00\xad\x00\xfd\x00\xfe\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xe1\x00\x22\x00\xb2\x00\x28\x00\x2c\x00\x22\x00\x39\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xc9\x00\x22\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x0a\x01\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x06\x01\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xb9\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\xbc\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x00\x00\x67\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x00\x00\x00\x00\x00\x00\x03\x00\x3b\x00\xf0\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xf1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xda\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xb9\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xbc\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xce\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x93\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xae\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3c\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3d\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x06\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x07\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xfe\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x04\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf2\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xe9\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xbd\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc0\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc4\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x70\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x71\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x72\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x73\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x74\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x75\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x76\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x77\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x78\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x79\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x80\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x81\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x82\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x83\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x84\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x85\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x86\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x98\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xab\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x37\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x39\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
 
-happyReduceArr = array (1, 118) [
+happyReduceArr = array (1, 121) [
 	(1 , happyReduce_1),
 	(2 , happyReduce_2),
 	(3 , happyReduce_3),
@@ -305,11 +317,14 @@
 	(115 , happyReduce_115),
 	(116 , happyReduce_116),
 	(117 , happyReduce_117),
-	(118 , happyReduce_118)
+	(118 , happyReduce_118),
+	(119 , happyReduce_119),
+	(120 , happyReduce_120),
+	(121 , happyReduce_121)
 	]
 
-happy_n_terms = 74 :: Int
-happy_n_nonterms = 24 :: Int
+happy_n_terms = 72 :: Int
+happy_n_nonterms = 26 :: Int
 
 happyReduce_1 = happySpecReduce_1  0# happyReduction_1
 happyReduction_1 happy_x_1
@@ -482,7 +497,7 @@
 
 happyReduce_16 = happySpecReduce_1  4# happyReduction_16
 happyReduction_16 happy_x_1
-	 =  case happyOut22 happy_x_1 of { happy_var_1 -> 
+	 =  case happyOut24 happy_x_1 of { happy_var_1 -> 
 	happyIn8
 		 (happy_var_1
 	)}
@@ -807,9 +822,9 @@
 
 happyReduce_50 = happySpecReduce_1  4# happyReduction_50
 happyReduction_50 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) -> 
+	 =  case happyOut21 happy_x_1 of { happy_var_1 -> 
 	happyIn8
-		 (Astring happy_var_1
+		 (happy_var_1
 	)}
 
 happyReduce_51 = happySpecReduce_1  4# happyReduction_51
@@ -1060,8 +1075,9 @@
 	case happyOutTok happy_x_5 of { (QName happy_var_5) -> 
 	happyIn18
 		 (if head happy_var_1 == Astring happy_var_5
-						  	     then Ast "construction" (happy_var_1++[concatAll happy_var_3])
-                                                          else error("Unmatched tags in element construction: "++(show (head happy_var_1))++" '"++happy_var_5++"'")
+						  	     then Ast "element_construction" (happy_var_1++[Ast "append" happy_var_3])
+                                                          else parseError [TError ("Unmatched tags in element construction: "
+                                                                                   ++(show (head happy_var_1))++" '"++happy_var_5++"'")]
 	) `HappyStk` happyRest}}}
 
 happyReduce_77 = happyReduce 5# 14# happyReduction_77
@@ -1075,8 +1091,9 @@
 	case happyOutTok happy_x_4 of { (QName happy_var_4) -> 
 	happyIn18
 		 (if head happy_var_1 == Astring happy_var_4
-							     then Ast "construction" (happy_var_1++[call "empty" []])
-                                                          else error("Unmatched tags in element construction: "++(show (head happy_var_1))++" '"++happy_var_4++"'")
+							     then Ast "element_construction" (happy_var_1++[Ast "append" []])
+                                                          else parseError [TError ("Unmatched tags in element construction: "
+                                                                                   ++(show (head happy_var_1))++" '"++happy_var_4++"'")]
 	) `HappyStk` happyRest}}
 
 happyReduce_78 = happySpecReduce_2  14# happyReduction_78
@@ -1084,7 +1101,7 @@
 	happy_x_1
 	 =  case happyOut19 happy_x_1 of { happy_var_1 -> 
 	happyIn18
-		 (Ast "construction" (happy_var_1++[call "empty" []])
+		 (Ast "element_construction" (happy_var_1++[Ast "append" []])
 	)}
 
 happyReduce_79 = happyReduce 7# 14# happyReduction_79
@@ -1099,7 +1116,7 @@
 	 = case happyOut8 happy_x_3 of { happy_var_3 -> 
 	case happyOut9 happy_x_6 of { happy_var_6 -> 
 	happyIn18
-		 (Ast "element_construction" [happy_var_3,concatenateAll happy_var_6]
+		 (Ast "element_construction" [happy_var_3,Ast "attributes" [],concatenateAll happy_var_6]
 	) `HappyStk` happyRest}}
 
 happyReduce_80 = happyReduce 7# 14# happyReduction_80
@@ -1127,7 +1144,7 @@
 	 = case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
 	case happyOut9 happy_x_4 of { happy_var_4 -> 
 	happyIn18
-		 (Ast "element_construction" [Astring happy_var_2,concatenateAll happy_var_4]
+		 (Ast "element_construction" [Astring happy_var_2,Ast "attributes" [],concatenateAll happy_var_4]
 	) `HappyStk` happyRest}}
 
 happyReduce_82 = happyReduce 5# 14# happyReduction_82
@@ -1156,7 +1173,7 @@
 	happy_x_2
 	happy_x_1
 	 =  case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	case happyOut21 happy_x_3 of { happy_var_3 -> 
+	case happyOut23 happy_x_3 of { happy_var_3 -> 
 	happyIn19
 		 ([Astring happy_var_2,Ast "attributes" happy_var_3]
 	)}}
@@ -1230,248 +1247,262 @@
 		 (happy_var_1++[happy_var_2]
 	)}}
 
-happyReduce_93 = happySpecReduce_3  17# happyReduction_93
-happyReduction_93 happy_x_3
+happyReduce_93 = happySpecReduce_1  17# happyReduction_93
+happyReduction_93 happy_x_1
+	 =  case happyOut22 happy_x_1 of { happy_var_1 -> 
+	happyIn21
+		 (if length happy_var_1 == 1 then head happy_var_1 else Ast "append" happy_var_1
+	)}
+
+happyReduce_94 = happySpecReduce_1  18# happyReduction_94
+happyReduction_94 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TString happy_var_1) -> 
+	happyIn22
+		 (if happy_var_1=="" then [] else [Astring happy_var_1]
+	)}
+
+happyReduce_95 = happySpecReduce_3  18# happyReduction_95
+happyReduction_95 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	case happyOutTok happy_x_3 of { (TString happy_var_3) -> 
-	happyIn21
-		 ([Ast "pair" [Astring happy_var_1,Astring happy_var_3]]
+	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
+	happyIn22
+		 ([concatenateAll happy_var_2]
+	)}
+
+happyReduce_96 = happySpecReduce_2  18# happyReduction_96
+happyReduction_96 happy_x_2
+	happy_x_1
+	 =  case happyOut22 happy_x_1 of { happy_var_1 -> 
+	case happyOutTok happy_x_2 of { (TString happy_var_2) -> 
+	happyIn22
+		 (if happy_var_2=="" then happy_var_1 else happy_var_1++[Astring happy_var_2]
 	)}}
 
-happyReduce_94 = happyReduce 5# 17# happyReduction_94
-happyReduction_94 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
+happyReduce_97 = happyReduce 4# 18# happyReduction_97
+happyReduction_97 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	case happyOut8 happy_x_4 of { happy_var_4 -> 
-	happyIn21
-		 ([Ast "pair" [Astring happy_var_1,happy_var_4]]
+	 = case happyOut22 happy_x_1 of { happy_var_1 -> 
+	case happyOut9 happy_x_3 of { happy_var_3 -> 
+	happyIn22
+		 (happy_var_1++[concatenateAll happy_var_3]
 	) `HappyStk` happyRest}}
 
-happyReduce_95 = happyReduce 4# 17# happyReduction_95
-happyReduction_95 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut21 happy_x_1 of { happy_var_1 -> 
-	case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	case happyOutTok happy_x_4 of { (TString happy_var_4) -> 
-	happyIn21
-		 (happy_var_1++[Ast "pair" [Astring happy_var_2,Astring happy_var_4]]
-	) `HappyStk` happyRest}}}
+happyReduce_98 = happySpecReduce_3  19# happyReduction_98
+happyReduction_98 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
+	case happyOut21 happy_x_3 of { happy_var_3 -> 
+	happyIn23
+		 ([Ast "pair" [Astring happy_var_1,happy_var_3]]
+	)}}
 
-happyReduce_96 = happyReduce 6# 17# happyReduction_96
-happyReduction_96 (happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
+happyReduce_99 = happyReduce 4# 19# happyReduction_99
+happyReduction_99 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut21 happy_x_1 of { happy_var_1 -> 
+	 = case happyOut23 happy_x_1 of { happy_var_1 -> 
 	case happyOutTok happy_x_2 of { (QName happy_var_2) -> 
-	case happyOut8 happy_x_5 of { happy_var_5 -> 
-	happyIn21
-		 (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_5]]
+	case happyOut21 happy_x_4 of { happy_var_4 -> 
+	happyIn23
+		 (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_4]]
 	) `HappyStk` happyRest}}}
 
-happyReduce_97 = happySpecReduce_1  18# happyReduction_97
-happyReduction_97 happy_x_1
-	 =  case happyOut25 happy_x_1 of { happy_var_1 -> 
-	happyIn22
+happyReduce_100 = happySpecReduce_1  20# happyReduction_100
+happyReduction_100 happy_x_1
+	 =  case happyOut27 happy_x_1 of { happy_var_1 -> 
+	happyIn24
 		 (Ast "step" (happy_var_1 "child_step" (Avar "."))
 	)}
 
-happyReduce_98 = happySpecReduce_2  18# happyReduction_98
-happyReduction_98 happy_x_2
+happyReduce_101 = happySpecReduce_2  20# happyReduction_101
+happyReduction_101 happy_x_2
 	happy_x_1
-	 =  case happyOut25 happy_x_2 of { happy_var_2 -> 
-	happyIn22
+	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
+	happyIn24
 		 (Ast "step" (happy_var_2 "attribute_step" (Avar "."))
 	)}
 
-happyReduce_99 = happySpecReduce_2  18# happyReduction_99
-happyReduction_99 happy_x_2
+happyReduce_102 = happySpecReduce_2  20# happyReduction_102
+happyReduction_102 happy_x_2
 	happy_x_1
-	 =  case happyOut25 happy_x_1 of { happy_var_1 -> 
-	case happyOut23 happy_x_2 of { happy_var_2 -> 
-	happyIn22
+	 =  case happyOut27 happy_x_1 of { happy_var_1 -> 
+	case happyOut25 happy_x_2 of { happy_var_2 -> 
+	happyIn24
 		 (Ast "step" [happy_var_2 (Ast "step" (happy_var_1 "child_step" (Avar ".")))]
 	)}}
 
-happyReduce_100 = happySpecReduce_3  18# happyReduction_100
-happyReduction_100 happy_x_3
+happyReduce_103 = happySpecReduce_3  20# happyReduction_103
+happyReduction_103 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut25 happy_x_2 of { happy_var_2 -> 
-	case happyOut23 happy_x_3 of { happy_var_3 -> 
-	happyIn22
+	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
+	case happyOut25 happy_x_3 of { happy_var_3 -> 
+	happyIn24
 		 (Ast "step" (map happy_var_3 (happy_var_2 "attribute_step" (Avar ".")))
 	)}}
 
-happyReduce_101 = happySpecReduce_1  19# happyReduction_101
-happyReduction_101 happy_x_1
-	 =  case happyOut24 happy_x_1 of { happy_var_1 -> 
-	happyIn23
+happyReduce_104 = happySpecReduce_1  21# happyReduction_104
+happyReduction_104 happy_x_1
+	 =  case happyOut26 happy_x_1 of { happy_var_1 -> 
+	happyIn25
 		 (happy_var_1
 	)}
 
-happyReduce_102 = happySpecReduce_2  19# happyReduction_102
-happyReduction_102 happy_x_2
+happyReduce_105 = happySpecReduce_2  21# happyReduction_105
+happyReduction_105 happy_x_2
 	happy_x_1
-	 =  case happyOut23 happy_x_1 of { happy_var_1 -> 
-	case happyOut24 happy_x_2 of { happy_var_2 -> 
-	happyIn23
+	 =  case happyOut25 happy_x_1 of { happy_var_1 -> 
+	case happyOut26 happy_x_2 of { happy_var_2 -> 
+	happyIn25
 		 (happy_var_2 . happy_var_1
 	)}}
 
-happyReduce_103 = happySpecReduce_2  20# happyReduction_103
-happyReduction_103 happy_x_2
+happyReduce_106 = happySpecReduce_2  22# happyReduction_106
+happyReduction_106 happy_x_2
 	happy_x_1
-	 =  case happyOut25 happy_x_2 of { happy_var_2 -> 
-	happyIn24
+	 =  case happyOut27 happy_x_2 of { happy_var_2 -> 
+	happyIn26
 		 (\e -> Ast "step" (happy_var_2 "child_step" e)
 	)}
 
-happyReduce_104 = happySpecReduce_3  20# happyReduction_104
-happyReduction_104 happy_x_3
+happyReduce_107 = happySpecReduce_3  22# happyReduction_107
+happyReduction_107 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut25 happy_x_3 of { happy_var_3 -> 
-	happyIn24
+	 =  case happyOut27 happy_x_3 of { happy_var_3 -> 
+	happyIn26
 		 (\e -> Ast "step" (happy_var_3 "attribute_step" e)
 	)}
 
-happyReduce_105 = happySpecReduce_3  20# happyReduction_105
-happyReduction_105 happy_x_3
+happyReduce_108 = happySpecReduce_3  22# happyReduction_108
+happyReduction_108 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut25 happy_x_3 of { happy_var_3 -> 
-	happyIn24
+	 =  case happyOut27 happy_x_3 of { happy_var_3 -> 
+	happyIn26
 		 (\e -> Ast "step" (happy_var_3 "descendant_step" e)
 	)}
 
-happyReduce_106 = happyReduce 4# 20# happyReduction_106
-happyReduction_106 (happy_x_4 `HappyStk`
+happyReduce_109 = happyReduce 4# 22# happyReduction_109
+happyReduction_109 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut25 happy_x_4 of { happy_var_4 -> 
-	happyIn24
+	 = case happyOut27 happy_x_4 of { happy_var_4 -> 
+	happyIn26
 		 (\e -> Ast "step" (happy_var_4 "attribute_descendant_step" e)
 	) `HappyStk` happyRest}
 
-happyReduce_107 = happySpecReduce_2  20# happyReduction_107
-happyReduction_107 happy_x_2
+happyReduce_110 = happySpecReduce_2  22# happyReduction_110
+happyReduction_110 happy_x_2
 	happy_x_1
-	 =  happyIn24
+	 =  happyIn26
 		 (\e -> Ast "step" [Ast "parent_step" [e]]
 	)
 
-happyReduce_108 = happySpecReduce_1  21# happyReduction_108
-happyReduction_108 happy_x_1
-	 =  case happyOut26 happy_x_1 of { happy_var_1 -> 
-	happyIn25
+happyReduce_111 = happySpecReduce_1  23# happyReduction_111
+happyReduction_111 happy_x_1
+	 =  case happyOut28 happy_x_1 of { happy_var_1 -> 
+	happyIn27
 		 (\t e -> [happy_var_1 t e]
 	)}
 
-happyReduce_109 = happyReduce 4# 21# happyReduction_109
-happyReduction_109 (happy_x_4 `HappyStk`
+happyReduce_112 = happyReduce 4# 23# happyReduction_112
+happyReduction_112 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut25 happy_x_1 of { happy_var_1 -> 
+	 = case happyOut27 happy_x_1 of { happy_var_1 -> 
 	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn25
+	happyIn27
 		 (\t e -> (happy_var_1 t e)++[happy_var_3]
 	) `HappyStk` happyRest}}
 
-happyReduce_110 = happySpecReduce_1  22# happyReduction_110
-happyReduction_110 happy_x_1
-	 =  case happyOut27 happy_x_1 of { happy_var_1 -> 
-	happyIn26
+happyReduce_113 = happySpecReduce_1  24# happyReduction_113
+happyReduction_113 happy_x_1
+	 =  case happyOut29 happy_x_1 of { happy_var_1 -> 
+	happyIn28
 		 (\t e -> happy_var_1 t e
 	)}
 
-happyReduce_111 = happySpecReduce_1  22# happyReduction_111
-happyReduction_111 happy_x_1
-	 =  happyIn26
+happyReduce_114 = happySpecReduce_1  24# happyReduction_114
+happyReduction_114 happy_x_1
+	 =  happyIn28
 		 (\t e -> Ast t [Astring "*",e]
 	)
 
-happyReduce_112 = happySpecReduce_1  22# happyReduction_112
-happyReduction_112 happy_x_1
+happyReduce_115 = happySpecReduce_1  24# happyReduction_115
+happyReduction_115 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	happyIn26
+	happyIn28
 		 (\t e -> Ast t [Astring happy_var_1,e]
 	)}
 
-happyReduce_113 = happySpecReduce_1  23# happyReduction_113
-happyReduction_113 happy_x_1
+happyReduce_116 = happySpecReduce_1  25# happyReduction_116
+happyReduction_116 happy_x_1
 	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
-	happyIn27
+	happyIn29
 		 (\_ _ -> happy_var_1
 	)}
 
-happyReduce_114 = happySpecReduce_1  23# happyReduction_114
-happyReduction_114 happy_x_1
-	 =  happyIn27
+happyReduce_117 = happySpecReduce_1  25# happyReduction_117
+happyReduction_117 happy_x_1
+	 =  happyIn29
 		 (\_ e -> e
 	)
 
-happyReduce_115 = happySpecReduce_3  23# happyReduction_115
-happyReduction_115 happy_x_3
+happyReduce_118 = happySpecReduce_3  25# happyReduction_118
+happyReduction_118 happy_x_3
 	happy_x_2
 	happy_x_1
 	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
-	happyIn27
+	happyIn29
 		 (\t e -> if e == Avar "."
                                                                      then concatenateAll happy_var_2
 	                                                          else Ast "context" [e,Astring t,concatenateAll happy_var_2]
 	)}
 
-happyReduce_116 = happySpecReduce_2  23# happyReduction_116
-happyReduction_116 happy_x_2
+happyReduce_119 = happySpecReduce_2  25# happyReduction_119
+happyReduction_119 happy_x_2
 	happy_x_1
-	 =  happyIn27
+	 =  happyIn29
 		 (\_ _ -> call "empty" []
 	)
 
-happyReduce_117 = happyReduce 4# 23# happyReduction_117
-happyReduction_117 (happy_x_4 `HappyStk`
+happyReduce_120 = happyReduce 4# 25# happyReduction_120
+happyReduction_120 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
 	 = case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
 	case happyOut9 happy_x_3 of { happy_var_3 -> 
-	happyIn27
-		 (\_ e -> if e == Avar "."
+	happyIn29
+		 (\t e -> if e == Avar "."
                                                                      then call happy_var_1 happy_var_3
-                                                                  else Ast "context" [e,call happy_var_1 happy_var_3]
+                                                                  else Ast "context" [e,Astring t,call happy_var_1 happy_var_3]
 	) `HappyStk` happyRest}}
 
-happyReduce_118 = happySpecReduce_3  23# happyReduction_118
-happyReduction_118 happy_x_3
+happyReduce_121 = happySpecReduce_3  25# happyReduction_121
+happyReduction_121 happy_x_3
 	happy_x_2
 	happy_x_1
 	 =  case happyOutTok happy_x_1 of { (QName happy_var_1) -> 
-	happyIn27
-		 (if elem happy_var_1 ["text"]
-                                                             then \_ e -> call happy_var_1 [e]
-                                                          else \_ _ -> call happy_var_1 []
+	happyIn29
+		 (\_ e -> call happy_var_1 (if e == Avar "." then [] else [e])
 	)}
 
 happyNewToken action sts stk [] =
-	happyDoAction 73# notHappyAtAll action sts stk []
+	happyDoAction 71# notHappyAtAll action sts stk []
 
 happyNewToken action sts stk (tk:tks) =
 	let cont i = happyDoAction i tk action sts stk tks in
@@ -1488,66 +1519,64 @@
 	RP -> cont 10#;
 	LSB -> cont 11#;
 	RSB -> cont 12#;
-	LESCAPE -> cont 13#;
-	RESCAPE -> cont 14#;
-	TO -> cont 15#;
-	PLUS -> cont 16#;
-	MINUS -> cont 17#;
-	TIMES -> cont 18#;
-	DIV -> cont 19#;
-	IDIV -> cont 20#;
-	MOD -> cont 21#;
-	TEQ -> cont 22#;
-	TNE -> cont 23#;
-	TLT -> cont 24#;
-	TLE -> cont 25#;
-	TGT -> cont 26#;
-	TGE -> cont 27#;
-	PRE -> cont 28#;
-	POST -> cont 29#;
-	IS -> cont 30#;
-	SEQ -> cont 31#;
-	SNE -> cont 32#;
-	SLT -> cont 33#;
-	SLE -> cont 34#;
-	SGT -> cont 35#;
-	SGE -> cont 36#;
-	AND -> cont 37#;
-	OR -> cont 38#;
-	NOT -> cont 39#;
-	UNION -> cont 40#;
-	INTERSECT -> cont 41#;
-	EXCEPT -> cont 42#;
-	FOR -> cont 43#;
-	LET -> cont 44#;
-	IN -> cont 45#;
-	COMMA -> cont 46#;
-	ASSIGN -> cont 47#;
-	WHERE -> cont 48#;
-	ORDER -> cont 49#;
-	BY -> cont 50#;
-	ASCENDING -> cont 51#;
-	DESCENDING -> cont 52#;
-	ELEMENT -> cont 53#;
-	ATTRIBUTE -> cont 54#;
-	STAG -> cont 55#;
-	ETAG -> cont 56#;
-	SATISFIES -> cont 57#;
-	ATSIGN -> cont 58#;
-	SLASH -> cont 59#;
-	QName happy_dollar_dollar -> cont 60#;
-	DECLARE -> cont 61#;
-	FUNCTION -> cont 62#;
-	VARIABLE -> cont 63#;
-	AT -> cont 64#;
-	DOTS -> cont 65#;
-	DOT -> cont 66#;
-	SEMI -> cont 67#;
-	Variable happy_dollar_dollar -> cont 68#;
-	XMLtext happy_dollar_dollar -> cont 69#;
-	TInteger happy_dollar_dollar -> cont 70#;
-	TFloat happy_dollar_dollar -> cont 71#;
-	TString happy_dollar_dollar -> cont 72#;
+	TO -> cont 13#;
+	PLUS -> cont 14#;
+	MINUS -> cont 15#;
+	TIMES -> cont 16#;
+	DIV -> cont 17#;
+	IDIV -> cont 18#;
+	MOD -> cont 19#;
+	TEQ -> cont 20#;
+	TNE -> cont 21#;
+	TLT -> cont 22#;
+	TLE -> cont 23#;
+	TGT -> cont 24#;
+	TGE -> cont 25#;
+	PRE -> cont 26#;
+	POST -> cont 27#;
+	IS -> cont 28#;
+	SEQ -> cont 29#;
+	SNE -> cont 30#;
+	SLT -> cont 31#;
+	SLE -> cont 32#;
+	SGT -> cont 33#;
+	SGE -> cont 34#;
+	AND -> cont 35#;
+	OR -> cont 36#;
+	NOT -> cont 37#;
+	UNION -> cont 38#;
+	INTERSECT -> cont 39#;
+	EXCEPT -> cont 40#;
+	FOR -> cont 41#;
+	LET -> cont 42#;
+	IN -> cont 43#;
+	COMMA -> cont 44#;
+	ASSIGN -> cont 45#;
+	WHERE -> cont 46#;
+	ORDER -> cont 47#;
+	BY -> cont 48#;
+	ASCENDING -> cont 49#;
+	DESCENDING -> cont 50#;
+	ELEMENT -> cont 51#;
+	ATTRIBUTE -> cont 52#;
+	STAG -> cont 53#;
+	ETAG -> cont 54#;
+	SATISFIES -> cont 55#;
+	ATSIGN -> cont 56#;
+	SLASH -> cont 57#;
+	QName happy_dollar_dollar -> cont 58#;
+	DECLARE -> cont 59#;
+	FUNCTION -> cont 60#;
+	VARIABLE -> cont 61#;
+	AT -> cont 62#;
+	DOTS -> cont 63#;
+	DOT -> cont 64#;
+	SEMI -> cont 65#;
+	Variable happy_dollar_dollar -> cont 66#;
+	XMLtext happy_dollar_dollar -> cont 67#;
+	TInteger happy_dollar_dollar -> cont 68#;
+	TFloat happy_dollar_dollar -> cont 69#;
+	TString happy_dollar_dollar -> cont 70#;
 	_ -> happyError' (tk:tks)
 	}
 
@@ -1588,8 +1617,8 @@
 
 instance Show Ast
   where show (Ast s []) = s ++ "()"
-        show (Ast s (x:xs)) = s ++ "(" ++ (show x)
-                              ++ (foldr (\a r -> ","++(show a)++r) "" xs)
+        show (Ast s (x:xs)) = s ++ "(" ++ show x
+                              ++ foldr (\a r -> ","++show a++r) "" xs
                               ++ ")"
         show (Avar s) = s
         show (Aint n) = show n
@@ -1597,23 +1626,45 @@
         show (Astring s) = "\'" ++ s ++ "\'"
 
 
+screenSize = 80::Int
+
+prettyAst :: Ast -> Int -> (String,Int)
+prettyAst (Avar s) p = (s,(length s)+p)
+prettyAst (Aint n) p = let s = show n in (s,(length s)+p)
+prettyAst (Afloat n) p = let s = show n in (s,(length s)+p)
+prettyAst (Astring s) p = ("\'" ++ s ++ "\'",(length s)+p+2)
+prettyAst (Ast s args) p
+    = let (ps,np) = prettyArgs args
+      in (s++"("++ps++")",np+1)
+    where prettyArgs [] = ("",p+1)
+          prettyArgs xs = let ss = show (head xs) ++ foldr (\a r -> ","++show a++r) "" (tail xs)
+                              np = (length s)+p+1
+                          in if (length ss)+p < screenSize
+                             then (ss,(length ss)+p)
+                             else let ds = map (\x -> let (s,ep) = prettyAst x np
+                                                      in (s ++ ",\n" ++ space np,ep)) (init xs)
+                                      (ls,lp) = prettyAst (last xs) np
+                                  in (concatMap fst ds ++ ls,lp)
+          space n = replicate n ' '
+
+
+ppAst :: Ast -> String
+ppAst e = let (s,_) = prettyAst e 0 in s
+
+
 call :: String -> [Ast] -> Ast
 call name args = Ast "call" ((Avar name):args)
 
 
 concatenateAll :: [Ast] -> Ast
+concatenateAll [x] = x
 concatenateAll (x:xs) = foldl (\a r -> call "concatenate" [a,r]) x xs
 concatenateAll _ = call "empty" []
 
 
-concatAll :: [Ast] -> Ast
-concatAll (x:xs) = foldl (\a r -> call "concat" [a,r]) x xs
-concatAll _ = call "empty" []
-
-
 data Token
   = RETURN | SOME | EVERY | IF | THEN | ELSE | LB | RB | LP | RP | LSB | RSB
-  | LESCAPE | RESCAPE | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD
+  | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD
   | TEQ | TNE | TLT | TLE | TGT | TGE | SEQ | SNE | SLT | SLE | SGT | SGE
   | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA
   | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT
@@ -1631,6 +1682,7 @@
 	  show (TInteger n) = "Integer("++(show n)++")"
 	  show (TFloat n) = "Double("++(show n)++")"
 	  show (TString s) = "String("++s++")"
+	  show (TError s) = "'"++s++"'"
           show t = case filter (\(n,_) -> n==t) tokenList of
                      (_,b):_ -> b
                      _ -> "Illegal token"
@@ -1638,7 +1690,7 @@
 
 tokenList :: [(Token,String)]
 tokenList = [(RETURN,"return"),(SOME,"some"),(EVERY,"every"),(IF,"if"),(THEN,"then"),(ELSE,"else"),
-             (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),(LESCAPE,"\"{"),(RESCAPE,"}\""),
+             (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),
              (TO,"to"),(PLUS,"+"),(MINUS,"-"),(TIMES,"*"),(DIV,"div"),(IDIV,"idiv"),(MOD,"mod"),
              (TEQ,"="),(TNE,"!="),(TLT,"<"),(TLE,"<="),(TGT,">"),(TGE,">="),(PRE,"<<"),(POST,">>"),
              (IS,"is"),(SEQ,"eq"),(SNE,"ne"),(SLT,"lt"),(SLE,"le"),(SGT,"gt"),(SGE,"ge"),(AND,"and"),
@@ -1650,50 +1702,60 @@
              (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";")]
 
 
-parseError [] = error "Reached end-of-input"
-parseError [_] = error "Reached end-of-input"
-parseError tk = error("Parse error: "++(show (take 10 (init tk))))
+parseError tk = error (case tk of
+                         ((TError s):_) -> "Parse error: "++s
+                         _ -> "Parse error: "++(foldr (\a r -> (show a)++" "++r) "" (take 20 tk)))
 
 
 scan :: String -> [Token]
-scan cs = lexer cs [0]
+scan cs = lexer cs ""
 
+
 xmlText :: String -> [Token]
 xmlText "" = []
 xmlText text = [XMLtext text]
 
+
 -- scans XML syntax and returns an XMLtext token with the text
-xml :: String -> String -> [Int] -> [Token]
-xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs (0:n))
-xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs n)
+xml :: String -> String -> String -> [Token]
+xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs ('{':n))
+xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs ('<':'/':n))
 xml ('<':'!':'-':cs) text n = xmlComment cs (text++"<!-") n
-xml ('<':cs) text (k:n) = (xmlText text)++(TLT : lexer cs (k+2:n))
-xml ('\'':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)
-xml ('\"':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)
+xml ('<':cs) text n = (xmlText text)++(TLT : lexer cs ('<':n))
 xml ('(':':':cs) text n = xqComment cs text n
 xml (c:cs) text n = xml cs (text++[c]) n
 xml [] text _ = xmlText text
 
-xqComment :: String -> String -> [Int] -> [Token]
+
+xqComment :: String -> String -> String -> [Token]
 xqComment (':':')':cs) text n = xml cs text n
 xqComment (_:cs) text n = xqComment cs text n
 xqComment [] text _ = xmlText text
 
-xmlComment :: String -> String -> [Int] -> [Token]
+
+xmlComment :: String -> String -> String -> [Token]
 xmlComment ('-':'>':cs) text n = xml cs (text++"->") n
 xmlComment (c:cs) text n = xmlComment cs (text++[c]) n
 xmlComment [] text _ = xmlText text
 
+
 isQN :: Char -> Bool
 isQN c = elem c "_:-" || isDigit c || isAlpha c
 
+
 isVar :: Char -> Bool
 isVar c = elem c "_" || isDigit c || isAlpha c
 
+
+inXML :: String -> Bool
+inXML ('>':'<':_) = True
+inXML _ = False
+
+
 -- the XQuery scanner
-lexer :: String -> [Int] -> [Token]
-lexer [] [0] = []
-lexer [] _ = error "Unbalanced tags"
+lexer :: String -> String -> [Token]
+lexer [] "" = []
+lexer [] _ = [ TError "Unexpected end of input" ]
 lexer (' ':'>':' ':cs) n = TGT : lexer cs n
 lexer (c:cs) n
       | isSpace c = lexer cs n
@@ -1702,46 +1764,50 @@
 lexer ('$':c:cs) n | isAlpha c
       = let (var,rest) = span isVar (c:cs)
         in (Variable var) : lexer rest n
-lexer ('\'':'{':cs) n = LESCAPE : lexer cs n
-lexer ('\"':'{':cs) n = LESCAPE : lexer cs n
 lexer (':':'=':cs) n = ASSIGN : lexer cs n
-lexer ('<':'/':cs) n = STAG : lexer cs n
+lexer ('<':'/':cs) n = STAG : lexer cs ('<':'/':n)
 lexer ('<':'=':cs) n = TLE : lexer cs n
 lexer ('>':'=':cs) n = TGE : lexer cs n
 lexer ('<':'<':cs) n = PRE : lexer cs n
 lexer ('>':'>':cs) n = POST : lexer cs n
-lexer ('/':'>':cs) (k:n) = ETAG : lexer cs (k-2:n)
+lexer ('/':'>':cs) m = case m of
+                         '<':n -> ETAG : (if inXML n then xml cs "" n else lexer cs n)
+                         _ -> [ TError "Unexpected token: '/>'" ]
 lexer ('(':':':cs) n = lexComment cs n
 lexer ('<':'!':'-':cs) n = lexXmlComment cs "<!-" n
 lexer ('.':'.':cs) n = DOTS : lexer cs n
 lexer ('.':cs) n = DOT : lexer cs n
-lexer ('}':'\'':cs) n = RESCAPE : lexer cs n
-lexer ('}':'\"':cs) n = RESCAPE : lexer cs n
 lexer ('!':'=':cs) n = TNE : lexer cs n
-lexer ('\'':cs) n = lexString cs n
-lexer ('\"':cs) n = lexString2 cs n
+lexer ('\'':cs) n = lexString cs "" ('\'':n)
+lexer ('\"':cs) n = lexString cs "" ('\"': n)
 lexer ('[':cs) n = LB : lexer cs n
 lexer (']':cs) n = RB : lexer cs n
 lexer ('(':cs) n = LP : lexer cs n
 lexer (')':cs) n = RP : lexer cs n
-lexer ('}':cs) [_,n] = RSB : lexer cs [n]
-lexer ('}':cs) (_:n:ns) = RSB : (if n==0 then lexer cs (n:ns) else xml cs "" (n:ns))
+lexer ('}':cs) m = case m of
+                     '{':'\"':n -> RSB : lexString cs "" ('\"':n)
+                     '{':'\'':n -> RSB : lexString cs "" ('\'':n)
+                     '{':n -> RSB : (if inXML n then xml cs "" n else lexer cs n)
+                     _ -> [ TError "Unexpected token: '}'" ]
 lexer ('+':cs) n = PLUS : lexer cs n
 lexer ('-':cs) n = MINUS : lexer cs n
 lexer ('*':cs) n = TIMES : lexer cs n
 lexer ('=':cs) n = TEQ : lexer cs n
-lexer ('<':c:cs) n | not(isAlpha c) = TLT : lexer (c:cs) n
-lexer ('<':cs) (k:n) = TLT : lexer cs (k+2:n)
-lexer ('>':cs) (k:n) = TGT : (if k==1 then lexer cs (0:n) else xml cs "" (k-1:n))
+lexer ('<':c:cs) n = TLT : (lexer (c:cs) (if isAlpha c then ('<':n) else n))
+lexer ('>':cs) m = case m of
+                     '<':'/':'>':'<':n -> TGT : (if inXML n then xml cs "" n else lexer cs n)
+                     '<':n -> TGT : xml cs "" ('>':m) 
+                     _ -> TGT : lexer cs m
 lexer (',':cs) n = COMMA : lexer cs n
 lexer ('@':cs) n = ATSIGN : lexer cs n
 lexer ('/':cs) n = SLASH : lexer cs n
-lexer ('{':cs) n = LSB : lexer cs (0:n)
+lexer ('{':cs) n = LSB : lexer cs ('{':n)
 lexer ('|':cs) n = UNION : lexer cs n
 lexer (';':cs) n = SEMI : lexer cs n
-lexer (c:cs) n = error("Illegal character "++[c])
+lexer (c:cs) n = TError ("Illegal character: '"++[c,'\'']) : lexer cs n
 
-lexNum :: String -> [Int] -> [Token]
+
+lexNum :: String -> String -> [Token]
 lexNum cs n = if null rest || head rest /= '.'
                  then TInteger (read k) : lexer rest n
               else let (m,rest2) = span isDigit (tail rest)
@@ -1752,68 +1818,75 @@
                         _ -> (TFloat val) : lexer rest2 n
       where (k,rest) = span isDigit cs
 
-lexString :: String -> [Int] -> [Token]
-lexString cs n = TString s : lexer (tail rest) n
-    where (s,rest) = span inString cs
-          inString c = c /= '\''
 
-lexString2 :: String -> [Int] -> [Token]
-lexString2 cs n = TString s : lexer (tail rest) n
-    where (s,rest) = span inString cs
-          inString c = c /= '\"'
+lexString :: String -> String -> String -> [Token]
+lexString ('\"':cs) s m = case m of
+                            '\"':n -> (TString s) : (lexer cs n)
+                            _ -> lexString cs (s++"\"") m
+lexString ('\'':cs) s m = case m of
+                            '\'':n -> (TString s) : (lexer cs n)
+                            _ -> lexString cs (s++"\'") m
+lexString ('{':cs) s n = (TString s) : LSB : (lexer cs ('{':n))
+lexString (c:cs) s n = lexString cs (s++[c]) n
+lexString [] s n = [ TError "End of input while in string" ]
 
-lexComment :: String -> [Int] -> [Token]
+
+lexComment :: String -> String -> [Token]
 lexComment (':':')':cs) n = lexer cs n
 lexComment (_:cs) n = lexComment cs n
-lexComment [] n = []
+lexComment [] n = [ TError "End of input while in comment" ]
 
-lexXmlComment :: String -> String -> [Int] -> [Token]
+
+lexXmlComment :: String -> String -> String -> [Token]
 lexXmlComment ('-':'>':cs) text n = (xmlText (text++"->"))++(lexer cs n)
 lexXmlComment (c:cs) text n = lexXmlComment cs (text++[c]) n
 lexXmlComment [] text _ = xmlText text
 
-lexVar :: String -> [Int] -> [Token]
+
+lexVar :: String -> String -> [Token]
 lexVar cs n =
-   case span isQN cs of
-      ("return",rest) -> RETURN : lexer rest n
-      ("some",rest) -> SOME : lexer rest n
-      ("every",rest) -> EVERY : lexer rest n
-      ("if",rest) -> IF : lexer rest n
-      ("then",rest) -> THEN : lexer rest n
-      ("else",rest) -> ELSE : lexer rest n
-      ("to",rest) -> TO : lexer rest n
-      ("div",rest) -> DIV : lexer rest n
-      ("idiv",rest) -> IDIV : lexer rest n
-      ("mod",rest) -> MOD : lexer rest n
-      ("and",rest) -> AND : lexer rest n
-      ("or",rest) -> OR : lexer rest n
-      ("not",rest) -> NOT : lexer rest n
-      ("union",rest) -> UNION : lexer rest n
-      ("intersect",rest) -> INTERSECT : lexer rest n
-      ("except",rest) -> EXCEPT : lexer rest n
-      ("for",rest) -> FOR : lexer rest n
-      ("let",rest) -> LET : lexer rest n
-      ("in",rest) -> IN : lexer rest n
-      ("where",rest) -> WHERE : lexer rest n
-      ("order",rest) -> ORDER : lexer rest n
-      ("by",rest) -> BY : lexer rest n
-      ("ascending",rest) -> ASCENDING : lexer rest n
-      ("descending",rest) -> DESCENDING : lexer rest n
-      ("element",rest) -> ELEMENT : lexer rest n
-      ("attribute",rest) -> ATTRIBUTE : lexer rest n
-      ("satisfies",rest) -> SATISFIES : lexer rest n
-      ("declare",rest) -> DECLARE : lexer rest n
-      ("function",rest) -> FUNCTION : lexer rest n
-      ("variable",rest) -> VARIABLE : lexer rest n
-      ("at",rest) -> AT : lexer rest n
-      ("eq",rest) -> SEQ : lexer rest n
-      ("ne",rest) -> SNE : lexer rest n
-      ("lt",rest) -> SLT : lexer rest n
-      ("le",rest) -> SLE : lexer rest n
-      ("gt",rest) -> SGT : lexer rest n
-      ("ge",rest) -> SGE : lexer rest n
-      ("is",rest) -> IS : lexer rest n
-      (var,rest) -> QName var : lexer rest n
+    let (nm,rest) = span isQN cs
+    in (case nm of
+          "return" -> RETURN
+          "some" -> SOME
+          "every" -> EVERY
+          "if" -> IF
+          "then" -> THEN
+          "else" -> ELSE
+          "to" -> TO
+          "div" -> DIV
+          "idiv" -> IDIV
+          "mod" -> MOD
+          "and" -> AND
+          "or" -> OR
+          "not" -> NOT
+          "union" -> UNION
+          "intersect" -> INTERSECT
+          "except" -> EXCEPT
+          "for" -> FOR
+          "let" -> LET
+          "in" -> IN
+          "where" -> WHERE
+          "order" -> ORDER
+          "by" -> BY
+          "ascending" -> ASCENDING
+          "descending" -> DESCENDING
+          "element" -> ELEMENT
+          "attribute" -> ATTRIBUTE
+          "satisfies" -> SATISFIES
+          "declare" -> DECLARE
+          "function" -> FUNCTION
+          "variable" -> VARIABLE
+          "at" -> AT
+          "eq" -> SEQ
+          "ne" -> SNE
+          "lt" -> SLT
+          "le" -> SLE
+          "gt" -> SGT
+          "ge" -> SGE
+          "is" -> IS
+          var -> QName var
+       ) : lexer rest n
 {-# LINE 1 "templates/GenericTemplate.hs" #-}
 {-# LINE 1 "templates/GenericTemplate.hs" #-}
 {-# LINE 1 "<built-in>" #-}
diff --git a/XML/HXQ/XQuery.hs b/XML/HXQ/XQuery.hs
--- a/XML/HXQ/XQuery.hs
+++ b/XML/HXQ/XQuery.hs
@@ -4,7 +4,7 @@
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 03/22/08, last update: 05/06/08
+- Creation: 03/22/08, last update: 05/30/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -13,10 +13,11 @@
 -
 --------------------------------------------------------------------------------------}
 
+
 -- | HXQ is a fast and space-efficient compiler from XQuery (the standard
 -- query language for XML) to embedded Haskell code. The translation is
 -- based on Haskell templates. It also provides an interpreter for
--- evaluating ad-hoc XQueries read from input or from files.
+-- evaluating ad-hoc XQueries read from input or from files and database connectivity using HDBC.
 -- For more information, look at <http://lambda.uta.edu/HXQ/>.
 module XML.HXQ.XQuery (
        -- * The XML Data Representation
@@ -24,10 +25,19 @@
        -- * The XQuery Compiler
        xq, xe,
        -- * The XQuery Interpreter
-       xquery, xfile
+       xquery, xfile,
+       -- * The XQuery Compiler with Database Connectivity
+       xqdb, connect, disconnect, prepareSQL, executeSQL,
+       -- * The XQuery Interpreter with Database Connectivity
+       xqueryDB, xfileDB,
+       -- * Shredding and Publishing XML Documents Using a Relational Database
+       shred, createIndex
     ) where
 
 import HXML(AttList)
 import XML.HXQ.XTree
 import XML.HXQ.Compiler
 import XML.HXQ.Interpreter
+import XML.HXQ.DB
+import XML.HXQ.DBConnect
+import Database.HDBC(disconnect)
diff --git a/XML/HXQ/XQueryDB.hs b/XML/HXQ/XQueryDB.hs
deleted file mode 100644
--- a/XML/HXQ/XQueryDB.hs
+++ /dev/null
@@ -1,38 +0,0 @@
-{-------------------------------------------------------------------------------------
--
-- The XQuery Compiler and Interpreter with HDBC connectivity
-- Programmer: Leonidas Fegaras
-- Email: fegaras@cse.uta.edu
-- Web: http://lambda.uta.edu/
-- Creation: 05/12/08, last update: 05/12/08
-- 
-- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
-- This material is provided as is, with absolutely no warranty expressed or implied.
-- Any use is at your own risk. Permission is hereby granted to use or copy this program
-- for any purpose, provided the above notices are retained on all copies.
--
---------------------------------------------------------------------------------------}
-
-
--- | HXQ is a fast and space-efficient compiler from XQuery (the standard
--- query language for XML) to embedded Haskell code. The translation is
--- based on Haskell templates. It also provides an interpreter for
--- evaluating ad-hoc XQueries read from input or from files.
--- For more information, look at <http://lambda.uta.edu/HXQ/>.
-module XML.HXQ.XQueryDB (
-       -- * The XML Data Representation
-       XTree(..), XSeq, Tag, AttList, putXSeq,
-       -- * The XQuery Compiler
-       xq, xe,
-       -- * The XQuery Interpreter
-       xquery, xfile,
-       -- * The XQuery Compiler with Database Connectivity
-       xqdb, disconnect, prepareSQL, executeSQL
-    ) where
-
-import HXML(AttList)
-import XML.HXQ.XTree
-import XML.HXQ.Compiler
-import XML.HXQ.Interpreter
-import XML.HXQ.DB
-import Database.HDBC(disconnect)
diff --git a/XML/HXQ/XTree.hs b/XML/HXQ/XTree.hs
--- a/XML/HXQ/XTree.hs
+++ b/XML/HXQ/XTree.hs
@@ -1,10 +1,10 @@
 {-------------------------------------------------------------------------------------
 -
-- XML Trees (rose trees)
+- XML Trees (represented as rose trees)
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 05/01/08, last update: 05/05/08
+- Creation: 05/01/08, last update: 05/30/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -22,8 +22,13 @@
 import System.IO
 import XMLParse(XMLEvent(..))
 import HXML(AttList)
+import XML.HXQ.Parser(Ast(..))
+import Database.HDBC(Statement)
 
 
+instance Eq Statement where x == y = False
+
+
 type Tag = String
 
 
@@ -38,23 +43,26 @@
            |  XGERef   Tag		-- ^ general entity reference
            |  XComment String		-- ^ comment
            |  XError   String		-- ^ error report
+           |  XStmt    Statement        -- ^ used internally to wrap an SQL statement
+           |  XNoPad                    -- ^ marker for no padding in XSeq
            deriving Eq
 
+
 type XSeq = [XTree]
 
 
 showAL :: AttList -> String
-showAL = foldr(\(a,v) r -> " "++a++"=\""++v++"\""++r) []
+showAL = foldr (\(a,v) r -> " "++a++"=\""++v++"\""++r) []
 
 showXT :: XTree -> Bool -> String
 showXT e pad
     = case e of
-        XElem tag al _ [] -> "<"++tag++(showAL al)++"/>"
-        XElem tag al _ xs -> "<"++tag++(showAL al)++">"++(showXS xs)++"</"++tag++">"
-        XText text -> text
-        XInt n -> p++(show n)
-        XFloat n -> p++(show n)
-        XBool v -> p++(if v then "true" else "false")
+        XElem tag al _ [] -> "<"++tag++showAL al++"/>"
+        XElem tag al _ xs -> "<"++tag++showAL al++">"++showXS xs++"</"++tag++">"
+        XText text -> p++text
+        XInt n -> p++show n
+        XFloat n -> p++show n
+        XBool v -> p++if v then "true" else "false"
         XComment s -> "<!--"++s++"-->"
         XPI n s -> "<?"++n++" "++s++">"
         XError s -> error s
@@ -63,15 +71,19 @@
 
 showXS :: XSeq -> String
 showXS [] = ""
-showXS (x:xs) = (showXT x False) ++ (concatMap (\x -> showXT x True) xs)
+showXS (x:xs) = showXT x False ++ sXS xs
+    where sXS (XNoPad:x:xs) = (showXT x False) ++ sXS xs
+          sXS (x:xs) = (showXT x True) ++ sXS xs
+          sXS _ = ""
 
 instance Show XTree where
     show t = showXT t False
 
 
--- | Print the XQuery result (which is a sequence of XML fragments) with no waiting
+-- | Print the XQuery result (which is a sequence of XML fragments) without buffering.
 putXSeq :: XSeq -> IO ()
 putXSeq xs = hSetBuffering stdout NoBuffering >> putStrLn (showXS xs)
+
 
 
 {--------------- Build the rose tree from the XML stream ----------------------------}
diff --git a/XQueryParser.y b/XQueryParser.y
--- a/XQueryParser.y
+++ b/XQueryParser.y
@@ -4,7 +4,7 @@
 - Programmer: Leonidas Fegaras
 - Email: fegaras@cse.uta.edu
 - Web: http://lambda.uta.edu/
-- Creation: 02/15/08, last update: 05/01/08
+- Creation: 02/15/08, last update: 05/15/08
 - 
 - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.
 - This material is provided as is, with absolutely no warranty expressed or implied.
@@ -35,9 +35,7 @@
 	')' 		{ RP }
 	'{' 		{ LSB }
 	'}' 		{ RSB }
-	'\'{' 		{ LESCAPE }
-	'}\'' 		{ RESCAPE }
-	'to' 		{ TO }
+        'to' 		{ TO }
 	'+' 		{ PLUS }
 	'-' 		{ MINUS }
 	'*' 		{ TIMES }
@@ -175,7 +173,7 @@
 		|   '+' expr       %prec UMINUS		{ call "uplus" [$2] }
 		|   '-' expr       %prec UMINUS		{ call "uminus" [$2] }
 		|   'not' expr     %prec UMINUS		{ call "not" [$2] }
-		|   'String'				{ Astring $1 }
+		|   string				{ $1 }
 		|   'Integer'				{ Aint $1 }
 		|   'Double'				{ Afloat $1 }
 
@@ -225,15 +223,17 @@
 
 element        :: { Ast }
 element		:   stag '>' content '</' 'QName' '>'	{ if head $1 == Astring $5
-						  	     then Ast "construction" ($1++[concatAll $3])
-                                                          else error("Unmatched tags in element construction: "++(show (head $1))++" '"++$5++"'") }
+						  	     then Ast "element_construction" ($1++[Ast "append" $3])
+                                                          else parseError [TError ("Unmatched tags in element construction: "
+                                                                                   ++(show (head $1))++" '"++$5++"'")] }
                 |   stag '>' '</' 'QName' '>'		{ if head $1 == Astring $4
-							     then Ast "construction" ($1++[call "empty" []])
-                                                          else error("Unmatched tags in element construction: "++(show (head $1))++" '"++$4++"'") }
-                |   stag '/>'     			{ Ast "construction" ($1++[call "empty" []]) }
-                |   'element' '{' expr '}' '{' expl '}'	{ Ast "element_construction" [$3,concatenateAll $6] }
+							     then Ast "element_construction" ($1++[Ast "append" []])
+                                                          else parseError [TError ("Unmatched tags in element construction: "
+                                                                                   ++(show (head $1))++" '"++$4++"'")] }
+                |   stag '/>'     			{ Ast "element_construction" ($1++[Ast "append" []]) }
+                |   'element' '{' expr '}' '{' expl '}'	{ Ast "element_construction" [$3,Ast "attributes" [],concatenateAll $6] }
                 |   'attribute' '{' expr '}''{' expl '}'{ Ast "attribute_construction" [$3,concatenateAll $6] }
-                |   'element' 'QName' '{' expl '}'	{ Ast "element_construction" [Astring $2,concatenateAll $4] }
+                |   'element' 'QName' '{' expl '}'	{ Ast "element_construction" [Astring $2,Ast "attributes" [],concatenateAll $4] }
                 |   'attribute' 'QName' '{' expl '}'    { Ast "attribute_construction" [Astring $2,concatenateAll $4] }
 
 stag           :: { [ Ast ] }
@@ -250,12 +250,18 @@
 		|   content 'XMLtext'			{ $1++[Astring $2] }
 		|   content element			{ $1++[$2] }
 
+string         :: { Ast }
+string          : stringc                               { if length $1 == 1 then head $1 else Ast "append" $1 }
+
+stringc        :: { [Ast] }
+stringc         :   'String'                            { if $1=="" then [] else [Astring $1] }
+                |   '{' expl '}'                        { [concatenateAll $2] }
+                |   stringc 'String'                    { if $2=="" then $1 else $1++[Astring $2] }
+                |   stringc '{' expl '}'                { $1++[concatenateAll $3] }
+
 attributes     :: { [ Ast ] }
-attributes	:   'QName' '=' 'String'		{ [Ast "pair" [Astring $1,Astring $3]] }
-		|   'QName' '=' '\'{' expr '}\''	{ [Ast "pair" [Astring $1,$4]] }
-		|   attributes 'QName' '=' 'String'	{ $1++[Ast "pair" [Astring $2,Astring $4]] }
-		|   attributes 'QName' '='
-                         '\'{' expr '}\''		{ $1++[Ast "pair" [Astring $2,$5]] }
+attributes	:   'QName' '=' string  	        { [Ast "pair" [Astring $1,$3]] }
+		|   attributes 'QName' '=' string	{ $1++[Ast "pair" [Astring $2,$4]] }
 
 full_path      :: { Ast }
 full_path       :   predicate_step                      { Ast "step" ($1 "child_step" (Avar ".")) }
@@ -290,13 +296,10 @@
                                                                      then concatenateAll $2
 	                                                          else Ast "context" [e,Astring t,concatenateAll $2] }
                 |   '(' ')'                             { \_ _ -> call "empty" [] }
-                |   'QName' '(' expl ')'                { \_ e -> if e == Avar "."
+                |   'QName' '(' expl ')'                { \t e -> if e == Avar "."
                                                                      then call $1 $3
-                                                                  else Ast "context" [e,call $1 $3] }
-                |   'QName' '(' ')'                     { if elem $1 ["text"]
-                                                             then \_ e -> call $1 [e]
-                                                          else \_ _ -> call $1 [] }
-
+                                                                  else Ast "context" [e,Astring t,call $1 $3] }
+                |   'QName' '(' ')'                     { \_ e -> call $1 (if e == Avar "." then [] else [e]) }
 
 {
 
@@ -311,8 +314,8 @@
 
 instance Show Ast
   where show (Ast s []) = s ++ "()"
-        show (Ast s (x:xs)) = s ++ "(" ++ (show x)
-                              ++ (foldr (\a r -> ","++(show a)++r) "" xs)
+        show (Ast s (x:xs)) = s ++ "(" ++ show x
+                              ++ foldr (\a r -> ","++show a++r) "" xs
                               ++ ")"
         show (Avar s) = s
         show (Aint n) = show n
@@ -320,23 +323,45 @@
         show (Astring s) = "\'" ++ s ++ "\'"
 
 
+screenSize = 80::Int
+
+prettyAst :: Ast -> Int -> (String,Int)
+prettyAst (Avar s) p = (s,(length s)+p)
+prettyAst (Aint n) p = let s = show n in (s,(length s)+p)
+prettyAst (Afloat n) p = let s = show n in (s,(length s)+p)
+prettyAst (Astring s) p = ("\'" ++ s ++ "\'",(length s)+p+2)
+prettyAst (Ast s args) p
+    = let (ps,np) = prettyArgs args
+      in (s++"("++ps++")",np+1)
+    where prettyArgs [] = ("",p+1)
+          prettyArgs xs = let ss = show (head xs) ++ foldr (\a r -> ","++show a++r) "" (tail xs)
+                              np = (length s)+p+1
+                          in if (length ss)+p < screenSize
+                             then (ss,(length ss)+p)
+                             else let ds = map (\x -> let (s,ep) = prettyAst x np
+                                                      in (s ++ ",\n" ++ space np,ep)) (init xs)
+                                      (ls,lp) = prettyAst (last xs) np
+                                  in (concatMap fst ds ++ ls,lp)
+          space n = replicate n ' '
+
+
+ppAst :: Ast -> String
+ppAst e = let (s,_) = prettyAst e 0 in s
+
+
 call :: String -> [Ast] -> Ast
 call name args = Ast "call" ((Avar name):args)
 
 
 concatenateAll :: [Ast] -> Ast
+concatenateAll [x] = x
 concatenateAll (x:xs) = foldl (\a r -> call "concatenate" [a,r]) x xs
 concatenateAll _ = call "empty" []
 
 
-concatAll :: [Ast] -> Ast
-concatAll (x:xs) = foldl (\a r -> call "concat" [a,r]) x xs
-concatAll _ = call "empty" []
-
-
 data Token
   = RETURN | SOME | EVERY | IF | THEN | ELSE | LB | RB | LP | RP | LSB | RSB
-  | LESCAPE | RESCAPE | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD
+  | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD
   | TEQ | TNE | TLT | TLE | TGT | TGE | SEQ | SNE | SLT | SLE | SGT | SGE
   | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA
   | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT
@@ -354,6 +379,7 @@
 	  show (TInteger n) = "Integer("++(show n)++")"
 	  show (TFloat n) = "Double("++(show n)++")"
 	  show (TString s) = "String("++s++")"
+	  show (TError s) = "'"++s++"'"
           show t = case filter (\(n,_) -> n==t) tokenList of
                      (_,b):_ -> b
                      _ -> "Illegal token"
@@ -361,7 +387,7 @@
 
 tokenList :: [(Token,String)]
 tokenList = [(RETURN,"return"),(SOME,"some"),(EVERY,"every"),(IF,"if"),(THEN,"then"),(ELSE,"else"),
-             (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),(LESCAPE,"\"{"),(RESCAPE,"}\""),
+             (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),
              (TO,"to"),(PLUS,"+"),(MINUS,"-"),(TIMES,"*"),(DIV,"div"),(IDIV,"idiv"),(MOD,"mod"),
              (TEQ,"="),(TNE,"!="),(TLT,"<"),(TLE,"<="),(TGT,">"),(TGE,">="),(PRE,"<<"),(POST,">>"),
              (IS,"is"),(SEQ,"eq"),(SNE,"ne"),(SLT,"lt"),(SLE,"le"),(SGT,"gt"),(SGE,"ge"),(AND,"and"),
@@ -373,50 +399,60 @@
              (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";")]
 
 
-parseError [] = error "Reached end-of-input"
-parseError [_] = error "Reached end-of-input"
-parseError tk = error("Parse error: "++(show (take 10 (init tk))))
+parseError tk = error (case tk of
+                         ((TError s):_) -> "Parse error: "++s
+                         _ -> "Parse error: "++(foldr (\a r -> (show a)++" "++r) "" (take 20 tk)))
 
 
 scan :: String -> [Token]
-scan cs = lexer cs [0]
+scan cs = lexer cs ""
 
+
 xmlText :: String -> [Token]
 xmlText "" = []
 xmlText text = [XMLtext text]
 
+
 -- scans XML syntax and returns an XMLtext token with the text
-xml :: String -> String -> [Int] -> [Token]
-xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs (0:n))
-xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs n)
+xml :: String -> String -> String -> [Token]
+xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs ('{':n))
+xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs ('<':'/':n))
 xml ('<':'!':'-':cs) text n = xmlComment cs (text++"<!-") n
-xml ('<':cs) text (k:n) = (xmlText text)++(TLT : lexer cs (k+2:n))
-xml ('\'':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)
-xml ('\"':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)
+xml ('<':cs) text n = (xmlText text)++(TLT : lexer cs ('<':n))
 xml ('(':':':cs) text n = xqComment cs text n
 xml (c:cs) text n = xml cs (text++[c]) n
 xml [] text _ = xmlText text
 
-xqComment :: String -> String -> [Int] -> [Token]
+
+xqComment :: String -> String -> String -> [Token]
 xqComment (':':')':cs) text n = xml cs text n
 xqComment (_:cs) text n = xqComment cs text n
 xqComment [] text _ = xmlText text
 
-xmlComment :: String -> String -> [Int] -> [Token]
+
+xmlComment :: String -> String -> String -> [Token]
 xmlComment ('-':'>':cs) text n = xml cs (text++"->") n
 xmlComment (c:cs) text n = xmlComment cs (text++[c]) n
 xmlComment [] text _ = xmlText text
 
+
 isQN :: Char -> Bool
 isQN c = elem c "_:-" || isDigit c || isAlpha c
 
+
 isVar :: Char -> Bool
 isVar c = elem c "_" || isDigit c || isAlpha c
 
+
+inXML :: String -> Bool
+inXML ('>':'<':_) = True
+inXML _ = False
+
+
 -- the XQuery scanner
-lexer :: String -> [Int] -> [Token]
-lexer [] [0] = []
-lexer [] _ = error "Unbalanced tags"
+lexer :: String -> String -> [Token]
+lexer [] "" = []
+lexer [] _ = [ TError "Unexpected end of input" ]
 lexer (' ':'>':' ':cs) n = TGT : lexer cs n
 lexer (c:cs) n
       | isSpace c = lexer cs n
@@ -425,46 +461,50 @@
 lexer ('$':c:cs) n | isAlpha c
       = let (var,rest) = span isVar (c:cs)
         in (Variable var) : lexer rest n
-lexer ('\'':'{':cs) n = LESCAPE : lexer cs n
-lexer ('\"':'{':cs) n = LESCAPE : lexer cs n
 lexer (':':'=':cs) n = ASSIGN : lexer cs n
-lexer ('<':'/':cs) n = STAG : lexer cs n
+lexer ('<':'/':cs) n = STAG : lexer cs ('<':'/':n)
 lexer ('<':'=':cs) n = TLE : lexer cs n
 lexer ('>':'=':cs) n = TGE : lexer cs n
 lexer ('<':'<':cs) n = PRE : lexer cs n
 lexer ('>':'>':cs) n = POST : lexer cs n
-lexer ('/':'>':cs) (k:n) = ETAG : lexer cs (k-2:n)
+lexer ('/':'>':cs) m = case m of
+                         '<':n -> ETAG : (if inXML n then xml cs "" n else lexer cs n)
+                         _ -> [ TError "Unexpected token: '/>'" ]
 lexer ('(':':':cs) n = lexComment cs n
 lexer ('<':'!':'-':cs) n = lexXmlComment cs "<!-" n
 lexer ('.':'.':cs) n = DOTS : lexer cs n
 lexer ('.':cs) n = DOT : lexer cs n
-lexer ('}':'\'':cs) n = RESCAPE : lexer cs n
-lexer ('}':'\"':cs) n = RESCAPE : lexer cs n
 lexer ('!':'=':cs) n = TNE : lexer cs n
-lexer ('\'':cs) n = lexString cs n
-lexer ('\"':cs) n = lexString2 cs n
+lexer ('\'':cs) n = lexString cs "" ('\'':n)
+lexer ('\"':cs) n = lexString cs "" ('\"': n)
 lexer ('[':cs) n = LB : lexer cs n
 lexer (']':cs) n = RB : lexer cs n
 lexer ('(':cs) n = LP : lexer cs n
 lexer (')':cs) n = RP : lexer cs n
-lexer ('}':cs) [_,n] = RSB : lexer cs [n]
-lexer ('}':cs) (_:n:ns) = RSB : (if n==0 then lexer cs (n:ns) else xml cs "" (n:ns))
+lexer ('}':cs) m = case m of
+                     '{':'\"':n -> RSB : lexString cs "" ('\"':n)
+                     '{':'\'':n -> RSB : lexString cs "" ('\'':n)
+                     '{':n -> RSB : (if inXML n then xml cs "" n else lexer cs n)
+                     _ -> [ TError "Unexpected token: '}'" ]
 lexer ('+':cs) n = PLUS : lexer cs n
 lexer ('-':cs) n = MINUS : lexer cs n
 lexer ('*':cs) n = TIMES : lexer cs n
 lexer ('=':cs) n = TEQ : lexer cs n
-lexer ('<':c:cs) n | not(isAlpha c) = TLT : lexer (c:cs) n
-lexer ('<':cs) (k:n) = TLT : lexer cs (k+2:n)
-lexer ('>':cs) (k:n) = TGT : (if k==1 then lexer cs (0:n) else xml cs "" (k-1:n))
+lexer ('<':c:cs) n = TLT : (lexer (c:cs) (if isAlpha c then ('<':n) else n))
+lexer ('>':cs) m = case m of
+                     '<':'/':'>':'<':n -> TGT : (if inXML n then xml cs "" n else lexer cs n)
+                     '<':n -> TGT : xml cs "" ('>':m) 
+                     _ -> TGT : lexer cs m
 lexer (',':cs) n = COMMA : lexer cs n
 lexer ('@':cs) n = ATSIGN : lexer cs n
 lexer ('/':cs) n = SLASH : lexer cs n
-lexer ('{':cs) n = LSB : lexer cs (0:n)
+lexer ('{':cs) n = LSB : lexer cs ('{':n)
 lexer ('|':cs) n = UNION : lexer cs n
 lexer (';':cs) n = SEMI : lexer cs n
-lexer (c:cs) n = error("Illegal character "++[c])
+lexer (c:cs) n = TError ("Illegal character: '"++[c,'\'']) : lexer cs n
 
-lexNum :: String -> [Int] -> [Token]
+
+lexNum :: String -> String -> [Token]
 lexNum cs n = if null rest || head rest /= '.'
                  then TInteger (read k) : lexer rest n
               else let (m,rest2) = span isDigit (tail rest)
@@ -475,66 +515,73 @@
                         _ -> (TFloat val) : lexer rest2 n
       where (k,rest) = span isDigit cs
 
-lexString :: String -> [Int] -> [Token]
-lexString cs n = TString s : lexer (tail rest) n
-    where (s,rest) = span inString cs
-          inString c = c /= '\''
 
-lexString2 :: String -> [Int] -> [Token]
-lexString2 cs n = TString s : lexer (tail rest) n
-    where (s,rest) = span inString cs
-          inString c = c /= '\"'
+lexString :: String -> String -> String -> [Token]
+lexString ('\"':cs) s m = case m of
+                            '\"':n -> (TString s) : (lexer cs n)
+                            _ -> lexString cs (s++"\"") m
+lexString ('\'':cs) s m = case m of
+                            '\'':n -> (TString s) : (lexer cs n)
+                            _ -> lexString cs (s++"\'") m
+lexString ('{':cs) s n = (TString s) : LSB : (lexer cs ('{':n))
+lexString (c:cs) s n = lexString cs (s++[c]) n
+lexString [] s n = [ TError "End of input while in string" ]
 
-lexComment :: String -> [Int] -> [Token]
+
+lexComment :: String -> String -> [Token]
 lexComment (':':')':cs) n = lexer cs n
 lexComment (_:cs) n = lexComment cs n
-lexComment [] n = []
+lexComment [] n = [ TError "End of input while in comment" ]
 
-lexXmlComment :: String -> String -> [Int] -> [Token]
+
+lexXmlComment :: String -> String -> String -> [Token]
 lexXmlComment ('-':'>':cs) text n = (xmlText (text++"->"))++(lexer cs n)
 lexXmlComment (c:cs) text n = lexXmlComment cs (text++[c]) n
 lexXmlComment [] text _ = xmlText text
 
-lexVar :: String -> [Int] -> [Token]
+
+lexVar :: String -> String -> [Token]
 lexVar cs n =
-   case span isQN cs of
-      ("return",rest) -> RETURN : lexer rest n
-      ("some",rest) -> SOME : lexer rest n
-      ("every",rest) -> EVERY : lexer rest n
-      ("if",rest) -> IF : lexer rest n
-      ("then",rest) -> THEN : lexer rest n
-      ("else",rest) -> ELSE : lexer rest n
-      ("to",rest) -> TO : lexer rest n
-      ("div",rest) -> DIV : lexer rest n
-      ("idiv",rest) -> IDIV : lexer rest n
-      ("mod",rest) -> MOD : lexer rest n
-      ("and",rest) -> AND : lexer rest n
-      ("or",rest) -> OR : lexer rest n
-      ("not",rest) -> NOT : lexer rest n
-      ("union",rest) -> UNION : lexer rest n
-      ("intersect",rest) -> INTERSECT : lexer rest n
-      ("except",rest) -> EXCEPT : lexer rest n
-      ("for",rest) -> FOR : lexer rest n
-      ("let",rest) -> LET : lexer rest n
-      ("in",rest) -> IN : lexer rest n
-      ("where",rest) -> WHERE : lexer rest n
-      ("order",rest) -> ORDER : lexer rest n
-      ("by",rest) -> BY : lexer rest n
-      ("ascending",rest) -> ASCENDING : lexer rest n
-      ("descending",rest) -> DESCENDING : lexer rest n
-      ("element",rest) -> ELEMENT : lexer rest n
-      ("attribute",rest) -> ATTRIBUTE : lexer rest n
-      ("satisfies",rest) -> SATISFIES : lexer rest n
-      ("declare",rest) -> DECLARE : lexer rest n
-      ("function",rest) -> FUNCTION : lexer rest n
-      ("variable",rest) -> VARIABLE : lexer rest n
-      ("at",rest) -> AT : lexer rest n
-      ("eq",rest) -> SEQ : lexer rest n
-      ("ne",rest) -> SNE : lexer rest n
-      ("lt",rest) -> SLT : lexer rest n
-      ("le",rest) -> SLE : lexer rest n
-      ("gt",rest) -> SGT : lexer rest n
-      ("ge",rest) -> SGE : lexer rest n
-      ("is",rest) -> IS : lexer rest n
-      (var,rest) -> QName var : lexer rest n
+    let (nm,rest) = span isQN cs
+    in (case nm of
+          "return" -> RETURN
+          "some" -> SOME
+          "every" -> EVERY
+          "if" -> IF
+          "then" -> THEN
+          "else" -> ELSE
+          "to" -> TO
+          "div" -> DIV
+          "idiv" -> IDIV
+          "mod" -> MOD
+          "and" -> AND
+          "or" -> OR
+          "not" -> NOT
+          "union" -> UNION
+          "intersect" -> INTERSECT
+          "except" -> EXCEPT
+          "for" -> FOR
+          "let" -> LET
+          "in" -> IN
+          "where" -> WHERE
+          "order" -> ORDER
+          "by" -> BY
+          "ascending" -> ASCENDING
+          "descending" -> DESCENDING
+          "element" -> ELEMENT
+          "attribute" -> ATTRIBUTE
+          "satisfies" -> SATISFIES
+          "declare" -> DECLARE
+          "function" -> FUNCTION
+          "variable" -> VARIABLE
+          "at" -> AT
+          "eq" -> SEQ
+          "ne" -> SNE
+          "lt" -> SLT
+          "le" -> SLE
+          "gt" -> SGT
+          "ge" -> SGE
+          "is" -> IS
+          var -> QName var
+       ) : lexer rest n
 }
diff --git a/data/q1.xq b/data/q1.xq
--- a/data/q1.xq
+++ b/data/q1.xq
@@ -4,8 +4,8 @@
 
 declare function f ( $name, $gpa ) {
    <student>{ $name/firstname/text(),
-              ' ',$name/lastname/text(),
-              ': ',$gpa
+              $name/lastname/text(),
+              ':',$gpa
    }</student>
 };
 
diff --git a/data/q3.xq b/data/q3.xq
new file mode 100644
--- /dev/null
+++ b/data/q3.xq
@@ -0,0 +1,8 @@
+<result>{
+let $a := distinct-values(doc("data/cs.xml")//gradstudent)
+for $s in $a
+return <st>{
+    doc("data/cs.xml")//gradstudent[.//lastname = $s//lastname]//name,
+    count(.//*)
+    }</st>
+}</result>
diff --git a/hxml-0.2/XMLScanner.hs b/hxml-0.2/XMLScanner.hs
--- a/hxml-0.2/XMLScanner.hs
+++ b/hxml-0.2/XMLScanner.hs
@@ -168,7 +168,8 @@
 doEntityRef entities k r = doSpan (';'/=) (++) replacement (k . drop1) r where
     replacement ename = case DTD.expandInternalEntity entities ename of
 	    Just s 	-> s
-	    _		-> error ("entity " ++ ename ++ " not defined")
+-- changed by Leonidas Fegaras 5/27/08
+	    _		-> "" -- error ("entity " ++ ename ++ " not defined")
 
 -- [...]
 markupMode []	= []
diff --git a/index.html b/index.html
--- a/index.html
+++ b/index.html
@@ -26,24 +26,26 @@
 Also <a href="http://xqilla.sourceforge.net/HomePage">XQilla</a>, which is written in C++, took 1 minute and 10 secs
 (using 1150MB of heap space). (All results are taken on an Intel Core 2 Duo 2.2GHz 2GB running ghc-6.8.2 on Linux 2.6.23 kernel.)
 <p>
-HXQ uses the <a href="http://www.flightlab.com/~joe/hxml/">HXML parser for XML</a> (developed by Joe English),
-which is included in the source.
-I have also tried hexpat, tagsoup, HXT, and HaXML Xtract, but they all have space leaks.
-For example, when I replaced the HXML parser with <a href="http://www-users.cs.york.ac.uk/~ndm/tagsoup/">tagsoup</a>
-in HXQ, it required more than 3GB heap space for the above query
-and gave partial results.
+Finally, HXQ can store XML documents in a relational database (currently SQLite), by shredding XML into relational
+tuples, and by translating XQueries over the shredded documents into optimized SQL queries.
 <p>
 <h2>Installation Instructions</h2>
 <p>
 First, you need to install the Glasgow Haskell Compiler,
 <a href="http://www.haskell.org/ghc/">ghc</a>,
-and the parser generator for Haskell,
-<a href="http://www.haskell.org/happy/">happy</a>.
-For example, in Fedora Linux, you install both using:
+the parser generator for Haskell,
+<a href="http://www.haskell.org/happy/">happy</a>,
+and <a href="http://sqlite.org/">SQLite</a> for database connectivity (optional).
+For example, in Fedora Linux, you install them using:
 <pre>
-yum install ghc happy
+yum install ghc happy sqlite
 </pre>
-Then download <a href="/HXQ-0.8.tar.gz">HXQ</a> and untar it.
+Then, you need to install the haskell packages: <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC">HDBC</a>
+and the
+<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-sqlite3">HDBC-sqlite3</a> driver
+to connect to SQLite relational databases.
+<p>
+Finally, download <a href="/HXQ-0.8.3.tar.gz">HXQ</a> and untar it.
 You can use either make or cabal to build it. To build it with cabal, you do:
 <pre>
 runhaskell Setup.lhs configure --prefix=$HOME
@@ -51,7 +53,7 @@
 runhaskell Setup.lhs install
 </pre>
 (The last command must be run as root.)
-It will create the executable <tt>xquery</tt>, which is the XQuery interepreter, and the HXQ library.
+It will create the executable <tt>xquery</tt>, which is the XQuery interpreter, and the HXQ library.
 To use the library, you run ghc or ghci with <tt>-package HXQ</tt>.
 <p>
 <h2>Current Status</h2>
@@ -64,9 +66,12 @@
 Some, but not all, parent axis steps are removed using optimization rules; all others cause a compilation error.
 Finally, the XQuery semantics requires duplicate elimination and
 sorting by document order for every XPath step, which is very expensive and unnecessary in most cases.
-For exmple, <tt>e//*//*</tt> may return duplicate elements in HXQ.
+For example, <tt>e//*//*</tt> may return duplicate elements in HXQ.
 This will be addressed in the future (needs a static analysis to determine when duplicate elimination is necessary).
 <p>
+HXQ uses the <a href="http://www.flightlab.com/~joe/hxml/">HXML parser for XML</a> (developed by Joe English),
+which is included in the source. I have also tried hexpat, tagsoup, HXT, and HaXML Xtract, but they all have space leaks.
+<p>
 <h2>Using the Compiler</h2>
 <p>
 The main functions for embedding XQueries in Haskell are:
@@ -131,16 +136,34 @@
 <tt>xquery -p "//inproceedings[100]" data/dblp.xml</tt>.
 With <tt>xquery -help</tt> you get the list of system functions and usage information. 
 <p>
-<h2>Experimental Features</h2>
+<h2>Database Connectivity</h2>
 <p>
-There is an experimental interface to HDBC to query relational data inside an XQuery.
-To use it, you need to install <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC">HDBC</a>
-and <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-sqlite3">HDBC-sqlite3</a>
-(or some other HDBC driver, such ODBC). The main function is
-<tt>$(xqdb query) :: (IConnection conn) => conn -> IO XSeq</tt>.
-The XQuery may contain multiple SQL queries in the form <tt>sql(query,args)</tt>,
-where <tt>query</tt> is the sql query that may contain parameters (denoted by ?), which are bound to the values in <tt>args</tt>.
-An example can be found in <a href="TestDB.hs">TestDB.hs</a>. To run it, you need
+HXQ provides an interface to HDBC to query relational data inside an XQuery.
+For the HXQ compiler, the main function that allows database connectivity is:
+<pre>
+$(xqdb query) :: (IConnection conn) => conn -> IO XSeq
+</pre>
+For example, if the database name is "myDB", then
+<pre>
+do db <- connect "myDB"
+   result <- $(xqdb xquery) db
+</pre>
+For the HXQ interpreter, the function is:
+<pre>
+xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq
+</pre>
+The xquery executable can also run xqueries that use a database by specifying the database name using the -db option.
+<p>
+Currently, HXQ works with <a href="http://sqlite.org/">SQLite</a> only, but is very easy to make it work
+with any relational database that supports ODBC: simply install 
+<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-odbc">HDBC-odbc</a>
+and change the file <a href="XML/HXQ/DBConnect.hs">XML/HXQ/DBConnect.hs</a> accordingly.
+<p>
+<h3>Querying an Existing Database</h3>
+<p>
+An XQuery may contain multiple SQL queries in the form <tt>sql(query,args)</tt>,
+where <tt>query</tt> is the sql query that may contain parameters (denoted by ?), which are bound to the values in <tt>args</tt> (an XSeq).
+An example can be found in <a href="TestDB.hs">TestDB.hs</a>. To run this example, you need
 to install the <a href="data/company.sql">company</a> database. For example, using the sqlite3
 interpreter, you do:
 <pre>
@@ -148,17 +171,52 @@
 .read data/company.sql
 .quit
 </pre>
-and then you do <tt>make testdb</tt> on linux.
+and then compile and run <tt>TestDB.hs</tt> (or just do <tt>make test3</tt> on linux).
 <p>
-Finally, there is an experimental
+<h3>Shredding</h3>
+<p>
+To store an XML document into a relational database, use the following Haskell function:
+<pre>
+shred :: (IConnection conn) => conn -> String -> String -> IO ()
+shred db file name
+</pre>
+that shreds and stores the XML document located at the file pathname in the database db under a unique name.
+HXQ will find a good relational schema (using hybrid inlining) to store the XML data by first scanning the document to
+extract its structural summary, then deriving a good relational schema, and finally scanning the document
+for a second time to store its data into the relational tables. For example,
+<pre>
+do db <- connect "myDB"
+   shred db "data/cs.xml" "c"
+</pre>
+<p>
+The haskell function
+<pre>
+createIndex db name tagname
+</pre>
+creates a secondary index on tagname for the shredded document under the given name.
+<p>
+<h3>Publishing</h3>
+<p>
+You can query a shredded XML document using the XQuery function:
+<pre>
+publish(dbame,name)
+</pre>
+where dbname is the database file name and name is the unique name assigned to the XML document when was shredded.
+The translation from XQuery to SQL is done at compile-time, so both dbname and name must be constant strings.
+HXQ will do its best to push relevant predicates to the generated SQL query (using partial evaluation and code folding),
+thus deriving an efficient execution. One example is <a href="TestDB2.hs">TestDB2.hs</a> (do <tt>make test4</tt> to run it on linux).
+<p>
+<h2>Experimental Features</h2>
+<p>
+There is an experimental
 program, called <tt>hxqc</tt>, that works like <tt>xquery</tt> but is faster because it uses the
-HXQ compiler instead of the interpreter. It's constracted with the Unix Makefile (<tt>make hxqc</tt>).
+HXQ compiler instead of the interpreter. It's constructed with the Unix Makefile (<tt>make hxqc</tt>).
 It is unstable and the <tt>hxqc</tt> executable is 10 times larger than <tt>xquery</tt> since it
 uses the ghc libraries at run-time. Also, although it is faster than the interpreter, it is slower than a
-compiled xquery since it uses part of the heap for the ghc compiler to compile Haskell code on-the-fly.
+compiled xquery because it uses part of the heap for the ghc compiler to compile Haskell code on-the-fly.
 <p>
 </body>
 <p>
 <hr>
 <p>
-<address>Last modified: 05/13/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
+<address>Last modified: 06/12/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
diff --git a/profile.hs b/profile.hs
deleted file mode 100644
--- a/profile.hs
+++ /dev/null
@@ -1,20 +0,0 @@
-{-# OPTIONS_GHC -fth #-}
-
-module Main where
-
-import XML.HXQ.XTree
-import XML.HXQ.Parser
-import XML.HXQ.Compiler
-import XMLParse(parseDocument)
-import IO
-
-main = do let [XText f_0] = [XText "data/dblp.xml"]
-          doc_1 <- readFile f_0
-          res <- (\_doc0 -> return (foldr (\x_2 -> (\x -> \r_3 -> foldir (\x_4 i_5 r_6 -> if case [trueXT | x_7 <- text (foldr (\a_8 s_9 -> child_step "author" a_8 ++ s_9) [] (x :: XSeq)),
-                                                                                                                                              y_10 <- text [XText "David Maier"],
-                                                                                                                                              compareXTrees x_7 y_10 == EQ] of
-                                                                                                                    [XInt k_11] -> k_11 == i_5
-                                                                                                                    b_12 -> conditionTest b_12
-                                                                                                              then x_4 : r_6
-                                                                                                              else r_6) [] [XElem "paper" [] 0 ((text (foldr (\a_13 s_14 -> child_step "booktitle" a_13 ++ s_14) [] (x :: XSeq)) ++ [XText ": "]) ++ text (foldr (\a_15 s_16 -> child_step "title" a_15 ++ s_16) [] (x :: XSeq)))] 1 ++ r_3) [x_2]) [] (foldr (\a_17 s_18 -> descendant_step "inproceedings" a_17 ++ s_18) [] [_doc0]))) (materialize (parseDocument doc_1))
-          putXSeq res
