 
 extension Profile.TagView: RandomAccessCollection {
     
-    public subscript(index: Int) -> Value {
+    public subscript(index: Int) -> TagValue {
         
         get {
             
             guard let tag = tag(at: index)
                 else { fatalError("No tag at index \(index)") }
             
-            guard let buffer = cmsReadTag(internalReference.reference.internalPointer, tag)
+            guard let value = read(tag)
                 else { fatalError("No value for tag \(tag) at index \(index)") }
             
-            // TODO
-            fatalError()
+            return value
         }
     }
     

            
            return internalReference.reference.tag(at: index)
        }
    }
}



// MARK: - Supporting Type

/// Any value that can be retrieved for a tag.
public protocol TagValue { }

fileprivate protocol TagValueConvertible: TagValue {
    
    init(tagValue pointer: UnsafeMutableRawPointer)
}

extension TagValueConvertible {
    
    /// Initializes value by casting pointer.
    init(tagValue pointer: UnsafeMutableRawPointer) {
        
        let pointer = pointer.assumingMemoryBound(to: Self.self)
        
        self = pointer[0]
    }
}

extension TagValueConvertible where Self: ReferenceConvertible, Self.Reference: DuplicableHandle {
    
    /// Initializes value by casting pointer to handle type, creating object wrapper, and then Swift struct.
    init(tagValue pointer: UnsafeMutableRawPointer) {
        
        let pointer = pointer.assumingMemoryBound(to: Self.Reference.InternalPointer.self)
        
        let internalPointer = pointer[0]
        
        // create copy to not corrupt profile handle internals
        guard let newInternalPointer = Self.Reference.cmsDuplicate(internalPointer)
            else { fatalError("Could not create duplicate \(Self.self)") }
        
        let reference = Self.Reference.init(newInternalPointer)
        
        self.init(reference)
    }
}

public extension Tag {
    
    /// The valye type for the specified tag.
    var valueType: TagValue.Type? {
        
        switch self {
            
        case cmsSigAToB0Tag: return Pipeline.self
        case cmsSigAToB1Tag: return Pipeline.self
        case cmsSigAToB2Tag: return Pipeline.self
        case cmsSigBlueColorantTag: return cmsCIEXYZ.self
        case cmsSigBlueMatrixColumnTag: return cmsCIEXYZ.self
            
        default: return nil
        }
    }
}

extension Pipeline: TagValueConvertible { }
extension cmsCIEXYZ: TagValueConvertible { }

// MARK: - Tag Properties

public extension Profile.TagView {
    
    // TODO: implement all tags
    
    public var aToB0: Pipeline? {
        
        return readCasting(cmsSigAToB0Tag)
    }
    
    public var blueColorant: cmsCIEXYZ? {
