<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -17,14 +17,37 @@ namespace FluentNHibernate.Testing.PersistenceModelTests
         public void SetUp()
         {
             providers = new List&lt;IIndeterminateSubclassMappingProvider&gt;();
+        }
+
+        [Test]
+        public void Should_add_subclass_that_implements_the_parent_interface()
+        {
+            /* The Parent is the IFoo interface the desired results 
+             * of this test is the inclusion of the Foo&lt;T&gt; through the
+             * GenericFooMap&lt;T&gt; subclass mapping.
+             */
+
             fooMapping = ((IMappingProvider)new FooMap()).GetClassMapping();
+
+            providers.Add(new StringFooMap());
+            var sut = CreateSut();
+            sut.ProcessClass(fooMapping);
+            Assert.AreEqual(1, fooMapping.Subclasses.Count());
+            Assert.AreEqual(1, fooMapping.Subclasses.Where(sub =&gt; sub.Type.Equals(typeof(Foo&lt;string&gt;))).Count());
         }
 
-        [Test, Ignore(&quot;Issue 340: http://code.google.com/p/fluent-nhibernate/issues/detail?id=340&quot;)]
-        public void Should_add_subclass_that_implement_the_parent_interface()
+        [Test]
+        public void Should_add_subclass_that_implements_the_parent_base()
         {
+            /* The Parent is the FooBase class the desired results 
+             * of this test is the inclusion of the Foo&lt;T&gt; through the
+             * GenericFooMap&lt;T&gt; subclass mapping.
+             */
+
+            fooMapping = ((IMappingProvider)new BaseMap()).GetClassMapping();
+
             providers.Add(new StringFooMap());
-            var sut = new SeparateSubclassVisitor(providers);
+            var sut = CreateSut();
             sut.ProcessClass(fooMapping);
             Assert.AreEqual(1, fooMapping.Subclasses.Count());
             Assert.AreEqual(1, fooMapping.Subclasses.Where(sub =&gt; sub.Type.Equals(typeof(Foo&lt;string&gt;))).Count());
@@ -33,45 +56,114 @@ namespace FluentNHibernate.Testing.PersistenceModelTests
         [Test]
         public void Should_not_add_subclassmap_that_does_not_implement_parent_interface()
         {
-            providers.Add(new OtherMap());
-            var sut = new SeparateSubclassVisitor(providers);
+            /* The Parent is the IFoo interface the desired results 
+             * of this test is the exclusion of the StandAlone class 
+             * since it does not implement the interface.
+             */
+
+            fooMapping = ((IMappingProvider)new FooMap()).GetClassMapping();
+
+            providers.Add(new StandAloneMap());
+            var sut = CreateSut();
             sut.ProcessClass(fooMapping);
             Assert.AreEqual(0, fooMapping.Subclasses.Count());
         }
 
-        private interface IFoo
+        [Test]
+        public void Should_not_add_subclassmap_that_does_not_implement_parent_base()
         {
-        }
+            /* The Parent is the FooBase class the desired results 
+             * of this test is the exclusion of the StandAlone class 
+             * since it does not implement the interface.
+             */
 
-        private interface IOther
-        {
-            IFoo Foo { get; }
+            fooMapping = ((IMappingProvider)new BaseMap()).GetClassMapping();
+
+            providers.Add(new StandAloneMap());
+            var sut = CreateSut();
+            sut.ProcessClass(fooMapping);
+            Assert.AreEqual(0, fooMapping.Subclasses.Count());
         }
 
-        private class Base
+        [Test]
+        public void Should_not_add_subclassmap_that_implements_a_subclass_of_the_parent_interface()
         {
-        }
+            /* The Parent is the IFoo interface the desired results 
+             * of this test is the inclusion of the BaseImpl class and 
+             * the exclusion of the Foo&lt;T&gt; class since it implements 
+             * the BaseImpl class which already implements FooBase.
+             */
 
-        private class Other : Base { }
+            fooMapping = ((IMappingProvider)new FooMap()).GetClassMapping();
 
-        private class Foo&lt;T&gt; : Base, IFoo
-        {
+            providers.Add(new BaseImplMap());
+            providers.Add(new StringFooMap());
+            var sut = CreateSut();
+            sut.ProcessClass(fooMapping);
+            Assert.AreEqual(1, fooMapping.Subclasses.Count());
+            Assert.AreEqual(1, fooMapping.Subclasses.Where(sub =&gt; sub.Type.Equals(typeof(BaseImpl))).Count());
         }
 
-        private class FooMap : ClassMap&lt;IFoo&gt;
+        [Test]
+        public void Should_not_add_subclassmap_that_implements_a_subclass_of_the_parent_base()
         {
-        }
+            /* The Parent is the FooBase class the desired results 
+             * of this test is the inclusion of the BaseImpl class and 
+             * the exclusion of the Foo&lt;T&gt; class since it implements 
+             * the BaseImpl class which already implements FooBase.
+             */
 
-        private abstract class SubFooMap&lt;T&gt; : SubclassMap&lt;Foo&lt;T&gt;&gt;
-        {
-        }
+            fooMapping = ((IMappingProvider)new BaseMap()).GetClassMapping();
 
-        private class StringFooMap : SubFooMap&lt;string&gt;
-        {
+            providers.Add(new BaseImplMap());
+            providers.Add(new StringFooMap());
+            var sut = CreateSut();
+            sut.ProcessClass(fooMapping);
+            Assert.AreEqual(1, fooMapping.Subclasses.Count());
+            Assert.AreEqual(1, fooMapping.Subclasses.Where(sub =&gt; sub.Type.Equals(typeof(BaseImpl))).Count());
         }
 
-        private class OtherMap : SubclassMap&lt;Other&gt;
+        private SeparateSubclassVisitor CreateSut()
         {
+            return new SeparateSubclassVisitor(providers);
         }
+
+
+        public interface IFoo
+        { }
+
+        public class Base : IFoo
+        { }
+
+        public abstract class BaseImpl : Base
+        { }
+
+        public class Foo&lt;T&gt; : BaseImpl, IFoo
+        { }
+
+        public class FooMap : ClassMap&lt;IFoo&gt;
+        { }
+
+        public class BaseMap : ClassMap&lt;Base&gt;
+        { }
+
+        public class BaseImplMap : SubclassMap&lt;BaseImpl&gt;
+        { }
+
+        public abstract class GenericFooMap&lt;T&gt; : SubclassMap&lt;Foo&lt;T&gt;&gt;
+        { }
+
+        public class StringFooMap : GenericFooMap&lt;string&gt;
+        { }
+
+
+        public interface IStand
+        { }
+
+        public class StandAlone : IStand
+        { }
+
+        public class StandAloneMap : SubclassMap&lt;StandAlone&gt;
+        { }
     }
 }</diff>
      <filename>src/FluentNHibernate.Testing/PersistenceModelTests/SeparateSubclassVisitorFixture.cs</filename>
    </modified>
    <modified>
      <diff>@@ -63,59 +63,100 @@ namespace FluentNHibernate
         {
             if (mapping.Discriminator == null)
                 return new JoinedSubclassMapping();
-            
+
             return new SubclassMapping();
         }
 
+        private bool IsMapped(Type type, IEnumerable&lt;IIndeterminateSubclassMappingProvider&gt; providers)
+        {
+            return providers.Any(x =&gt; x.EntityType == type);
+        }
+
         /// &lt;summary&gt;
         /// Takes a type that represents the level in the class/subclass-hiearchy that we're starting from, the parent,
         /// this can be a class or subclass; also takes a list of subclass providers. The providers are then iterated
         /// and added to a dictionary key'd by the types &quot;distance&quot; from the parentType; distance being the number of levels
         /// between parentType and the subclass-type.
+        /// 
+        /// By default if the Parent type is an interface the level will always be zero. At this time there is no check for
+        /// hierarchical interface inheritance.
         /// &lt;/summary&gt;
         /// &lt;param name=&quot;parentType&quot;&gt;Starting point, parent type.&lt;/param&gt;
-        /// &lt;param name=&quot;providers&quot;&gt;List of subclasses&lt;/param&gt;
+        /// &lt;param name=&quot;subProviders&quot;&gt;List of subclasses&lt;/param&gt;
         /// &lt;returns&gt;Dictionary key'd by the distance from the parentType.&lt;/returns&gt;
-        private IDictionary&lt;int, IList&lt;IIndeterminateSubclassMappingProvider&gt;&gt; SortByDistanceFrom(Type parentType, IEnumerable&lt;IIndeterminateSubclassMappingProvider&gt; providers)
+        private IDictionary&lt;int, IList&lt;IIndeterminateSubclassMappingProvider&gt;&gt; SortByDistanceFrom(Type parentType, IEnumerable&lt;IIndeterminateSubclassMappingProvider&gt; subProviders)
         {
             var arranged = new Dictionary&lt;int, IList&lt;IIndeterminateSubclassMappingProvider&gt;&gt;();
 
-            foreach (var provider in providers)
+            foreach (var subclassProvider in subProviders)
             {
-                var subclassType = provider.EntityType;
+                var subclassType = subclassProvider.EntityType;
                 var level = 0;
 
-                // while not reached parent yet, or have reached the top without finding the parent and parent is an interface and
-                // the current level implements that interface
-                while (subclassType.BaseType != parentType ||
-                    (subclassType.IsTopLevel() &amp;&amp; parentType.IsInterface &amp;&amp; subclassType.HasInterface(parentType)))
-                {
-                    if (IsMapped(subclassType.BaseType, providers))
-                        level++;
-
-                    // reached the top, stop
-                    if (subclassType.IsTopLevel())
-                        break;
+                bool implOfParent = parentType.IsInterface
+                           ? DistanceFromParentInterface(parentType, subclassType, ref level)
+                           : DistanceFromParentBase(parentType, subclassType.BaseType, ref level);
 
-                    subclassType = subclassType.BaseType;
-                }
-
-                // reached the top and the parent isn't an interface (or the current level doesn't implement it)
-                if (subclassType.IsTopLevel() &amp;&amp; !(parentType.IsInterface &amp;&amp; subclassType.HasInterface(parentType)))
-                    continue;
+                if (!implOfParent) continue;
 
                 if (!arranged.ContainsKey(level))
                     arranged[level] = new List&lt;IIndeterminateSubclassMappingProvider&gt;();
 
-                arranged[level].Add(provider);
+                arranged[level].Add(subclassProvider);
             }
 
             return arranged;
         }
 
-        private bool IsMapped(Type type, IEnumerable&lt;IIndeterminateSubclassMappingProvider&gt; providers)
+        /// &lt;summary&gt;
+        /// The evalType starts out as the original subclass. The class hiearchy is only
+        /// walked if the subclass inherits from a class that is included in the subclassProviders.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;parentType&quot;&gt;&lt;/param&gt;
+        /// &lt;param name=&quot;evalType&quot;&gt;&lt;/param&gt;
+        /// &lt;param name=&quot;level&quot;&gt;&lt;/param&gt;
+        /// &lt;returns&gt;&lt;/returns&gt;
+        private bool DistanceFromParentInterface(Type parentType, Type evalType, ref int level)
         {
-            return providers.Any(x =&gt; x.EntityType == type);
+            if (!evalType.HasInterface(parentType)) return false;
+
+            if (!(evalType == typeof(object)) &amp;&amp;
+                IsMapped(evalType.BaseType, subclassProviders))
+            {
+                //Walk the tree if the subclasses base class is also in the subclassProviders
+                level++;
+                DistanceFromParentInterface(parentType, evalType.BaseType, ref level);
+            }
+
+            return true;
+        }
+
+        /// &lt;summary&gt;
+        /// The evalType is always one class higher in the hiearchy starting from the original subclass. The class 
+        /// hiearchy is walked until the IsTopLevel (base class is Object) is met. The level is only incremented if 
+        /// the subclass inherits from a class that is also in the subclassProviders.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;parentType&quot;&gt;&lt;/param&gt;
+        /// &lt;param name=&quot;evalType&quot;&gt;&lt;/param&gt;
+        /// &lt;param name=&quot;level&quot;&gt;&lt;/param&gt;
+        /// &lt;returns&gt;&lt;/returns&gt;
+        private bool DistanceFromParentBase(Type parentType, Type evalType, ref int level)
+        {
+            var evalImplementsParent = false;
+            if (evalType == parentType)
+                evalImplementsParent = true;
+
+            if (!evalImplementsParent &amp;&amp; !(evalType == typeof(object)))
+            {
+                //If the eval class does not inherit the parent but it is included
+                //in the subclassprovides, then the original subclass can not inherit 
+                //directly from the parent.
+                if (IsMapped(evalType, subclassProviders))
+                    level++;
+                evalImplementsParent = DistanceFromParentBase(parentType, evalType.BaseType, ref level);
+            }
+
+            return evalImplementsParent;
         }
     }
 }
\ No newline at end of file</diff>
      <filename>src/FluentNHibernate/SeparateSubclassVisitor.cs</filename>
    </modified>
    <modified>
      <diff>@@ -43,10 +43,5 @@ namespace FluentNHibernate.Utils
         {
             return type.GetInterfaces().Contains(interfaceType);
         }
-
-        public static bool IsTopLevel(this Type type)
-        {
-            return type.BaseType == typeof(object);
-        }
     }
 }
\ No newline at end of file</diff>
      <filename>src/FluentNHibernate/Utils/TypeExtensions.cs</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>e31329f1ecb5c9c6f47f537f97afceea5672a36c</id>
    </parent>
  </parents>
  <author>
    <name>Paul Batum</name>
    <email>paul.batum@gmail.com</email>
  </author>
  <url>http://github.com/jagregory/fluent-nhibernate/commit/2fb27381d70b998fb11fe92b44e6b101b4525bff</url>
  <id>2fb27381d70b998fb11fe92b44e6b101b4525bff</id>
  <committed-date>2009-11-02T16:37:07-08:00</committed-date>
  <authored-date>2009-11-02T16:37:07-08:00</authored-date>
  <message>Applied patch from rik.bardrof resolving subclassing issue #345</message>
  <tree>859bb01173efd31dc36bc50e6070472c0a2e93e4</tree>
  <committer>
    <name>Paul Batum</name>
    <email>paul.batum@gmail.com</email>
  </committer>
</commit>
