Added the JsonFormatWriter/Reader
diff --git a/src/ProtocolBuffers/Serialization/JsonFormatReader.cs b/src/ProtocolBuffers/Serialization/JsonFormatReader.cs
new file mode 100644
index 0000000..e9df913
--- /dev/null
+++ b/src/ProtocolBuffers/Serialization/JsonFormatReader.cs
@@ -0,0 +1,181 @@
+using System;

+using System.Collections.Generic;

+using System.IO;

+using System.Xml;

+

+namespace Google.ProtocolBuffers.Serialization

+{

+    /// <summary>

+    /// JsonFormatReader is used to parse Json into a message or an array of messages

+    /// </summary>

+    public class JsonFormatReader : AbstractTextReader

+    {

+        private readonly JsonTextCursor _input;

+        private readonly Stack<int> _stopChar;

+

+        enum ReaderState { Start, BeginValue, EndValue, BeginObject, BeginArray }

+        string _current;

+        ReaderState _state;

+

+        /// <summary>

+        /// Constructs a JsonFormatReader to parse Json into a message

+        /// </summary>

+        public JsonFormatReader(string jsonText)

+        {

+            _input = new JsonTextCursor(jsonText.ToCharArray());

+            _stopChar = new Stack<int>();

+            _stopChar.Push(-1);

+            _state = ReaderState.Start;

+        }

+        /// <summary>

+        /// Constructs a JsonFormatReader to parse Json into a message

+        /// </summary>

+        public JsonFormatReader(TextReader input)

+        {

+            _input = new JsonTextCursor(input);

+            _stopChar = new Stack<int>();

+            _stopChar.Push(-1);

+            _state = ReaderState.Start;

+        }

+

+        /// <summary>

+        /// Returns true if the reader is currently on an array element

+        /// </summary>

+        public bool IsArrayMessage { get { return _input.NextChar == '['; } }

+

+        /// <summary>

+        /// Returns an enumerator that is used to cursor over an array of messages

+        /// </summary>

+        /// <remarks>

+        /// This is generally used when receiving an array of messages rather than a single root message

+        /// </remarks>

+        public IEnumerable<JsonFormatReader> EnumerateArray()

+        {

+            foreach (string ignored in ForeachArrayItem(_current))

+                yield return this;

+        }

+

+        /// <summary>

+        /// Merges the contents of stream into the provided message builder

+        /// </summary>

+        public override TBuilder Merge<TBuilder>(TBuilder builder, ExtensionRegistry registry)

+        {

+            _input.Consume('{');

+            _stopChar.Push('}');

+

+            _state = ReaderState.BeginObject;

+            builder.WeakMergeFrom(this, registry);

+            _input.Consume((char)_stopChar.Pop());

+            _state = ReaderState.EndValue;

+            return builder;

+        }

+

+        /// <summary>

+        /// Causes the reader to skip past this field

+        /// </summary>

+        protected override void Skip()

+        {

+            object temp;

+            _input.ReadVariant(out temp);

+            _state = ReaderState.EndValue;

+        }

+

+        /// <summary>

+        /// Peeks at the next field in the input stream and returns what information is available.

+        /// </summary>

+        /// <remarks>

+        /// This may be called multiple times without actually reading the field.  Only after the field

+        /// is either read, or skipped, should PeekNext return a different value.

+        /// </remarks>

+        protected override bool PeekNext(out string field)

+        {

+            field = _current;

+            if(_state == ReaderState.BeginValue)

+                return true;

+

+            int next = _input.NextChar;

+            if (next == _stopChar.Peek())

+                return false;

+

+            _input.Assert(next != -1, "Unexpected end of file.");

+

+            //not sure about this yet, it will allow {, "a":true }

+            if (_state == ReaderState.EndValue && !_input.TryConsume(','))

+                return false;

+

+            field = _current = _input.ReadString();

+            _input.Consume(':');

+            _state = ReaderState.BeginValue;

+            return true;

+        }

+

+        /// <summary>

+        /// Returns true if it was able to read a String from the input

+        /// </summary>

+        protected override bool ReadAsText(ref string value, Type typeInfo)

+        {

+            object temp;

+            JsonTextCursor.JsType type = _input.ReadVariant(out temp);

+            _state = ReaderState.EndValue;

+

+            _input.Assert(type != JsonTextCursor.JsType.Array && type != JsonTextCursor.JsType.Object, "Encountered {0} while expecting {1}", type, typeInfo);

+            if (type == JsonTextCursor.JsType.Null)

+                return false;

+            if (type == JsonTextCursor.JsType.True) value = "1";

+            else if (type == JsonTextCursor.JsType.False) value = "0";

+            else value = temp as string;

+

+            //exponent representation of integer number:

+            if (value != null && type == JsonTextCursor.JsType.Number &&

+                (typeInfo != typeof(double) && typeInfo != typeof(float)) &&

+                value.IndexOf("e", StringComparison.OrdinalIgnoreCase) > 0)

+            {

+                value = XmlConvert.ToString((long)Math.Round(XmlConvert.ToDouble(value), 0));

+            }

+            return value != null;

+        }

+

+        /// <summary>

+        /// Returns true if it was able to read a ByteString from the input

+        /// </summary>

+        protected override bool Read(ref ByteString value)

+        {

+            string bytes = null;

+            if (Read(ref bytes))

+            {

+                value = ByteString.FromBase64(bytes);

+                return true;

+            }

+            return false;

+        }

+

+        /// <summary>

+        /// Cursors through the array elements and stops at the end of the array

+        /// </summary>

+        protected override IEnumerable<string> ForeachArrayItem(string field)

+        {

+            _input.Consume('[');

+            _stopChar.Push(']');

+            _state = ReaderState.BeginArray;

+            while (_input.NextChar != ']')

+            {

+                _current = field;

+                yield return field;

+                if(!_input.TryConsume(','))

+                    break;

+            }

+            _input.Consume((char)_stopChar.Pop());

+            _state = ReaderState.EndValue;

+        }

+

+        /// <summary>

+        /// Merges the input stream into the provided IBuilderLite 

+        /// </summary>

+        protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry)

+        {

+            Merge(builder, registry);

+            return true;

+        }

+

+    }

+}