         case .Number(let v):    return v.description
         case .String(let v):    return v.debugDescription
         case .Array(let a):
-            return "[" + a.map{ $0.description }.joined(separator:",") + "]"
+            return "[" + t
+                + a.map{ $0.toString(depth:d+1, separator:s, terminator:t, sortedKey:sortedKey) }
+                    .map{ i + s + $0 }.joined(separator:","+t) + t
+                + i + "]" + (d == 0 ? t : "")
         case .Object(let o):
-            var ds = [Swift.String]()
-            for (k, v) in o {
-                ds.append(k.debugDescription + ":" + v.description)
-            }
-            return "{" + ds.joined(separator:",") + "}"
-        }
+            let a = sortedKey ? o.map{ $0 }.sorted{ $0.0 < $1.0 } : o.map{ $0 }
+            return "{" + t
+                + a.map { $0.debugDescription + g + ":" + g + $1.toString(depth:d+1, separator:s, terminator:t, sortedKey:sortedKey) }
+                    .map{ i + s + $0 }.joined(separator:"," + t) + t
+                + i + "}" + (d == 0 ? t : "")
+        }
+    }
+    public func toString(space:Int=0)->String {
+        return space == 0
+            ? toString(depth:0, separator:"", terminator:"")
+            : toString(depth:0, separator:Swift.String(repeating:" ", count:space), terminator:"\n", sortedKey:true)
+    }
+    public var description:String {
+        return self.toString()
     }
 }
 // Inits

    }
}
extension JSON : CustomStringConvertible {
    public var description:String {
        switch self {
        case .Error(let m):     return ".Error(\"\(m)\")"
        case .Null:             return "null"

        return self.description.data(using:.utf8)!
    }
    public var jsonObject:Any {
        return try! JSONSerialization.jsonObject(with:self.data, options:[.allowFragments])
    }
}
extension JSON {
