 public protocol JSONDescribeable {
   var jsonDescription: JSON { get }
 }
+
+extension JSON {
+  func getValue(key: String) throws -> JSON {
+    switch self {
+    case .JDictionary(let dictionary):
+      guard let value = dictionary[key] else {
+        throw JSONError.Parse("Could not find \(key) in dictionary \(dictionary)")
+      }
+      return value
+    default:
+      throw JSONError.Parse("\(self) not a dictionary")
+    }
+  }
+
+  func getArray() throws -> [JSON] {
+    switch self {
+    case .JArray(let array):
+      return array
+    default:
+      throw JSONError.Parse("\(self) not an array")
+    }
+  }
+
+  func getDictionary() throws -> [String : JSON] {
+    switch self {
+    case .JDictionary(let dictionary):
+      return dictionary
+    default:
+      throw JSONError.Parse("\(self) not a dictionary")
+    }
+  }
+
+  func getString() throws -> String {
+    switch self {
+    case .JString(let string):
+      return string
+    default:
+      throw JSONError.Parse("\(self) not a string")
+    }
+  }
+
+  func getArrayOfStrings() throws -> [String] {
+    return try self.getArray().map { try $0.getString() }
+  }
+
+  func getDictionaryOfStrings() throws -> [String : String] {
+    var dictionary: [String : String] = [:]
+    for (key, value) in try self.getDictionary() {
+      dictionary[key] = try value.getString()
+    }
+    return dictionary
+  }
+}

        return "Serialization \(error.description)"
      case .Stringifying(let data):
        return "Stringifying \(data.description)"
      }
    }
  }

  case NonEncodable(AnyObject)
  case Serialization(NSError)
  case Stringifying(NSData)
  case Parse(String)

  public var description: String {
    get {
