First pass at interface breakup
diff --git a/src/ProtocolBuffers/ExtensionRegistryLite.cs b/src/ProtocolBuffers/ExtensionRegistryLite.cs
index 154b690..693aeb2 100644
--- a/src/ProtocolBuffers/ExtensionRegistryLite.cs
+++ b/src/ProtocolBuffers/ExtensionRegistryLite.cs
@@ -33,14 +33,15 @@
 #endregion
 
 using System.Collections.Generic;
-using Google.ProtocolBuffers.Descriptors;
 using System;
 
 namespace Google.ProtocolBuffers {
+
+
   /// <summary>
   /// A table of known extensions, searchable by name or field number.  When
   /// parsing a protocol message that might have extensions, you must provide
-  /// an <see cref="ExtensionRegistry"/> in which you have registered any extensions
+  /// an <see cref="ExtensionRegistryLite"/> in which you have registered any extensions
   /// that you want to be able to parse.  Otherwise, those extensions will just
   /// be treated like unknown fields.
   /// </summary>
@@ -61,7 +62,7 @@
   /// Then you might write code like:
   ///
   /// <code>
-  /// ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+  /// ExtensionRegistryLite registry = ExtensionRegistryLite.CreateInstance();
   /// registry.Add(MyProto.Bar);
   /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry);
   /// </code>
@@ -88,21 +89,17 @@
   /// could take advantage of this to inject a mutable object into a message
   /// belonging to privileged code and create mischief.</para>
   /// </remarks>
-  public sealed class ExtensionRegistry {
+  public class ExtensionRegistryLite {
 
-    private static readonly ExtensionRegistry empty = new ExtensionRegistry(
-        new Dictionary<string, ExtensionInfo>(),
-        new Dictionary<DescriptorIntPair, ExtensionInfo>(),
+    private static readonly ExtensionRegistryLite empty = new ExtensionRegistryLite(
+        new Dictionary<ExtensionIntPair, IGeneratedExtensionLite>(),
         true);
 
-    private readonly IDictionary<string, ExtensionInfo> extensionsByName;
-    private readonly IDictionary<DescriptorIntPair, ExtensionInfo> extensionsByNumber;
-    private readonly bool readOnly;
+    protected readonly IDictionary<ExtensionIntPair, IGeneratedExtensionLite> extensionsByNumber;
+    protected readonly bool readOnly;
 
-    private ExtensionRegistry(IDictionary<String, ExtensionInfo> extensionsByName,
-        IDictionary<DescriptorIntPair, ExtensionInfo> extensionsByNumber,
+    protected ExtensionRegistryLite(IDictionary<ExtensionIntPair, IGeneratedExtensionLite> extensionsByNumber,
         bool readOnly) {
-      this.extensionsByName = extensionsByName;
       this.extensionsByNumber = extensionsByNumber;
       this.readOnly = readOnly;
     }
@@ -110,44 +107,30 @@
     /// <summary>
     /// Construct a new, empty instance.
     /// </summary>
-    public static ExtensionRegistry CreateInstance() {
-      return new ExtensionRegistry(new Dictionary<string, ExtensionInfo>(),
-        new Dictionary<DescriptorIntPair, ExtensionInfo>(), false);
+    public static ExtensionRegistryLite CreateInstance() {
+      return new ExtensionRegistryLite(
+        new Dictionary<ExtensionIntPair, IGeneratedExtensionLite>(), false);
     }
 
     /// <summary>
     /// Get the unmodifiable singleton empty instance.
     /// </summary>
-    public static ExtensionRegistry Empty {
+    public static ExtensionRegistryLite Empty {
       get { return empty; }
     }
 
-    public ExtensionRegistry AsReadOnly() {
-      return new ExtensionRegistry(extensionsByName, extensionsByNumber, true);
-    }
-
-    /// <summary>
-    /// Finds an extension by fully-qualified field name, in the
-    /// proto namespace, i.e. result.Descriptor.FullName will match
-    /// <paramref name="fullName"/> if a match is found. A null
-    /// reference is returned if the extension can't be found.
-    /// </summary>
-    public ExtensionInfo this[string fullName] {
-      get {
-        ExtensionInfo ret;
-        extensionsByName.TryGetValue(fullName, out ret);
-        return ret;
-      }
+    public virtual ExtensionRegistryLite AsReadOnly() {
+      return new ExtensionRegistryLite(extensionsByNumber, true);
     }
 
     /// <summary>
     /// Finds an extension by containing type and field number.
     /// A null reference is returned if the extension can't be found.
     /// </summary>
-    public ExtensionInfo this[MessageDescriptor containingType, int fieldNumber] {
+    public IGeneratedExtensionLite this[IMessageLite containingType, int fieldNumber] {
       get {
-        ExtensionInfo ret;
-        extensionsByNumber.TryGetValue(new DescriptorIntPair(containingType, fieldNumber), out ret);
+        IGeneratedExtensionLite ret;
+        extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret);
         return ret;
       }
     }
@@ -155,90 +138,41 @@
     /// <summary>
     /// Add an extension from a generated file to the registry.
     /// </summary>
-    public void Add<TExtension> (GeneratedExtensionBase<TExtension> extension) {
-      if (extension.Descriptor.MappedType == MappedType.Message) {
-        Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance));
-      } else {
-        Add(new ExtensionInfo(extension.Descriptor, null));
-      }
-    }
-
-    /// <summary>
-    /// Adds a non-message-type extension to the registry by descriptor.
-    /// </summary>
-    /// <param name="type"></param>
-    public void Add(FieldDescriptor type) {
-      if (type.MappedType == MappedType.Message) {
-        throw new ArgumentException("ExtensionRegistry.Add() must be provided a default instance "
-            + "when adding an embedded message extension.");
-      }
-      Add(new ExtensionInfo(type, null));
-    }
-
-    /// <summary>
-    /// Adds a message-type-extension to the registry by descriptor.
-    /// </summary>
-    /// <param name="type"></param>
-    /// <param name="defaultInstance"></param>
-    public void Add(FieldDescriptor type, IMessage defaultInstance) {
-      if (type.MappedType != MappedType.Message) {
-        throw new ArgumentException("ExtensionRegistry.Add() provided a default instance for a "
-            + "non-message extension.");
-      }
-      Add(new ExtensionInfo(type, defaultInstance));
-    }
-
-    private void Add(ExtensionInfo extension) {
+    public virtual void Add(IGeneratedExtensionLite extension) {
       if (readOnly) {
         throw new InvalidOperationException("Cannot add entries to a read-only extension registry");
       }
-      if (!extension.Descriptor.IsExtension) {
-        throw new ArgumentException("ExtensionRegistry.add() was given a FieldDescriptor for a "
-            + "regular (non-extension) field.");
-      }
-
-      extensionsByName[extension.Descriptor.FullName] = extension;
-      extensionsByNumber[new DescriptorIntPair(extension.Descriptor.ContainingType,
-          extension.Descriptor.FieldNumber)] = extension;
-
-      FieldDescriptor field = extension.Descriptor;
-      if (field.ContainingType.Options.MessageSetWireFormat
-          && field.FieldType == FieldType.Message
-          && field.IsOptional
-          && field.ExtensionScope == field.MessageType) {
-        // This is an extension of a MessageSet type defined within the extension
-        // type's own scope. For backwards-compatibility, allow it to be looked
-        // up by type name.
-        extensionsByName[field.MessageType.FullName] = extension;
-      }
+      extensionsByNumber.Add(
+        new ExtensionIntPair(extension.ContainingType, extension.Number),
+        extension);
     }
 
     /// <summary>
     /// Nested type just used to represent a pair of MessageDescriptor and int, as
     /// the key into the "by number" map.
     /// </summary>
-    private struct DescriptorIntPair : IEquatable<DescriptorIntPair> {
-      readonly MessageDescriptor descriptor;
+    protected struct ExtensionIntPair : IEquatable<ExtensionIntPair> {
+      readonly object msgType;
       readonly int number;
 
-      internal DescriptorIntPair(MessageDescriptor descriptor, int number) {
-        this.descriptor = descriptor;
+      internal ExtensionIntPair(object msgType, int number) {
+        this.msgType = msgType;
         this.number = number;
       }
 
       public override int GetHashCode() {
-        return descriptor.GetHashCode() * ((1 << 16) - 1) + number;
+        return msgType.GetHashCode() * ((1 << 16) - 1) + number;
       }
 
       public override bool Equals(object obj) {
-        if (!(obj is DescriptorIntPair)) {
+        if (!(obj is ExtensionIntPair)) {
           return false;
         }
-        return Equals((DescriptorIntPair)obj);
+        return Equals((ExtensionIntPair)obj);
       }
 
-      public bool Equals(DescriptorIntPair other) {
-        return descriptor == other.descriptor && number == other.number;
+      public bool Equals(ExtensionIntPair other) {
+        return msgType.Equals(other.msgType) && number == other.number;
       }
     }
   }