     /// Helper method to improve decoding speed for large objects:
     /// method returns index map to read value for key without enumerating through all the items
     private static func propertiesIndexMapForType(type: Any.Type, value: CoderTreeValue) -> [String: Int] {
-        for mapInfo in indexMaps {
-            if mapInfo.type == type {
-                return mapInfo.map
-            }
+        if let map = typesHolder.typeMap(forType: type) {
+            return map
         }
 
         func buildIndexMap(items: [CoderTreeValue]) -> [String: Int] {

        switch value {
        case let .IdentifyingTree(_, items):
            let map = buildIndexMap(items)
            indexMaps.append(TypeIndexMap(type: type, map: map))
            return map

        case let .SubTree(items):
            let map = buildIndexMap(items)
            indexMaps.append(TypeIndexMap(type: type, map: map))
            return map
        default:
            return [:]

    let type: Any.Type
    let map: [String: Int]
}

private class TypeIndexMapHolder: SyncHolder<TypeIndexMap> {
    func typeMap(forType type: Any.Type) -> [String: Int]? {
        var result: [String: Int]? = nil
        self.sync {
            for item in self.values where item.type == type {
                result = item.map
                break
            }
        }

        return result
    }

    func save(map map: [String: Int], forType type: Any.Type) {
        self.appendData(TypeIndexMap(type: type, map: map))
    }
}

private let typesHolder = TypeIndexMapHolder()

/**
    A CerealDecoder handles decoding items that were encoded by a `CerealEncoder`.
