         self.t2icache = LRUCache(capacity: 64)
     }
     
-    private static func idRange(for type: UInt8) -> Range<UInt64> {
+    internal class func isIRI(id: Result) -> Bool {
+        let typebyte = UInt8(UInt64(id) >> 56)
+        return typebyte == iriTypeByte
+    }
+    
+    internal class func isBlank(id: Result) -> Bool {
+        let typebyte = UInt8(UInt64(id) >> 56)
+        return typebyte == blankTypeByte
+    }
+    
+    internal class func isLanguageLiteral(id: Result) -> Bool {
+        let typebyte = UInt8(UInt64(id) >> 56)
+        return typebyte == languageTypeByte
+    }
+    
+    internal class func isDatatypeLiteral(id: Result) -> Bool {
+        let typebyte = UInt8(UInt64(id) >> 56)
+        return typebyte == datatypeTypeByte
+    }
+    
+    private static func idRange(for type: UInt8) -> Range<Result> {
         let min = (UInt64(type) << 56)
         let max = (UInt64(type+1) << 56)
         return min..<max

        return AnyIterator {
            repeat {
                guard let idquad = i.next() else { return nil }
                guard let quad = self.quad(from: idquad) else { return nil }
                if self.accept(quad: quad, languages: self.acceptLanguages) {
                    return idquad
                }
            } while true
        }

        return nil
    }
    
    public func id(for value: Element) -> Result? {
        if let id = self.t2icache[value] {
            return id
        } else if let id = self.pack(value: value) {
