~ type/isomorphic patterns are now injected through mixins
authorAlexandre Bertails <bertails@w3.org>
Mon, 10 Jan 2011 12:26:03 -0500
changeset 301 0723e0dfeb73
parent 300 1fe229a63701
child 302 e2bf09a1a9d6
~ type/isomorphic patterns are now injected through mixins
directmapping/src/main/scala/DirectMapping.scala
directmapping/src/test/scala/DirectMappingTest.scala
rdf/src/main/scala/RDF.scala
rdfxml/src/main/scala/RDFXML.scala
rdfxml/src/test/scala/RDFXMLTest.scala
turtle/src/main/scala/turtle.scala
turtle/src/test/scala/turtleTest.scala
--- a/directmapping/src/main/scala/DirectMapping.scala	Sun Jan 09 17:42:49 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala	Mon Jan 10 12:26:03 2011 -0500
@@ -1,243 +1,209 @@
 package org.w3.directmapping
 
-import org.w3.rdf._
+import org.w3.rdf.{Model => RDFModel, Implicits => RDFImplicits, _}
 
 import org.w3.rdb.RDB._
 
-trait DirectMapping[IRI,
-                    Graph <: Traversable[Triple],
-                    Triple,
-                    BNode,
-                    Node,
-                    NodeIRI <: Node,
-                    NodeBNode <: Node,
-                    Subject,
-                    SubjectNode <: Subject,
-                    Predicate,
-                    PredicateIRI <: Predicate,
-                    Object,
-                    ObjectNode <: Object,
-                    ObjectLiteral <: Object,
-                    Literal,
-                    PlainLiteral <: Literal,
-                    TypedLiteral <: Literal,
-                    LangTag] {
-
-  val RDFModule:RDFModule[IRI,
-                          Graph,
-                          Triple,
-                          BNode,
-                          Node,
-                          NodeIRI,
-                          NodeBNode,
-                          Subject,
-                          SubjectNode,
-                          Predicate,
-                          PredicateIRI,
-                          Object,
-                          ObjectNode,
-                          ObjectLiteral,
-                          Literal,
-                          PlainLiteral,
-                          TypedLiteral,
-                          LangTag]
-
-  import RDFModule._
+trait DirectMappingModule extends RDFModel {
 
-  /** A KeyMap associates the candidate key and key values with the
-   * node for any tuple in a unique relation. */
-  case class KeyMap(m:Map[CandidateKey,  Map[List[CellValue], Node]]) {
-    //def KeyMap() : KeyMap = KeyMap(Map[CandidateKey,  Map[List[CellValue], Node]]())
-    def apply(i:CandidateKey) : Map[List[CellValue], Node] = m(i)
-    def ++(pairs:List[(CandidateKey, List[CellValue])], n:Node):KeyMap = {
-      val m2:Map[CandidateKey,  Map[List[CellValue], Node]] =
-	pairs.foldLeft(m)((m, p) => {
-	  if (m.get(p._1).isDefined) {
-	    val byKey = m(p._1)
-	    if (byKey.get(p._2).isDefined) {
-	      error("tried to set " + p._1 + p._2 + " = " + n + "(was " + byKey(p._2) + ")")
-	    } else {
-	      val im1 = byKey ++ Map[List[CellValue], Node](p._2 -> n)
-	      m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> im1)
-	    }
-	  } else {
-	    m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> Map(p._2 -> n))
-	  }
-	})
-      KeyMap(m2)
+  trait DirectMapping {
+
+    /** A KeyMap associates the candidate key and key values with the
+     * node for any tuple in a unique relation. */
+    case class KeyMap(m:Map[CandidateKey,  Map[List[CellValue], Node]]) {
+      //def KeyMap() : KeyMap = KeyMap(Map[CandidateKey,  Map[List[CellValue], Node]]())
+      def apply(i:CandidateKey) : Map[List[CellValue], Node] = m(i)
+      def ++(pairs:List[(CandidateKey, List[CellValue])], n:Node):KeyMap = {
+        val m2:Map[CandidateKey,  Map[List[CellValue], Node]] =
+          pairs.foldLeft(m)((m, p) => {
+            if (m.get(p._1).isDefined) {
+              val byKey = m(p._1)
+              if (byKey.get(p._2).isDefined) {
+                error("tried to set " + p._1 + p._2 + " = " + n + "(was " + byKey(p._2) + ")")
+              } else {
+                val im1 = byKey ++ Map[List[CellValue], Node](p._2 -> n)
+                m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> im1)
+              }
+            } else {
+              m ++ Map[CandidateKey, Map[List[CellValue], Node]](p._1 -> Map(p._2 -> n))
+            }
+          })
+        KeyMap(m2)
+      }
+      def contains(ck:CandidateKey) = m.contains(ck)
     }
-    def contains(ck:CandidateKey) = m.contains(ck)
-  }
-  case class NodeMap(m:Map[RelName, KeyMap]) {
-    def apply(rn:RelName) = m(rn)
-    def ultimateReferent (rn:RelName, k:CandidateKey, vs:List[LexicalValue], db:Database) : Node = {
-      // Issue: What if fk is a rearrangement of the pk, per issue fk-pk-order?
-      if (db(rn).pk.isDefined && db(rn).fks.contains(db(rn).pk.get.attrs)) {
-	/** Table's primary key is a foreign key. */
-	val target = db(rn).fks(db(rn).pk.get.attrs)
-	ultimateReferent(target.rel, target.key, vs, db)
-      } else
-	m(rn)(k)(vs)
+    case class NodeMap(m:Map[RelName, KeyMap]) {
+      def apply(rn:RelName) = m(rn)
+      def ultimateReferent (rn:RelName, k:CandidateKey, vs:List[LexicalValue], db:Database) : Node = {
+        // Issue: What if fk is a rearrangement of the pk, per issue fk-pk-order?
+        if (db(rn).pk.isDefined && db(rn).fks.contains(db(rn).pk.get.attrs)) {
+          /** Table's primary key is a foreign key. */
+          val target = db(rn).fks(db(rn).pk.get.attrs)
+          ultimateReferent(target.rel, target.key, vs, db)
+        } else
+          m(rn)(k)(vs)
+      }
+      def contains(rn:RelName) = m.contains(rn)
     }
-    def contains(rn:RelName) = m.contains(rn)
-  }
-  implicit def list2map (l:Set[(RelName, KeyMap)]):Map[RelName,KeyMap] = l.toMap
-  implicit def list2Nmap (l:Set[(RelName, KeyMap)]):NodeMap = NodeMap(l)
+    implicit def list2map (l:Set[(RelName, KeyMap)]):Map[RelName,KeyMap] = l.toMap
+    implicit def list2Nmap (l:Set[(RelName, KeyMap)]):NodeMap = NodeMap(l)
+  
+    /** The direct mapping requires one parameter: the StemIRI */
+    case class StemIRI(stem:String) {
+      def +(path:String):IRI = IRI(stem + path)
+    }
+  
+    /**
+     * The mapping functions implementing
+     * <http://www.w3.org/2001/sw/rdb2rdf/directGraph/>
+     */
+  
+    def references (t:Tuple, r:Relation):Set[List[AttrName]] = {
+      val allFKs:Set[List[AttrName]] = r.fks.keySet.toSet
+      val nulllist:Set[AttrName] = t.nullAttributes(r.header)
+      val nullFKs:Set[List[AttrName]] = allFKs.flatMap(a => {
+        val int:Set[AttrName] = nulllist & a.toSet
+        if (int.toList.length == 0) None else List(a)
+      })
+  
+      /** Check to see if r's primary key is a hierarchical key.
+       * http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
+      if (r.pk.isDefined && r.fks.contains(r.pk.get.attrs))
+        r.fks.keySet.toSet -- nullFKs - r.fks(r.pk.get.attrs).key.attrs
+      else
+        r.fks.keySet.toSet -- nullFKs
+    }
+  
+    def scalars (t:Tuple, r:Relation):Set[AttrName] = {
+      val allAttrs:Set[AttrName] = r.header.keySet.toSet
+      val allFKs:Set[List[AttrName]] = r.fks.keySet.toSet
+      val unaryFKs:Set[AttrName] = allFKs.flatMap(a => {
+        if (a.length == 1) a else None
+      })
+      val nulllist:Set[AttrName] = t.nullAttributes(r.header)
+  
+      /** Check to see if r's primary key is a hierarchical key.
+       * http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
+      if (r.pk.isDefined && r.fks.contains(r.pk.get.attrs))
+        allAttrs -- unaryFKs -- nulllist ++ r.fks(r.pk.get.attrs).key.attrs
+      else
+        allAttrs -- unaryFKs -- nulllist
+    }
+  
+    /** The NodeMap-generating functions: */
+    def relation2KeyMap (r:Relation) : KeyMap = {
+      val m = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
+      r.body.foldLeft(m)((m, t) => {
+        val (pairs, node) = rdfNodeForTuple(t, r)
+        m ++ (pairs, node)
+      })
+    }
+  
+    def rdfNodeForTuple (t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
+      val s:Node =
+        if (r.pk.isDefined) {
+          /** Table has a primkary key. */
+          val vs = t.lexvaluesNoNulls(r.pk.get.attrs)
+          NodeIRI(nodemap(r.name, r.pk.get.attrs, vs))
+        } else
+          /** Table has no primkary key (but has some candidate keys). */
+          NodeBNode(freshbnode())
+      (r.candidates.map(k => {
+        val values:List[CellValue] = k.attrs.map(a => t(a))
+        (k, values)
+      }), s)
+    }
+  
+    /** The triples-generating functions start with databasemap: */
+    def directDB (db:Database) : Graph = {
+      val idxables = db.keySet.toSet filter { rn => !db(rn).candidates.isEmpty }
+      val nodeMap:NodeMap = idxables map {rn => rn -> relation2KeyMap(db(rn))}
+      Graph(db.keySet flatMap  { (rn:RelName) => directR(db(rn), nodeMap, db) })
+    }
+  
+    def directR (r:Relation, nodes:NodeMap, db:Database) : Graph =
+      /* flatMap.toSet assumes that no two triples from directT would be the same.
+       * We know this because relations with candidate keys are mapped to unique
+       * subjects, and potentially redundant rows get unique blank node subjects.
+       */
+      Graph(r.body flatMap { t => directT(t, r, nodes, db) })
+  
+    def directT (t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
+      val s:Node =
+        if (r.candidates.size > 0) {
+          // Known to have at least one key, so take the first one.
+          val k = r.candidates(0)
+          val vs = t.lexvaluesNoNulls(k.attrs)
+          nodes.ultimateReferent(r.name, k, vs, db)
+        } else
+          /** Table has no candidate keys. */
+          NodeBNode(freshbnode())
+      directS(s, t, r, nodes, db)
+    }
+  
+    def directS (s:Node, t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
+      references(t, r).map(as => directN(s, as, r, t, nodes)) ++
+      scalars(t, r).map(a => directL(r.name, s, a, r.header, t))
+    }
+  
+    var NextBNode = 97
+    def freshbnode () : BNode = {
+      val ret = NextBNode
+      NextBNode = NextBNode + 1
+      BNode(ret.toChar.toString)
+    }
+  
+    def directL (rn:RelName, s:Node, a:AttrName, h:Header, t:Tuple) : Triple = {
+      val p = predicatemap (rn, List(a))
+      val l = t.lexvalue(a).get
+      val o = literalmap(l, h.sqlDatatype(a))
+      Triple(SubjectNode(s),
+             PredicateIRI(p),
+             ObjectLiteral(o))
+    }
+    def directN (s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
+      val p = predicatemap (r.name, as)
+      val ls:List[LexicalValue] = t.lexvaluesNoNulls(as)
+      val target = r.fks(as)
+      if (!nodes.contains(target.rel))
+        error("No referent relation \"" + target.rel + "\" to match " + r.name + t)
+      if (!nodes(target.rel).contains(target.key))
+        error("Relation " + target.rel + " has no attributes (" + target.key + ") to match " + r.name + t)
+      if (!nodes(target.rel)(target.key).contains(ls))
+        error("Relation " + target.rel + "(" + target.key + ") has no values " + ls + " to match " + r.name + t)
+      val o:Object = ObjectNode(nodes(target.rel)(target.key)(ls))
+      Triple(SubjectNode(s), PredicateIRI(p), o)
+    }
+  
+    // These implicits make nodemap and predicatemap functions prettier.
+    implicit def relName2string (rn:RelName) = rn.n
+    implicit def attrName2string (rn:AttrName) = rn.n
+  
+    def nodemap (rn:RelName, as:List[AttrName], ls:List[LexicalValue]) : IRI = {
+      val pairs:List[String] = as.zip(ls).map(x => UE(x._1) + "." + UE(x._2.s))
+      IRI(UE(rn) + "/" + pairs.mkString("_") + "#_")
+    }
+  
+    def predicatemap (rn:RelName, as:List[AttrName]) : IRI =
+      IRI(UE(rn) + "#" + as.mkString("_"))
+  
+    def XSD (d:Datatype) : IRI =
+      d match {
+        case Datatype.INTEGER => IRI("http://www.w3.org/2001/XMLSchema#integer")
+        case Datatype.FLOAT => IRI("http://www.w3.org/2001/XMLSchema#float")
+        case Datatype.DATE => IRI("http://www.w3.org/2001/XMLSchema#date")
+        case Datatype.TIME => IRI("http://www.w3.org/2001/XMLSchema#time")
+        case Datatype.TIMESTAMP => IRI("http://www.w3.org/2001/XMLSchema#timestamp")
+        case Datatype.CHAR => IRI("http://www.w3.org/2001/XMLSchema#char")
+        case Datatype.VARCHAR => IRI("http://www.w3.org/2001/XMLSchema#varchar")
+        case Datatype.STRING => IRI("http://www.w3.org/2001/XMLSchema#string")
+      }
+  
+    def literalmap (l:LexicalValue, d:Datatype) : TypedLiteral =
+      TypedLiteral(l.s, XSD(d))
+  
+    def UE (s:String) : String = s.replaceAll(" ", "+")
 
-  /** The direct mapping requires one parameter: the StemIRI */
-  case class StemIRI(stem:String) {
-    def +(path:String):IRI = IRI(stem + path)
-  }
-
-  /**
-   * The mapping functions implementing
-   * <http://www.w3.org/2001/sw/rdb2rdf/directGraph/>
-   */
-
-  def references (t:Tuple, r:Relation):Set[List[AttrName]] = {
-    val allFKs:Set[List[AttrName]] = r.fks.keySet.toSet
-    val nulllist:Set[AttrName] = t.nullAttributes(r.header)
-    val nullFKs:Set[List[AttrName]] = allFKs.flatMap(a => {
-      val int:Set[AttrName] = nulllist & a.toSet
-      if (int.toList.length == 0) None else List(a)
-    })
-
-    /** Check to see if r's primary key is a hierarchical key.
-     * http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
-    if (r.pk.isDefined && r.fks.contains(r.pk.get.attrs))
-      r.fks.keySet.toSet -- nullFKs - r.fks(r.pk.get.attrs).key.attrs
-    else
-      r.fks.keySet.toSet -- nullFKs
   }
 
-  def scalars (t:Tuple, r:Relation):Set[AttrName] = {
-    val allAttrs:Set[AttrName] = r.header.keySet.toSet
-    val allFKs:Set[List[AttrName]] = r.fks.keySet.toSet
-    val unaryFKs:Set[AttrName] = allFKs.flatMap(a => {
-      if (a.length == 1) a else None
-    })
-    val nulllist:Set[AttrName] = t.nullAttributes(r.header)
-
-    /** Check to see if r's primary key is a hierarchical key.
-     * http://www.w3.org/2001/sw/rdb2rdf/directGraph/#rule3 */
-    if (r.pk.isDefined && r.fks.contains(r.pk.get.attrs))
-      allAttrs -- unaryFKs -- nulllist ++ r.fks(r.pk.get.attrs).key.attrs
-    else
-      allAttrs -- unaryFKs -- nulllist
-  }
-
-  /** The NodeMap-generating functions: */
-  def relation2KeyMap (r:Relation) : KeyMap = {
-    val m = KeyMap(Map[CandidateKey, Map[List[CellValue], Node]]())
-    r.body.foldLeft(m)((m, t) => {
-      val (pairs, node) = rdfNodeForTuple(t, r)
-      m ++ (pairs, node)
-    })
-  }
-
-  def rdfNodeForTuple (t:Tuple, r:Relation) : (List[(CandidateKey, List[CellValue])], Node) = {
-    val s:Node =
-      if (r.pk.isDefined) {
-	/** Table has a primkary key. */
-	val vs = t.lexvaluesNoNulls(r.pk.get.attrs)
-	NodeIRI(nodemap(r.name, r.pk.get.attrs, vs))
-      } else
-	/** Table has no primkary key (but has some candidate keys). */
-	NodeBNode(freshbnode())
-    (r.candidates.map(k => {
-      val values:List[CellValue] = k.attrs.map(a => t(a))
-      (k, values)
-    }), s)
-  }
-
-  /** The triples-generating functions start with databasemap: */
-  def directDB (db:Database) : Graph = {
-    val idxables = db.keySet.toSet filter { rn => !db(rn).candidates.isEmpty }
-    val nodeMap:NodeMap = idxables map {rn => rn -> relation2KeyMap(db(rn))}
-    Graph(db.keySet flatMap  { (rn:RelName) => directR(db(rn), nodeMap, db) })
-  }
-
-  def directR (r:Relation, nodes:NodeMap, db:Database) : Graph =
-    /* flatMap.toSet assumes that no two triples from directT would be the same.
-     * We know this because relations with candidate keys are mapped to unique
-     * subjects, and potentially redundant rows get unique blank node subjects.
-     */
-    Graph(r.body flatMap { t => directT(t, r, nodes, db) })
-
-  def directT (t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
-    val s:Node =
-      if (r.candidates.size > 0) {
-	// Known to have at least one key, so take the first one.
-	val k = r.candidates(0)
-	val vs = t.lexvaluesNoNulls(k.attrs)
-	nodes.ultimateReferent(r.name, k, vs, db)
-      } else
-	/** Table has no candidate keys. */
-	NodeBNode(freshbnode())
-    directS(s, t, r, nodes, db)
-  }
-
-  def directS (s:Node, t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
-    references(t, r).map(as => directN(s, as, r, t, nodes)) ++
-    scalars(t, r).map(a => directL(r.name, s, a, r.header, t))
-  }
-
-  var NextBNode = 97
-  def freshbnode () : BNode = {
-    val ret = NextBNode
-    NextBNode = NextBNode + 1
-    BNode(ret.toChar.toString)
-  }
-
-  def directL (rn:RelName, s:Node, a:AttrName, h:Header, t:Tuple) : Triple = {
-    val p = predicatemap (rn, List(a))
-    val l = t.lexvalue(a).get
-    val o = literalmap(l, h.sqlDatatype(a))
-    Triple(SubjectNode(s),
-           PredicateIRI(p),
-           ObjectLiteral(o))
-  }
-  def directN (s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
-    val p = predicatemap (r.name, as)
-    val ls:List[LexicalValue] = t.lexvaluesNoNulls(as)
-    val target = r.fks(as)
-    if (!nodes.contains(target.rel))
-      error("No referent relation \"" + target.rel + "\" to match " + r.name + t)
-    if (!nodes(target.rel).contains(target.key))
-      error("Relation " + target.rel + " has no attributes (" + target.key + ") to match " + r.name + t)
-    if (!nodes(target.rel)(target.key).contains(ls))
-      error("Relation " + target.rel + "(" + target.key + ") has no values " + ls + " to match " + r.name + t)
-    val o:Object = ObjectNode(nodes(target.rel)(target.key)(ls))
-    Triple(SubjectNode(s), PredicateIRI(p), o)
-  }
-
-  // These implicits make nodemap and predicatemap functions prettier.
-  implicit def relName2string (rn:RelName) = rn.n
-  implicit def attrName2string (rn:AttrName) = rn.n
-
-  def nodemap (rn:RelName, as:List[AttrName], ls:List[LexicalValue]) : IRI = {
-    val pairs:List[String] = as.zip(ls).map(x => UE(x._1) + "." + UE(x._2.s))
-    IRI(UE(rn) + "/" + pairs.mkString("_") + "#_")
-  }
-
-  def predicatemap (rn:RelName, as:List[AttrName]) : IRI =
-    IRI(UE(rn) + "#" + as.mkString("_"))
-
-  def XSD (d:Datatype) : IRI =
-    d match {
-      case Datatype.INTEGER => IRI("http://www.w3.org/2001/XMLSchema#integer")
-      case Datatype.FLOAT => IRI("http://www.w3.org/2001/XMLSchema#float")
-      case Datatype.DATE => IRI("http://www.w3.org/2001/XMLSchema#date")
-      case Datatype.TIME => IRI("http://www.w3.org/2001/XMLSchema#time")
-      case Datatype.TIMESTAMP => IRI("http://www.w3.org/2001/XMLSchema#timestamp")
-      case Datatype.CHAR => IRI("http://www.w3.org/2001/XMLSchema#char")
-      case Datatype.VARCHAR => IRI("http://www.w3.org/2001/XMLSchema#varchar")
-      case Datatype.STRING => IRI("http://www.w3.org/2001/XMLSchema#string")
-    }
-
-  def literalmap (l:LexicalValue, d:Datatype) : TypedLiteral =
-    TypedLiteral(l.s, XSD(d))
-
-  def UE (s:String) : String = s.replaceAll(" ", "+")
 }
-
--- a/directmapping/src/test/scala/DirectMappingTest.scala	Sun Jan 09 17:42:49 2011 -0500
+++ b/directmapping/src/test/scala/DirectMappingTest.scala	Mon Jan 10 12:26:03 2011 -0500
@@ -1,73 +1,20 @@
 package org.w3.directmapping
 
-import org.w3.rdf._
+import org.w3.rdf.{Model => RDFModel, Implicits => RDFImplicits, _}
 import org.w3.rdb.RDB._
 import org.w3.sql
-import org.w3.rdf.turtle.Turtle
+import org.w3.rdf.turtle.TurtleModule
 //import org.w3.directmapping.DirectMapping
 import java.io.File
 
 import org.scalatest.FunSuite
 
-class FundamentalTestWithRDF extends FundamentalTest(RDFConcreteModuleWithImplicits)
+class FundamentalTestWithRDF extends FundamentalTest with ConcreteModel with RDFImplicits
 
-abstract class FundamentalTest[IRI,
-                          Graph <: Traversable[Triple],
-                          Triple,
-                          BNode,
-                          Node,
-                          NodeIRI <: Node,
-                          NodeBNode <: Node,
-                          Subject,
-                          SubjectNode <: Subject,
-                          Predicate,
-                          PredicateIRI <: Predicate,
-                          Object,
-                          ObjectNode <: Object,
-                          ObjectLiteral <: Object,
-                          Literal,
-                          PlainLiteral <: Literal,
-                          TypedLiteral <: Literal,
-                          LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
-                                                                        Graph,
-                                                                        Triple,
-                                                                        BNode,
-                                                                        Node,
-                                                                        NodeIRI,
-                                                                        NodeBNode,
-                                                                        Subject,
-                                                                        SubjectNode,
-                                                                        Predicate,
-                                                                        PredicateIRI,
-                                                                        Object,
-                                                                        ObjectNode,
-                                                                        ObjectLiteral,
-                                                                        Literal,
-                                                                        PlainLiteral,
-                                                                        TypedLiteral,
-                                                                        LangTag])
-extends FunSuite { self =>
+abstract class FundamentalTest extends FunSuite with DirectMappingModule with RDFImplicits {
 
-  import RDFModule._
+  val DirectMapping = new DirectMapping {  }
 
-  val DirectMapping = new DirectMapping[IRI,
-                                        Graph,
-                                        Triple,
-                                        BNode,
-                                        Node,
-                                        NodeIRI,
-                                        NodeBNode,
-                                        Subject,
-                                        SubjectNode,
-                                        Predicate,
-                                        PredicateIRI,
-                                        Object,
-                                        ObjectNode,
-                                        ObjectLiteral,
-                                        Literal,
-                                        PlainLiteral,
-                                        TypedLiteral,
-                                        LangTag] { val RDFModule = self.RDFModule }
   import DirectMapping._
 
   test("NodeMap") {
@@ -101,89 +48,17 @@
 
 
 
-class DirectMappingTestWithRDF extends DirectMappingTest(RDFConcreteModuleWithImplicits)
-
-
+class DirectMappingTestWithConcreteModel extends DirectMappingTest with ConcreteModel
 
-abstract class DirectMappingTest[IRI,
-                                 Graph <: Traversable[Triple],
-                                 Triple,
-                                 BNode,
-                                 Node,
-                                 NodeIRI <: Node,
-                                 NodeBNode <: Node,
-                                 Subject,
-                                 SubjectNode <: Subject,
-                                 Predicate,
-                                 PredicateIRI <: Predicate,
-                                 Object,
-                                 ObjectNode <: Object,
-                                 ObjectLiteral <: Object,
-                                 Literal,
-                                 PlainLiteral <: Literal,
-                                 TypedLiteral <: Literal,
-                                 LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
-                                                                               Graph,
-                                                                               Triple,
-                                                                               BNode,
-                                                                               Node,
-                                                                               NodeIRI,
-                                                                               NodeBNode,
-                                                                               Subject,
-                                                                               SubjectNode,
-                                                                               Predicate,
-                                                                               PredicateIRI,
-                                                                               Object,
-                                                                               ObjectNode,
-                                                                               ObjectLiteral,
-                                                                               Literal,
-                                                                               PlainLiteral,
-                                                                               TypedLiteral,
-                                                                               LangTag])
-extends FunSuite { self =>
+trait DirectMappingTest extends FunSuite with RDFModel with RDFImplicits with DirectMappingModule with TurtleModule {
 
-  import RDFModule._
+  val DirectMapping = new DirectMapping {  }
 
-  val DirectMapping = new DirectMapping[IRI,
-                                        Graph,
-                                        Triple,
-                                        BNode,
-                                        Node,
-                                        NodeIRI,
-                                        NodeBNode,
-                                        Subject,
-                                        SubjectNode,
-                                        Predicate,
-                                        PredicateIRI,
-                                        Object,
-                                        ObjectNode,
-                                        ObjectLiteral,
-                                        Literal,
-                                        PlainLiteral,
-                                        TypedLiteral,
-                                        LangTag] { val RDFModule = self.RDFModule }
   import DirectMapping._
 
   val SqlParser = sql.SqlParser()
 
-  val TurtleParser = new Turtle[IRI,
-                                Graph,
-                                Triple,
-                                BNode,
-                                Node,
-                                NodeIRI,
-                                NodeBNode,
-                                Subject,
-                                SubjectNode,
-                                Predicate,
-                                PredicateIRI,
-                                Object,
-                                ObjectNode,
-                                ObjectLiteral,
-                                Literal,
-                                PlainLiteral,
-                                TypedLiteral,
-                                LangTag] { val RDFModule = self.RDFModule }
+  val turtleParser = new TurtleParser { }
 
   def testDirectMapping(testName:String, db:Database, expectedGraph:Graph):Unit =
     test(testName) {
@@ -193,7 +68,7 @@
 
   def testDirectMapping(testName:String, dbFile:File, expectedGraphFile:File):Unit = {
     val db = SqlParser.toDB(dbFile)
-    val expectedGraph:Graph = TurtleParser.toGraph(expectedGraphFile)
+    val expectedGraph:Graph = turtleParser.toGraph(expectedGraphFile)
     testDirectMapping(testName, db, expectedGraph)
   }
 
--- a/rdf/src/main/scala/RDF.scala	Sun Jan 09 17:42:49 2011 -0500
+++ b/rdf/src/main/scala/RDF.scala	Mon Jan 10 12:26:03 2011 -0500
@@ -2,32 +2,35 @@
 
 import org.w3.isomorphic._
 
-trait RDFModule[IRI,
-                Graph <: Traversable[Triple],
-                Triple,
-                BNode,
-                Node,
-                NodeIRI <: Node,
-                NodeBNode <: Node,
-                Subject,
-                SubjectNode <: Subject,
-                Predicate,
-                PredicateIRI <: Predicate,
-                Object,
-                ObjectNode <: Object,
-                ObjectLiteral <: Object,
-                Literal,
-                PlainLiteral <: Literal,
-                TypedLiteral <: Literal,
-                LangTag] {
+trait Model {
+
+  type IRI
+  type Graph <: Traversable[Triple]
+  type Triple
+  type BNode
+  type Node
+  type NodeIRI <: Node
+  type NodeBNode <: Node
+  type Subject
+  type SubjectNode <: Subject
+  type Predicate
+  type PredicateIRI <: Predicate
+  type Object
+  type ObjectNode <: Object
+  type ObjectLiteral <: Object
+  type Literal
+  type PlainLiteral <: Literal
+  type TypedLiteral <: Literal
+  type LangTag
 
   val IRI : Isomorphic1[String, IRI]
 
-  val Graph : {
+  trait GraphObject {
     def empty:Graph
     def apply(elems:Triple*):Graph
     def apply(it:Iterable[Triple]):Graph
   }
+  val Graph : GraphObject
 
   val Triple : Isomorphic3[Subject, Predicate, Object, Triple]
 
@@ -48,50 +51,16 @@
 
   val LangTag : Isomorphic1[String, LangTag]
 
-  lazy val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
-  lazy val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
-  lazy val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
-  lazy val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
+  val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
+  val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
+  val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
+  val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
 
 }
 
 
-trait RDFModuleWithImplicits[IRI,
-                             Graph <: Traversable[Triple],
-                             Triple,
-                             BNode,
-                             Node,
-                             NodeIRI <: Node,
-                             NodeBNode <: Node,
-                             Subject,
-                             SubjectNode <: Subject,
-                             Predicate,
-                             PredicateIRI <: Predicate,
-                             Object,
-                             ObjectNode <: Object,
-                             ObjectLiteral <: Object,
-                             Literal,
-                             PlainLiteral <: Literal,
-                             TypedLiteral <: Literal,
-                             LangTag]
-extends RDFModule[IRI,
-                  Graph,
-                  Triple,
-                  BNode,
-                  Node,
-                  NodeIRI,
-                  NodeBNode,
-                  Subject,
-                  SubjectNode,
-                  Predicate,
-                  PredicateIRI,
-                  Object,
-                  ObjectNode,
-                  ObjectLiteral,
-                  Literal,
-                  PlainLiteral,
-                  TypedLiteral,
-                  LangTag] {
+trait Implicits extends Model {
+
   implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
   implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
   implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
@@ -105,13 +74,13 @@
   implicit def plain2object(b:PlainLiteral):Object = ObjectLiteral(b)
 }
 
-object RDFConcreteModel {
+trait ConcreteModel extends Model {
 
   case class IRI(iri:String) { override def toString = '"' + iri + '"' }
   object IRI extends Isomorphic1[String, IRI]
 
   type Graph = Set[Triple]
-  val Graph = new Object {
+  object Graph extends GraphObject {
     def empty:Graph = Set[Triple]()
     def apply(elems:Triple*):Graph = Set[Triple](elems:_*)
     def apply(it:Iterable[Triple]):Graph = it.toSet
@@ -158,56 +127,6 @@
 
 }
 
-import RDFConcreteModel._
-trait RDFConcreteModule extends RDFModule[IRI,
-                                          Graph,
-                                          Triple,
-                                          BNode,
-                                          Node,
-                                          NodeIRI,
-                                          NodeBNode,
-                                          Subject,
-                                          SubjectNode,
-                                          Predicate,
-                                          PredicateIRI,
-                                          Object,
-                                          ObjectNode,
-                                          ObjectLiteral,
-                                          Literal,
-                                          PlainLiteral,
-                                          TypedLiteral,
-                                          LangTag] {
-  val IRI = RDFConcreteModel.IRI
-  val Graph = RDFConcreteModel.Graph
-  val Triple = RDFConcreteModel.Triple
-  val BNode = RDFConcreteModel.BNode
-  val NodeIRI = RDFConcreteModel.NodeIRI
-  val NodeBNode = RDFConcreteModel.NodeBNode
-  val SubjectNode = RDFConcreteModel.SubjectNode
-  val PredicateIRI = RDFConcreteModel.PredicateIRI
-  val ObjectNode = RDFConcreteModel.ObjectNode
-  val ObjectLiteral = RDFConcreteModel.ObjectLiteral
-  val PlainLiteral = RDFConcreteModel.PlainLiteral
-  val TypedLiteral = RDFConcreteModel.TypedLiteral
-  val LangTag = RDFConcreteModel.LangTag
-}
+object ConcreteModel extends ConcreteModel
 
-object RDFConcreteModule extends RDFConcreteModule
-object RDFConcreteModuleWithImplicits extends RDFConcreteModule with RDFModuleWithImplicits[IRI,
-                                                                                            Graph,
-                                                                                            Triple,
-                                                                                            BNode,
-                                                                                            Node,
-                                                                                            NodeIRI,
-                                                                                            NodeBNode,
-                                                                                            Subject,
-                                                                                            SubjectNode,
-                                                                                            Predicate,
-                                                                                            PredicateIRI,
-                                                                                            Object,
-                                                                                            ObjectNode,
-                                                                                            ObjectLiteral,
-                                                                                            Literal,
-                                                                                            PlainLiteral,
-                                                                                            TypedLiteral,
-                                                                                            LangTag]
+object ConcreteModelWithImplicits extends ConcreteModel with Implicits
--- a/rdfxml/src/main/scala/RDFXML.scala	Sun Jan 09 17:42:49 2011 -0500
+++ b/rdfxml/src/main/scala/RDFXML.scala	Mon Jan 10 12:26:03 2011 -0500
@@ -1,6 +1,6 @@
 package org.w3.rdf.rdfxml
 
-import org.w3.rdf._
+import org.w3.rdf.{Model => RDFModel, Implicits => RDFImplicits, _}
 
 import com.hp.hpl.jena.rdf.arp._
 import org.xml.sax._
@@ -38,116 +38,80 @@
   }
 }
 
-trait RDFXML[IRI,
-             Graph <: Traversable[Triple],
-             Triple,
-             BNode,
-             Node,
-             NodeIRI <: Node,
-             NodeBNode <: Node,
-             Subject,
-             SubjectNode <: Subject,
-             Predicate,
-             PredicateIRI <: Predicate,
-             Object,
-             ObjectNode <: Object,
-             ObjectLiteral <: Object,
-             Literal,
-             PlainLiteral <: Literal,
-             TypedLiteral <: Literal,
-             LangTag] {
-
-   val RDFModule:RDFModule[IRI,
-                           Graph,
-                           Triple,
-                           BNode,
-                           Node,
-                           NodeIRI,
-                           NodeBNode,
-                           Subject,
-                           SubjectNode,
-                           Predicate,
-                           PredicateIRI,
-                           Object,
-                           ObjectNode,
-                           ObjectLiteral,
-                           Literal,
-                           PlainLiteral,
-                           TypedLiteral,
-                           LangTag]
-  
-  import RDFModule._
-
-  /**
-   * http://jena.sourceforge.net/javadoc/com/hp/hpl/jena/rdf/arp/AResource.html
-   * note: see setUserData and getUserData for when BNode will be abstract
-   */
-  def toNode(a:AResource):Node =
-    if (a.isAnonymous)
-      NodeBNode(BNode(a.getAnonymousID))
-    else
-      NodeIRI(IRI(a.getURI))
-
-  def toPredicate(a:AResource):Predicate = PredicateIRI(IRI(a.getURI))
+trait RDFXMLModule extends RDFModel {
 
-  def toLiteral(l:ALiteral):Literal = {
-    val datatype:String = l.getDatatypeURI
-    if (datatype == null) {
-      val lang = l.getLang match {
-	case "" => None
-	case l  => Some(LangTag(l))
-      }
-      PlainLiteral(l.toString, lang)
-    } else {
-      TypedLiteral(l.toString, IRI(datatype))
-    }
-  }
-
-  def toGraph(file:File):(Graph, List[ParseError]) = toGraph(new FileInputStream(file))
-
-  def toGraph(rdfxml:String):(Graph, List[ParseError]) = toGraph(new StringReader(rdfxml))
-
-  def toGraph(in:InputStream):(Graph, List[ParseError]) = toGraph(new BufferedReader(new InputStreamReader(in)))
-
-  def toGraph(in:Reader):(Graph, List[ParseError]) = {
-
-    // the accumulator for the triples
-    var triples = Set[Triple]()
-
-    // the accumulators for the problems we encounter
-    var parseErrors = List[ParseError]()
+  trait RDFXMLParser {
 
-    // this ErrorHandler keeps track of all the problems during the parsing
-    val errorHandler = new ErrorHandler {
-      def fatalError(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, FatalError)
-      def error(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, Error)
-      def warning(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, Warning)
+    /**
+     * http://jena.sourceforge.net/javadoc/com/hp/hpl/jena/rdf/arp/AResource.html
+     * note: see setUserData and getUserData for when BNode will be abstract
+     */
+    def toNode(a:AResource):Node =
+      if (a.isAnonymous)
+        NodeBNode(BNode(a.getAnonymousID))
+      else
+        NodeIRI(IRI(a.getURI))
+  
+    def toPredicate(a:AResource):Predicate = PredicateIRI(IRI(a.getURI))
+  
+    def toLiteral(l:ALiteral):Literal = {
+      val datatype:String = l.getDatatypeURI
+      if (datatype == null) {
+        val lang = l.getLang match {
+          case "" => None
+          case l  => Some(LangTag(l))
+        }
+        PlainLiteral(l.toString, lang)
+      } else {
+        TypedLiteral(l.toString, IRI(datatype))
+      }
     }
-
-    // this StatementHandler read the parsed triples
-    val statementHandler = new StatementHandler {
-      def statement(s:AResource, p:AResource, o:ALiteral):Unit =
-	triples += Triple(SubjectNode(toNode(s)),
-			  toPredicate(p),
-			  ObjectLiteral(toLiteral(o)))
-      def statement(s:AResource, p:AResource, o:AResource):Unit =
-	triples += Triple(SubjectNode(toNode(s)),
-			  toPredicate(p),
-			  ObjectNode(toNode(o)))
+  
+    def toGraph(file:File):(Graph, List[ParseError]) = toGraph(new FileInputStream(file))
+  
+    def toGraph(rdfxml:String):(Graph, List[ParseError]) = toGraph(new StringReader(rdfxml))
+  
+    def toGraph(in:InputStream):(Graph, List[ParseError]) = toGraph(new BufferedReader(new InputStreamReader(in)))
+  
+    def toGraph(in:Reader):(Graph, List[ParseError]) = {
+  
+      // the accumulator for the triples
+      var triples = Set[Triple]()
+  
+      // the accumulators for the problems we encounter
+      var parseErrors = List[ParseError]()
+  
+      // this ErrorHandler keeps track of all the problems during the parsing
+      val errorHandler = new ErrorHandler {
+        def fatalError(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, FatalError)
+        def error(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, Error)
+        def warning(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, Warning)
+      }
+  
+      // this StatementHandler read the parsed triples
+      val statementHandler = new StatementHandler {
+        def statement(s:AResource, p:AResource, o:ALiteral):Unit =
+          triples += Triple(SubjectNode(toNode(s)),
+                            toPredicate(p),
+                            ObjectLiteral(toLiteral(o)))
+        def statement(s:AResource, p:AResource, o:AResource):Unit =
+          triples += Triple(SubjectNode(toNode(s)),
+                            toPredicate(p),
+                            ObjectNode(toNode(o)))
+      }
+  
+      // http://jena.sourceforge.net/ARP/standalone.html
+  
+      val arp = new ARP
+      arp.getOptions.setStrictErrorMode
+      arp.getHandlers.setErrorHandler(errorHandler)
+      arp.getHandlers.setStatementHandler(statementHandler)
+      arp.load(in)
+  
+      // returns an immutable set and the potential errors
+      (Graph(triples), parseErrors)
     }
-
-    // http://jena.sourceforge.net/ARP/standalone.html
-
-    val arp = new ARP
-    arp.getOptions.setStrictErrorMode
-    arp.getHandlers.setErrorHandler(errorHandler)
-    arp.getHandlers.setStatementHandler(statementHandler)
-    arp.load(in)
-
-    // returns an immutable set and the potential errors
-    (Graph(triples), parseErrors)
+  
   }
 
 }
-
-
--- a/rdfxml/src/test/scala/RDFXMLTest.scala	Sun Jan 09 17:42:49 2011 -0500
+++ b/rdfxml/src/test/scala/RDFXMLTest.scala	Mon Jan 10 12:26:03 2011 -0500
@@ -1,68 +1,14 @@
 package org.w3.rdf.rdfxml
 
-import org.w3.rdf._
+import org.w3.rdf.{Model => RDFModel, Implicits => RDFImplicits, _}
 
 import org.scalatest.FunSuite
 
-class RDFXMLTestWithRDF extends RDFXMLTest(RDFConcreteModuleWithImplicits)
+class RDFXMLTestWithRDF extends RDFXMLTest with ConcreteModel with RDFImplicits
 
-abstract class RDFXMLTest[IRI,
-                          Graph <: Traversable[Triple],
-                          Triple,
-                          BNode,
-                          Node,
-                          NodeIRI <: Node,
-                          NodeBNode <: Node,
-                          Subject,
-                          SubjectNode <: Subject,
-                          Predicate,
-                          PredicateIRI <: Predicate,
-                          Object,
-                          ObjectNode <: Object,
-                          ObjectLiteral <: Object,
-                          Literal,
-                          PlainLiteral <: Literal,
-                          TypedLiteral <: Literal,
-                          LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
-                                                                        Graph,
-                                                                        Triple,
-                                                                        BNode,
-                                                                        Node,
-                                                                        NodeIRI,
-                                                                        NodeBNode,
-                                                                        Subject,
-                                                                        SubjectNode,
-                                                                        Predicate,
-                                                                        PredicateIRI,
-                                                                        Object,
-                                                                        ObjectNode,
-                                                                        ObjectLiteral,
-                                                                        Literal,
-                                                                        PlainLiteral,
-                                                                        TypedLiteral,
-                                                                        LangTag])
-extends FunSuite { self =>
+abstract class RDFXMLTest extends FunSuite with RDFXMLModule with RDFImplicits {
 
-  import RDFModule._
-
-  val parser = new RDFXML[IRI,
-                                Graph,
-                                Triple,
-                                BNode,
-                                Node,
-                                NodeIRI,
-                                NodeBNode,
-                                Subject,
-                                SubjectNode,
-                                Predicate,
-                                PredicateIRI,
-                                Object,
-                                ObjectNode,
-                                ObjectLiteral,
-                                Literal,
-                                PlainLiteral,
-                                TypedLiteral,
-                                LangTag] { val RDFModule = self.RDFModule }
+  val parser = new RDFXMLParser {  }
 
   test("default on http://www.rdfabout.com/demo/validator/") {
 
--- a/turtle/src/main/scala/turtle.scala	Sun Jan 09 17:42:49 2011 -0500
+++ b/turtle/src/main/scala/turtle.scala	Mon Jan 10 12:26:03 2011 -0500
@@ -1,6 +1,6 @@
 package org.w3.rdf.turtle
 
-import org.w3.rdf._
+import org.w3.rdf.{Model => RDFModel, Implicits => RDFImplicits, _}
 import scala.util.parsing.combinator._
 import java.net.URI
 
@@ -14,116 +14,80 @@
 
 import MyParsers._
 
-trait Turtle[IRI,
-             Graph <: Traversable[Triple],
-             Triple,
-             BNode,
-             Node,
-             NodeIRI <: Node,
-             NodeBNode <: Node,
-             Subject,
-             SubjectNode <: Subject,
-             Predicate,
-             PredicateIRI <: Predicate,
-             Object,
-             ObjectNode <: Object,
-             ObjectLiteral <: Object,
-             Literal,
-             PlainLiteral <: Literal,
-             TypedLiteral <: Literal,
-             LangTag]
- extends JavaTokenParsers {
-               
-   val RDFModule:RDFModule[IRI,
-                           Graph,
-                           Triple,
-                           BNode,
-                           Node,
-                           NodeIRI,
-                           NodeBNode,
-                           Subject,
-                           SubjectNode,
-                           Predicate,
-                           PredicateIRI,
-                           Object,
-                           ObjectNode,
-                           ObjectLiteral,
-                           Literal,
-                           PlainLiteral,
-                           TypedLiteral,
-                           LangTag]
-
-   import RDFModule._
-
-   def toGraph(t:String):Graph = parseAll(turtle, t).get
-
-   def toGraph(file:java.io.File):Graph = {
-     val t = scala.io.Source.fromFile(file).getLines.reduceLeft(_+_)
-     parseAll(turtle, t).get
-   }
-
-   def turtle:Parser[Graph] =
-     opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(RDFModule.Graph.empty) }
-
-   def prefixdecl:Parser[Unit] =
-     "@prefix" ~ name ~ ":" ~ qnameORuri ~ "." ^^ { case "@prefix"~pre~":"~u~"." => prefixes += (pre -> { val IRI(iri) = u ; iri }) }
+trait TurtleModule extends RDFModel {
+ 
+  trait TurtleParser extends JavaTokenParsers {
+ 
+    def toGraph(t:String):Graph = parseAll(turtle, t).get
 
-   def triplesblock:Parser[Graph] =
-     rep(triplepatternOrPrefixOrBase) ^^ { case pats => Graph(pats.flatten) }
- 
-   def triplepatternOrPrefixOrBase:Parser[Option[Triple]] = (
-       triplepattern ^^ { case p => Some(p) }
-     | prefixdecl ^^ { case _ => None }
-   )
- 
-   def triplepattern:Parser[Triple] =
-     subject ~ predicate ~ objectt ~ "." ^^ { case s~p~o~"." => Triple(s, p, o) }
- 
-   def subject:Parser[Subject] = (
-       qnameORuri ^^ { case x => SubjectNode(NodeIRI(x)) }
-     | bnode ^^ { case x => SubjectNode(NodeBNode(x)) }
-   )
- 
-   def predicate:Parser[Predicate] = (
-       qnameORuri ^^ { case x => PredicateIRI(x) }
-     | "a" ^^ { x => PredicateIRI(IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
-   )
- 
-   def objectt:Parser[Object] = (
-       qnameORuri ^^ { case x => ObjectNode(NodeIRI(x)) }
-     | bnode ^^ { case x => ObjectNode(NodeBNode(x)) }
-     | literal ^^ { case x => ObjectLiteral(x) }
-   )
+    def toGraph(file:java.io.File):Graph = {
+      val t = scala.io.Source.fromFile(file).getLines.reduceLeft(_+_)
+      parseAll(turtle, t).get
+    }
  
-   def qnameORuri:Parser[IRI] = (
-       "<"~uri~">" ^^ { case "<"~x~">" => IRI(x) }
-     | name~":"~name ^^ {
-       case prefix~":"~localName => try {
- 	IRI(prefixes(prefix) + localName)
-       } catch {
- 	case e:java.util.NoSuchElementException =>
- 	  throw new Exception("unknown prefix " + prefix)
-       }
-     }
-   )
- 
-   def bnode:Parser[BNode] =
-     "_:"~name ^^ { case "_:"~name => BNode(name) }
- 
-   def literal:Parser[Literal] = (
-       stringLiteral~"^^"~qnameORuri ^^
-       {
- 	case lit~"^^"~dt => TypedLiteral(lit.substring(1,lit.size - 1), dt match {
-  	  case IRI("http://www.w3.org/2001/XMLSchema#string") => StringDatatype
-  	  case IRI("http://www.w3.org/2001/XMLSchema#integer") => IntegerDatatype
-  	  case IRI("http://www.w3.org/2001/XMLSchema#date") => DateDatatype
-  	  case IRI("http://www.w3.org/2001/XMLSchema#dateTime") => DateTimeDatatype
-  	  case x => error("only programed to deal with string and integer, not " + x)
-  	})
-       }
-     | integer ^^ { l => TypedLiteral(l, IntegerDatatype) }
-   )
-
+    def turtle:Parser[Graph] =
+      opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(Graph.empty) }
+    
+    def prefixdecl:Parser[Unit] =
+      "@prefix" ~ name ~ ":" ~ qnameORuri ~ "." ^^ { case "@prefix"~pre~":"~u~"." => prefixes += (pre -> { val IRI(iri) = u ; iri }) }
+    
+    def triplesblock:Parser[Graph] =
+      rep(triplepatternOrPrefixOrBase) ^^ {
+        case pats => Graph(pats.flatten)
+      }
+    
+    def triplepatternOrPrefixOrBase:Parser[Option[Triple]] = (
+        triplepattern ^^ { case p => Some(p) }
+      | prefixdecl ^^ { case _ => None }
+    )
+      
+    def triplepattern:Parser[Triple] =
+      subject ~ predicate ~ objectt ~ "." ^^ { case s~p~o~"." => Triple(s, p, o) }
+  
+    def subject:Parser[Subject] = (
+        qnameORuri ^^ { case x => SubjectNode(NodeIRI(x)) }
+      | bnode ^^ { case x => SubjectNode(NodeBNode(x)) }
+    )
+      
+    def predicate:Parser[Predicate] = (
+        qnameORuri ^^ { case x => PredicateIRI(x) }
+      | "a" ^^ { x => PredicateIRI(IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
+    )
+      
+    def objectt:Parser[Object] = (
+        qnameORuri ^^ { case x => ObjectNode(NodeIRI(x)) }
+      | bnode ^^ { case x => ObjectNode(NodeBNode(x)) }
+      | literal ^^ { case x => ObjectLiteral(x) }
+    )
+  
+    def qnameORuri:Parser[IRI] = (
+        "<"~uri~">" ^^ { case "<"~x~">" => IRI(x) }
+      | name~":"~name ^^ {
+        case prefix~":"~localName => try {
+          IRI(prefixes(prefix) + localName)
+        } catch {
+          case e:java.util.NoSuchElementException =>
+            throw new Exception("unknown prefix " + prefix)
+        }
+      }
+    )
+  
+    def bnode:Parser[BNode] =
+      "_:"~name ^^ { case "_:"~name => BNode(name) }
+  
+    def literal:Parser[Literal] = (
+      stringLiteral~"^^"~qnameORuri ^^ {
+        case lit~"^^"~dt => TypedLiteral(lit.substring(1,lit.size - 1), dt match {
+          case IRI("http://www.w3.org/2001/XMLSchema#string") => StringDatatype
+          case IRI("http://www.w3.org/2001/XMLSchema#integer") => IntegerDatatype
+          case IRI("http://www.w3.org/2001/XMLSchema#date") => DateDatatype
+          case IRI("http://www.w3.org/2001/XMLSchema#dateTime") => DateTimeDatatype
+          case x => error("only programed to deal with string and integer, not " + x)
+        })
+      }
+      | integer ^^ { l => TypedLiteral(l, IntegerDatatype) }
+    )
+  }
 }
 
 
--- a/turtle/src/test/scala/turtleTest.scala	Sun Jan 09 17:42:49 2011 -0500
+++ b/turtle/src/test/scala/turtleTest.scala	Mon Jan 10 12:26:03 2011 -0500
@@ -1,67 +1,13 @@
 package org.w3.rdf.turtle
 
-import org.w3.rdf._
+import org.w3.rdf.{Model => RDFModel, Implicits => RDFImplicits, _}
 import org.scalatest.FunSuite
 
-class TurtleTestWithRDF extends TurtleTest(RDFConcreteModuleWithImplicits)
+class TurtleTestWithRDF extends TurtleTest with ConcreteModel with RDFImplicits
 
-abstract class TurtleTest[IRI,
-                          Graph <: Traversable[Triple],
-                          Triple,
-                          BNode,
-                          Node,
-                          NodeIRI <: Node,
-                          NodeBNode <: Node,
-                          Subject,
-                          SubjectNode <: Subject,
-                          Predicate,
-                          PredicateIRI <: Predicate,
-                          Object,
-                          ObjectNode <: Object,
-                          ObjectLiteral <: Object,
-                          Literal,
-                          PlainLiteral <: Literal,
-                          TypedLiteral <: Literal,
-                          LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
-                                                                        Graph,
-                                                                        Triple,
-                                                                        BNode,
-                                                                        Node,
-                                                                        NodeIRI,
-                                                                        NodeBNode,
-                                                                        Subject,
-                                                                        SubjectNode,
-                                                                        Predicate,
-                                                                        PredicateIRI,
-                                                                        Object,
-                                                                        ObjectNode,
-                                                                        ObjectLiteral,
-                                                                        Literal,
-                                                                        PlainLiteral,
-                                                                        TypedLiteral,
-                                                                        LangTag])
-extends FunSuite { self =>
+abstract class TurtleTest extends FunSuite with TurtleModule with RDFImplicits {
 
-  import RDFModule._
-
-  val turtleParser = new Turtle[IRI,
-                                Graph,
-                                Triple,
-                                BNode,
-                                Node,
-                                NodeIRI,
-                                NodeBNode,
-                                Subject,
-                                SubjectNode,
-                                Predicate,
-                                PredicateIRI,
-                                Object,
-                                ObjectNode,
-                                ObjectLiteral,
-                                Literal,
-                                PlainLiteral,
-                                TypedLiteral,
-                                LangTag] { val RDFModule = self.RDFModule }
+  val turtleParser = new TurtleParser { }
 
   test("directgraph_emp_adder") {
     val directgraph_emp_adder:Graph =