Implementation work for Lite runtime and generator
diff --git a/src/ProtoGen/Helpers.cs b/src/ProtoGen/Helpers.cs
index 7fb7d8f..6b6e316 100644
--- a/src/ProtoGen/Helpers.cs
+++ b/src/ProtoGen/Helpers.cs
@@ -38,11 +38,5 @@
   /// Helpers to resolve class names etc.
   /// </summary>
   internal static class Helpers {
-    internal static void WriteNamespaces(TextGenerator writer) {
-      writer.WriteLine("using pb = global::Google.ProtocolBuffers;");
-      writer.WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;");
-      writer.WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;");
-      writer.WriteLine("using scg = global::System.Collections.Generic;");
-    }
   }
 }
diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs
index 3488cdc..907a1c0 100644
--- a/src/ProtoGen/MessageGenerator.cs
+++ b/src/ProtoGen/MessageGenerator.cs
@@ -69,12 +69,13 @@
 
       string identifier = GetUniqueFileScopeIdentifier(Descriptor);
 
-      // The descriptor for this type.
-      string access = Descriptor.File.CSharpOptions.NestClasses ? "private" : "internal";
-      writer.WriteLine("{0} static pbd::MessageDescriptor internal__{1}__Descriptor;", access, identifier);
-      writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable;",
-          access, FullClassName, identifier);
-
+      if (!UseLiteRuntime) {
+        // The descriptor for this type.
+        string access = Descriptor.File.CSharpOptions.NestClasses ? "private" : "internal";
+        writer.WriteLine("{0} static pbd::MessageDescriptor internal__{1}__Descriptor;", access, identifier);
+        writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable;",
+                         access, FullClassName, identifier);
+      }
       // Generate static members for all nested types.
       foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
         new MessageGenerator(nestedMessage).GenerateStaticVariables(writer);
@@ -84,21 +85,23 @@
     internal void GenerateStaticVariableInitializers(TextGenerator writer) {
       string identifier = GetUniqueFileScopeIdentifier(Descriptor);
 
-      writer.Write("internal__{0}__Descriptor = ", identifier);
-      if (Descriptor.ContainingType == null) {
-        writer.WriteLine("Descriptor.MessageTypes[{0}];", Descriptor.Index);
-      } else {
-        writer.WriteLine("internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
-      }
+      if (!UseLiteRuntime) {
+        writer.Write("internal__{0}__Descriptor = ", identifier);
+        if (Descriptor.ContainingType == null) {
+          writer.WriteLine("Descriptor.MessageTypes[{0}];", Descriptor.Index);
+        } else {
+          writer.WriteLine("internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
+        }
 
-      writer.WriteLine("internal__{0}__FieldAccessorTable = ", identifier);
-      writer.WriteLine("    new pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder>(internal__{0}__Descriptor,",
-          identifier, FullClassName);
-      writer.Print("        new string[] { ");
-      foreach (FieldDescriptor field in Descriptor.Fields) {
-        writer.Write("\"{0}\", ", field.CSharpOptions.PropertyName);
+        writer.WriteLine("internal__{0}__FieldAccessorTable = ", identifier);
+        writer.WriteLine("    new pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder>(internal__{0}__Descriptor,",
+                         identifier, FullClassName);
+        writer.Print("        new string[] { ");
+        foreach (FieldDescriptor field in Descriptor.Fields) {
+          writer.Write("\"{0}\", ", field.CSharpOptions.PropertyName);
+        }
+        writer.WriteLine("});");
       }
-      writer.WriteLine("});");
 
       // Generate static member initializers for all nested types.
       foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
@@ -111,8 +114,10 @@
     }
 
     public void Generate(TextGenerator writer) {
-      writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message<{1}, {1}.Builder> {{",
-          ClassAccessLevel, ClassName, Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated");
+      writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message{3}<{1}, {1}.Builder> {{",
+          ClassAccessLevel, ClassName, 
+          Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated",
+          UseLiteRuntime ? "Lite" : "");
       writer.Indent();
       // Must call BuildPartial() to make sure all lists are made read-only
       writer.WriteLine("private static readonly {0} defaultInstance = new Builder().BuildPartial();", ClassName);
@@ -128,16 +133,18 @@
       writer.WriteLine("  get { return this; }");
       writer.WriteLine("}");
       writer.WriteLine();
-      writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
-      writer.WriteLine("  get {{ return {0}.internal__{1}__Descriptor; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
-          GetUniqueFileScopeIdentifier(Descriptor));
-      writer.WriteLine("}");
-      writer.WriteLine();
-      writer.WriteLine("protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{", ClassName);
-      writer.WriteLine("  get {{ return {0}.internal__{1}__FieldAccessorTable; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
-          GetUniqueFileScopeIdentifier(Descriptor));
-      writer.WriteLine("}");
-      writer.WriteLine();
+      if (!UseLiteRuntime) {
+        writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
+        writer.WriteLine("  get {{ return {0}.internal__{1}__Descriptor; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
+                         GetUniqueFileScopeIdentifier(Descriptor));
+        writer.WriteLine("}");
+        writer.WriteLine();
+        writer.WriteLine("protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{", ClassName);
+        writer.WriteLine("  get {{ return {0}.internal__{1}__FieldAccessorTable; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
+                         GetUniqueFileScopeIdentifier(Descriptor));
+        writer.WriteLine("}");
+        writer.WriteLine();
+      }
 
       // Extensions don't need to go in an extra nested type 
       WriteChildren(writer, null, Descriptor.Extensions);
diff --git a/src/ProtoGen/SourceGeneratorBase.cs b/src/ProtoGen/SourceGeneratorBase.cs
index 02f8457..5fa420f 100644
--- a/src/ProtoGen/SourceGeneratorBase.cs
+++ b/src/ProtoGen/SourceGeneratorBase.cs
@@ -40,8 +40,16 @@
 
     private readonly T descriptor;
 
+    protected readonly bool OptimizeSpeed;
+    protected readonly bool OptimizeSize;
+    protected readonly bool UseLiteRuntime;
+
     protected SourceGeneratorBase(T descriptor) {
       this.descriptor = descriptor;
+
+      OptimizeSize = descriptor.File.Options.OptimizeFor == Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.CODE_SIZE;
+      OptimizeSpeed = descriptor.File.Options.OptimizeFor == Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED;
+      UseLiteRuntime = descriptor.File.Options.OptimizeFor == Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode.LITE_RUNTIME;
     }
 
     protected T Descriptor {
diff --git a/src/ProtoGen/UmbrellaClassGenerator.cs b/src/ProtoGen/UmbrellaClassGenerator.cs
index 6f98704..3c643c3 100644
--- a/src/ProtoGen/UmbrellaClassGenerator.cs
+++ b/src/ProtoGen/UmbrellaClassGenerator.cs
@@ -83,7 +83,11 @@
         new MessageGenerator(message).GenerateStaticVariables(writer);
       }
       writer.WriteLine("#endregion");
-      WriteDescriptor(writer);
+      if (!UseLiteRuntime) {
+        WriteDescriptor(writer);
+      } else {
+        WriteLiteExtensions(writer);
+      }
       // The class declaration either gets closed before or after the children are written.
       if (!Descriptor.CSharpOptions.NestClasses) {
         writer.Outdent();
@@ -111,7 +115,12 @@
     private void WriteIntroduction(TextGenerator writer) {
       writer.WriteLine("// Generated by the protocol buffer compiler.  DO NOT EDIT!");
       writer.WriteLine();
-      Helpers.WriteNamespaces(writer);
+      writer.WriteLine("using pb = global::Google.ProtocolBuffers;");
+      if (!UseLiteRuntime) {
+        writer.WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;");
+        writer.WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;");
+      }
+      writer.WriteLine("using scg = global::System.Collections.Generic;");
 
       if (Descriptor.CSharpOptions.Namespace != "") {
         writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.Namespace);
@@ -211,5 +220,23 @@
       writer.WriteLine("#endregion");
       writer.WriteLine();
     }
+
+    private void WriteLiteExtensions(TextGenerator writer) {
+      writer.WriteLine("#region Extensions");
+
+      writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
+      writer.Indent();
+
+      foreach (MessageDescriptor message in Descriptor.MessageTypes) {
+        new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
+      }
+      foreach (FieldDescriptor extension in Descriptor.Extensions) {
+        new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
+      }
+      writer.Outdent();
+      writer.WriteLine("}");
+      writer.WriteLine("#endregion");
+      writer.WriteLine();
+    }
   }
 }
diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs
index df17716..922957f 100644
--- a/src/ProtocolBuffers/CodedInputStream.cs
+++ b/src/ProtocolBuffers/CodedInputStream.cs
@@ -36,9 +36,7 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
-#if !LITE
 using Google.ProtocolBuffers.Descriptors;
-#endif
 
 namespace Google.ProtocolBuffers {
 
@@ -363,7 +361,7 @@
     public long ReadSInt64() {
       return DecodeZigZag64(ReadRawVarint64());
     }
-#if !LITE
+
     /// <summary>
     /// Reads a field of any primitive type. Enums, groups and embedded
     /// messages are not handled by this method.
@@ -397,7 +395,6 @@
           throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
       }
     }
-#endif
     #endregion
 
     #region Underlying reading primitives
diff --git a/src/ProtocolBuffers/CodedOutputStream.cs b/src/ProtocolBuffers/CodedOutputStream.cs
index b261375..264ca6e 100644
--- a/src/ProtocolBuffers/CodedOutputStream.cs
+++ b/src/ProtocolBuffers/CodedOutputStream.cs
@@ -35,9 +35,8 @@
 using System;
 using System.IO;
 using System.Text;
-#if !LITE
 using Google.ProtocolBuffers.Descriptors;
-#endif
+
 namespace Google.ProtocolBuffers {
 
   /// <summary>
@@ -279,7 +278,6 @@
       WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);
     }
 
-#if !LITE
     public void WriteField(FieldType fieldType, int fieldNumber, object value) {
       switch (fieldType) {
         case FieldType.Double: WriteDouble(fieldNumber, (double)value); break;
@@ -291,15 +289,15 @@
         case FieldType.Fixed32: WriteFixed32(fieldNumber, (uint)value); break;
         case FieldType.Bool: WriteBool(fieldNumber, (bool)value); break;
         case FieldType.String: WriteString(fieldNumber, (string)value); break;
-        case FieldType.Group: WriteGroup(fieldNumber, (IMessage)value); break;
-        case FieldType.Message: WriteMessage(fieldNumber, (IMessage)value); break;
+        case FieldType.Group: WriteGroup(fieldNumber, (IMessageLite)value); break;
+        case FieldType.Message: WriteMessage(fieldNumber, (IMessageLite)value); break;
         case FieldType.Bytes: WriteBytes(fieldNumber, (ByteString)value); break;
         case FieldType.UInt32: WriteUInt32(fieldNumber, (uint)value); break;
         case FieldType.SFixed32: WriteSFixed32(fieldNumber, (int)value); break;
         case FieldType.SFixed64: WriteSFixed64(fieldNumber, (long)value); break;
         case FieldType.SInt32: WriteSInt32(fieldNumber, (int)value); break;
         case FieldType.SInt64: WriteSInt64(fieldNumber, (long)value); break;
-        case FieldType.Enum: WriteEnum(fieldNumber, ((EnumValueDescriptor)value).Number);
+        case FieldType.Enum: WriteEnum(fieldNumber, ((IEnumLite)value).Number);
           break;
       }
     }
@@ -315,19 +313,18 @@
         case FieldType.Fixed32: WriteFixed32NoTag((uint)value); break;
         case FieldType.Bool: WriteBoolNoTag((bool)value); break;
         case FieldType.String: WriteStringNoTag((string)value); break;
-        case FieldType.Group: WriteGroupNoTag((IMessage)value); break;
-        case FieldType.Message: WriteMessageNoTag((IMessage)value); break;
+        case FieldType.Group: WriteGroupNoTag((IMessageLite)value); break;
+        case FieldType.Message: WriteMessageNoTag((IMessageLite)value); break;
         case FieldType.Bytes: WriteBytesNoTag((ByteString)value); break;
         case FieldType.UInt32: WriteUInt32NoTag((uint)value); break;
         case FieldType.SFixed32: WriteSFixed32NoTag((int)value); break;
         case FieldType.SFixed64: WriteSFixed64NoTag((long)value); break;
         case FieldType.SInt32: WriteSInt32NoTag((int)value); break;
         case FieldType.SInt64: WriteSInt64NoTag((long)value); break;
-        case FieldType.Enum: WriteEnumNoTag(((EnumValueDescriptor)value).Number);
+        case FieldType.Enum: WriteEnumNoTag(((IEnumLite)value).Number);
           break;
       }
     }
-#endif
     #endregion
 
     #region Writing of values without tags
@@ -995,7 +992,6 @@
       return 10;
     }
 
-#if !LITE
     /// <summary>
     /// Compute the number of bytes that would be needed to encode a
     /// field of arbitrary type, including the tag, to the stream.
@@ -1011,15 +1007,15 @@
         case FieldType.Fixed32: return ComputeFixed32Size(fieldNumber, (uint)value);
         case FieldType.Bool: return ComputeBoolSize(fieldNumber, (bool)value);
         case FieldType.String: return ComputeStringSize(fieldNumber, (string)value);
-        case FieldType.Group: return ComputeGroupSize(fieldNumber, (IMessage)value);
-        case FieldType.Message: return ComputeMessageSize(fieldNumber, (IMessage)value);
+        case FieldType.Group: return ComputeGroupSize(fieldNumber, (IMessageLite)value);
+        case FieldType.Message: return ComputeMessageSize(fieldNumber, (IMessageLite)value);
         case FieldType.Bytes: return ComputeBytesSize(fieldNumber, (ByteString)value);
         case FieldType.UInt32: return ComputeUInt32Size(fieldNumber, (uint)value);
         case FieldType.SFixed32: return ComputeSFixed32Size(fieldNumber, (int)value);
         case FieldType.SFixed64: return ComputeSFixed64Size(fieldNumber, (long)value);
         case FieldType.SInt32: return ComputeSInt32Size(fieldNumber, (int)value);
         case FieldType.SInt64: return ComputeSInt64Size(fieldNumber, (long)value);
-        case FieldType.Enum: return ComputeEnumSize(fieldNumber, ((EnumValueDescriptor)value).Number);
+        case FieldType.Enum: return ComputeEnumSize(fieldNumber, ((IEnumLite)value).Number);
         default:
           throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
       }
@@ -1040,20 +1036,19 @@
         case FieldType.Fixed32: return ComputeFixed32SizeNoTag((uint)value);
         case FieldType.Bool: return ComputeBoolSizeNoTag((bool)value);
         case FieldType.String: return ComputeStringSizeNoTag((string)value);
-        case FieldType.Group: return ComputeGroupSizeNoTag((IMessage)value);
-        case FieldType.Message: return ComputeMessageSizeNoTag((IMessage)value);
+        case FieldType.Group: return ComputeGroupSizeNoTag((IMessageLite)value);
+        case FieldType.Message: return ComputeMessageSizeNoTag((IMessageLite)value);
         case FieldType.Bytes: return ComputeBytesSizeNoTag((ByteString)value);
         case FieldType.UInt32: return ComputeUInt32SizeNoTag((uint)value);
         case FieldType.SFixed32: return ComputeSFixed32SizeNoTag((int)value);
         case FieldType.SFixed64: return ComputeSFixed64SizeNoTag((long)value);
         case FieldType.SInt32: return ComputeSInt32SizeNoTag((int)value);
         case FieldType.SInt64: return ComputeSInt64SizeNoTag((long)value);
-        case FieldType.Enum: return ComputeEnumSizeNoTag(((EnumValueDescriptor)value).Number);
+        case FieldType.Enum: return ComputeEnumSizeNoTag(((IEnumLite)value).Number);
         default:
           throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
       }
     }
-#endif
 
     /// <summary>
     /// Compute the number of bytes that would be needed to encode a tag.
diff --git a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
index 2fa18d9..c121c7e 100644
--- a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
@@ -37,7 +37,7 @@
   /// <summary>
   /// Descriptor for an enum type in a .proto file.
   /// </summary>
-  public sealed class EnumDescriptor : IndexedDescriptorBase<EnumDescriptorProto, EnumOptions> {
+  public sealed class EnumDescriptor : IndexedDescriptorBase<EnumDescriptorProto, EnumOptions>, IEnumLiteMap<EnumValueDescriptor> {
 
     private readonly MessageDescriptor containingType;
     private readonly IList<EnumValueDescriptor> values;
@@ -73,10 +73,17 @@
     }
 
     /// <summary>
+    /// Logic moved from FieldSet to continue current behavior
+    /// </summary>
+    public bool IsValidValue(IEnumLite value) {
+      return value is EnumValueDescriptor && ((EnumValueDescriptor)value).EnumDescriptor == this;
+    }
+
+    /// <summary>
     /// Finds an enum value by number. If multiple enum values have the
     /// same number, this returns the first defined value with that number.
     /// </summary>
-    internal EnumValueDescriptor FindValueByNumber(int number) {
+    public EnumValueDescriptor FindValueByNumber(int number) {
       return File.DescriptorPool.FindEnumValueByNumber(this, number);
     }
 
diff --git a/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs
index 4125814..732dec0 100644
--- a/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs
@@ -36,7 +36,7 @@
   /// <summary>
   /// Descriptor for a single enum value within an enum in a .proto file.
   /// </summary>
-  public sealed class EnumValueDescriptor : IndexedDescriptorBase<EnumValueDescriptorProto, EnumValueOptions> {
+  public sealed class EnumValueDescriptor : IndexedDescriptorBase<EnumValueDescriptorProto, EnumValueOptions>, IEnumLite {
 
     private readonly EnumDescriptor enumDescriptor;
 
diff --git a/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs b/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
index 7d99ed2..854b3a8 100644
--- a/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
@@ -40,7 +40,7 @@
   /// <summary>
   /// Descriptor for a field or extension within a message in a .proto file.
   /// </summary>
-  public sealed class FieldDescriptor : IndexedDescriptorBase<FieldDescriptorProto, FieldOptions>, IComparable<FieldDescriptor> {
+  public sealed class FieldDescriptor : IndexedDescriptorBase<FieldDescriptorProto, FieldOptions>, IComparable<FieldDescriptor>, IFieldDescriptorLite {
 
     private readonly MessageDescriptor extensionScope;
     private EnumDescriptor enumType;
@@ -299,9 +299,26 @@
       }
       return FieldNumber - other.FieldNumber;
     }
-    
 
     /// <summary>
+    /// Compares this descriptor with another one, ordering in "canonical" order
+    /// which simply means ascending order by field number. <paramref name="other"/>
+    /// must be a field of the same type, i.e. the <see cref="ContainingType"/> of
+    /// both fields must be the same.
+    /// </summary>
+    public int CompareTo(IFieldDescriptorLite other) {
+      return FieldNumber - other.FieldNumber;
+    }
+
+    IEnumLiteMap IFieldDescriptorLite.EnumType {
+      get { return EnumType; }
+    }
+
+    bool IFieldDescriptorLite.MessageSetWireFormat {
+      get { return ContainingType.Options.MessageSetWireFormat; }
+    }
+
+      /// <summary>
     /// For enum fields, returns the field's type.
     /// </summary>
     public EnumDescriptor EnumType {
diff --git a/src/ProtocolBuffers/DynamicMessage.cs b/src/ProtocolBuffers/DynamicMessage.cs
index 12f2186..34a50c5 100644
--- a/src/ProtocolBuffers/DynamicMessage.cs
+++ b/src/ProtocolBuffers/DynamicMessage.cs
@@ -180,7 +180,7 @@
     }
 
     public override IDictionary<FieldDescriptor, object> AllFields {
-      get { return fields.AllFields; }
+      get { return fields.AllFieldDescriptors; }
     }
 
     public override bool HasField(FieldDescriptor field) {
@@ -216,7 +216,7 @@
     }
 
     public bool Initialized {
-      get { return fields.IsInitializedWithRespectTo(type); }
+      get { return fields.IsInitializedWithRespectTo(type.Fields); }
     }
 
     public override void WriteTo(CodedOutputStream output) {
@@ -335,7 +335,7 @@
       }
 
       public override bool IsInitialized {
-          get { return fields.IsInitializedWithRespectTo(type); }
+          get { return fields.IsInitializedWithRespectTo(type.Fields); }
       }
 
       public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
@@ -354,7 +354,7 @@
       }
 
       public override IDictionary<FieldDescriptor, object> AllFields {
-        get { return fields.AllFields; }
+        get { return fields.AllFieldDescriptors; }
       }
 
       public override IBuilder CreateBuilderForField(FieldDescriptor field) {
diff --git a/src/ProtocolBuffers/EnumLite.cs b/src/ProtocolBuffers/EnumLite.cs
new file mode 100644
index 0000000..0c6c9af
--- /dev/null
+++ b/src/ProtocolBuffers/EnumLite.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Google.ProtocolBuffers {
+
+  ///<summary>
+  ///Interface for an enum value or value descriptor, to be used in FieldSet.
+  ///The lite library stores enum values directly in FieldSets but the full
+  ///library stores EnumValueDescriptors in order to better support reflection.
+  ///</summary>
+  public interface IEnumLite {
+    int Number { get; }
+  }
+
+  ///<summary>
+  ///Interface for an object which maps integers to {@link EnumLite}s.
+  ///{@link Descriptors.EnumDescriptor} implements this interface by mapping
+  ///numbers to {@link Descriptors.EnumValueDescriptor}s.  Additionally,
+  ///every generated enum type has a static method internalGetValueMap() which
+  ///returns an implementation of this type that maps numbers to enum values.
+  ///</summary>
+  public interface IEnumLiteMap<T> : IEnumLiteMap
+    where T : IEnumLite {
+    T FindValueByNumber(int number);
+  }
+
+  public interface IEnumLiteMap {
+    bool IsValidValue(IEnumLite value);
+  }
+}
diff --git a/src/ProtocolBuffers/ExtendableMessage.cs b/src/ProtocolBuffers/ExtendableMessage.cs
index 4450f4f..c67b5a1 100644
--- a/src/ProtocolBuffers/ExtendableMessage.cs
+++ b/src/ProtocolBuffers/ExtendableMessage.cs
@@ -102,8 +102,8 @@
     public override IDictionary<FieldDescriptor, object> AllFields {
       get {
         IDictionary<FieldDescriptor, object> result = GetMutableFieldMap();
-        foreach(KeyValuePair<FieldDescriptor, object> entry in extensions.AllFields) {
-          result[entry.Key] = entry.Value;
+        foreach(KeyValuePair<IFieldDescriptorLite, object> entry in extensions.AllFields) {
+          result[(FieldDescriptor)entry.Key] = entry.Value;
         }
         return Dictionaries.AsReadOnly(result);
       }
@@ -173,9 +173,9 @@
     /// TODO(jonskeet): See if we can improve this in terms of readability.
     /// </summary>
     protected class ExtensionWriter {
-      readonly IEnumerator<KeyValuePair<FieldDescriptor, object>> iterator;
+      readonly IEnumerator<KeyValuePair<IFieldDescriptorLite, object>> iterator;
       readonly FieldSet extensions;
-      KeyValuePair<FieldDescriptor, object>? next = null;
+      KeyValuePair<IFieldDescriptorLite, object>? next = null;
 
       internal ExtensionWriter(ExtendableMessage<TMessage, TBuilder> message) {
         extensions = message.extensions;
diff --git a/src/ProtocolBuffers/FieldSet.cs b/src/ProtocolBuffers/FieldSet.cs
index 7c373b9..3ac3e3d 100644
--- a/src/ProtocolBuffers/FieldSet.cs
+++ b/src/ProtocolBuffers/FieldSet.cs
@@ -39,6 +39,20 @@
 using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers {
+
+  public interface IFieldDescriptorLite : IComparable<IFieldDescriptorLite> {
+    bool IsRepeated { get; }
+    bool IsRequired { get; }
+    bool IsPacked { get; }
+    bool IsExtension { get; }
+    bool MessageSetWireFormat { get; } //field.ContainingType.Options.MessageSetWireFormat
+    int FieldNumber { get; }
+    IEnumLiteMap EnumType { get; }
+    FieldType FieldType { get; }
+    MappedType MappedType { get; }
+    object DefaultValue { get; }
+  }
+
   /// <summary>
   /// A class which represents an arbitrary set of fields of some message type.
   /// This is used to implement DynamicMessage, and also to represent extensions
@@ -56,17 +70,17 @@
   /// </summary>
   internal sealed class FieldSet {
 
-    private static readonly FieldSet defaultInstance = new FieldSet(new Dictionary<FieldDescriptor, object>()).MakeImmutable();
+    private static readonly FieldSet defaultInstance = new FieldSet(new Dictionary<IFieldDescriptorLite, object>()).MakeImmutable();
 
-    private IDictionary<FieldDescriptor, object> fields;
+    private IDictionary<IFieldDescriptorLite, object> fields;
 
-    private FieldSet(IDictionary<FieldDescriptor, object> fields) {
+    private FieldSet(IDictionary<IFieldDescriptorLite, object> fields) {
       this.fields = fields;
     }
 
     public static FieldSet CreateInstance() {
       // Use SortedList to keep fields in the canonical order
-      return new FieldSet(new SortedList<FieldDescriptor, object>());
+      return new FieldSet(new SortedList<IFieldDescriptorLite, object>());
     }
 
     /// <summary>
@@ -85,8 +99,8 @@
       }
 
       if (hasRepeats) {
-        var tmp = new SortedList<FieldDescriptor, object>();
-        foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
+        var tmp = new SortedList<IFieldDescriptorLite, object>();
+        foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
           IList<object> list = entry.Value as IList<object>;
           tmp[entry.Key] = list == null ? entry.Value : Lists.AsReadOnly(list);
         }
@@ -110,14 +124,26 @@
     /// is immutable, the entries may not be (i.e. any repeated values are represented by
     /// mutable lists). The behaviour is not specified if the contents are mutated.
     /// </summary>
-    internal IDictionary<FieldDescriptor, object> AllFields {
+    internal IDictionary<IFieldDescriptorLite, object> AllFields {
       get { return Dictionaries.AsReadOnly(fields); }
     }
-
+#if !LITE
     /// <summary>
-    /// See <see cref="IMessage.HasField"/>.
+    /// Force coercion to full descriptor dictionary.
     /// </summary>
-    public bool HasField(FieldDescriptor field) {
+    internal IDictionary<Descriptors.FieldDescriptor, object> AllFieldDescriptors {
+      get {
+        SortedList<Descriptors.FieldDescriptor, object> copy = new SortedList<Google.ProtocolBuffers.Descriptors.FieldDescriptor, object>();
+        foreach (KeyValuePair<IFieldDescriptorLite, object> fd in fields)
+          copy.Add((Descriptors.FieldDescriptor)fd.Key, fd.Value);
+        return Dictionaries.AsReadOnly(copy); 
+      }
+    }
+#endif
+    /// <summary>
+    /// See <see cref="IMessageLite.HasField"/>.
+    /// </summary>
+    public bool HasField(IFieldDescriptorLite field) {
       if (field.IsRepeated) {
         throw new ArgumentException("HasField() can only be called on non-repeated fields.");
       }
@@ -133,7 +159,7 @@
     }
 
     /// <summary>
-    /// See <see cref="IMessage.Item(FieldDescriptor)"/>
+    /// See <see cref="IMessageLite.Item(IFieldDescriptorLite)"/>
     /// </summary>
     /// <remarks>
     /// If the field is not set, the behaviour when fetching this property varies by field type:
@@ -153,7 +179,7 @@
     /// to ensure it is of an appropriate type.
     /// </remarks>
     /// 
-    internal object this[FieldDescriptor field] {
+    internal object this[IFieldDescriptorLite field] {
       get {
         object result;
         if (fields.TryGetValue(field, out result)) {
@@ -191,9 +217,9 @@
     }
 
     /// <summary>
-    /// See <see cref="IMessage.Item(FieldDescriptor,int)" />
+    /// See <see cref="IMessageLite.Item(IFieldDescriptorLite,int)" />
     /// </summary>
-    internal object this[FieldDescriptor field, int index] {
+    internal object this[IFieldDescriptorLite field, int index] {
       get {
         if (!field.IsRepeated) {
           throw new ArgumentException("Indexer specifying field and index can only be called on repeated fields.");
@@ -217,7 +243,7 @@
     /// <summary>
     /// See <see cref="IBuilder{TMessage, TBuilder}.AddRepeatedField" />
     /// </summary>
-    internal void AddRepeatedField(FieldDescriptor field, object value) {
+    internal void AddRepeatedField(IFieldDescriptorLite field, object value) {
       if (!field.IsRepeated) {
         throw new ArgumentException("AddRepeatedField can only be called on repeated fields.");
       }
@@ -233,12 +259,12 @@
     /// <summary>
     /// Returns an enumerator for the field map. Used to write the fields out.
     /// </summary>
-    internal IEnumerator<KeyValuePair<FieldDescriptor, object>> GetEnumerator() {
+    internal IEnumerator<KeyValuePair<IFieldDescriptorLite, object>> GetEnumerator() {
       return fields.GetEnumerator();
     }
 
     /// <summary>
-    /// See <see cref="IMessage.IsInitialized" />
+    /// See <see cref="IMessageLite.IsInitialized" />
     /// </summary>
     /// <remarks>
     /// Since FieldSet itself does not have any way of knowing about
@@ -248,17 +274,17 @@
     /// </remarks>
     internal bool IsInitialized {
       get {
-        foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
-          FieldDescriptor field = entry.Key;
+        foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
+          IFieldDescriptorLite field = entry.Key;
           if (field.MappedType == MappedType.Message) {
             if (field.IsRepeated) {
-              foreach(IMessage message in (IEnumerable) entry.Value) {
+              foreach(IMessageLite message in (IEnumerable) entry.Value) {
                 if (!message.IsInitialized) {
                   return false;
                 }
               }
             } else {
-              if (!((IMessage) entry.Value).IsInitialized) {
+              if (!((IMessageLite)entry.Value).IsInitialized) {
                 return false;
               }
             }
@@ -273,8 +299,8 @@
     /// descriptor are present in this field set, as well as whether
     /// all the embedded messages are themselves initialized.
     /// </summary>
-    internal bool IsInitializedWithRespectTo(MessageDescriptor type) {
-      foreach (FieldDescriptor field in type.Fields) {
+    internal bool IsInitializedWithRespectTo(IEnumerable typeFields) {
+      foreach (IFieldDescriptorLite field in typeFields) {
         if (field.IsRequired && !HasField(field)) {
           return false;
         }
@@ -285,14 +311,14 @@
     /// <summary>
     /// See <see cref="IBuilder{TMessage, TBuilder}.ClearField" />
     /// </summary>
-    public void ClearField(FieldDescriptor field) {
+    public void ClearField(IFieldDescriptorLite field) {
       fields.Remove(field);
     }
 
     /// <summary>
-    /// See <see cref="IMessage.GetRepeatedFieldCount" />
+    /// See <see cref="IMessageLite.GetRepeatedFieldCount" />
     /// </summary>
-    public int GetRepeatedFieldCount(FieldDescriptor field) {
+    public int GetRepeatedFieldCount(IFieldDescriptorLite field) {
       if (!field.IsRepeated) {
         throw new ArgumentException("GetRepeatedFieldCount() can only be called on repeated fields.");
       }
@@ -300,64 +326,63 @@
       return ((IList<object>) this[field]).Count;
     }
 
+#if !LITE
+    /// <summary>
+    /// See <see cref="IBuilder{TMessage, TBuilder}.MergeFrom(IMessageLite)" />
+    /// </summary>
+    public void MergeFrom(IMessage other) {
+      foreach (KeyValuePair<Descriptors.FieldDescriptor, object> fd in other.AllFields)
+        MergeField(fd.Key, fd.Value);
+    }
+#endif
+
     /// <summary>
     /// Implementation of both <c>MergeFrom</c> methods.
     /// </summary>
     /// <param name="otherFields"></param>
-    private void MergeFields(IEnumerable<KeyValuePair<FieldDescriptor, object>> otherFields) {
+    public void MergeFrom(FieldSet other) {
       // Note:  We don't attempt to verify that other's fields have valid
       //   types.  Doing so would be a losing battle.  We'd have to verify
       //   all sub-messages as well, and we'd have to make copies of all of
       //   them to insure that they don't change after verification (since
-      //   the IMessage interface itself cannot enforce immutability of
+      //   the IMessageLite interface itself cannot enforce immutability of
       //   implementations).
       // TODO(jonskeet):  Provide a function somewhere called MakeDeepCopy()
       //   which allows people to make secure deep copies of messages.
 
-      foreach (KeyValuePair<FieldDescriptor, object> entry in otherFields) {
-        FieldDescriptor field = entry.Key;
-        object existingValue;
-        fields.TryGetValue(field, out existingValue);
-        if (field.IsRepeated) {
-          if (existingValue == null) {
-            existingValue = new List<object>();
-            fields[field] = existingValue;
-          }
-          IList<object> list = (IList<object>) existingValue;
-          foreach (object otherValue in (IEnumerable) entry.Value) {
-            list.Add(otherValue);
-          }
-        } else if (field.MappedType == MappedType.Message && existingValue != null) {
-          IMessage existingMessage = (IMessage)existingValue;
-          IMessage merged = existingMessage.WeakToBuilder()
-              .WeakMergeFrom((IMessage) entry.Value)
-              .WeakBuild();
-          this[field] = merged;
-        } else {
-          this[field] = entry.Value;
+      foreach (KeyValuePair<IFieldDescriptorLite, object> entry in other.fields) {
+        MergeField(entry.Key, entry.Value);
+      }
+    }
+
+    private void MergeField(IFieldDescriptorLite field, object mergeValue) {
+      object existingValue;
+      fields.TryGetValue(field, out existingValue);
+      if (field.IsRepeated) {
+        if (existingValue == null) {
+          existingValue = new List<object>();
+          fields[field] = existingValue;
         }
+        IList<object> list = (IList<object>) existingValue;
+        foreach (object otherValue in (IEnumerable)mergeValue) {
+          list.Add(otherValue);
+        }
+      } else if (field.MappedType == MappedType.Message && existingValue != null) {
+        IMessageLite existingMessage = (IMessageLite)existingValue;
+        IMessageLite merged = existingMessage.WeakToBuilder()
+          .WeakMergeFrom((IMessageLite)mergeValue)
+          .WeakBuild();
+        this[field] = merged;
+      } else {
+        this[field] = mergeValue;
       }
     }
 
     /// <summary>
-    /// See <see cref="IBuilder{TMessage, TBuilder}.MergeFrom(IMessage)" />
-    /// </summary>
-    public void MergeFrom(IMessage other) {
-      MergeFields(other.AllFields);
-    }
-
-    /// <summary>
-    /// Like <see cref="MergeFrom(IMessage)"/>, but merges from another <c>FieldSet</c>.
-    /// </summary>
-    public void MergeFrom(FieldSet other) {
-      MergeFields(other.fields);
-    }
-
-    /// <summary>
-    /// See <see cref="IMessage.WriteTo(CodedOutputStream)" />.
+    /// See <see cref="IMessageLite.WriteTo(CodedOutputStream)" />.
     /// </summary>
     public void WriteTo(CodedOutputStream output) {
-      foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
+      foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
         WriteField(entry.Key, entry.Value, output);
       }
     }
@@ -365,9 +390,9 @@
     /// <summary>
     /// Writes a single field to a CodedOutputStream.
     /// </summary>
-    public void WriteField(FieldDescriptor field, Object value, CodedOutputStream output) {
-      if (field.IsExtension && field.ContainingType.Options.MessageSetWireFormat) {
-        output.WriteMessageSetExtension(field.FieldNumber, (IMessage) value);
+    public void WriteField(IFieldDescriptorLite field, Object value, CodedOutputStream output) {
+      if (field.IsExtension && field.MessageSetWireFormat) {
+        output.WriteMessageSetExtension(field.FieldNumber, (IMessageLite) value);
       } else {
         if (field.IsRepeated) {
           IEnumerable valueList = (IEnumerable) value;
@@ -395,18 +420,18 @@
     }
 
     /// <summary>
-    /// See <see cref="IMessage.SerializedSize" />. It's up to the caller to
+    /// See <see cref="IMessageLite.SerializedSize" />. It's up to the caller to
     /// cache the resulting size if desired.
     /// </summary>
     public int SerializedSize {
       get {
         int size = 0;
-        foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
-          FieldDescriptor field = entry.Key;
+        foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
+          IFieldDescriptorLite field = entry.Key;
           object value = entry.Value;
 
-          if (field.IsExtension && field.ContainingType.Options.MessageSetWireFormat) {
-            size += CodedOutputStream.ComputeMessageSetExtensionSize(field.FieldNumber, (IMessage)value);
+          if (field.IsExtension && field.MessageSetWireFormat) {
+            size += CodedOutputStream.ComputeMessageSetExtensionSize(field.FieldNumber, (IMessageLite)value);
           } else {
             if (field.IsRepeated) {
               IEnumerable valueList = (IEnumerable)value;
@@ -440,7 +465,7 @@
     /// </remarks>
     /// <exception cref="ArgumentException">The value is not of the right type.</exception>
     /// <exception cref="ArgumentNullException">The value is null.</exception>
-    private static void VerifyType(FieldDescriptor field, object value) {
+    private static void VerifyType(IFieldDescriptorLite field, object value) {
       ThrowHelper.ThrowIfNull(value, "value");
       bool isValid = false;
       switch (field.MappedType) {
@@ -454,12 +479,15 @@
         case MappedType.String:      isValid = value is string; break;
         case MappedType.ByteString:  isValid = value is ByteString; break;        
         case MappedType.Enum:
-          EnumValueDescriptor enumValue = value as EnumValueDescriptor;
-          isValid = enumValue != null && enumValue.EnumDescriptor == field.EnumType;
+          IEnumLite enumValue = value as IEnumLite;
+          isValid = enumValue != null && field.EnumType.IsValidValue(enumValue);
           break;
         case MappedType.Message:
-          IMessage messageValue = value as IMessage;
-          isValid = messageValue != null && messageValue.DescriptorForType == field.MessageType;
+          IMessageLite messageValue = value as IMessageLite;
+          isValid = messageValue != null;
+#if !LITE
+          isValid = isValid && ((IMessage)messageValue).DescriptorForType == ((Google.ProtocolBuffers.Descriptors.FieldDescriptor)field).MessageType;
+#endif
           break;
       }
 
@@ -468,10 +496,16 @@
         // the stack trace which exact call failed, since the whole chain is
         // considered one line of code.  So, let's make sure to include the
         // field name and other useful info in the exception.
-        throw new ArgumentException("Wrong object type used with protocol message reflection. "
-            + "Message type \"" + field.ContainingType.FullName
-            + "\", field \"" + (field.IsExtension ? field.FullName : field.Name)
-            + "\", value was type \"" + value.GetType().Name + "\".");
+        string message = "Wrong object type used with protocol message reflection.";
+#if !LITE
+        Google.ProtocolBuffers.Descriptors.FieldDescriptor fieldinfo = field as Google.ProtocolBuffers.Descriptors.FieldDescriptor;
+        if (fieldinfo != null) {
+          message += "Message type \"" + fieldinfo.ContainingType.FullName;
+          message += "\", field \"" + (fieldinfo.IsExtension ? fieldinfo.FullName : fieldinfo.Name);
+          message += "\", value was type \"" + value.GetType().Name + "\".";
+        }
+#endif
+        throw new ArgumentException(message);
       }
     }     
   }
diff --git a/src/ProtocolBuffers/GeneratedExtensionLite.cs b/src/ProtocolBuffers/GeneratedExtensionLite.cs
index 9b3cf50..da07fb8 100644
--- a/src/ProtocolBuffers/GeneratedExtensionLite.cs
+++ b/src/ProtocolBuffers/GeneratedExtensionLite.cs
@@ -1,4 +1,5 @@
 using System;
+using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers {
 
@@ -7,4 +8,111 @@
     object ContainingType { get; }
     IMessageLite MessageDefaultInstance { get; }
   }
+
+  public class ExtensionDescriptorLite {
+    private readonly EnumLiteMap enumTypeMap;
+    private readonly int number;
+    private readonly FieldType type;
+    private readonly bool isRepeated;
+    private readonly bool isPacked;
+
+    public ExtensionDescriptorLite(EnumLiteMap enumTypeMap, int number, FieldType type, bool isRepeated, bool isPacked) {
+      this.enumTypeMap = enumTypeMap;
+      this.number = number;
+      this.type = type;
+      this.isRepeated = isRepeated;
+      this.isPacked = isPacked;
+    }
+
+    public int Number {
+      get { return number; }
+    }
+  }
+  
+  public class EnumLiteMap { }
+
+  public class GeneratedExtensionLite<TContainingType, TExtensionType> : IGeneratedExtensionLite
+    where TContainingType : IMessageLite {
+
+    private readonly TContainingType containingTypeDefaultInstance;
+    private readonly TExtensionType defaultValue;
+    private readonly IMessageLite messageDefaultInstance;
+    private readonly ExtensionDescriptorLite descriptor;
+
+    // We can't always initialize a GeneratedExtension when we first construct
+    // it due to initialization order difficulties (namely, the default
+    // instances may not have been constructed yet).  So, we construct an
+    // uninitialized GeneratedExtension once, then call internalInit() on it
+    // later.  Generated code will always call internalInit() on all extensions
+    // as part of the static initialization code, and internalInit() throws an
+    // exception if called more than once, so this method is useless to users.
+    protected GeneratedExtensionLite(
+        TContainingType containingTypeDefaultInstance,
+        TExtensionType defaultValue,
+        IMessageLite messageDefaultInstance,
+        ExtensionDescriptorLite descriptor) {
+      this.containingTypeDefaultInstance = containingTypeDefaultInstance;
+      this.messageDefaultInstance = messageDefaultInstance;
+      this.defaultValue = defaultValue;
+      this.descriptor = descriptor;
+    }
+
+    /** For use by generated code only. */
+    public GeneratedExtensionLite(
+        TContainingType containingTypeDefaultInstance,
+        TExtensionType defaultValue,
+        IMessageLite messageDefaultInstance,
+      EnumLiteMap enumTypeMap,
+        int number,
+        FieldType type)
+      : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
+          new ExtensionDescriptorLite(enumTypeMap, number, type,
+            false /* isRepeated */, false /* isPacked */)) {
+    }
+
+    /** For use by generated code only. */
+    public GeneratedExtensionLite(
+      TContainingType containingTypeDefaultInstance,
+      TExtensionType defaultValue,
+      IMessageLite messageDefaultInstance,
+      EnumLiteMap enumTypeMap,
+      int number,
+      FieldType type,
+      bool isPacked)
+      : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
+          new ExtensionDescriptorLite(enumTypeMap, number, type,
+            true /* isRepeated */, isPacked)) {
+    }
+
+    /// <summary>
+    /// used for the extension registry
+    /// </summary>
+    object IGeneratedExtensionLite.ContainingType {
+      get { return ContainingTypeDefaultInstance; }
+    }
+      /**
+     * Default instance of the type being extended, used to identify that type.
+     */
+    public TContainingType ContainingTypeDefaultInstance {
+      get {
+        return containingTypeDefaultInstance;
+      }
+    }
+
+    /** Get the field number. */
+    public int Number {
+      get {
+        return descriptor.Number;
+      }
+    }
+    /**
+     * If the extension is an embedded message, this is the default instance of
+     * that type.
+     */
+    public IMessageLite MessageDefaultInstance {
+      get {
+        return messageDefaultInstance;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/ProtocolBuffers/ProtocolBuffers.csproj b/src/ProtocolBuffers/ProtocolBuffers.csproj
index 59dfaa0..dece65a 100644
--- a/src/ProtocolBuffers/ProtocolBuffers.csproj
+++ b/src/ProtocolBuffers/ProtocolBuffers.csproj
@@ -90,6 +90,7 @@
     <Compile Include="Descriptors\PackageDescriptor.cs" />
     <Compile Include="Descriptors\ServiceDescriptor.cs" />
     <Compile Include="DynamicMessage.cs" />
+    <Compile Include="EnumLite.cs" />
     <Compile Include="ExtendableBuilder.cs" />
     <Compile Include="ExtendableMessage.cs" />
     <Compile Include="ExtensionInfo.cs">
diff --git a/src/ProtocolBuffers/ProtocolBuffersLite.csproj b/src/ProtocolBuffers/ProtocolBuffersLite.csproj
index a08b024..d3d60b2 100644
--- a/src/ProtocolBuffers/ProtocolBuffersLite.csproj
+++ b/src/ProtocolBuffers/ProtocolBuffersLite.csproj
@@ -46,6 +46,8 @@
   <ItemGroup>
     <Reference Include="mscorlib" />
     <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
   </ItemGroup>
@@ -55,7 +57,17 @@
   <ItemGroup>
     <Compile Include="AbstractBuilderLite.cs" />
     <Compile Include="AbstractMessageLite.cs" />
+    <Compile Include="Collections\Dictionaries.cs" />
+    <Compile Include="Collections\Lists.cs" />
+    <Compile Include="Descriptors\FieldMappingAttribute.cs" />
+    <Compile Include="Descriptors\FieldType.cs" />
+    <Compile Include="Descriptors\MappedType.cs" />
+    <Compile Include="EnumLite.cs" />
+    <Compile Include="ExtendableMessageLite.cs" />
+    <Compile Include="FieldSet.cs" />
+    <Compile Include="GeneratedBuilderLite.cs" />
     <Compile Include="GeneratedExtensionLite.cs" />
+    <Compile Include="GeneratedMessageLite.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ByteString.cs" />
     <Compile Include="CodedInputStream.cs" />
@@ -66,6 +78,7 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="InvalidProtocolBufferException.cs" />
+    <Compile Include="ThrowHelper.cs" />
     <Compile Include="UninitializedMessageException.cs" />
     <Compile Include="WireFormat.cs" />
   </ItemGroup>
diff --git a/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj b/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj
index 19bd4b6..794b3fd 100644
--- a/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj
+++ b/src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj
@@ -54,9 +54,13 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="..\..\tmp\UnitTestLiteProtoFile.cs">
+      <Link>UnitTestLiteProtoFile.cs</Link>
+    </Compile>
     <Compile Include="..\ProtocolBuffers.Test\Properties\AssemblyInfo.cs">
       <Link>Properties\AssemblyInfo.cs</Link>
     </Compile>
+    <Compile Include="Todo.cs" />
     <None Include="TestProtos\UnittestLite.cs" />
     <None Include="TestProtos\UnittestLiteImportsNonlite.cs" />
   </ItemGroup>