diff --git a/Swish/RDF/N3Formatter.hs b/Swish/RDF/N3Formatter.hs
--- a/Swish/RDF/N3Formatter.hs
+++ b/Swish/RDF/N3Formatter.hs
@@ -92,7 +92,7 @@
 
 import Data.Char (ord, isDigit)
 
-import Data.List (foldl', delete, groupBy, intercalate, partition, sort)
+import Data.List (foldl', delete, groupBy, partition, sort)
 
 import Text.Printf (printf)
 
@@ -136,7 +136,7 @@
     , bNodesCheck   :: [RDFLabel]      -- these bNodes are not to be converted to '[..]' format
     , traceBuf  :: [String]
     }
-
+             
 type Formatter a = State N3FormatterState a
 
 emptyN3FS :: NodeGenState -> N3FormatterState
@@ -231,7 +231,7 @@
   put $ st { objs = os }
 -}
 
-getBnodesCheck :: Formatter ([RDFLabel])
+getBnodesCheck :: Formatter [RDFLabel]
 getBnodesCheck = bNodesCheck `liftM` get
 
 {-
@@ -455,17 +455,16 @@
   setIndent ind
   setLineBreak dobreak
   setGraph gr
+  
   fp <- if dopref
         then formatPrefixes (getNamespaces gr)
         else return $ puts ""
   more <- moreSubjects
-  res  <- if more
-          then do
-            fr <- formatSubjects
-            return $ fp . fr . puts end
-          else return fp
-
-  return res
+  if more
+    then do
+      fr <- formatSubjects
+      return $ fp . fr . puts end
+    else return fp
 
 formatPrefixes :: NamespaceMap -> Formatter ShowS
 formatPrefixes pmap = do
@@ -491,13 +490,19 @@
           fr <- formatSubjects
           return $ puts (prstr ++ " .") . fr
           -- return $ puts (prstr ++ fmstr ++ " .") . fr
-        else return $ puts $ prstr
+        else return $ puts prstr
         -- else return $ puts $ prstr ++ fmstr
            
     else do
-         txt <- nextLine sbstr
-         return $ puts txt
+      txt <- nextLine sbstr
     
+      flagS <- moreSubjects
+      if flagS
+        then do
+          fr <- formatSubjects
+          return $ puts (txt ++ " .") . fr
+        else return $ puts txt
+
 formatProperties :: RDFLabel -> String -> Formatter String
 formatProperties sb sbstr = do
   pr <- nextProperty sb
@@ -578,10 +583,10 @@
 by ().
 -}
 insertList :: [RDFLabel] -> Formatter String
-insertList [] = return $ "()" -- not convinced this can happen
+insertList [] = return "()" -- not convinced this can happen
 insertList xs = do
   ls <- mapM (formatLabel ObjContext) xs
-  return $ "( " ++ intercalate " " ls ++ " )"
+  return $ "( " ++ unwords ls ++ " )"
   
   
 {-
diff --git a/Swish/RDF/N3Parser.hs b/Swish/RDF/N3Parser.hs
--- a/Swish/RDF/N3Parser.hs
+++ b/Swish/RDF/N3Parser.hs
@@ -401,10 +401,12 @@
 
 -- Add statement to graph in N3 parser state
 
-addStatement :: RDFLabel -> RDFLabel -> RDFLabel -> N3Parser ()
+type AddStatement = RDFLabel -> N3Parser ()
+
+addStatement :: RDFLabel -> RDFLabel -> AddStatement
 addStatement s p o = updateState (updateGraph (addArc (arc s p o) ))
 
-addStatementRev :: RDFLabel -> RDFLabel -> RDFLabel -> N3Parser ()
+addStatementRev :: RDFLabel -> RDFLabel -> AddStatement
 addStatementRev o p s = addStatement s p o
 
 {-
@@ -696,13 +698,6 @@
 {-
 qname ::=	(([A-Z_a-z#x00c0-#x00d6#x00d8-#x00f6#x00f8-#x02ff#x0370-#x037d#x037f-#x1fff#x200c-#x200d#x2070-#x218f#x2c00-#x2fef#x3001-#xd7ff#xf900-#xfdcf#xfdf0-#xfffd#x00010000-#x000effff][\-0-9A-Z_a-z#x00b7#x00c0-#x00d6#x00d8-#x00f6#x00f8-#x037d#x037f-#x1fff#x200c-#x200d#x203f-#x2040#x2070-#x218f#x2c00-#x2fef#x3001-#xd7ff#xf900-#xfdcf#xfdf0-#xfffd#x00010000-#x000effff]*)?:)?[A-Z_a-z#x00c0-#x00d6#x00d8-#x00f6#x00f8-#x02ff#x0370-#x037d#x037f-#x1fff#x200c-#x200d#x2070-#x218f#x2c00-#x2fef#x3001-#xd7ff#xf900-#xfdcf#xfdf0-#xfffd#x00010000-#x000effff][\-0-9A-Z_a-z#x00b7#x00c0-#x00d6#x00d8-#x00f6#x00f8-#x037d#x037f-#x1fff#x200c-#x200d#x203f-#x2040#x2070-#x218f#x2c00-#x2fef#x3001-#xd7ff#xf900-#xfdcf#xfdf0-#xfffd#x00010000-#x000effff]*
 
-Turtle appears to support ':' as a valid qname, which is not
-supported by the above production. Let's support and see
-what happens. This support may be removed since, if we allow
-white space between : and prefix or local name then statements like
-   : a : b : c .
-are not parseable.
-
 TODO:
   Note that, for now, we explicitly handle blank nodes
   (of the form _:name) direcly in pathItem'.
@@ -979,20 +974,23 @@
 
 -}
 
+-- it's probably important that bNode is created *after*
+-- processing the plist (mainly for the assumptions made by
+-- formatting the output as N3; e.g. list/sequence ordering)
+--
 propertyListBNode :: N3Parser RDFLabel
 propertyListBNode = do
   plist <- sepEndBy ((,) <$> lexeme verb <*> objectList) semiColon
   bNode <- newBlankNode
-  let addList (vrb,items) = mapM_ (addItem vrb) items
-      addItem (True,vrb) obj  = addStatement bNode vrb obj
-      addItem (_,vrb)    subj = addStatement subj vrb bNode
-  
+  let addList ((addFunc,vrb),items) = mapM_ (addFunc bNode vrb) items
   forM_ plist addList
   return bNode
 
 propertyListWith :: RDFLabel -> N3Parser ()
 propertyListWith subj = 
-  ignore $ sepEndBy (lexeme verb >>= objectListWith subj) semiColon
+  let -- term = lexeme verb >>= objectListWith subj
+      term = lexeme verb >>= \(addFunc, vrb) -> objectListWith (addFunc subj vrb)
+  in ignore $ sepEndBy term semiColon
   
 {-
 object ::=		|	expression
@@ -1000,7 +998,16 @@
 		|	void
 
 We change the production rule from objecttail to objectlist for lists of
-objects (may change back)
+objects (may change back).
+
+May be an optimisation needed in the case of
+
+ :s :p :o1 , .. , :o<large number>.
+
+Is parsec creating the list of actions, using sepBy1
+in objectListWith, and then evaluating them all once the list
+has been created?
+
 -}
 
 object :: N3Parser RDFLabel
@@ -1009,14 +1016,12 @@
 objectList :: N3Parser [RDFLabel]
 objectList = sepBy1 object comma
 
-objectWith :: RDFLabel -> (Bool, RDFLabel) -> N3Parser ()
-objectWith subj (flag,vrb) = object >>= addFunc subj vrb
-  where
-    addFunc = if flag then addStatement else addStatementRev
+objectWith :: AddStatement -> N3Parser ()
+objectWith addFunc = object >>= addFunc 
 
-objectListWith :: RDFLabel -> (Bool, RDFLabel) -> N3Parser ()
-objectListWith subj vrb =
-  ignore $ sepBy1 (objectWith subj vrb) comma
+objectListWith :: AddStatement -> N3Parser ()
+objectListWith addFunc =
+  ignore $ sepBy1 (objectWith addFunc) comma
 
 {-
 objectList1 :: N3Parser [RDFLabel]
@@ -1033,11 +1038,11 @@
 		|	expression
 -}
 
-verb :: N3Parser (Bool, RDFLabel)
+verb :: N3Parser (RDFLabel -> RDFLabel -> AddStatement, RDFLabel)
 verb = 
   -- we check reverse first so that <= is tried before looking for a URI via expression rule
-  (,) False <$> verbReverse
-  <|> (,) True <$> verbForward
+  (,) addStatementRev <$> verbReverse
+  <|> (,) addStatement <$> verbForward
   <?> "verb"
 
 -- those verbs for which subject is on the right and object on the left
diff --git a/Swish/RDF/SwishCommands.hs b/Swish/RDF/SwishCommands.hs
--- a/Swish/RDF/SwishCommands.hs
+++ b/Swish/RDF/SwishCommands.hs
@@ -80,6 +80,8 @@
 
 import System.IO.Error
 
+import Data.Maybe (isJust)
+
 ------------------------------------------------------------
 --  Set file format to supplied value
 ------------------------------------------------------------
@@ -149,24 +151,21 @@
   let p1 = partitionGraph (getArcs oldGr)
       p2 = partitionGraph (getArcs gr)
       diffs = comparePartitions p1 p2
-  maybehandleclose <- swishWriteFile Nothing
-  case maybehandleclose of
-    Just (h,c) -> do
-      swishOutputDiffs "" h diffs
-      when c (lift $ hClose h)
-   
-    _  -> return ()
+      
+  swishWriteFile (swishOutputDiffs diffs) Nothing
   
 swishOutputDiffs :: (Label lb) =>
-    String -> Handle
-    -> [(Maybe (GraphPartition lb),Maybe (GraphPartition lb))]
+    [(Maybe (GraphPartition lb),Maybe (GraphPartition lb))]
+    -> Maybe String 
+    -> Handle
     -> SwishStateIO ()
-swishOutputDiffs fnam hnd diffs = do
+swishOutputDiffs diffs fnam hnd = do
   lift $ hPutStrLn hnd ("Graph differences: "++show (length diffs))
   mapM_ (swishOutputDiff fnam hnd) (zip [1..] diffs)
 
 swishOutputDiff :: (Label lb) =>
-    String -> Handle
+    Maybe String 
+    -> Handle
     -> (Int,(Maybe (GraphPartition lb),Maybe (GraphPartition lb)))
     -> SwishStateIO ()
 swishOutputDiff fnam hnd (diffnum,(part1,part2)) = do
@@ -177,7 +176,10 @@
   swishOutputPart fnam hnd part2
 
 swishOutputPart :: (Label lb) =>
-    String -> Handle -> Maybe (GraphPartition lb) -> SwishStateIO ()
+    Maybe String 
+    -> Handle 
+    -> Maybe (GraphPartition lb) 
+    -> SwishStateIO ()
 swishOutputPart _ hnd part = 
   let out = maybe "\n(No arcs)" (partitionShowP "\n") part
   in lift $ hPutStrLn hnd out
@@ -190,13 +192,7 @@
 swishScript fnam = swishReadScript fnam >>= mapM_ swishCheckResult
 
 swishReadScript :: Maybe String -> SwishStateIO [SwishStateIO ()]
-swishReadScript fnam =
-  let hdlr (h,i) = do
-        res <- swishParseScript fnam i
-        lift $ hClose h
-        return res
-  
-  in swishOpenFile fnam >>= maybe (return []) hdlr
+swishReadScript = swishReadFile swishParseScript []
 
 {-|
 Calculate the base URI to use; it combines the file name
@@ -279,10 +275,8 @@
 ------------------------------------------------------------
 
 swishOutput :: Maybe String -> SwishStateIO ()
-swishOutput fnam = 
-  let hdlr (h,c) = swishOutputGraph fnam h >> when c (lift $ hClose h)
-  in swishWriteFile fnam >>= maybe (return ()) hdlr
-     
+swishOutput = swishWriteFile swishOutputGraph
+   
 swishOutputGraph :: Maybe String -> Handle -> SwishStateIO ()
 swishOutputGraph _ hnd = do
   fmt <- gets format
@@ -304,19 +298,28 @@
 --  parsing it to an RDF graph value.
 
 swishReadGraph :: Maybe String -> SwishStateIO (Maybe RDFGraph)
-swishReadGraph fnam =
-  let reader (h,i) = do
-        res <- swishParse fnam i
-        lift $ hClose h
+swishReadGraph = swishReadFile swishParse Nothing
+
+-- | Open a file (or stdin), read its contents, and process them.
+--
+swishReadFile :: 
+  (Maybe String -> String -> SwishStateIO a) -- ^ Convert filename and contents into desired value
+  -> a -- ^ the value to use if the file can not be read in
+  -> Maybe String -- ^ the file name or @stdin@ if @Nothing@
+  -> SwishStateIO a
+swishReadFile conv errVal fnam = 
+  let reader (h,f,i) = do
+        res <- conv fnam i
+        when (f) $ lift $ hClose h
         return res
   
-  in swishOpenFile fnam >>= maybe (return Nothing) reader
+  in swishOpenFile fnam >>= maybe (return errVal) reader
 
--- Open and read file, returning its handle and content, or Nothing
+-- | Open and read file, returning its handle and content, or Nothing
 -- WARNING:  the handle must not be closed until input is fully evaluated
 --
-swishOpenFile :: Maybe String -> SwishStateIO (Maybe (Handle,String))
-swishOpenFile Nothing     = readFromHandle stdin "standard input."
+swishOpenFile :: Maybe String -> SwishStateIO (Maybe (Handle, Bool, String))
+swishOpenFile Nothing     = readFromHandle stdin Nothing
 swishOpenFile (Just fnam) = do
   o <- lift $ try $ openFile fnam ReadMode
   case o of
@@ -324,19 +327,20 @@
       swishError ("Cannot open file: "++fnam) SwishDataAccessError
       return Nothing
       
-    Right hnd -> readFromHandle hnd ("file: " ++ fnam)
+    Right hnd -> readFromHandle hnd $ Just ("file: " ++ fnam)
 
-readFromHandle :: Handle -> String -> SwishStateIO (Maybe (Handle, String))
-readFromHandle hdl lbl = do
+readFromHandle :: Handle -> Maybe String -> SwishStateIO (Maybe (Handle, Bool, String))
+readFromHandle hdl mlbl = do
   hrd <- lift $ hIsReadable hdl
   if hrd
     then do
       fc <- lift $ hGetContents hdl
-      return $ Just (hdl,fc)
+      return $ Just (hdl, isJust mlbl, fc)
   
     else do
-      -- closing stdin should not be an issue here?
-      lift $ hClose hdl
+      lbl <- case mlbl of
+        Just l  -> lift (hClose hdl) >> return l
+        Nothing -> return "standard input"
       swishError ("Cannot read from " ++ lbl) SwishDataAccessError
       return Nothing
 
@@ -366,13 +370,21 @@
           return Nothing
     -}
     
---  Open file for writing, returning its handle, or Nothing
+swishWriteFile :: 
+  (Maybe String -> Handle -> SwishStateIO ()) -- ^ given a file name and a handle, write to it
+  -> Maybe String
+  -> SwishStateIO ()
+swishWriteFile conv fnam =  
+  let hdlr (h, c) = conv fnam h >> when (c) (lift $ hClose h)
+  in swishCreateWriteableFile fnam >>= maybe (return ()) hdlr
+   
+-- | Open file for writing, returning its handle, or Nothing
 --  Also returned is a flag indicating whether or not the
 --  handled should be closed when writing is done (if writing
 --  to standard output, the handle should not be closed as the
 --  run-time system should deal with that).
-swishWriteFile :: Maybe String -> SwishStateIO (Maybe (Handle,Bool))
-swishWriteFile Nothing = do
+swishCreateWriteableFile :: Maybe String -> SwishStateIO (Maybe (Handle,Bool))
+swishCreateWriteableFile Nothing = do
   hwt <- lift $ hIsWritable stdout
   if hwt
     then return $ Just (stdout, False)
@@ -380,7 +392,7 @@
       swishError ("Cannot write to standard output") SwishDataAccessError
       return Nothing
   
-swishWriteFile (Just fnam) = do
+swishCreateWriteableFile (Just fnam) = do
   o <- lift $ try $ openFile fnam WriteMode
   case o of
     Left _ -> do
diff --git a/Swish/RDF/SwishScript.hs b/Swish/RDF/SwishScript.hs
--- a/Swish/RDF/SwishScript.hs
+++ b/Swish/RDF/SwishScript.hs
@@ -107,7 +107,7 @@
 import Text.ParserCombinators.Parsec
     ( (<?>), (<|>)
     , many, manyTill, option, sepBy, between, try, notFollowedBy
-    , string, char, anyChar
+    , string, anyChar
     , getState
     )
 
@@ -356,9 +356,15 @@
             ; whiteSpace
             }
 
+-- taken ftom NTParser
+eoln :: N3Parser ()
+-- eoln = ignore (newline <|> (lineFeed *> optional newline))
+eoln = (try (string "\r\n") <|> string "\r" <|> string "\n") >> return ()
+       <?> "new line"
+
 restOfLine :: N3Parser String
 restOfLine =
-        do  { s <- manyTill anyChar (char '\n')
+        do  { s <- manyTill anyChar eoln
             ; whiteSpace
             ; return s
             }
@@ -469,6 +475,21 @@
 --  The functions below operate in the SwishStateIO monad, and are used
 --  to assemble an executable version of the parsed script.
 
+-- | Return a message to the user. At present the message begins with '# '
+-- but this may be removed.
+--
+ssReport :: 
+  String  -- ^ message contents
+  -> SwishStateIO ()
+-- ssReport msg = lift $ putStrLn $ "# " ++ msg
+ssReport msg = modify $ setInfo $ "# " ++ msg
+
+ssReportLabel :: 
+  String     -- ^ label for the message
+  -> String  -- ^ message contents
+  -> SwishStateIO ()
+ssReportLabel lbl msg = ssReport $ lbl ++ ": " ++ msg
+
 ssAddReturnFormula ::
     ScopedName -> SwishStateIO (Either String RDFGraph)
     -> SwishStateIO (Either String RDFFormula)
@@ -585,7 +606,8 @@
 ssMerge nam gfs =
     let errmsg = "Graph merge not defined: "++show nam++"; "
     in
-        do  { esg <- sequence gfs       -- [Either String RDFGraph]
+        do  { ssReportLabel "Merge" (show nam)
+            ; esg <- sequence gfs       -- [Either String RDFGraph]
             ; let egs = sequence esg    -- Either String [RDFGraph]
             ; let fgs = case egs of
                     Left  er -> setError  (errmsg++er)
@@ -597,7 +619,8 @@
 
 ssCompare :: ScopedName -> ScopedName -> SwishStateIO ()
 ssCompare n1 n2 =
-        do  { g1 <- ssGetGraph n1
+        do  { ssReportLabel "Compare" (show n1 ++ " " ++ show n2)
+            ; g1 <- ssGetGraph n1
             ; g2 <- ssGetGraph n2
             ; when (g1 /= g2) (modify $ setStatus SwishGraphCompareError)
             }
@@ -606,12 +629,13 @@
 ssAssertEq n1 n2 comment =
     let er1 = ":\n  Graph or list compare not performed:  invalid graph/list."
     in
-        do  { g1 <- ssGetList n1
+        do  { ssReportLabel "AssertEq" comment
+            ; g1 <- ssGetList n1
             ; g2 <- ssGetList n2
             ; case (g1,g2) of
                 (Left er,_) -> modify $ setError (comment++er1++"\n  "++er)
                 (_,Left er) -> modify $ setError (comment++er1++"\n  "++er)
-                (Right gr1,Right gr2) ->
+                (Right gr1,Right gr2) -> 
                     unless (equiv gr1 gr2) $ modify $
                       setError (comment++":\n  Graph "++show n1
                                 ++" differs from "++show n2++".")
@@ -622,7 +646,8 @@
     let er1 = ":\n  Membership test not performed:  invalid graph."
         er2 = ":\n  Membership test not performed:  invalid list."
     in
-        do  { g1 <- ssGetGraph n1
+        do  { ssReportLabel "AssertIn" comment
+            ; g1 <- ssGetGraph n1
             ; g2 <- ssGetList  n2
             ; case (g1,g2) of
                 (Left er,_) -> modify $ setError (comment++er1++"\n  "++er)
diff --git a/swish.cabal b/swish.cabal
--- a/swish.cabal
+++ b/swish.cabal
@@ -1,5 +1,5 @@
 Name:               swish
-Version:            0.3.0.1
+Version:            0.3.0.2
 Stability:          experimental
 License:            LGPL
 License-file:       LICENSE 
@@ -45,8 +45,15 @@
                     .
                     Major Changes:
                     .
+                    [Version 0.3.0.2] Bugfix: stop losing triples with a bnode subject when
+                    using the N3Formatter; this also makes the @scripts/SwishTest.ss@ test
+                    pass again. Several commands in Swish scripts now create screen
+                    output (mainly to check what it is doing). Added the @developer@
+		    flag for building.
+                    .
                     [Version 0.3.0.1] updates the Swish script parser to work with the
-                    changes in 0.3.0.0. Several example scripts are installed in the
+                    changes in 0.3.0.0 (reported by Rick Murphy).
+                    Several example scripts are installed in the
                     @scripts/@ directory, although only @VehicleCapacity.ss@ works
                     with this release.
                     .
@@ -74,6 +81,10 @@
   type:     mercurial
   location: https://bitbucket.org/doug_burke/swish
 
+Flag  developer
+  Description: Turn on developer flags
+  Default:     False
+
 Flag  tests
   Description: Build the test programs.
   Default:     False
@@ -149,6 +160,10 @@
    ghc-options:
       -Wall -fno-warn-orphans
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
 Executable         BuiltInMapTest
    Main-Is:        tests/BuiltInMapTest.hs
    if !flag(tests)
@@ -157,6 +172,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -169,6 +188,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -180,6 +203,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -191,6 +218,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -202,6 +233,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -213,6 +248,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -224,6 +263,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -235,6 +278,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -246,6 +293,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -257,6 +308,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -268,6 +323,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -279,6 +338,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -290,6 +353,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -301,6 +368,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -312,6 +383,10 @@
    if flag(hpc)
       ghc-options: -fhpc
 
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
+
    ghc-options:
       -Wall -fno-warn-orphans
 
@@ -325,4 +400,8 @@
 
    ghc-options:
       -Wall -fno-warn-orphans
+
+   if flag(developer)
+      ghc-options: -Werror
+      ghc-prof-options: -auto-all
 
diff --git a/tests/N3FormatterTest.hs b/tests/N3FormatterTest.hs
--- a/tests/N3FormatterTest.hs
+++ b/tests/N3FormatterTest.hs
@@ -602,7 +602,8 @@
 
 -- bnode graphs
 
-graph_b1, graph_b1rev, graph_b2, graph_b2rev, graph_b3 :: RDFGraph
+graph_b1, graph_b1rev, graph_b2, graph_b2rev, graph_b3, 
+  graph_b4, graph_b5 :: RDFGraph
 graph_b1    = toGraph [arc s1 p1 b1]
 graph_b1rev = toGraph [arc b1 p1 o1]
 graph_b2    = toGraph [arc s1 p1 b1,
@@ -616,6 +617,11 @@
                        arc b1 o2 o3,
                        arc s1 p2 b2,
                        arc s2 p2 o2]
+graph_b4    = toGraph [arc b1 res_rdf_type o1,
+                       arc b2 res_rdf_type o2]
+graph_b5    = toGraph [arc b1 res_rdf_type o1,
+                       arc b2 p2 o2,
+                       arc b3 res_rdf_type o3]
 
 ------------------------------------------------------------
 --  Trivial formatter tests
@@ -813,6 +819,19 @@
     "         base2:p2 [] .\n" ++
     "base2:s2 base2:p2 base2:o2 .\n"
 
+simpleN3Graph_b4 :: String
+simpleN3Graph_b4 =
+  commonPrefixes ++
+  "[\n a base1:o1\n] .\n" ++ 
+  "[\n a base2:o2\n] .\n"
+
+simpleN3Graph_b5 :: String
+simpleN3Graph_b5 =
+  commonPrefixes ++
+  "[\n a base1:o1\n] .\n" ++ 
+  "[\n base2:p2 base2:o2\n] .\n" ++
+  "[\n a base3:o3\n] .\n"
+
 -- diag13 = diagTest "trivialTest13" x13a simpleN3Graph_x13a
 
 trivialTestSuite :: Test
@@ -838,6 +857,8 @@
  , formatTest "trivialTestb1" graph_b1 simpleN3Graph_b1
  , formatTest "trivialTestb2" graph_b2 simpleN3Graph_b2
  , formatTest "trivialTestb3" graph_b3 simpleN3Graph_b3
+ , formatTest "trivialTestb4" graph_b4 simpleN3Graph_b4
+ , formatTest "trivialTestb5" graph_b5 simpleN3Graph_b5
  , formatTest "trivialTestb1rev" graph_b1rev simpleN3Graph_b1rev
  , formatTest "trivialTestb2rev" graph_b2rev simpleN3Graph_b2rev
 
diff --git a/tests/N3ParserTest.hs b/tests/N3ParserTest.hs
--- a/tests/N3ParserTest.hs
+++ b/tests/N3ParserTest.hs
@@ -405,6 +405,9 @@
 g1b :: RDFGraph
 g1b = toGraph [t01b]
 
+g1b_1 :: RDFGraph
+g1b_1 = toGraph [arc b1 p1 o1]
+
 g2 :: RDFGraph
 g2 = toGraph [t01,t02,t03]
 
@@ -412,12 +415,14 @@
 g3 = toGraph [t01,t04]
 
 g4 :: RDFGraph
-g4 = NSGraph
-        { namespaces = nslist
-        , formulae   = emptyFormulaMap
-        , statements = [t01,t05]
-        }
+g4 = toGraph [t01,t05]
 
+g4_1 :: RDFGraph
+g4_1 = toGraph [arc b1 p1 o1, arc b2 p2 o2]
+
+g4_2 :: RDFGraph
+g4_2 = toGraph [arc b1 res_rdf_type o1, arc b2 res_rdf_type o2]
+
 g5 :: RDFGraph
 g5 = NSGraph
         { namespaces = nslist
@@ -941,8 +946,7 @@
     "@prefix : <" ++ nsURI base1 ++ "> .\n" ++
     " :s1 :p1 :o1 . "
 
---  Turtle supports ':' but (apparently) not N3, but try
---  and support it.
+--  Check we can handle ':' and 'prefix:' forms.
 --
 simpleN3Graph_g1_03_1 :: String
 simpleN3Graph_g1_03_1 =
@@ -966,6 +970,11 @@
     "@base <" ++ nsURI base1 ++ "> .\n" ++
     " _:b1 _:b2 _:b3 . "
 
+simpleN3Graph_g1_05_1 :: String
+simpleN3Graph_g1_05_1 =
+    commonPrefixes ++
+    " _:b1 base1:p1 base1:o1 . "
+
 --  Single statement with junk following
 simpleN3Graph_g1_06 :: String
 simpleN3Graph_g1_06 =
@@ -995,6 +1004,22 @@
     " base1:s1 base1:p1 base1:o1 . \n" ++
     " base2:s2 base1:p1 _:b1 . \n"
 
+simpleN3Graph_g4_1 :: String
+simpleN3Graph_g4_1 =
+    commonPrefixes ++
+    " _:b1 base1:p1 base1:o1._:b2 base2:p2 base2:o2."
+
+simpleN3Graph_g4_2 :: String
+simpleN3Graph_g4_2 =
+    commonPrefixes ++
+    " _:foo1 a base1:o1. _:bar2 a base2:o2."
+
+-- same graph as g4_2
+simpleN3Graph_g4_3 :: String
+simpleN3Graph_g4_3 =
+    commonPrefixes ++
+    " [] a base1:o1.[a base2:o2]."
+
 --  Graph with literal and nodeid
 simpleN3Graph_g5 :: String
 simpleN3Graph_g5 =
@@ -1162,10 +1187,14 @@
   , parseTest "simpleTest013_2" simpleN3Graph_g1_03_2 g1_31  noError
   , parseTest "simpleTest014" simpleN3Graph_g1_04 g1  noError
   , parseTest "simpleTest015" simpleN3Graph_g1_05 g1b noError
+  , parseTest "simpleTest015_1" simpleN3Graph_g1_05_1 g1b_1 noError
   , parseTest "simpleTest016" simpleN3Graph_g1_06 emptyRDFGraph emsg16
   , parseTest "simpleTest03"  simpleN3Graph_g2    g2  noError
   , parseTest "simpleTest04"  simpleN3Graph_g3    g3  noError
   , parseTest "simpleTest05"  simpleN3Graph_g4    g4  noError
+  , parseTest "simpleTest05_1"  simpleN3Graph_g4_1    g4_1  noError
+  , parseTest "simpleTest05_2"  simpleN3Graph_g4_2    g4_2  noError
+  , parseTest "simpleTest05_3"  simpleN3Graph_g4_3    g4_2  noError
   , parseTest "simpleTest06"  simpleN3Graph_g5    g5  noError
   , parseTest "simpleTest07"  simpleN3Graph_g6    g6  noError
   , parseTest "simpleTest08"  simpleN3Graph_g7    g7  noError
