diff --git a/JSON/JSON.h b/JSON/JSON.h
new file mode 100755
index 0000000..db3c516
--- /dev/null
+++ b/JSON/JSON.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2009-2010 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ @mainpage A strict JSON parser and generator for Objective-C
+
+ JSON (JavaScript Object Notation) is a lightweight data-interchange
+ format. This framework provides two apis for parsing and generating
+ JSON. One standard object-based and a higher level api consisting of
+ categories added to existing Objective-C classes.
+
+ This framework does its best to be as strict as possible, both in what it accepts and what it generates. For example, it does not support trailing commas in arrays or objects. Nor does it support embedded comments, or anything else not in the JSON specification. This is considered a feature. 
+  
+ @section Links
+
+ @li <a href="http://stig.github.com/json-framework">Project home page</a>.
+ @li Online version of the <a href="http://stig.github.com/json-framework/api">API documentation</a>. 
+ 
+*/
+
+
+// This setting of 1 is best if you copy the source into your project. 
+// The build transforms the 1 to a 0 when building the framework and static lib.
+
+#if 1
+
+#import "SBJsonParser.h"
+#import "SBJsonWriter.h"
+#import "NSObject+SBJSON.h"
+#import "NSString+SBJSON.h"
+
+#else
+
+#import <JSON/SBJsonParser.h>
+#import <JSON/SBJsonWriter.h>
+#import <JSON/NSObject+SBJSON.h>
+#import <JSON/NSString+SBJSON.h>
+
+#endif
diff --git a/JSON/LICENSE b/JSON/LICENSE
new file mode 100755
index 0000000..2e3ec20
--- /dev/null
+++ b/JSON/LICENSE
@@ -0,0 +1,24 @@
+Copyright (C) 2007-2011 Stig Brautaset. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of its contributors may be used
+  to endorse or promote products derived from this software without specific
+  prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/JSON/NSObject+SBJSON.h b/JSON/NSObject+SBJSON.h
new file mode 100755
index 0000000..8e9620e
--- /dev/null
+++ b/JSON/NSObject+SBJSON.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+
+/**
+ @brief Adds JSON generation to Foundation classes
+ 
+ This is a category on NSObject that adds methods for returning JSON representations
+ of standard objects to the objects themselves. This means you can call the
+ -JSONRepresentation method on an NSArray object and it'll do what you want.
+ */
+@interface NSObject (NSObject_SBJSON)
+
+/**
+ @brief Returns a string containing the receiver encoded in JSON.
+
+ This method is added as a category on NSObject but is only actually
+ supported for the following objects:
+ @li NSDictionary
+ @li NSArray
+ */
+- (NSString *)JSONRepresentation;
+
+@end
+
diff --git a/JSON/NSObject+SBJSON.m b/JSON/NSObject+SBJSON.m
new file mode 100755
index 0000000..30570b5
--- /dev/null
+++ b/JSON/NSObject+SBJSON.m
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "NSObject+SBJSON.h"
+#import "SBJsonWriter.h"
+
+@implementation NSObject (NSObject_SBJSON)
+
+- (NSString *)JSONRepresentation {
+    SBJsonWriter *jsonWriter = [SBJsonWriter new];    
+    NSString *json = [jsonWriter stringWithObject:self];
+    if (!json)
+        NSLog(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]);
+    [jsonWriter release];
+    return json;
+}
+
+@end
diff --git a/JSON/NSString+SBJSON.h b/JSON/NSString+SBJSON.h
new file mode 100755
index 0000000..029aa30
--- /dev/null
+++ b/JSON/NSString+SBJSON.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+/**
+ @brief Adds JSON parsing methods to NSString
+ 
+This is a category on NSString that adds methods for parsing the target string.
+*/
+@interface NSString (NSString_SBJSON)
+
+/**
+ @brief Returns the NSDictionary or NSArray represented by the current string's JSON representation.
+ 
+ Returns the dictionary or array represented in the receiver, or nil on error.
+
+ Returns the NSDictionary or NSArray represented by the current string's JSON representation.
+ */
+- (id)JSONValue;
+
+@end
diff --git a/JSON/NSString+SBJSON.m b/JSON/NSString+SBJSON.m
new file mode 100755
index 0000000..bb132e1
--- /dev/null
+++ b/JSON/NSString+SBJSON.m
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2007-2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "NSString+SBJSON.h"
+#import "SBJsonParser.h"
+
+@implementation NSString (NSString_SBJSON)
+
+- (id)JSONValue
+{
+    SBJsonParser *jsonParser = [SBJsonParser new];
+    id repr = [jsonParser objectWithString:self];
+    if (!repr)
+        NSLog(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]);
+    [jsonParser release];
+    return repr;
+}
+
+@end
diff --git a/JSON/SBJsonBase.h b/JSON/SBJsonBase.h
new file mode 100755
index 0000000..7b10844
--- /dev/null
+++ b/JSON/SBJsonBase.h
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+extern NSString * SBJSONErrorDomain;
+
+
+enum {
+    EUNSUPPORTED = 1,
+    EPARSENUM,
+    EPARSE,
+    EFRAGMENT,
+    ECTRL,
+    EUNICODE,
+    EDEPTH,
+    EESCAPE,
+    ETRAILCOMMA,
+    ETRAILGARBAGE,
+    EEOF,
+    EINPUT
+};
+
+/**
+ @brief Common base class for parsing & writing.
+
+ This class contains the common error-handling code and option between the parser/writer.
+ */
+@interface SBJsonBase : NSObject {
+    NSMutableArray *errorTrace;
+
+@protected
+    NSUInteger depth, maxDepth;
+}
+
+/**
+ @brief The maximum recursing depth.
+ 
+ Defaults to 512. If the input is nested deeper than this the input will be deemed to be
+ malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
+ turn off this security feature by setting the maxDepth value to 0.
+ */
+@property NSUInteger maxDepth;
+
+/**
+ @brief Return an error trace, or nil if there was no errors.
+ 
+ Note that this method returns the trace of the last method that failed.
+ You need to check the return value of the call you're making to figure out
+ if the call actually failed, before you know call this method.
+ */
+ @property(copy,readonly) NSArray* errorTrace;
+
+/// @internal for use in subclasses to add errors to the stack trace
+- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str;
+
+/// @internal for use in subclasess to clear the error before a new parsing attempt
+- (void)clearErrorTrace;
+
+@end
diff --git a/JSON/SBJsonBase.m b/JSON/SBJsonBase.m
new file mode 100755
index 0000000..6684325
--- /dev/null
+++ b/JSON/SBJsonBase.m
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SBJsonBase.h"
+NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain";
+
+
+@implementation SBJsonBase
+
+@synthesize errorTrace;
+@synthesize maxDepth;
+
+- (id)init {
+    self = [super init];
+    if (self)
+        self.maxDepth = 512;
+    return self;
+}
+
+- (void)dealloc {
+    [errorTrace release];
+    [super dealloc];
+}
+
+- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str {
+    NSDictionary *userInfo;
+    if (!errorTrace) {
+        errorTrace = [NSMutableArray new];
+        userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey];
+        
+    } else {
+        userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+                    str, NSLocalizedDescriptionKey,
+                    [errorTrace lastObject], NSUnderlyingErrorKey,
+                    nil];
+    }
+    
+    NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo];
+
+    [self willChangeValueForKey:@"errorTrace"];
+    [errorTrace addObject:error];
+    [self didChangeValueForKey:@"errorTrace"];
+}
+
+- (void)clearErrorTrace {
+    [self willChangeValueForKey:@"errorTrace"];
+    [errorTrace release];
+    errorTrace = nil;
+    [self didChangeValueForKey:@"errorTrace"];
+}
+
+@end
diff --git a/JSON/SBJsonParser.h b/JSON/SBJsonParser.h
new file mode 100755
index 0000000..feaccd8
--- /dev/null
+++ b/JSON/SBJsonParser.h
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+#import "SBJsonBase.h"
+
+/**
+ @brief The JSON parser class.
+ 
+ JSON is mapped to Objective-C types in the following way:
+ 
+ @li Null -> NSNull
+ @li String -> NSMutableString
+ @li Array -> NSMutableArray
+ @li Object -> NSMutableDictionary
+ @li Boolean -> NSNumber (initialised with -initWithBool:)
+ @li Number -> (NSNumber | NSDecimalNumber)
+ 
+ Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber
+ instances. These are initialised with the -initWithBool: method, and 
+ round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be
+ represented as 'true' and 'false' again.)
+ 
+ As an optimisation short JSON integers turn into NSNumber instances, while complex ones turn into NSDecimalNumber instances.
+ We can thus avoid any loss of precision as JSON allows ridiculously large numbers.
+ 
+ */
+@interface SBJsonParser : SBJsonBase {
+    
+@private
+    const char *c;
+}
+
+/**
+ @brief Return the object represented by the given string
+ 
+ Returns the object represented by the passed-in string or nil on error. The returned object can be
+ a string, number, boolean, null, array or dictionary.
+ 
+ @param repr the json string to parse
+ */
+- (id)objectWithString:(NSString *)repr;
+
+/**
+ @brief Return the object represented by the given string
+ 
+ Returns the object represented by the passed-in string or nil on error. The returned object can be
+ a string, number, boolean, null, array or dictionary.
+ 
+ @param jsonText the json string to parse
+ @param error pointer to an NSError object to populate on error
+ */
+
+- (id)objectWithString:(NSString*)jsonText
+                 error:(NSError**)error;
+
+
+@end
+
+
diff --git a/JSON/SBJsonParser.m b/JSON/SBJsonParser.m
new file mode 100755
index 0000000..222ef70
--- /dev/null
+++ b/JSON/SBJsonParser.m
@@ -0,0 +1,516 @@
+/*
+ Copyright (C) 2009,2010 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SBJsonParser.h"
+
+@interface SBJsonParser ()
+
+- (BOOL)scanValue:(NSObject **)o;
+
+- (BOOL)scanRestOfArray:(NSMutableArray **)o;
+- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o;
+- (BOOL)scanRestOfNull:(NSNull **)o;
+- (BOOL)scanRestOfFalse:(NSNumber **)o;
+- (BOOL)scanRestOfTrue:(NSNumber **)o;
+- (BOOL)scanRestOfString:(NSMutableString **)o;
+
+// Cannot manage without looking at the first digit
+- (BOOL)scanNumber:(NSNumber **)o;
+
+- (BOOL)scanHexQuad:(unichar *)x;
+- (BOOL)scanUnicodeChar:(unichar *)x;
+
+- (BOOL)scanIsAtEnd;
+
+@end
+
+#define skipWhitespace(c) while (isspace(*c)) c++
+#define skipDigits(c) while (isdigit(*c)) c++
+
+
+@implementation SBJsonParser
+
+static char ctrl[0x22];
+
+
++ (void)initialize {
+    ctrl[0] = '\"';
+    ctrl[1] = '\\';
+    for (int i = 1; i < 0x20; i++)
+        ctrl[i+1] = i;
+    ctrl[0x21] = 0;    
+}
+
+- (id)objectWithString:(NSString *)repr {
+    [self clearErrorTrace];
+    
+    if (!repr) {
+        [self addErrorWithCode:EINPUT description:@"Input was 'nil'"];
+        return nil;
+    }
+    
+    depth = 0;
+    c = [repr UTF8String];
+    
+    id o;
+    if (![self scanValue:&o]) {
+        return nil;
+    }
+    
+    // We found some valid JSON. But did it also contain something else?
+    if (![self scanIsAtEnd]) {
+        [self addErrorWithCode:ETRAILGARBAGE description:@"Garbage after JSON"];
+        return nil;
+    }
+    
+    NSAssert1(o, @"Should have a valid object from %@", repr);
+    
+    // Check that the object we've found is a valid JSON container.
+    if (![o isKindOfClass:[NSDictionary class]] && ![o isKindOfClass:[NSArray class]]) {
+        [self addErrorWithCode:EFRAGMENT description:@"Valid fragment, but not JSON"];
+        return nil;
+    }
+    
+    return o;
+}
+
+- (id)objectWithString:(NSString*)repr error:(NSError**)error {
+    id tmp = [self objectWithString:repr];
+    if (tmp)
+        return tmp;
+    
+    if (error)
+        *error = [self.errorTrace lastObject];
+    return nil;
+}
+
+
+/*
+ In contrast to the public methods, it is an error to omit the error parameter here.
+ */
+- (BOOL)scanValue:(NSObject **)o
+{
+    skipWhitespace(c);
+    
+    switch (*c++) {
+        case '{':
+            return [self scanRestOfDictionary:(NSMutableDictionary **)o];
+            break;
+        case '[':
+            return [self scanRestOfArray:(NSMutableArray **)o];
+            break;
+        case '"':
+            return [self scanRestOfString:(NSMutableString **)o];
+            break;
+        case 'f':
+            return [self scanRestOfFalse:(NSNumber **)o];
+            break;
+        case 't':
+            return [self scanRestOfTrue:(NSNumber **)o];
+            break;
+        case 'n':
+            return [self scanRestOfNull:(NSNull **)o];
+            break;
+        case '-':
+        case '0'...'9':
+            c--; // cannot verify number correctly without the first character
+            return [self scanNumber:(NSNumber **)o];
+            break;
+        case '+':
+            [self addErrorWithCode:EPARSENUM description: @"Leading + disallowed in number"];
+            return NO;
+            break;
+        case 0x0:
+            [self addErrorWithCode:EEOF description:@"Unexpected end of string"];
+            return NO;
+            break;
+        default:
+            [self addErrorWithCode:EPARSE description: @"Unrecognised leading character"];
+            return NO;
+            break;
+    }
+    
+    NSAssert(0, @"Should never get here");
+    return NO;
+}
+
+- (BOOL)scanRestOfTrue:(NSNumber **)o
+{
+    if (!strncmp(c, "rue", 3)) {
+        c += 3;
+        *o = [NSNumber numberWithBool:YES];
+        return YES;
+    }
+    [self addErrorWithCode:EPARSE description:@"Expected 'true'"];
+    return NO;
+}
+
+- (BOOL)scanRestOfFalse:(NSNumber **)o
+{
+    if (!strncmp(c, "alse", 4)) {
+        c += 4;
+        *o = [NSNumber numberWithBool:NO];
+        return YES;
+    }
+    [self addErrorWithCode:EPARSE description: @"Expected 'false'"];
+    return NO;
+}
+
+- (BOOL)scanRestOfNull:(NSNull **)o {
+    if (!strncmp(c, "ull", 3)) {
+        c += 3;
+        *o = [NSNull null];
+        return YES;
+    }
+    [self addErrorWithCode:EPARSE description: @"Expected 'null'"];
+    return NO;
+}
+
+- (BOOL)scanRestOfArray:(NSMutableArray **)o {
+    if (maxDepth && ++depth > maxDepth) {
+        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
+        return NO;
+    }
+    
+    *o = [NSMutableArray arrayWithCapacity:8];
+    
+    for (; *c ;) {
+        id v;
+        
+        skipWhitespace(c);
+        if (*c == ']' && c++) {
+            depth--;
+            return YES;
+        }
+        
+        if (![self scanValue:&v]) {
+            [self addErrorWithCode:EPARSE description:@"Expected value while parsing array"];
+            return NO;
+        }
+        
+        [*o addObject:v];
+        
+        skipWhitespace(c);
+        if (*c == ',' && c++) {
+            skipWhitespace(c);
+            if (*c == ']') {
+                [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in array"];
+                return NO;
+            }
+        }        
+    }
+    
+    [self addErrorWithCode:EEOF description: @"End of input while parsing array"];
+    return NO;
+}
+
+- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o 
+{
+    if (maxDepth && ++depth > maxDepth) {
+        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
+        return NO;
+    }
+    
+    *o = [NSMutableDictionary dictionaryWithCapacity:7];
+    
+    for (; *c ;) {
+        id k, v;
+        
+        skipWhitespace(c);
+        if (*c == '}' && c++) {
+            depth--;
+            return YES;
+        }    
+        
+        if (!(*c == '\"' && c++ && [self scanRestOfString:&k])) {
+            [self addErrorWithCode:EPARSE description: @"Object key string expected"];
+            return NO;
+        }
+        
+        skipWhitespace(c);
+        if (*c != ':') {
+            [self addErrorWithCode:EPARSE description: @"Expected ':' separating key and value"];
+            return NO;
+        }
+        
+        c++;
+        if (![self scanValue:&v]) {
+            NSString *string = [NSString stringWithFormat:@"Object value expected for key: %@", k];
+            [self addErrorWithCode:EPARSE description: string];
+            return NO;
+        }
+        
+        [*o setObject:v forKey:k];
+        
+        skipWhitespace(c);
+        if (*c == ',' && c++) {
+            skipWhitespace(c);
+            if (*c == '}') {
+                [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in object"];
+                return NO;
+            }
+        }        
+    }
+    
+    [self addErrorWithCode:EEOF description: @"End of input while parsing object"];
+    return NO;
+}
+
+- (BOOL)scanRestOfString:(NSMutableString **)o 
+{
+    // if the string has no control characters in it, return it in one go, without any temporary allocations.
+    size_t len = strcspn(c, ctrl);
+    if (len && *(c + len) == '\"')
+    {
+        *o = [[[NSMutableString alloc] initWithBytes:(char*)c length:len encoding:NSUTF8StringEncoding] autorelease];
+        c += len + 1;
+        return YES;
+    }
+    
+    *o = [NSMutableString stringWithCapacity:16];
+    do {
+        // First see if there's a portion we can grab in one go. 
+        // Doing this caused a massive speedup on the long string.
+        len = strcspn(c, ctrl);
+        if (len) {
+            // check for 
+            id t = [[NSString alloc] initWithBytesNoCopy:(char*)c
+                                                  length:len
+                                                encoding:NSUTF8StringEncoding
+                                            freeWhenDone:NO];
+            if (t) {
+                [*o appendString:t];
+                [t release];
+                c += len;
+            }
+        }
+        
+        if (*c == '"') {
+            c++;
+            return YES;
+            
+        } else if (*c == '\\') {
+            unichar uc = *++c;
+            switch (uc) {
+                case '\\':
+                case '/':
+                case '"':
+                    break;
+                    
+                case 'b':   uc = '\b';  break;
+                case 'n':   uc = '\n';  break;
+                case 'r':   uc = '\r';  break;
+                case 't':   uc = '\t';  break;
+                case 'f':   uc = '\f';  break;                    
+                    
+                case 'u':
+                    c++;
+                    if (![self scanUnicodeChar:&uc]) {
+                        [self addErrorWithCode:EUNICODE description: @"Broken unicode character"];
+                        return NO;
+                    }
+                    c--; // hack.
+                    break;
+                default:
+                    [self addErrorWithCode:EESCAPE description: [NSString stringWithFormat:@"Illegal escape sequence '0x%x'", uc]];
+                    return NO;
+                    break;
+            }
+            CFStringAppendCharacters((CFMutableStringRef)*o, &uc, 1);
+            c++;
+            
+        } else if (*c < 0x20) {
+            [self addErrorWithCode:ECTRL description: [NSString stringWithFormat:@"Unescaped control character '0x%x'", *c]];
+            return NO;
+            
+        } else {
+            NSLog(@"should not be able to get here");
+        }
+    } while (*c);
+    
+    [self addErrorWithCode:EEOF description:@"Unexpected EOF while parsing string"];
+    return NO;
+}
+
+- (BOOL)scanUnicodeChar:(unichar *)x
+{
+    unichar hi, lo;
+    
+    if (![self scanHexQuad:&hi]) {
+        [self addErrorWithCode:EUNICODE description: @"Missing hex quad"];
+        return NO;        
+    }
+    
+    if (hi >= 0xd800) {     // high surrogate char?
+        if (hi < 0xdc00) {  // yes - expect a low char
+            
+            if (!(*c == '\\' && ++c && *c == 'u' && ++c && [self scanHexQuad:&lo])) {
+                [self addErrorWithCode:EUNICODE description: @"Missing low character in surrogate pair"];
+                return NO;
+            }
+            
+            if (lo < 0xdc00 || lo >= 0xdfff) {
+                [self addErrorWithCode:EUNICODE description:@"Invalid low surrogate char"];
+                return NO;
+            }
+            
+            hi = (hi - 0xd800) * 0x400 + (lo - 0xdc00) + 0x10000;
+            
+        } else if (hi < 0xe000) {
+            [self addErrorWithCode:EUNICODE description:@"Invalid high character in surrogate pair"];
+            return NO;
+        }
+    }
+    
+    *x = hi;
+    return YES;
+}
+
+- (BOOL)scanHexQuad:(unichar *)x
+{
+    *x = 0;
+    for (int i = 0; i < 4; i++) {
+        unichar uc = *c;
+        c++;
+        int d = (uc >= '0' && uc <= '9')
+        ? uc - '0' : (uc >= 'a' && uc <= 'f')
+        ? (uc - 'a' + 10) : (uc >= 'A' && uc <= 'F')
+        ? (uc - 'A' + 10) : -1;
+        if (d == -1) {
+            [self addErrorWithCode:EUNICODE description:@"Missing hex digit in quad"];
+            return NO;
+        }
+        *x *= 16;
+        *x += d;
+    }
+    return YES;
+}
+
+- (BOOL)scanNumber:(NSNumber **)o
+{
+    BOOL simple = YES;
+    
+    const char *ns = c;
+    
+    // The logic to test for validity of the number formatting is relicensed
+    // from JSON::XS with permission from its author Marc Lehmann.
+    // (Available at the CPAN: http://search.cpan.org/dist/JSON-XS/ .)
+    
+    if ('-' == *c)
+        c++;
+    
+    if ('0' == *c && c++) {        
+        if (isdigit(*c)) {
+            [self addErrorWithCode:EPARSENUM description: @"Leading 0 disallowed in number"];
+            return NO;
+        }
+        
+    } else if (!isdigit(*c) && c != ns) {
+        [self addErrorWithCode:EPARSENUM description: @"No digits after initial minus"];
+        return NO;
+        
+    } else {
+        skipDigits(c);
+    }
+    
+    // Fractional part
+    if ('.' == *c && c++) {
+        simple = NO;
+        if (!isdigit(*c)) {
+            [self addErrorWithCode:EPARSENUM description: @"No digits after decimal point"];
+            return NO;
+        }        
+        skipDigits(c);
+    }
+    
+    // Exponential part
+    if ('e' == *c || 'E' == *c) {
+        simple = NO;
+        c++;
+        
+        if ('-' == *c || '+' == *c)
+            c++;
+        
+        if (!isdigit(*c)) {
+            [self addErrorWithCode:EPARSENUM description: @"No digits after exponent"];
+            return NO;
+        }
+        skipDigits(c);
+    }
+    
+    // If we are only reading integers, don't go through the expense of creating an NSDecimal.
+    // This ends up being a very large perf win.
+    if (simple) {
+        BOOL negate = NO;
+        long long val = 0;
+        const char *d = ns;
+        
+        if (*d == '-') {
+            negate = YES;
+            d++;
+        }
+        
+        while (isdigit(*d)) {
+            val *= 10;
+            if (val < 0)
+                goto longlong_overflow;
+            val += *d - '0';
+            if (val < 0)
+                goto longlong_overflow;
+            d++;
+        }
+        
+        *o = [NSNumber numberWithLongLong:negate ? -val : val];
+        return YES;
+        
+    } else {
+        // jumped to by simple branch, if an overflow occured
+        longlong_overflow:;
+        
+        id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns
+                                                length:c - ns
+                                              encoding:NSUTF8StringEncoding
+                                          freeWhenDone:NO];
+        [str autorelease];
+        if (str && (*o = [NSDecimalNumber decimalNumberWithString:str]))
+            return YES;
+        
+        [self addErrorWithCode:EPARSENUM description: @"Failed creating decimal instance"];
+        return NO;
+    }
+}
+
+- (BOOL)scanIsAtEnd
+{
+    skipWhitespace(c);
+    return !*c;
+}
+
+
+@end
diff --git a/JSON/SBJsonWriter.h b/JSON/SBJsonWriter.h
new file mode 100755
index 0000000..ae1a597
--- /dev/null
+++ b/JSON/SBJsonWriter.h
@@ -0,0 +1,127 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+#import "SBJsonBase.h"
+
+/**
+ @brief The JSON writer class.
+ 
+ Objective-C types are mapped to JSON types in the following way:
+ 
+ @li NSNull -> Null
+ @li NSString -> String
+ @li NSArray -> Array
+ @li NSDictionary -> Object
+ @li NSNumber (-initWithBool:) -> Boolean
+ @li NSNumber -> Number
+ 
+ In JSON the keys of an object must be strings. NSDictionary keys need
+ not be, but attempting to convert an NSDictionary with non-string keys
+ into JSON will throw an exception.
+ 
+ NSNumber instances created with the +initWithBool: method are
+ converted into the JSON boolean "true" and "false" values, and vice
+ versa. Any other NSNumber instances are converted to a JSON number the
+ way you would expect.
+ 
+ */
+@interface SBJsonWriter : SBJsonBase {
+
+@private
+    BOOL sortKeys, humanReadable;
+}
+
+/**
+ @brief Whether we are generating human-readable (multiline) JSON.
+ 
+ Set whether or not to generate human-readable JSON. The default is NO, which produces
+ JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable
+ JSON with linebreaks after each array value and dictionary key/value pair, indented two
+ spaces per nesting level.
+ */
+@property BOOL humanReadable;
+
+/**
+ @brief Whether or not to sort the dictionary keys in the output.
+ 
+ If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
+ (This is useful if you need to compare two structures, for example.) The default is NO.
+ */
+@property BOOL sortKeys;
+
+/**
+ @brief Return JSON representation (or fragment) for the given object.
+ 
+ Returns a string containing JSON representation of the passed in value, or nil on error.
+ If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
+ 
+ @param value any instance that can be represented as a JSON fragment
+ 
+ */
+- (NSString*)stringWithObject:(id)value;
+
+/**
+ @brief Return JSON representation (or fragment) for the given object.
+ 
+ Returns a string containing JSON representation of the passed in value, or nil on error.
+ If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
+ 
+ @param value any instance that can be represented as a JSON fragment
+ @param error pointer to object to be populated with NSError on failure
+ 
+ */- (NSString*)stringWithObject:(id)value
+                           error:(NSError**)error;
+
+
+@end
+
+/**
+ @brief Allows generation of JSON for otherwise unsupported classes.
+ 
+ If you have a custom class that you want to create a JSON representation for you can implement
+ this method in your class. It should return a representation of your object defined
+ in terms of objects that can be translated into JSON. For example, a Person
+ object might implement it like this:
+ 
+ @code
+ - (id)proxyForJson {
+    return [NSDictionary dictionaryWithObjectsAndKeys:
+        name, @"name",
+        phone, @"phone",
+        email, @"email",
+        nil];
+ }
+ @endcode
+ 
+ */
+@interface NSObject (SBProxyForJson)
+- (id)proxyForJson;
+@end
+
diff --git a/JSON/SBJsonWriter.m b/JSON/SBJsonWriter.m
new file mode 100755
index 0000000..83e8a20
--- /dev/null
+++ b/JSON/SBJsonWriter.m
@@ -0,0 +1,239 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ 
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ 
+ * Neither the name of the author nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SBJsonWriter.h"
+
+@interface SBJsonWriter ()
+
+- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json;
+- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json;
+- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json;
+- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json;
+
+- (NSString*)indent;
+
+@end
+
+@implementation SBJsonWriter
+
+@synthesize sortKeys;
+@synthesize humanReadable;
+
+static NSMutableCharacterSet *kEscapeChars;
+
++ (void)initialize {
+	kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain];
+	[kEscapeChars addCharactersInString: @"\"\\"];
+}
+
+- (NSString*)stringWithObject:(id)value {
+    [self clearErrorTrace];
+    
+    if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
+        depth = 0;
+        NSMutableString *json = [NSMutableString stringWithCapacity:128];
+        if ([self appendValue:value into:json])
+            return json;
+    }
+    
+    if ([value respondsToSelector:@selector(proxyForJson)]) {
+        NSString *tmp = [self stringWithObject:[value proxyForJson]];
+        if (tmp)
+            return tmp;
+    }
+        
+    [self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"];
+    return nil;
+}
+
+- (NSString*)stringWithObject:(id)value error:(NSError**)error {
+    NSString *tmp = [self stringWithObject:value];
+    if (tmp)
+        return tmp;
+    
+    if (error)
+        *error = [self.errorTrace lastObject];
+    return nil;
+}
+
+- (NSString*)indent {
+    return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0];
+}
+
+- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json {
+    if ([fragment isKindOfClass:[NSDictionary class]]) {
+        if (![self appendDictionary:fragment into:json])
+            return NO;
+        
+    } else if ([fragment isKindOfClass:[NSArray class]]) {
+        if (![self appendArray:fragment into:json])
+            return NO;
+        
+    } else if ([fragment isKindOfClass:[NSString class]]) {
+        if (![self appendString:fragment into:json])
+            return NO;
+        
+    } else if ([fragment isKindOfClass:[NSNumber class]]) {
+        if ('c' == *[fragment objCType]) {
+            [json appendString:[fragment boolValue] ? @"true" : @"false"];
+        } else if ([fragment isEqualToNumber:(NSNumber*)kCFNumberNaN]) {
+            [self addErrorWithCode:EUNSUPPORTED description:@"NaN is not a valid number in JSON"];
+            return NO;
+
+        } else if (isinf([fragment doubleValue])) {
+            [self addErrorWithCode:EUNSUPPORTED description:@"Infinity is not a valid number in JSON"];
+            return NO;
+
+        } else {
+            [json appendString:[fragment stringValue]];
+        }
+    } else if ([fragment isKindOfClass:[NSNull class]]) {
+        [json appendString:@"null"];
+    } else if ([fragment respondsToSelector:@selector(proxyForJson)]) {
+        [self appendValue:[fragment proxyForJson] into:json];
+        
+    } else {
+        [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]];
+        return NO;
+    }
+    return YES;
+}
+
+- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json {
+    if (maxDepth && ++depth > maxDepth) {
+        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
+        return NO;
+    }
+    [json appendString:@"["];
+    
+    BOOL addComma = NO;    
+    for (id value in fragment) {
+        if (addComma)
+            [json appendString:@","];
+        else
+            addComma = YES;
+        
+        if ([self humanReadable])
+            [json appendString:[self indent]];
+        
+        if (![self appendValue:value into:json]) {
+            return NO;
+        }
+    }
+    
+    depth--;
+    if ([self humanReadable] && [fragment count])
+        [json appendString:[self indent]];
+    [json appendString:@"]"];
+    return YES;
+}
+
+- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json {
+    if (maxDepth && ++depth > maxDepth) {
+        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
+        return NO;
+    }
+    [json appendString:@"{"];
+    
+    NSString *colon = [self humanReadable] ? @" : " : @":";
+    BOOL addComma = NO;
+    NSArray *keys = [fragment allKeys];
+    if (self.sortKeys)
+        keys = [keys sortedArrayUsingSelector:@selector(compare:)];
+    
+    for (id value in keys) {
+        if (addComma)
+            [json appendString:@","];
+        else
+            addComma = YES;
+        
+        if ([self humanReadable])
+            [json appendString:[self indent]];
+        
+        if (![value isKindOfClass:[NSString class]]) {
+            [self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"];
+            return NO;
+        }
+        
+        if (![self appendString:value into:json])
+            return NO;
+        
+        [json appendString:colon];
+        if (![self appendValue:[fragment objectForKey:value] into:json]) {
+            [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]];
+            return NO;
+        }
+    }
+    
+    depth--;
+    if ([self humanReadable] && [fragment count])
+        [json appendString:[self indent]];
+    [json appendString:@"}"];
+    return YES;    
+}
+
+- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json {
+    
+    [json appendString:@"\""];
+    
+    NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars];
+    if ( !esc.length ) {
+        // No special chars -- can just add the raw string:
+        [json appendString:fragment];
+        
+    } else {
+        NSUInteger length = [fragment length];
+        for (NSUInteger i = 0; i < length; i++) {
+            unichar uc = [fragment characterAtIndex:i];
+            switch (uc) {
+                case '"':   [json appendString:@"\\\""];       break;
+                case '\\':  [json appendString:@"\\\\"];       break;
+                case '\t':  [json appendString:@"\\t"];        break;
+                case '\n':  [json appendString:@"\\n"];        break;
+                case '\r':  [json appendString:@"\\r"];        break;
+                case '\b':  [json appendString:@"\\b"];        break;
+                case '\f':  [json appendString:@"\\f"];        break;
+                default:    
+                    if (uc < 0x20) {
+                        [json appendFormat:@"\\u%04x", uc];
+                    } else {
+                        CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1);
+                    }
+                    break;
+                    
+            }
+        }
+    }
+    
+    [json appendString:@"\""];
+    return YES;
+}
+
+
+@end
