 extension _CSVRowDecoder: SingleValueDecodingContainer {
 
     private var value: String {
-        let key = codingPath.last!
-        guard let index = key.intValue else {
-            return reader[key.stringValue]!
-        }
-        return reader[index]!
+        let key = self.codingPath.last!
+        if let index = key.intValue {
+            return self.reader.currentRow![index]
+        } else {
+            return self.reader[key.stringValue]!
+        }
     }
 
     private func expectNonNull<T>(_ type: T.Type) throws {

        }
    }

    fileprivate func unbox(_ value: String, as type: Decimal.Type) throws -> Decimal? {
        if value.isEmpty { return nil }

        let doubleValue = try self.unbox(value, as: Double.self)!
        return Decimal(doubleValue)
    }

    fileprivate func unbox<T: Decodable>(_ value: String, as type: T.Type) throws -> T? {
        if value.isEmpty { return nil }

        let decoded: T
        if T.self == Date.self {
            guard let date = try unbox(value, as: Date.self) else { return nil }
            decoded = date as! T
        } else if type == Data.self {
            guard let data = try unbox(value, as: Data.self) else { return nil }
            decoded = data as! T
        } else if type == URL.self {
            guard let url = URL(string: value) else {
                throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath,
                                                                        debugDescription: "Invalid URL string."))
            }
            decoded = (url as! T)
        } else if type == Decimal.self {
            guard let decimal = try self.unbox(value, as: Decimal.self) else { return nil }
            decoded = decimal as! T
        } else {
            return try type.init(from: self)
        }
        return decoded
    }

}

extension DecodingError {

    internal static func _typeMismatch(at path: [CodingKey], expectation: Any.Type, reality: String) -> DecodingError {
        let description = "Expected to decode \(expectation) but found \(reality) instead."
        return .typeMismatch(expectation, Context(codingPath: path, debugDescription: description))
    }

    /// Initializes `self` with default strategies.
    public init() {}

    /// Decodes a top-level value of the given type from the given CSV row representation.
    open func decode<T: Decodable>(_ type: T.Type, from reader: CSVReader) throws -> T {
        let decoder = _CSVRowDecoder(referencing: reader, options: self.options)
        return try type.init(from: decoder)
    }

}

fileprivate final class _CSVRowDecoder: Decoder {

    fileprivate let reader: CSVReader

    fileprivate let options: CSVRowDecoder._Options

    public var codingPath: [CodingKey] = []

    public var userInfo: [CodingUserInfoKey: Any] {
        return self.options.userInfo
    }

    fileprivate init(referencing reader: CSVReader, options: CSVRowDecoder._Options) {
        self.reader = reader
        self.options = options
    }

    public func container<Key: CodingKey>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> {
        let container = CSVKeyedDecodingContainer<Key>(referencing: self)
        return KeyedDecodingContainer(container)
    }
