Added initial DictionaryReader/Writer implementations
diff --git a/src/ProtocolBuffers/Serialization/DictionaryReader.cs b/src/ProtocolBuffers/Serialization/DictionaryReader.cs
new file mode 100644
index 0000000..f8ef1ed
--- /dev/null
+++ b/src/ProtocolBuffers/Serialization/DictionaryReader.cs
@@ -0,0 +1,227 @@
+using System;

+using System.Collections.Generic;

+using System.Text;

+using Google.ProtocolBuffers.Descriptors;

+

+namespace Google.ProtocolBuffers.Serialization

+{

+    /// <summary>

+    /// Allows reading messages from a name/value dictionary

+    /// </summary>

+    public class DictionaryReader : AbstractReader

+    {

+        private readonly IEnumerator<KeyValuePair<string, object>> _input;

+        private bool _ready;

+

+        /// <summary>

+        /// Creates a dictionary reader from an enumeration of KeyValuePair data, like an IDictionary

+        /// </summary>

+        public DictionaryReader(IEnumerable<KeyValuePair<string, object>> input)

+        {

+            _input = input.GetEnumerator();

+            _ready = _input.MoveNext();

+        }

+

+        /// <summary>

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

+        /// </summary>

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

+        {

+            builder.WeakMergeFrom(this, registry);

+            return builder;

+        }

+

+        /// <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 = _ready ? _input.Current.Key : null;

+            return _ready;

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override void Skip()

+        {

+            _ready = _input.MoveNext();

+        }

+

+        private bool GetValue<T>(ref T value)

+        {

+            if (!_ready) return false;

+

+            object obj = _input.Current.Value;

+            if (obj is T)

+                value = (T)obj;

+            else

+            {

+                try 

+                {

+                    if (obj is IConvertible)

+                        value = (T)Convert.ChangeType(obj, typeof(T));

+                    else

+                        value = (T)obj;

+                }

+                catch

+                {

+                    _ready = _input.MoveNext(); 

+                    return false;

+                }

+            }

+            _ready = _input.MoveNext();

+            return true;

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override bool Read(ref bool value)

+        {

+            return GetValue(ref value); 

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override bool Read(ref int value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

+        [CLSCompliant(false)]

+        protected override bool Read(ref uint value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override bool Read(ref long value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

+        [CLSCompliant(false)]

+        protected override bool Read(ref ulong value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override bool Read(ref float value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override bool Read(ref double value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override bool Read(ref string value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

+        protected override bool Read(ref ByteString value)

+        {

+            byte[] rawbytes = null;

+            if (GetValue(ref rawbytes))

+            {

+                value = ByteString.AttachBytes(rawbytes);

+                return true;

+            }

+            return false;

+        }

+

+        /// <summary>

+        /// returns true if it was able to read a single value into the value reference.  The value

+        /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap.

+        /// </summary>

+        protected override bool ReadEnum(ref object value)

+        {

+            return GetValue(ref value);

+        }

+

+        /// <summary>

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

+        /// </summary>

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

+        {

+            IDictionary<string, object> values = null;

+            if (GetValue(ref values))

+            {

+                new DictionaryReader(values).Merge(builder, registry);

+                return true;

+            }

+            return false;

+        }

+

+        public override bool ReadArray<T>(FieldType type, string field, ICollection<T> items)

+        {

+            object[] array = null;

+            if (GetValue(ref array))

+            {

+                foreach (T item in array)

+                    items.Add(item);

+                return true;

+            }

+            return false;

+        }

+        

+        public override bool ReadEnumArray(string field, ICollection<object> items)

+        {

+            object[] array = null;

+            if (GetValue(ref array))

+            {

+                foreach (object item in array)

+                    items.Add(item);

+                return true;

+            }

+            return false;

+        }

+

+        public override bool ReadMessageArray<T>(string field, ICollection<T> items, IMessageLite messageType, ExtensionRegistry registry)

+        {

+            object[] array = null;

+            if (GetValue(ref array))

+            {

+                foreach (IDictionary<string, object> item in array)

+                {

+                    IBuilderLite builder = messageType.WeakCreateBuilderForType();

+                    new DictionaryReader(item).Merge(builder);

+                    items.Add((T)builder.WeakBuild());

+                }

+                return true;

+            }

+            return false;

+        }

+

+        public override bool ReadGroupArray<T>(string field, ICollection<T> items, IMessageLite messageType, ExtensionRegistry registry)

+        { return ReadMessageArray(field, items, messageType, registry); }

+    }

+}