diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -28,9 +28,10 @@
 Changes
 -------
 
-0.0.16 - Fix bug for issue 7, blowing up when calculating if space needed after return
+0.1.0 - Major update to work with language-javascript 0.5.1. All changes should be internal.
+        Update of build process to make use of Cabal testing support, and Travis CI.
 
-0.0.15 - Fix ambiguous symbols with GHC 7.4.1, from @luite
+0.0.15 - Fix GHC 7.4.1 compile compatibility. Patch accepted from github.com/luite
 
 0.0.14 - Allow unicode characters in comments
 
diff --git a/Text/Jasmine.hs b/Text/Jasmine.hs
--- a/Text/Jasmine.hs
+++ b/Text/Jasmine.hs
@@ -1,13 +1,13 @@
 module Text.Jasmine
-    (       
+    (
       minify
-    , minifym  
-    , minifyBb  
-    , minifyFile  
-    ) where      
-    
+    , minifym
+    , minifyBb
+    , minifyFile
+    ) where
+
 --import Text.Jasmine.Parse
-import Language.JavaScript.Parser
+import Language.JavaScript.Parser (readJs, parse, JSNode(..))
 import Text.Jasmine.Pretty
 import qualified Blaze.ByteString.Builder as BB
 import qualified Data.ByteString.Lazy as LB
@@ -19,13 +19,13 @@
 minifym :: LB.ByteString -> Either String LB.ByteString
 minifym s = case parse' s of
              Left msg -> Left (show msg)
-             Right p  -> Right $ BB.toLazyByteString $ renderJS p                   
+             Right p  -> Right $ BB.toLazyByteString $ renderJS p
 
 minifyBb :: LB.ByteString -> Either String BB.Builder
 minifyBb s = case parse' s  of
              Left msg -> Left (show msg)
              Right p  -> Right (renderJS p)
-             
+
 minify :: LB.ByteString -> LB.ByteString
 --minify s = BB.toLazyByteString $ renderJS $ readJs s
 minify s = BB.toLazyByteString $ renderJS $ readJs (lbToStr s)
@@ -35,11 +35,13 @@
 
 minifyFile :: FilePath -> IO LB.ByteString
 minifyFile filename =
-  do 
+  do
      x <- LB.readFile (filename)
      return $ minify x
-    
-parse' :: S8.ByteString -> Either ParseError JSNode
+
+--parse' :: S8.ByteString -> Either ParseError JSNode
+parse'
+  :: S8.ByteString -> Either String JSNode
 parse' input = parse (lbToStr input) "src"
 
 lbToStr :: S8.ByteString -> [Char]
@@ -48,5 +50,5 @@
 _strToLb :: String -> S8.ByteString
 _strToLb str = S8.pack str
 
-     
--- EOF    
+
+-- EOF
diff --git a/Text/Jasmine/Pretty.hs b/Text/Jasmine/Pretty.hs
--- a/Text/Jasmine/Pretty.hs
+++ b/Text/Jasmine/Pretty.hs
@@ -6,8 +6,7 @@
 import Data.Char
 import Data.List
 import Data.Monoid (Monoid, mappend, mempty, mconcat)
--- import Text.Jasmine.Parse
-import Language.JavaScript.Parser
+import Language.JavaScript.Parser (JSNode(..),Node(..),tokenPosnEmpty,readJs,CommentAnnotation(..),TokenPosn(..))
 import qualified Blaze.ByteString.Builder as BB
 import qualified Blaze.ByteString.Builder.Char.Utf8 as BS
 import qualified Data.ByteString.Lazy as LB
@@ -42,112 +41,133 @@
 -- ---------------------------------------------------------------------
 
 renderJS :: JSNode -> BB.Builder
-renderJS (NS node _) = rn node
+renderJS (NN node    ) = rn node
+renderJS (NT node _ _) = rn node
 
 rn :: Node -> BB.Builder
-rn (JSEmpty l)             = (renderJS l)
+--rn (JSEmpty l)             = (renderJS l)
+
+-- Terminals
 rn (JSIdentifier s)        = text s
 rn (JSDecimal i)           = text i
-rn (JSOperator s)          = text s
-rn (JSExpression xs)       = rJS xs
+rn (JSLiteral l)           = (text l)
+rn (JSHexInteger i)        = (text $ show i) -- TODO: need to tweak this
+rn (JSStringLiteral s l)   = empty <> (char s) <> (text l) <> (char s)
+rn (JSRegEx s)             = (text s)
 
---rn (JSSourceElements xs)   = rJS (map fixBlock $ fixSourceElements xs)
-rn (JSSourceElements xs)   = rJS (fixSourceElements $ map fixBlock xs)
+-- Non Terminals
+rn (JSOperator x)          = renderJS x
+rn (JSExpression xs)       = rJS $ fixNew xs
 
+
+--rn (JSSourceElements xs)   = rJS (fixSourceElements $ map fixBlock xs)
+
 --rn (JSSourceElementsTop xs)= rJS (fixTop $ map fixBlock $ fixSourceElements xs)
 rn (JSSourceElementsTop xs)= rJS (fixTop $ fixSourceElements $ map fixBlock xs)
 
 
-rn (JSFunction s p xs)     = (text "function") <+> (renderJS s) <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)
-rn (JSFunctionBody xs)     = (text "{") <> (rJS xs) <> (text "}")
-rn (JSFunctionExpression [] p xs) = (text "function")             <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)
-rn (JSFunctionExpression  s p xs) = (text "function") <+> (rJS s) <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)
-rn (JSArguments xs)        = (text "(") <> (commaListList $ map fixLiterals xs) <> (text ")")
+--rn (JSFunction s p xs)     = (text "function") <+> (renderJS s) <> (text "(") <> (rJS p) <> (text ")") <> (renderJS xs)
+rn (JSFunction _f s _lb p _rb x) = (text "function") <+> (renderJS s) <> (text "(") <> (rJS $ fixNew p) <> (text ")") <> (renderJS $ fixFnBlock x)
 
-rn (JSBlock x)             = (text "{") <> (renderJS x) <> (text "}")
+-- rn (JSFunctionBody xs)     = (text "{") <> (rJS xs) <> (text "}")
 
-rn (JSIf c (NS (JSLiteral ";") _))= (text "if") <> (text "(") <> (renderJS c) <> (text ")")
-rn (JSIf c t)                     = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (renderJS $ fixBlock t)
+--rn (JSFunctionExpression [] p xs) = (text "function")             <> (text "(") <> (rJS p) <> (text ")") <> (renderJS xs)
+--rn (JSFunctionExpression  s p xs) = (text "function") <+> (rJS s) <> (text "(") <> (rJS p) <> (text ")") <> (renderJS xs)
+rn (JSFunctionExpression _f [] _lb p _rb x) = (text "function")             <> (text "(") <> (rJS $ fixNew p) <> (text ")") <> (renderJS $ fixFnBlock x)
+rn (JSFunctionExpression _f s  _lb p _rb x) = (text "function") <+> (rJS s) <> (text "(") <> (rJS $ fixNew p) <> (text ")") <> (renderJS $ fixFnBlock x)
 
-rn (JSIfElse c t (NS (JSLiteral ";") _)) = (text "if") <> (text "(") <> (renderJS c) <> (text ")")  <> (renderJS t)
-                                   <> (text "else")
-rn (JSIfElse c t e)        = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (renderJS t)
-                                   <> (text "else") <> (spaceOrBlock $ fixBlock e)
-rn (JSMemberDot xs y)        = (rJS xs) <> (text ".") <> (renderJS y)
-rn (JSMemberSquare xs x)   = (rJS xs) <> (text "[") <> (renderJS x) <> (text "]")
-rn (JSLiteral l)           = (text l)
-rn (JSStringLiteral s l)   = empty <> (char s) <> (text l) <> (char s)
-rn (JSUnary l  )           = text l
-rn (JSArrayLiteral xs)     = (text "[") <> (rJS xs) <> (text "]")
+--rn (JSArguments xs ) = (text "(") <> (rJSList $ map fixLiterals xs) <> (text ")")
+rn (JSArguments _lb xs _rb) = (text "(") <> (rJS $ fixLiterals $ fixNew xs) <> (text ")")
 
-rn (JSBreak [] [])            = (text "break")
-rn (JSBreak [] _xs)           = (text "break") -- <> (rJS xs) -- <> (text ";")
-rn (JSBreak is _xs)           = (text "break") <+> (rJS is) -- <> (rJS xs)
+rn (JSBlock lb xs rb)            = (rJS lb) <> (rJS xs) <> (rJS rb)
 
-rn (JSCallExpression "()" xs) = (rJS xs)
-rn (JSCallExpression   t  xs) = (char $ head t) <> (rJS xs) <> (if ((length t) > 1) then (char $ last t) else empty)
+rn (JSIf _i _lb c _rb [(NT (JSLiteral ";") _ _)] [])     = (text "if") <> (text "(") <> (renderJS c) <> (text ")")
+--rn (JSIf _i _lb c _rb t                        [])     = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (renderJS $ fixBlock t)
 
+rn (JSIf _i _lb c _rb t                        [])     = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (rJS $ fixSourceElements $ map fixBlock t)
+
+rn (JSIf _i _lb c _rb t [_e,(NT (JSLiteral ";") _ _)]) = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (rJS $ fixIfBlock t)
+                                                         <> (text "else")
+rn (JSIf _i _lb c _rb t [_e,e])                        = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (rJS $ fixIfElse $ fixSourceElements t)
+                                                         <> (text "else") <> (spaceOrBlock $ fixBlock e)
+
+
+
+rn (JSMemberDot xs _d y)          = (rJS xs) <> (text ".") <> (renderJS y)
+rn (JSMemberSquare xs _lb x _rb)  = (rJS xs) <> (text "[") <> (renderJS x) <> (text "]")
+rn (JSUnary l _s )                = text l
+rn (JSArrayLiteral _lb xs _rb)    = (text "[") <> (rJS xs) <> (text "]")
+
+rn (JSBreak _b [] as)           = (text "break") -- <> (renderJS as)
+rn (JSBreak _b is as)           = (text "break") <+> (rJS $ fixSourceElements $ map fixFnBlock is) -- <> (renderJS as)
+
+rn (JSCallExpression "()" _os xs _cs) = (rJS xs)
+rn (JSCallExpression   t  _os xs _cs) = (char $ head t) <> (rJS xs) <> (if ((length t) > 1) then (char $ last t) else empty)
+
+
 -- No space between 'case' and string literal. TODO: what about expression in parentheses?
 --rn (JSCase (JSExpression [JSStringLiteral sepa s]) xs) = (text "case") <> (renderJS (JSStringLiteral sepa s))
-rn (JSCase (NS (JSExpression [(NS (JSStringLiteral sepa s) s1)]) _) xs) = (text "case") <> (renderJS (NS (JSStringLiteral sepa s) s1))
-                                                               <> (char ':') <> (renderJS xs)
-rn (JSCase e xs)           = (text "case") <+> (renderJS e) <> (char ':') <> (renderJS xs) -- <> (text ";");
+rn (JSCase _ca (NN (JSExpression [(NT (JSStringLiteral sepa s) s1 c1)])) _c xs) =
+  (text "case") <> (renderJS (NT (JSStringLiteral sepa s) s1 c1)) <> (char ':') <> (rJS $ fixSourceElements $ map fixFnBlock xs)
 
-rn (JSCatch i [] s)        = (text "catch") <> (char '(') <> (renderJS i) <>  (char ')') <> (renderJS s)
-rn (JSCatch i c s)         = (text "catch") <> (char '(') <> (renderJS i) <>
-                                   (text " if ") <> (rJS c) <> (char ')') <> (renderJS s)
+rn (JSCase _ca e _c xs)           = (text "case") <+> (renderJS e) <> (char ':') <> (rJS $ fixSourceElements $ map fixFnBlock xs) -- <> (text ";");
 
-rn (JSContinue is)         = (text "continue") <> (rJS is) -- <> (char ';')
-rn (JSDefault xs)          = (text "default") <> (char ':') <> (renderJS xs)
-rn (JSDoWhile s e _ms)     = (text "do") <> (renderJS s) <> (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS ms)
+
+rn (JSCatch _c _lb i [] _rb s)  = (text "catch") <> (char '(') <> (renderJS i) <>  (char ')') <> (renderJS $ fixFnBlock s)
+rn (JSCatch _c _lb i  c _rb s)  = (text "catch") <> (char '(') <> (renderJS i) <>
+                                  (text " if ") <> (rJS $ tail c) <> (char ')') <> (renderJS $ fixFnBlock s)
+
+rn (JSContinue _c is _as)  = (text "continue") <> (rJS is) -- <> (char ';')
+rn (JSDefault _d _c xs)    = (text "default") <> (char ':') <> (rJS $ fixSourceElements xs)
+
+rn (JSDoWhile _d s _w _lb e _rb as)     = (text "do") <> (renderJS $ fixFnBlock s) <> (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS as)
+
+
 --rn (JSElementList xs)      = rJS xs
-rn (JSElision xs)          = (char ',') <> (rJS xs)
-rn (JSExpressionBinary o e1 e2) = (rJS e1) <> (text o) <> (rJS e2)
---rn (JSExpressionBinary o e1 e2) = (text o) <> (rJS e1) <> (rJS e2)
-rn (JSExpressionParen e)        = (char '(') <> (renderJS e) <> (char ')')
-rn (JSExpressionPostfix o e)    = (rJS e) <> (text o)
-rn (JSExpressionTernary c v1 v2) = (rJS c) <> (char '?') <> (rJS v1) <> (char ':') <> (rJS v2)
-rn (JSFinally b)                 = (text "finally") <> (renderJS b)
+--rn (JSElision xs)          = (char ',') <> (rJS xs)
+rn (JSElision x)          = renderJS x
 
-rn (JSFor e1 e2 e3 s)            = (text "for") <> (char '(') <> (commaList e1) <> (char ';')
+rn (JSExpressionBinary o e1 _op e2) = (rJS e1) <> (text o) <> (rJS e2)
+rn (JSExpressionParen _lp e _rp)    = (char '(') <> (renderJS e) <> (char ')')
+rn (JSExpressionPostfix o e _op)    = (rJS e) <> (text o)
+rn (JSExpressionTernary c _q v1 _c v2) = (rJS $ fixNew c) <> (char '?') <> (rJS $ fixNew v1) <> (char ':') <> (rJS $ fixNew v2)
+rn (JSFinally _f b)                    = (text "finally") <> (renderJS $ fixFnBlock b)
+
+rn (JSFor _f _lb e1 _s1 e2 _s2 e3 _rb s) = (text "for") <> (char '(') <> (rJS e1) <> (char ';')
                                          <> (rJS e2) <> (char ';') <> (rJS e3) <> (char ')') <> (renderJS $ fixBlock s)
-rn (JSForIn e1 e2 s)             = (text "for") <> (char '(') <> (rJS e1) <+> (text "in")
+
+rn (JSForIn _f _lb e1 _i e2 _rb s)       = (text "for") <> (char '(') <> (rJS e1) <+> (text "in")
                                          <+> (renderJS e2) <> (char ')') <> (renderJS $ fixBlock s)
-rn (JSForVar e1 e2 e3 s)         = (text "for") <> (char '(') <> (text "var") <+> (commaList e1) <> (char ';')
+rn (JSForVar _f _lb _v e1 _s1 e2 _s3 e3 _rb s) = (text "for") <> (char '(') <> (text "var") <+> (rJS e1) <> (char ';')
                                          <> (rJS e2) <> (char ';') <> (rJS e3) <> (char ')') <> (renderJS $ fixBlock s)
-rn (JSForVarIn e1 e2 s)          = (text "for") <> (char '(') <> (text "var") <+> (renderJS e1) <+> (text "in")
+rn (JSForVarIn _f _lb _v e1 _i e2 _rb s) = (text "for") <> (char '(') <> (text "var") <+> (renderJS e1) <+> (text "in")
                                          <+> (renderJS e2) <> (char ')') <> (renderJS $ fixBlock s)
 
-rn (JSHexInteger i)              = (text $ show i) -- TODO: need to tweak this
-rn (JSLabelled l v)              = (renderJS l) <> (text ":") <> (rJS $ fixSourceElements [fixBlock v])
-rn (JSObjectLiteral xs)          = (text "{") <> (commaList xs) <> (text "}")
-rn (JSPropertyAccessor s n ps b) = (text s) <+> (renderJS n) <> (char '(') <> (rJS ps) <> (text ")") <> (renderJS b)
-rn (JSPropertyNameandValue n vs) = (renderJS n) <> (text ":") <> (rJS vs)
-rn (JSRegEx s)                   = (text s)
+rn (JSLabelled l _c v)           = (renderJS l) <> (text ":") <> (rJS $ fixSourceElements [fixBlock v])
 
-rn (JSReturn [])                 = (text "return")
-rn (JSReturn [(NS (JSLiteral ";") _)])    = (text "return;")
-rn (JSReturn xs)                 = (text "return") <> (if (spaceNeeded xs) then (text " ") else (empty)) <> (rJS $ fixSourceElements xs)
+rn (JSObjectLiteral _lb xs _rb)  = (text "{") <> (rJS xs) <> (text "}")
+rn (JSPropertyAccessor s n _lb1 ps _rb1 b) = (renderJS s) <+> (renderJS n) <> (char '(') <> (rJS ps) <> (text ")") <> (renderJS $ fixFnBlock b)
+rn (JSPropertyNameandValue n _c vs) = (renderJS n) <> (text ":") <> (rJS $ fixNew vs)
 
-rn (JSThrow e)                   = (text "throw") <+> (renderJS e)
+rn (JSReturn _r []                         _as) = (text "return")
+rn (JSReturn _r [(NT (JSLiteral ";") _ _)] _as) = (text "return;++foobar+will_never_happen++") -- ++AZ++ get rid of this
+rn (JSReturn _r xs                          as) = (text "return") <> (if (spaceNeeded xs) then (text " ") else (empty)) <> (rJS $ fixSourceElements xs) -- <> (renderJS as)
 
-rn (JSStatementBlock x)          = (text "{") <> (renderJS x) <> (text "}")
+rn (JSThrow _t e)                 = (text "throw") <+> (renderJS $ fixBlock e)
 
-rn (JSStatementList xs)          = rJS (fixSourceElements $ map fixBlock xs)
+rn (JSSwitch _s _lb e _rb x)     = (text "switch") <> (char '(') <> (renderJS e) <> (char ')') <> (renderJS $ fixFnBlock x)
 
-rn (JSSwitch e xs)               = (text "switch") <> (char '(') <> (renderJS e) <> (char ')') <>
-                                         (char '{') <> (rJS $ fixSemis xs)  <> (char '}')
-rn (JSTry e xs)                  = (text "try") <> (renderJS e) <> (rJS xs)
+rn (JSTry _t e xs)               = (text "try") <> (renderJS $ fixFnBlock e) <> (rJS xs)
 
 rn (JSVarDecl i [])              = (renderJS i)
-rn (JSVarDecl i xs)              = (renderJS i) <> (text "=") <> (rJS xs)
+rn (JSVarDecl i xs)              = (renderJS i) <> (rJS $ fixNew xs)
 
-rn (JSVariables kw xs)           = (text kw) <+> (commaList xs)
+rn (JSVariables kw xs _as)       = (renderJS kw) <+> (rJS xs)
 
-rn (JSWhile e (NS (JSLiteral ";") _))   = (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS s)
-rn (JSWhile e s)                 = (text "while") <> (char '(') <> (renderJS e) <> (char ')') <> (renderJS s)
+rn (JSWhile _w _lb e _rb (NT (JSLiteral ";") _ _)) = (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS s)
+rn (JSWhile _w _lb e _rb s)                        = (text "while") <> (char '(') <> (renderJS e) <> (char ')') <> (renderJS $ fixFnBlock s)
 
-rn (JSWith e s)                  = (text "with") <> (char '(') <> (renderJS e) <> (char ')') <> (rJS s)
+rn (JSWith _w _lb e _rb s)                  = (text "with") <> (char '(') <> (renderJS e) <> (char ')') <> (rJS s)
 
 -- Helper functions
 rJS :: [JSNode] -> BB.Builder
@@ -155,21 +175,21 @@
 
 commaList :: [JSNode] -> BB.Builder
 commaList [] = empty
-commaList xs = (hcat $ (punctuate comma (toDoc xs') ++ trail))
-  where
-    -- (xs', trail) = if (last xs == JSLiteral ",") then (init xs, [comma]) else (xs,[])
-    (xs', trail) = if (x' == JSLiteral ",") then (init xs, [comma]) else (xs,[])
-    (NS x' _) = last xs
+commaList xs = rJS xs
 
-commaListList :: [[JSNode]] -> BB.Builder
-commaListList xs = (hcat $ punctuate comma $ map rJS xs)
+extractNode :: JSNode -> Node
+extractNode (NT x _ _) = x
+extractNode (NN x    ) = x
 
+--commaListList :: [[JSNode]] -> BB.Builder
+--commaListList xs = (hcat $ punctuate comma $ map rJS xs)
+
 toDoc :: [JSNode] -> [BB.Builder]
 toDoc xs = map renderJS xs
 
 spaceOrBlock :: JSNode -> BB.Builder
-spaceOrBlock (NS (JSBlock xs) _) = rn (JSBlock xs)
-spaceOrBlock (NS (JSStatementBlock xs) _) = rn (JSStatementBlock xs)
+spaceOrBlock (NN (JSBlock lb xs rb)) = rn (JSBlock lb xs rb)
+--spaceOrBlock (NN (JSStatementBlock lb xs rb)) = rn (JSStatementBlock lb xs rb)
 spaceOrBlock x            = (text " ") <> (renderJS x)
 
 
@@ -187,48 +207,56 @@
 fixTop [] = []
 fixTop xs = if (n == (JSLiteral ";")) then (init xs) else (xs)
   where
-    (NS n _) = last xs
+    n = extractNode $ last xs
 
+-- The "new" literal always need a space after it
+fixNew :: [JSNode] -> [JSNode]
+fixNew []                               = []
+fixNew ((NT (JSLiteral "new") p cs):xs) = (NT (JSLiteral "new ") p cs) : fixNew xs
+fixNew (x                          :xs) = x                            : fixNew xs
+
 -- Fix semicolons in output of sourceelements and statementlist
 
 fixSourceElements :: [JSNode] -> [JSNode]
-fixSourceElements xs = fixSemis $ myFix xs
+fixSourceElements xs = fixSemis $ myFix $ fixNew xs
 
 myFix :: [JSNode] -> [JSNode]
 myFix []      = []
 
+
 -- Sort out empty IF statements
-myFix ((NS (JSIf c (NS (JSStatementBlock (NS (JSStatementList []) s1)) s2)) _s3):xs) = (NS (JSIf c (NS (JSLiteral "") s1)) s2) : myFix (xs)
+--myFix ((NN (JSIf i lb c rb  (NN (JSStatementBlock _lb (NN (JSStatementList []) ) _rb) ) e)):xs) = (NN (JSIf i lb c rb (NT (JSLiteral "") tokenPosnEmpty []) e) ) : myFix (xs)
 
 myFix [x]     = [x]
 
-myFix (x:(NS (JSFunction v1 v2 v3) s1):xs)  = x : (NS (JSLiteral "\n") s1) : myFix ((NS (JSFunction v1 v2 v3) s1) : xs)
+myFix (x:(NN (JSFunction v1 v2 v3 v4 v5 v6) ):xs)  = x : (NT (JSLiteral "\n") tokenPosnEmpty []) : myFix ((NN (JSFunction v1 v2 v3 v4 v5 v6) ) : xs)
+
 -- Messy way, but it works, until the 3rd element arrives ..
 -- TODO: JSStatementBlock.  Damn.
-myFix ((NS (JSExpression x) s1):(NS (JSExpression y) s2):xs) = (NS (JSExpression x) s1):(NS (JSLiteral ";") s1):myFix ((NS (JSExpression y) s2):xs)
-myFix ((NS (JSExpression x) s1):(NS (JSBlock y) s2):xs)      = (NS (JSExpression x) s1):(NS (JSLiteral ";") s1):myFix ((NS (JSBlock y) s2):xs)
-myFix ((NS (JSBlock x) s1)     :(NS (JSBlock y) s2):xs)      = (NS (JSBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSBlock y) s2):xs)
-myFix ((NS (JSBlock x) s1)     :(NS (JSExpression y) s2):xs) = (NS (JSBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSExpression y) s2):xs)
+myFix ((NN (JSExpression x) ):(NN (JSExpression y) ):xs) = (NN (JSExpression x) ):(NT (JSLiteral ";") tokenPosnEmpty []):myFix ((NN (JSExpression y) ):xs)
+myFix ((NN (JSExpression x) ):(NN (JSBlock l y r) ):xs)  = (NN (JSExpression x) ):(NT (JSLiteral ";") tokenPosnEmpty []):myFix ((NN (JSBlock l y r) ):xs)
+myFix ((NN (JSBlock x1 x2 x3) )     :(NN (JSBlock y1 y2 y3) ):xs)      = (NN (JSBlock x1 x2 x3) )     :(NT (JSLiteral ";") tokenPosnEmpty []):myFix ((NN (JSBlock y1 y2 y3) ):xs)
+myFix ((NN (JSBlock x1 x2 x3) )     :(NN (JSExpression y) ):xs) = (NN (JSBlock x1 x2 x3) )     :(NT (JSLiteral ";") tokenPosnEmpty []):myFix ((NN (JSExpression y) ):xs)
 
-myFix ((NS (JSExpression x) s1):(NS (JSStatementBlock y) s2):xs)      =
-  (NS (JSExpression x) s1):(NS (JSLiteral ";") s1):myFix ((NS (JSStatementBlock y) s2):xs)
-myFix ((NS (JSStatementBlock x) s1)     :(NS (JSStatementBlock y) s2):xs)      =
-  (NS (JSStatementBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSStatementBlock y) s2):xs)
-myFix ((NS (JSStatementBlock x) s1)     :(NS (JSExpression y) s2):xs) =
-  (NS (JSStatementBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSExpression y) s2):xs)
+-- myFix ((NN (JSExpression x) ):(NN (JSStatementBlock y1 y2 y3) ):xs)      =
+--   (NN (JSExpression x) ):(NT (JSLiteral ";") tokenPosnEmpty []):myFix ((NN (JSStatementBlock y1 y2 y3) ):xs)
+-- myFix ((NN (JSStatementBlock x1 x2 x3) )     :(NN (JSStatementBlock y1 y2 y3) ):xs)      =
+--   (NN (JSStatementBlock x1 x2 x3) )     :(NT (JSLiteral ";") tokenPosnEmpty []):myFix ((NN (JSStatementBlock y1 y2 y3) ):xs)
+-- myFix ((NN (JSStatementBlock x1 x2 x3) )     :(NN (JSExpression y) ):xs) =
+--   (NN (JSStatementBlock x1 x2 x3) )     :(NT (JSLiteral ";") tokenPosnEmpty []):myFix ((NN (JSExpression y) ):xs)
 
 -- Merge adjacent variable declarations, but only of the same type
-myFix ((NS (JSVariables t1 x1s) s1):(NS (JSLiteral l) s2):(NS (JSVariables t2 x2s) s3):xs)
-  | t1 == t2 = myFix ((NS (JSVariables t1 (x1s++x2s)) s1):xs)
-  | otherwise = (NS (JSVariables t1 x1s) s1):myFix ((NS (JSLiteral l) s2):(NS (JSVariables t2 x2s) s3):xs)
+myFix ((NN (JSVariables t1 x1s a1) ):(NT (JSLiteral l) s2 c2):(NN (JSVariables t2 x2s a2) ):xs)
+  | extractNode t1 == extractNode t2 = myFix ((NN (JSVariables t1 (x1s++[(NT (JSLiteral ",") tokenPosnEmpty [])]++x2s) a2) ):xs)
+  | otherwise = (NN (JSVariables t1 x1s a1) ):myFix ((NT (JSLiteral l) s2 c2):(NN (JSVariables t2 x2s a2) ):xs)
 
-myFix ((NS (JSVariables t1 x1s) s1):(NS (JSVariables t2 x2s) s2):xs)
-  | t1 == t2 = myFix ((NS (JSVariables t1 (x1s++x2s)) s1):xs)
-  | otherwise = (NS (JSVariables t1 x1s) s1):myFix ((NS (JSVariables t2 x2s) s2):xs)
+myFix ((NN (JSVariables t1 x1s a1) ):(NN (JSVariables t2 x2s a2) ):xs)
+  | extractNode t1 == extractNode t2 = myFix ((NN (JSVariables t1 (x1s++[(NT (JSLiteral ",") tokenPosnEmpty [])]++x2s) a2) ):xs)
+  | otherwise = (NN (JSVariables t1 x1s a1) ):myFix ((NN (JSVariables t2 x2s a2) ):xs)
 
 -- Merge adjacent semi colons
-myFix ((NS (JSLiteral ";") s1):(NS (JSLiteral ";") _s2):xs)  = myFix ((NS (JSLiteral ";") s1):xs)
-myFix ((NS (JSLiteral ";") s1):(NS (JSLiteral "" ) _s2):xs)  = myFix ((NS (JSLiteral "") s1):xs)
+myFix ((NT (JSLiteral ";") s1 c1):(NT (JSLiteral ";") _s2 _c2):xs)  = myFix ((NT (JSLiteral ";") s1 c1):xs)
+myFix ((NT (JSLiteral ";") s1 c1):(NT (JSLiteral "" ) _s2 _c2):xs)  = myFix ((NT (JSLiteral "" ) s1 c1):xs)
 
 
 myFix (x:xs)  = x : myFix xs
@@ -237,57 +265,82 @@
 fixLiterals :: [JSNode] -> [JSNode]
 fixLiterals [] = []
 -- Old version
-fixLiterals ((NS (JSStringLiteral d1 s1) ss1):(NS (JSExpressionBinary "+" [(NS (JSStringLiteral d2 s2) ss2)] r) ss3):xs)
-       | d1 == d2 = fixLiterals ((NS (JSStringLiteral d1 (s1++s2)) ss1):(r++xs))
-       | otherwise = (NS (JSStringLiteral d1 s1) ss1):fixLiterals ((NS (JSExpressionBinary "+" [(NS (JSStringLiteral d2 s2) ss2)] r) ss3):xs)
+fixLiterals ((NT (JSStringLiteral d1 s1) ss1 c1):(NN (JSExpressionBinary "+" [(NT (JSStringLiteral d2 s2) ss2 c2)] op r) ):xs)
+       | d1 == d2 = fixLiterals ((NT (JSStringLiteral d1 (s1++s2)) ss1 c1):(r++xs))
+       | otherwise = (NT (JSStringLiteral d1 s1) ss1 c1):fixLiterals ((NN (JSExpressionBinary "+" [(NT (JSStringLiteral d2 s2) ss2 c2)] op r) ):xs)
 
-fixLiterals ((NS (JSExpressionBinary "+" [(NS (JSStringLiteral d1 s1) ss2)] [(NS (JSStringLiteral d2 s2) ss3)]) ss4):xs)
-       | d1 == d2 = fixLiterals ((NS (JSStringLiteral d1 (s1++s2)) ss2):xs)
-       | otherwise = (NS (JSExpressionBinary "+" [(NS (JSStringLiteral d1 s1) ss2)] [(NS (JSStringLiteral d2 s2) ss3)]) ss4):fixLiterals xs
+fixLiterals ((NN (JSExpressionBinary "+" [(NT (JSStringLiteral d1 s1) ss2 c2)] o1 [(NT (JSStringLiteral d2 s2) ss3 c3)]) ):xs)
+       | d1 == d2 = fixLiterals ((NT (JSStringLiteral d1 (s1++s2)) ss2 c2):xs)
+       | otherwise = (NN (JSExpressionBinary "+" [(NT (JSStringLiteral d1 s1) ss2 c2)] o1 [(NT (JSStringLiteral d2 s2) ss3 c3)]) ):fixLiterals xs
 
 fixLiterals (x:xs) = x:fixLiterals xs
 
 -- Sort out Semicolons
 fixSemis :: [JSNode] -> [JSNode]
 --fixSemis xs = fixSemis' $ filter (\x -> x /= JSLiteral ";" && x /= JSLiteral "") xs
-fixSemis xs = fixSemis' $ filter (\(NS x _) -> x /= JSLiteral ";" && x /= JSLiteral "") xs
+fixSemis xs = fixSemis' $ stripSemis xs
 
+stripSemis :: [JSNode] -> [JSNode]
+stripSemis xs = filter (\x -> (extractNode x) /= JSLiteral ";" && (extractNode x) /= JSLiteral "") xs
+
 fixSemis' :: [JSNode] -> [JSNode]
 fixSemis' [] = []
-fixSemis' [(NS (JSContinue [(NS (JSLiteral ";") _)]) s2)] = [(NS (JSContinue []) s2)]
+fixSemis' [(NN (JSContinue c [(NT (JSLiteral ";") _ _)] as) )] = [(NN (JSContinue c [] as) )]
 fixSemis' [x] = [x]
-fixSemis' ((NS (JSIf c (NS (JSReturn [(NS (JSLiteral ";") s1)]) s2) ) s3):xs)  =
-  (NS (JSIf c (NS (JSReturn [(NS (JSLiteral ";") s1)]) s2)) s3):(fixSemis' xs)
-fixSemis' ((NS (JSIf c (NS (JSContinue [(NS (JSLiteral ";") s1)]) s2) ) s3):xs)    =
-  (NS (JSIf c (NS (JSContinue [(NS (JSLiteral ";") s1)]) s2)) s3):(fixSemis' xs)
-fixSemis' (x:(NS (JSLiteral "\n") s1):xs) = x:(NS (JSLiteral "\n") s1):(fixSemis' xs) -- TODO: is this needed?
-fixSemis' ((NS (JSCase e1 ((NS (JSStatementList []) s1))) s2):(NS (JSCase e2 x) s3):xs) =
-  (NS (JSCase e1 ((NS (JSStatementList []) s1))) s2):fixSemis' ((NS (JSCase e2 x) s3):xs)
-fixSemis' (x:xs) = x:(NS (JSLiteral ";") SpanEmpty):fixSemis' xs
 
--- Remove extraneous braces around blocks
-fixBlock :: JSNode -> JSNode
+fixSemis' ((NN (JSIf i lb c rb [NN (JSBlock [NT (JSLiteral "{") p1 cs1] [] [NT (JSLiteral "}") p2 cs2])] []) ):xs)  =
+           (NN (JSIf i lb c rb [NN (JSBlock [NT (JSLiteral "{") p1 cs1] [] [NT (JSLiteral "}") p2 cs2])] []) ):(fixSemis' xs)
 
-fixBlock (NS (JSBlock          (NS (JSStatementList []) s1) ) _) = (NS (JSLiteral ";") s1)
-fixBlock (NS (JSStatementBlock (NS (JSStatementList []) s1) ) _) = (NS (JSLiteral ";") s1)
+fixSemis' ((NN (JSIf i lb c rb [(NT (JSLiteral ";") s1 c1)] []) ):xs)  =
+           (NN (JSIf i lb c rb [(NT (JSLiteral ";") s1 c1)] []) ):(fixSemis' xs)
 
-fixBlock (NS (JSBlock          (NS (JSStatementList [x]) _) ) _) = fixBlock x
-fixBlock (NS (JSStatementBlock (NS (JSStatementList [x]) _) ) _) = fixBlock x
+fixSemis' ((NN (JSIf i lb c rb [(NN (JSReturn r [(NT (JSLiteral ";") s1 c1)] as) )] e) ):xs)  =
+           (NN (JSIf i lb c rb [(NN (JSReturn r [(NT (JSLiteral ";") s1 c1)] as) )] e) ):(fixSemis' xs)
 
-fixBlock (NS (JSBlock (NS (JSStatementList xs) s1) ) s2) =
-  fixBlock' (NS (JSBlock (NS (JSStatementList (fixSourceElements xs)) s1)) s2)
+fixSemis' ((NN (JSIf i lb c rb [(NN (JSContinue co [(NT (JSLiteral ";") s1 c1)] as) )] e) ):xs)    =
+           (NN (JSIf i lb c rb [(NN (JSContinue co [(NT (JSLiteral ";") s1 c1)] as) )] e) ):(fixSemis' xs)
 
-fixBlock (NS (JSStatementBlock (NS (JSStatementList xs) s1) ) s2) =
-  fixBlock' (NS (JSStatementBlock (NS (JSStatementList (fixSourceElements xs)) s1)) s2)
+fixSemis' (x:(NT (JSLiteral "\n") s1 c1):xs) = x:(NT (JSLiteral "\n") s1 c1):(fixSemis' xs) -- TODO: is this needed?
 
-fixBlock x = x
+fixSemis' ((NN (JSCase ca1 e1 c1 [] ) ):(NN (JSCase ca2 e2 c2 x) ):xs) =
+           (NN (JSCase ca1 e1 c1 [] ) ):fixSemis' ((NN (JSCase ca2 e2 c2 x) ):xs)
 
-fixBlock' :: JSNode -> JSNode
-fixBlock' (NS (JSBlock          (NS (JSStatementList [x]) _)) _) = x
-fixBlock' (NS (JSStatementBlock (NS (JSStatementList [x]) _)) _) = x
---fixBlock' (JSBlock (JSStatementList [x,JSLiteral ""])) = x -- TODO: fix parser to not emit this case
-fixBlock' x = x
+fixSemis' (x:xs) = x:(NT (JSLiteral ";") tokenPosnEmpty []):fixSemis' xs
 
+fixIfElse :: [JSNode] -> [JSNode]
+fixIfElse [(NN (JSBlock lb xs rb))] = [(NN (JSBlock lb (fixSourceElements xs) rb))]
+fixIfElse [x] = [(NN (JSBlock [(NT (JSLiteral "{") tokenPosnEmpty [])] (fixSourceElements [x]) [(NT (JSLiteral "}") tokenPosnEmpty [])]))]
+fixIfElse xs = xs
+
+fixFnBlock :: JSNode -> JSNode
+-- fixFnBlock (NN (JSBlock lb [] rb)) = (NT (JSLiteral ";") tokenPosnEmpty [])
+fixFnBlock (NN (JSBlock lb xs rb)) = (NN (JSBlock lb (fixSourceElements xs) rb))
+fixFnBlock x = fixBlock x
+
+fixIfBlock :: [JSNode] -> [JSNode]
+fixIfBlock xs =
+  case xs' of
+    [(NT (JSLiteral ";") p cs)]   -> [] -- rely on fixSemis to add this again [(NT (JSLiteral ";") p cs)]
+    [(NN (JSBlock lb [] rb))]     -> [] -- rely on fixSemis to add this again [(NT (JSLiteral ";") tokenPosnEmpty [])]
+    -- [(NN (JSBlock lb [y] rb))]    -> [fixBlock y]
+    [(NN (JSBlock lb x2s rb))]    -> [(NN (JSBlock lb ((fixSourceElements $ map fixBlock x2s)) rb))]
+    [x]                           -> fixSourceElements [x]
+  where xs' = stripSemis xs
+
+-- Remove extraneous braces around blocks
+fixBlock :: JSNode -> JSNode
+
+fixBlock (NN (JSBlock lb xs rb)) =
+  case xs' of
+    []  -> (NT (JSLiteral ";") tokenPosnEmpty [])
+    -- [(NN (JSExpression [y]))] -> fixBlock (NN (JSExpression [y]))
+    -- [(NN (JSExpression xs))]  -> (NN (JSBlock lb (fixSourceElements $ map fixBlock xs') rb))
+    [x] -> fixBlock x
+    _   -> (NN (JSBlock lb (fixSourceElements $ map fixBlock xs') rb))
+  where xs' = stripSemis xs
+
+fixBlock x = x
+
 -- A space is needed if this expression starts with an identifier etc, but not if with a '('
 spaceNeeded :: [JSNode] -> Bool
 spaceNeeded xs =
@@ -295,7 +348,7 @@
    -- str = show $ rJS xs
     str = LB.unpack $ BB.toLazyByteString $ rJS xs
   in
-   (str /= []) && head str /= (fromIntegral $ ord '(')
+   head str /= (fromIntegral $ ord '(')
 
 -- ---------------------------------------------------------------------
 -- Test stuff
@@ -305,24 +358,23 @@
 
 --readJs "{{{}}}"
 _case0 :: JSNode
-_case0 = NS (JSSourceElementsTop [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 3})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 2}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})
-
-_case01 :: [JSNode]
-_case01 = [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 3})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 2}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})]
+_case0 = undefined --
 
 -- readJs "if(x){}{a=2}"
 _case1 :: JSNode
-_case1 = NS (JSSourceElementsTop [NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NS (JSStatementBlock (NS (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 1, span_column = 9}),NS (JSOperator "=") (SpanPoint {span_filename = "", span_row = 1, span_column = 10}),NS (JSDecimal "2") (SpanPoint {span_filename = "", span_row = 1, span_column = 11})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})
+_case1 = undefined --
 
 _case11 :: [JSNode]
-_case11 = [NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NS (JSStatementBlock (NS (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 1, span_column = 9}),NS (JSOperator "=") (SpanPoint {span_filename = "", span_row = 1, span_column = 10}),NS (JSDecimal "2") (SpanPoint {span_filename = "", span_row = 1, span_column = 11})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})]
+_case11 = undefined -- [NN (JSIf (NN (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NN (JSStatementBlock (NN (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NN (JSStatementBlock (NN (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 1, span_column = 9}),NS (JSOperator "=") (SpanPoint {span_filename = "", span_row = 1, span_column = 10}),NS (JSDecimal "2") (SpanPoint {span_filename = "", span_row = 1, span_column = 11})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})]
 
 _case12 :: JSNode
-_case12 = (NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NS (JSLiteral "") (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))
+_case12 = undefined -- (NN (JSIf (NN (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NT (JSLiteral "") (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))
 
 -- readJs "bob:if(x){}\n{a}"
 _case2 :: JSNode
-_case2 = NS (JSSourceElementsTop [NS (JSLabelled (NS (JSIdentifier "bob") (SpanPoint {span_filename = "", span_row = 1, span_column = 1})) (NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 8})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})) (NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 10}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 10}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 5}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NS (JSStatementBlock (NS (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 2, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 2, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 2, span_column = 2}))) (SpanPoint {span_filename = "", span_row = 2, span_column = 1})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})
+_case2 = undefined -- NS (JSSourceElementsTop [NS (JSLabelled (NS (JSIdentifier "bob") (SpanPoint {span_filename = "", span_row = 1, span_column = 1})) (NN (JSIf (NN (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 8})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})) (NN (JSStatementBlock (NN (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 10}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 10}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 5}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NN (JSStatementBlock (NN (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 2, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 2, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 2, span_column = 2}))) (SpanPoint {span_filename = "", span_row = 2, span_column = 1})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})
+
+-- readJs "switch(i){case 1:1;case 2:2}"
 
 -- EOF
 
diff --git a/buildall.sh b/buildall.sh
--- a/buildall.sh
+++ b/buildall.sh
@@ -1,6 +1,5 @@
 #!/bin/sh
 
 # do a clean build of all, including the tests
-cabal clean && cabal configure -fbuildtests && cabal build && cabal haddock
-
-
+#cabal clean && cabal configure -fbuildtests && cabal build && cabal haddock
+cabal clean && cabal configure --enable-tests && cabal build && cabal test && cabal haddock
diff --git a/hjsmin.cabal b/hjsmin.cabal
--- a/hjsmin.cabal
+++ b/hjsmin.cabal
@@ -1,5 +1,5 @@
 name:            hjsmin
-version:         0.0.16
+version:         0.1.0
 license:         BSD3
 license-file:    LICENSE
 author:          Alan Zimmerman <alan.zimm@gmail.com>
@@ -10,7 +10,7 @@
    other syntactic elements, without changing the semantics.
 category:        Web
 stability:       unstable
-cabal-version:   >= 1.6
+cabal-version:   >= 1.9.2
 build-type:      Simple
 homepage:        http://github.com/alanz/hjsmin
 bug-reports:     http://github.com/alanz/hjsmin/issues
@@ -19,33 +19,32 @@
   TODO.txt, README.markdown, buildall.sh
 
 
-flag buildtests
-  description: Build the executable to run unit tests
-  default: False
-
 library
     build-depends:   base                >= 4       && < 5
                    , bytestring          >= 0.9     && < 0.10
                    , blaze-builder       >= 0.2     && < 1
                    , text                >= 0.8     && < 1
                    , containers          >= 0.2     && < 0.5
-                   , language-javascript >= 0.4.4   && < 0.5
+                   , language-javascript >= 0.5.1   && < 0.6
     exposed-modules: Text.Jasmine
     other-modules:   Text.Jasmine.Pretty
     ghc-options:     -Wall
 
-executable             runtests
-    if flag(buildtests)
-        Buildable: True
-        cpp-options:   -DTEST
-        build-depends: QuickCheck >= 2 && < 3,
-                       HUnit,
-                       test-framework-hunit,
-                       test-framework
 
-    else
-        Buildable: False
-    main-is:         runtests.hs
+Test-Suite test-hjsmin
+  Type: exitcode-stdio-1.0
+  Main-is: runtests.hs
+  build-depends: Cabal >= 1.9.2
+                 , QuickCheck >= 2 && < 3
+                 , HUnit
+                 , test-framework
+                 , test-framework-hunit
+                 , base                >= 4       && < 5
+                 , bytestring          >= 0.9     && < 0.10
+                 , blaze-builder       >= 0.2     && < 1
+                 , text                >= 0.8     && < 1
+                 , containers          >= 0.2     && < 0.5
+                 , language-javascript >= 0.5.1   && < 0.6
 
 source-repository head
   type:     git
diff --git a/runtests.hs b/runtests.hs
--- a/runtests.hs
+++ b/runtests.hs
@@ -1,3 +1,4 @@
+module Main where
 
 import Test.Framework (defaultMain, testGroup, Test)
 import Test.Framework.Providers.HUnit
@@ -34,11 +35,15 @@
     , testCase "Unicode"          caseUnicode
     , testCase "Issue3"           caseIssue3
     , testCase "Issue4"           caseIssue4
-    , testCase "Issue7"           caseIssue7
+    , testCase "Switch1"          caseSwitch1
+    , testCase "If1"              caseIf1
+    , testCase "If2"              caseIf2
+    , testCase "If3"              caseIf3
+    , testCase "BootstrapDropdown" caseBootstrapDropdown
     ]
 
 testSuiteMin :: Test
-testSuiteMin = testGroup "Text.Jasmine.Pretty"
+testSuiteMin = testGroup "Text.Jasmine.Pretty Min"
     [ testCase "helloWorld"       caseMinHelloWorld
     , testCase "helloWorld2"      caseMinHelloWorld2
     , testCase "simpleAssignment" caseMinSimpleAssignment
@@ -56,7 +61,11 @@
     , testCase "Unicode"          caseMinUnicode
     , testCase "MinIssue3"        caseMinIssue3
     , testCase "MinIssue4"        caseMinIssue4
-    , testCase "MinIssue7"        caseMinIssue7
+    , testCase "MinSwitch1"       caseMinSwitch1
+    , testCase "MinIf1"           caseMinIf1
+    , testCase "MinIf2"           caseMinIf2
+    , testCase "MinIf3"           caseMinIf3
+    , testCase "MinBootstrapDropdown" caseMinBootstrapDropdown
     ]
 
 testSuiteFiles :: Test
@@ -121,12 +130,11 @@
   , testCase "122_jsexec.js"    (testFileUnminified "122_jsexec.js")
 
   --, testCase "122_jsexec2.js"   (testFileUnminified "122_jsexec2.js")
-
   ]
 
 srcHelloWorld = "function Hello(a) {}"
 caseHelloWorld =
-  "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [])])"
+  "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSBlock ([])),JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcHelloWorld)
 caseMinHelloWorld =
   -- "function Hello(a){}" @=? (minify (U.fromString srcHelloWorld))
@@ -134,7 +142,7 @@
 
 srcHelloWorld2 = "function Hello(a) {b=1}"
 caseHelloWorld2 =
-  "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]]])])"
+  "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSBlock ([JSExpression [JSIdentifier \"b\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]])),JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcHelloWorld2)
 caseMinHelloWorld2 =
   -- "function Hello(a){b=1}" @=? (minify (U.fromString srcHelloWorld2))
@@ -142,43 +150,42 @@
 
 srcSimpleAssignment = "a=1;"
 caseSimpleAssignment =
-  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])"
+  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcSimpleAssignment)
 caseMinSimpleAssignment =
   testMinify "a=1" srcSimpleAssignment
 
 srcEmptyFor = "for (i = 0;;){}"
 caseEmptyFor =
-  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator \"=\",JSDecimal \"0\"]] [] [] (JSStatementBlock (JSStatementList []))])"
+  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator JSLiteral \"=\",JSDecimal \"0\"]] [] [] (JSBlock ([])),JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcEmptyFor)
 srcFullFor = "for (i = 0;i<10;i++){}"
 caseFullFor =
-  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator \"=\",JSDecimal \"0\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSStatementBlock (JSStatementList []))])"
+  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator JSLiteral \"=\",JSDecimal \"0\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSBlock ([])),JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcFullFor)
 
 srcForVarFull = "for(var i=0,j=tokens.length;i<j;i++){}"
 caseForVarFull =
-  "Right (JSSourceElementsTop [JSForVar [JSVarDecl (JSIdentifier \"i\") [JSDecimal \"0\"],JSVarDecl (JSIdentifier \"j\") [JSMemberDot [JSIdentifier \"tokens\"] (JSIdentifier \"length\")]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSIdentifier \"j\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSStatementBlock (JSStatementList []))])"
+  "Right (JSSourceElementsTop [JSForVar [JSVarDecl (JSIdentifier \"i\") [JSLiteral \"=\",JSDecimal \"0\"],JSLiteral \",\",JSVarDecl (JSIdentifier \"j\") [JSLiteral \"=\",JSMemberDot [JSIdentifier \"tokens\"] (JSIdentifier \"length\")]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSIdentifier \"j\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSBlock ([])),JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcForVarFull)
 
 srcIfElse1 = "if(a){b=1}else c=2";
 caseIfElse1 =
-  "Right (JSSourceElementsTop [JSIfElse (JSExpression [JSIdentifier \"a\"]) (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]])) (JSExpression [JSIdentifier \"c\",JSOperator \"=\",JSDecimal \"2\"])])"
+   "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) ([JSBlock ([JSExpression [JSIdentifier \"b\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]])]) ([JSLiteral \"else\",JSExpression [JSIdentifier \"c\",JSOperator JSLiteral \"=\",JSDecimal \"2\"]]),JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcIfElse1)
 caseMinIfElse1 =
   testMinify "if(a){b=1}else c=2" srcIfElse1
 
 srcIfElse2 = "if(a){b=1}else {c=2;d=4}";
 caseIfElse2 =
-  "Right (JSSourceElementsTop [JSIfElse (JSExpression [JSIdentifier \"a\"]) (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]])) (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"c\",JSOperator \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"d\",JSOperator \"=\",JSDecimal \"4\"]]))])"
+  "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) ([JSBlock ([JSExpression [JSIdentifier \"b\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]])]) ([JSLiteral \"else\",JSBlock ([JSExpression [JSIdentifier \"c\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"d\",JSOperator JSLiteral \"=\",JSDecimal \"4\"]])]),JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcIfElse2)
 caseMinIfElse2 =
   testMinify "if(a){b=1}else{c=2;d=4}" srcIfElse2
 
 src0_f = "function Hello(a) {ExprArray(1,1);}"
 case0_f =
-  -- "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"ExprArray\",JSArguments [[JSDecimal 1],[JSDecimal 1]]],JSLiteral \"\"]])]"
-  "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"ExprArray\",JSArguments [[JSDecimal \"1\"],[JSDecimal \"1\"]]],JSLiteral \";\"]])])"
+   "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSBlock ([JSExpression [JSIdentifier \"ExprArray\",JSArguments [JSDecimal \"1\",JSLiteral \",\",JSDecimal \"1\"]],JSLiteral \";\"])),JSLiteral \"\"])"
   -- @=? (show $ parseString program src0_f)
   @=? (showStrippedMaybe $ parseProgram src0_f)
 caseMin0_f =
@@ -192,21 +199,21 @@
     "// five\n"++
     "five")
 case01_semi1 =
-  "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSExpression [JSMemberDot [JSIdentifier \"zero\"] (JSIdentifier \"one1\")],JSLiteral \";\",JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"one1\"],JSExpression [JSIdentifier \"two\"],JSLiteral \";\",JSExpression [JSIdentifier \"three\"],JSStatementBlock (JSStatementList [JSStatementBlock (JSStatementList [])]),JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"five\"]])"
+  "Right (JSSourceElementsTop [JSBlock ([JSExpression [JSMemberDot [JSIdentifier \"zero\"] (JSIdentifier \"one1\")],JSLiteral \";\",JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"one1\"],JSExpression [JSIdentifier \"two\"],JSLiteral \";\",JSExpression [JSIdentifier \"three\"],JSBlock ([JSBlock ([])]),JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"five\"],JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram src01_semi1)
 caseMin01_semi1 =
   testMinify "{zero.one1;zero};one1;two;three;four;five" src01_semi1
 
 src_min_100_animals = "function Animal(name){if(!name)throw new Error('Must specify an animal name');this.name=name};Animal.prototype.toString=function(){return this.name};o=new Animal(\"bob\");o.toString()==\"bob\""
 case_min_100_animals =
-  "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Animal\") [JSIdentifier \"name\"] (JSFunctionBody [JSSourceElements [JSIf (JSExpression [JSUnary \"!\",JSIdentifier \"name\"]) (JSBlock (JSStatementList [JSThrow (JSExpression [JSLiteral \"new \",JSIdentifier \"Error\",JSArguments [[JSStringLiteral '\\'' \"Must specify an animal name\"]]])])),JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\"),JSOperator \"=\",JSIdentifier \"name\"]]]),JSLiteral \";\",JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"Animal\"] (JSIdentifier \"prototype\")] (JSIdentifier \"toString\"),JSOperator \"=\",JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")],JSLiteral \"\"]]])],JSLiteral \";\",JSExpression [JSIdentifier \"o\",JSOperator \"=\",JSLiteral \"new \",JSIdentifier \"Animal\",JSArguments [[JSStringLiteral '\"' \"bob\"]]],JSLiteral \";\",JSExpression [JSExpressionBinary \"==\" [JSMemberDot [JSIdentifier \"o\"] (JSIdentifier \"toString\"),JSArguments []] [JSStringLiteral '\"' \"bob\"]]])"
+  "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Animal\") [JSIdentifier \"name\"] (JSBlock ([JSIf (JSExpression [JSUnary \"!\",JSIdentifier \"name\"]) ([JSThrow (JSExpression [JSLiteral \"new\",JSIdentifier \"Error\",JSArguments [JSStringLiteral '\\'' \"Must specify an animal name\"]]),JSLiteral \";\"]) ([]),JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\"),JSOperator JSLiteral \"=\",JSIdentifier \"name\"]])),JSLiteral \";\",JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"Animal\"] (JSIdentifier \"prototype\")] (JSIdentifier \"toString\"),JSOperator JSLiteral \"=\",JSFunctionExpression [] [] (JSBlock ([JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")]] JSLiteral \"\"]))],JSLiteral \";\",JSExpression [JSIdentifier \"o\",JSOperator JSLiteral \"=\",JSLiteral \"new\",JSIdentifier \"Animal\",JSArguments [JSStringLiteral '\"' \"bob\"]],JSLiteral \";\",JSExpression [JSExpressionBinary \"==\" [JSMemberDot [JSIdentifier \"o\"] (JSIdentifier \"toString\"),JSArguments []] [JSStringLiteral '\"' \"bob\"]],JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram src_min_100_animals)
 caseMin_min_100_animals =
   testMinify src_min_100_animals src_min_100_animals
 
 srcMergeStrings = "throw new TypeError(\"Function.prototype.apply called on\"+\" uncallable object\");"
 caseMergeStrings =
-  "Right (JSSourceElementsTop [JSThrow (JSExpression [JSLiteral \"new \",JSIdentifier \"TypeError\",JSArguments [[JSExpressionBinary \"+\" [JSStringLiteral '\"' \"Function.prototype.apply called on\"] [JSStringLiteral '\"' \" uncallable object\"]]]]),JSLiteral \";\"])"
+  "Right (JSSourceElementsTop [JSThrow (JSExpression [JSLiteral \"new\",JSIdentifier \"TypeError\",JSArguments [JSExpressionBinary \"+\" [JSStringLiteral '\"' \"Function.prototype.apply called on\"] [JSStringLiteral '\"' \" uncallable object\"]]]),JSLiteral \";\",JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcMergeStrings)
 caseMinMergeStrings =
   testMinify "throw new TypeError(\"Function.prototype.apply called on uncallable object\")" srcMergeStrings
@@ -219,8 +226,9 @@
   testMinify "this.cursor+=match[0].length" srcNestedSquare
 
 caseEitherLeft  =
-  Left "UnexpectedToken (MulToken {token_span = (AlexPn 2 1 3,'=',\"*SYNTAX*ERROR*\")})"
-  -- Left "UnexpectedToken (MulToken {token_span = SpanPoint {span_filename = \"src\", span_row = 1, span_column = 3}})"
+  -- Left "UnexpectedToken (MulToken {token_span = (AlexPn 2 1 3,'=',\"*SYNTAX*ERROR*\")})"
+  -- Left "\"MulToken {token_span = TokenPn 2 1 3, token_comment = [NoComment]}\""
+  Left "\"MulToken {token_span = TokenPn 2 1 3, token_comment = [NoComment]}\""
   @=? minifym (LB.fromChunks [(E.encodeUtf8 $ T.pack "a=*SYNTAX*ERROR*")])
 
 caseEitherRight  =
@@ -228,54 +236,74 @@
 
 srcTrailingCommas = "x={a:1,};y=[d,e,];"
 caseTrailingCommas =
-  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"a\") [JSDecimal \"1\"],JSLiteral \",\"]],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator \"=\",JSArrayLiteral [JSIdentifier \"d\",JSElision [],JSIdentifier \"e\",JSLiteral \",\"]],JSLiteral \";\"])"
+  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"a\") [JSDecimal \"1\"],JSLiteral \",\"]],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSArrayLiteral [JSIdentifier \"d\",JSElision JSLiteral \",\",JSIdentifier \"e\",JSLiteral \",\"]],JSLiteral \";\",JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcTrailingCommas)
 caseMinTrailingCommas =
   testMinify "x={a:1,};y=[d,e,]" srcTrailingCommas
 
 srcGetSet = "x={get foo() {return 1},set foo(a) {x=a}}"
 caseGetSet =
-  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSObjectLiteral [JSPropertyAccessor \"get\" (JSIdentifier \"foo\") [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSDecimal \"1\"],JSLiteral \"\"]]]),JSPropertyAccessor \"set\" (JSIdentifier \"foo\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSIdentifier \"a\"]]])]]])"
+  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyAccessor NT (JSLiteral \"get\") (TokenPn 3 1 4) [NoComment] (JSIdentifier \"foo\") [] (JSBlock ([JSReturn [JSExpression [JSDecimal \"1\"]] JSLiteral \"\"])),JSLiteral \",\",JSPropertyAccessor NT (JSLiteral \"set\") (TokenPn 24 1 25) [NoComment] (JSIdentifier \"foo\") [JSIdentifier \"a\"] (JSBlock ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"a\"]]))]],JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcGetSet)
 caseMinGetSet =
   testMinify "x={get foo(){return 1},set foo(a){x=a}}" srcGetSet
 
 srcUnicode = "var x = \"שלום\";"
 caseUnicode =
-  "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"x\") [JSStringLiteral '\"' \"\\1513\\1500\\1493\\1501\"]]])"
+  "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSStringLiteral '\"' \"\\1513\\1500\\1493\\1501\"]],JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcUnicode)
 caseMinUnicode =
   testMinify "var x=\"שלום\"" srcUnicode
 
 srcIssue3 = "var myLatlng = new google.maps.LatLng(56.8379100, 60.5806664);"
 caseIssue3 =
-  "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"myLatlng\") [JSLiteral \"new \",JSMemberDot [JSMemberDot [JSIdentifier \"google\"] (JSIdentifier \"maps\")] (JSIdentifier \"LatLng\"),JSArguments [[JSDecimal \"56.8379100\"],[JSDecimal \"60.5806664\"]]]]])"
+  "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"myLatlng\") [JSLiteral \"=\",JSLiteral \"new\",JSMemberDot [JSMemberDot [JSIdentifier \"google\"] (JSIdentifier \"maps\")] (JSIdentifier \"LatLng\"),JSArguments [JSDecimal \"56.8379100\",JSLiteral \",\",JSDecimal \"60.5806664\"]]],JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcIssue3)
 caseMinIssue3 =
   testMinify "var myLatlng=new google.maps.LatLng(56.8379100,60.5806664)" srcIssue3
 
 srcIssue4 = "/* * geolocation. пытаемся определить свое местоположение * если не получается то используем defaultLocation * @Param {object} map экземпляр карты * @Param {object LatLng} defaultLocation Координаты центра по умолчанию * @Param {function} callbackAfterLocation Фу-ия которая вызывается после * геолокации. Т.к запрос геолокации асинхронен */x"
 caseIssue4 =
-  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\"]])"
+  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\"],JSLiteral \"\"])"
   @=? (showStrippedMaybe $ parseProgram srcIssue4)
 caseMinIssue4 =
   testMinify "x" srcIssue4
 
+srcSwitch1 = "switch(i){case 1:1;case 2:2}"
+caseSwitch1 =
+   "Right (JSSourceElementsTop [JSSwitch (JSExpression [JSIdentifier \"i\"]) JSBlock ([JSCase (JSExpression [JSDecimal \"1\"]) ([JSExpression [JSDecimal \"1\"],JSLiteral \";\"]),JSCase (JSExpression [JSDecimal \"2\"]) ([JSExpression [JSDecimal \"2\"]])]),JSLiteral \"\"])"
+  @=? (showStrippedMaybe $ parseProgram srcSwitch1)
+caseMinSwitch1 =
+  testMinify "switch(i){case 1:1;case 2:2}" srcSwitch1
 
---srcIssue7="var hljs=new function(){function k(){if(k.called){return}k.called=true;var r=document.getElementsByTagName(\"pre\");for(var p=0;p<r.length;p++){}}}();"
-srcIssue7="var hljs=new function(){function k(){if(k.called){return}}}();"
-caseIssue7 =
-  "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"hljs\") [JSLiteral \"new \",JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSFunction (JSIdentifier \"k\") [] (JSFunctionBody [JSSourceElements [JSIf (JSExpression [JSMemberDot [JSIdentifier \"k\"] (JSIdentifier \"called\")]) (JSStatementBlock (JSStatementList [JSReturn [JSLiteral \"\"]]))]])]]),JSArguments []]]])"
-  @=? (showStrippedMaybe $ parseProgram srcIssue7)
-caseMinIssue7 =
-  testMinify "var hljs=new function(){function k(){if(k.called)return}}()" srcIssue7
+srcIf1="if(i>0)consts+=\", \";var t=tokens[i];"
+caseIf1 =
+  "Right (JSSourceElementsTop [JSIf (JSExpression [JSExpressionBinary \">\" [JSIdentifier \"i\"] [JSDecimal \"0\"]]) ([JSExpression [JSIdentifier \"consts\",JSOperator JSLiteral \"+=\",JSStringLiteral '\"' \", \"],JSLiteral \";\"]) ([]),JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"t\") [JSLiteral \"=\",JSMemberSquare [JSIdentifier \"tokens\"] (JSExpression [JSIdentifier \"i\"])]],JSLiteral \"\"])"
+  @=? (showStrippedMaybe $ parseProgram srcIf1)
+caseMinIf1 =
+  testMinify "if(i>0)consts+=\", \";var t=tokens[i]" srcIf1
 
-caseIssue7file =
-  do
-     x <- readFile ("./test/parsingonly/issue7.js")
-     y <- readFile ("./test/parsingonly/issue7.js")
-     let x' = trim x
-     testMinify x' y
+srcIf2 = "if (getValue)\n   execute;\nelse {\n   execute;\n}"
+caseIf2 =
+  "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"getValue\"]) ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"]) ([JSLiteral \"else\",JSBlock ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"])]),JSLiteral \"\"])"
+  @=? (showStrippedMaybe $ parseProgram srcIf2)
+caseMinIf2 =
+  testMinify "if(getValue){execute}else execute" srcIf2
+
+srcIf3 = "if(getValue){execute}else execute"
+caseIf3 =
+  "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"getValue\"]) ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"]) ([JSLiteral \"else\",JSBlock ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"])]),JSLiteral \"\"])"
+  @=? (showStrippedMaybe $ parseProgram srcIf2)
+caseMinIf3 =
+  testMinify "if(getValue){execute}else execute" srcIf3
+
+srcBootstrapDropdown = "clearMenus()\n!isActive && $parent.toggleClass('open')"
+caseBootstrapDropdown =
+  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"clearMenus\",JSArguments []],JSExpression [JSExpressionBinary \"&&\" [JSUnary \"!\",JSIdentifier \"isActive\"] [JSMemberDot [JSIdentifier \"$parent\"] (JSIdentifier \"toggleClass\"),JSArguments [JSStringLiteral '\\'' \"open\"]]],JSLiteral \"\"])"
+  @=? (showStrippedMaybe $ parseProgram srcBootstrapDropdown)
+caseMinBootstrapDropdown =
+  -- Note: jsmin preserves the \n, rather than the semi. A matter of taste, it is the same number of chars.
+  testMinify "clearMenus();!isActive&&$parent.toggleClass('open')" srcBootstrapDropdown
 
 -- ---------------------------------------------------------------------
 -- utilities
