Split off the Serialization namespace into a new assembly.
diff --git a/src/ProtocolBuffers.Serialization/DictionaryReader.cs b/src/ProtocolBuffers.Serialization/DictionaryReader.cs
new file mode 100644
index 0000000..cc5c680
--- /dev/null
+++ b/src/ProtocolBuffers.Serialization/DictionaryReader.cs
@@ -0,0 +1,255 @@
+using System;

+using System.Collections.Generic;

+using System.Globalization;

+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), CultureInfo.InvariantCulture);

+                    }

+                    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.CopyFrom(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))

+            {

+                if (typeof (T) == typeof (ByteString))

+                {

+                    ICollection<ByteString> output = (ICollection<ByteString>) items;

+                    foreach (byte[] item in array)

+                    {

+                        output.Add(ByteString.CopyFrom(item));

+                    }

+                }

+                else

+                {

+                    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);

+        }

+    }

+}
\ No newline at end of file