     ///   * `TypeNotConvertible`: The target value's type inside of the `JSON`
     ///     instance does not match the decoded value.
     ///   * Any error that arises from decoding the value.
-    public func decode<Decoded: JSONDecodable>(path: JSONPathType..., ifNull: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? {
-        return try decodedAtPath(path, ifNotFound: false, ifNull: ifNull)
+    public func decode<Decoded: JSONDecodable>(first: PathFragment? = nil, _ rest: PathFragment..., ifNull: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? {
+        return try decodedAtPath(first, rest, ifNotFound: false, ifNull: ifNull)
     }
 
     /// Optionally retrieves a `Double` from a path into JSON.

//  Copyright © 2015 Big Nerd Ranch. All rights reserved.
//

import Foundation

// MARK: - JSON Path

/// A protocol representing known paths to a descendant of a `JSON` structure.
///
/// Do not declare new conformances to this protocol; they will not be
/// respected.
public protocol JSONPathType {}

extension String: JSONPathType {}
extension Int: JSONPathType    {}

// MARK: - Subscripting

extension JSON {

    // MARK: Native subscripting

    private enum SubscriptError: ErrorType {
        case SubscriptIntoNull(type: JSONPathType.Type)
    }

    private func descendantAtPath<Path: CollectionType where Path.Generator.Element == JSONPathType>(path: Path, detectNull: Swift.Bool = false) throws -> JSON {
        return try path.reduce(self) { json, path in
            switch (json, path) {
            case let (.Dictionary(dict), key as Swift.String):
                guard let next = dict[key] else {
                    throw Error.KeyNotFound(key: key)
                }
                return next
            case let (.Array(array), index as Swift.Int):
                guard array.startIndex.advancedBy(index, limit: array.endIndex) != array.endIndex else {
                    throw Error.IndexOutOfBounds(index: index)
                }
                return array[index]
            case (.Null, let badSubscript) where detectNull:
                throw SubscriptError.SubscriptIntoNull(type: badSubscript.dynamicType)
            case (_, let badSubscript):
                throw Error.UnexpectedSubscript(type: badSubscript.dynamicType)
            }
        }
    }

    public subscript(key: Swift.String) -> JSON? {
        return try? descendantAtPath(CollectionOfOne(key))
    }

    public subscript(index: Swift.Int) -> JSON? {
        return try? descendantAtPath(CollectionOfOne(index))
    }

    // MARK: Simple member unpacking

    private func decodedAtPath<Decoded: JSONDecodable>(path: [JSONPathType], detectNull: Swift.Bool = false) throws -> Decoded {
        let json = try descendantAtPath(path, detectNull: detectNull)
        return try Decoded(json: json)
    }

    private func arrayAtPath(path: [JSONPathType], detectNull: Swift.Bool = false) throws -> [JSON] {
        let json = try descendantAtPath(path, detectNull: detectNull)
        guard case let .Array(array) = json else {
            throw Error.ValueNotConvertible(type: Swift.Array<JSON>.self)
        }
        return array
    }

    private func dictionaryAtPath(path: [JSONPathType], detectNull: Swift.Bool = false) throws -> [Swift.String: JSON] {
        let json = try descendantAtPath(path, detectNull: detectNull)
        guard case let .Dictionary(dictionary) = json else {
            throw Error.ValueNotConvertible(type: Swift.Dictionary<Swift.String, JSON>.self)
        }
        return dictionary
    }

    /// Attempts to decode into the returning type from a path into JSON.

    /// - throws: One of the `JSON.Error` cases thrown by `decode(_:ifNull:type:)`,
    ///   or any error that arises from decoding the contained values.
    /// - seealso: `JSON.decode(_:ifNull:type:)`
    public func arrayOf<Decoded: JSONDecodable>(first: PathFragment? = nil, _ rest: PathFragment..., ifNull: Swift.Bool) throws -> [Decoded]? {
        let array = try optionalAtPath(first, rest, ifNotFound: false, ifNull: ifNull) { try $0.array() }
        return try array?.map(Decoded.init)
    }

    /// Optionally retrieves a `[String: JSON]` from a path into the recieving
