             throw error
         }
     }
+}
+
+extension JSONObject: CustomStringConvertible {
+    public var description: String {
+        return dictionary.description
+    }
+}
+
+extension JSONObject: CustomDebugStringConvertible {
+    public var debugDescription: String {
+        return dictionary.debugDescription
+    }
 }
}

//
// MARK: - JSONKeyType
//

public protocol JSONKeyType: Hashable {
    var stringValue: String { get }
}

extension String: JSONKeyType {
    public var stringValue: String {
        return self
    }
}

//
// MARK: - JSONValueType
//

public protocol JSONValueType {
    typealias ValueType = Self
    
    static func JSONValue(object: Any) throws -> ValueType
}

extension JSONValueType {
    public static func JSONValue(object: Any) throws -> ValueType {
        guard let objectValue = object as? ValueType else {
            throw JSONError.TypeMismatch(expected: ValueType.self, actual: object.dynamicType)
        }
        return objectValue
    }
}

//
// MARK: - JSONValueType Implementations
//

extension String: JSONValueType {}
extension Int: JSONValueType {}
extension UInt: JSONValueType {}
extension Float: JSONValueType {}
extension Double: JSONValueType {}
extension Bool: JSONValueType {}

extension Array where Element: JSONValueType {
    public static func JSONValue(object: Any) throws -> [Element] {
        guard let anyArray = object as? [AnyObject] else {
            throw JSONError.TypeMismatch(expected: self, actual: object.dynamicType)

        return result
    }
    
    public func valueForKey<A: JSONValue>(key: String) throws -> [A] {
        let any = try anyForKey(key)
        return try Array<A>.JSONValue(any)
    }
    
    public func valueForKey<A: JSONValue>(key: String) throws -> A? {
        do {
            return try self.valueForKey(key) as A
        }
        catch JSONError.KeyNotFound {
            return nil
