Logic for comparing lists that are out of order based on a key
Inheritance: KellermanSoftware.CompareNetObjects.TypeComparers.BaseComparer
        /// <summary>
        /// Compare two hash sets
        /// </summary>
        public override void CompareType(CompareParms parms)
        {
            try
            {
                parms.Result.AddParent(parms.Object1.GetHashCode());
                parms.Result.AddParent(parms.Object2.GetHashCode());

                Type t1 = parms.Object1.GetType();
                parms.Object1Type = t1;

                bool countsDifferent = HashSetsDifferentCount(parms);

                if (parms.Result.ExceededDifferences)
                    return;

                if (parms.Config.IgnoreCollectionOrder)
                {
                    IgnoreOrderLogic logic = new IgnoreOrderLogic(RootComparer);
                    logic.CompareEnumeratorIgnoreOrder(parms, countsDifferent);
                }
                else
                {
                    CompareItems(parms);
                }
            }
            finally
            {
                parms.Result.RemoveParent(parms.Object1.GetHashCode());
                parms.Result.RemoveParent(parms.Object2.GetHashCode());
            }
        }
        /// <summary>
        /// Compare two dictionaries
        /// </summary>
        public override void CompareType(CompareParms parms)
        {
            //This should never happen, null check happens one level up
            if (parms.Object1 == null || parms.Object2 == null)
                return;

            try
            {
                parms.Result.AddParent(parms.Object1.GetHashCode());
                parms.Result.AddParent(parms.Object2.GetHashCode());

                //Objects must be the same length
                bool countsDifferent = DictionaryCountsDifferent(parms);

                if (parms.Result.ExceededDifferences)
                    return;

                if (parms.Config.IgnoreCollectionOrder)
                {
                    IgnoreOrderLogic logic = new IgnoreOrderLogic(RootComparer);
                    logic.CompareEnumeratorIgnoreOrder(parms, countsDifferent);
                }
                else
                {
                    CompareEachItem(parms);
                }

            }
            finally
            {
                parms.Result.RemoveParent(parms.Object1.GetHashCode());
                parms.Result.RemoveParent(parms.Object2.GetHashCode());
            }
        }
        /// <summary>
        /// Compare an integer indexer
        /// </summary>
        public void CompareIndexer(CompareParms parms, PropertyInfo info)
        {
            int indexerCount1 = (int)info.ReflectedType.GetProperty("Count").GetGetMethod().Invoke(parms.Object1, new object[] { });
            int indexerCount2 = (int)info.ReflectedType.GetProperty("Count").GetGetMethod().Invoke(parms.Object2, new object[] { });

            bool differentCounts = IndexersHaveDifferentLength(parms, info);

            if (parms.Result.ExceededDifferences)
                return;

            if (parms.Config.IgnoreCollectionOrder)
            {
                var enumerable1 = new IndexerCollectionLooper(parms.Object1, info, indexerCount1);
                var enumerable2 = new IndexerCollectionLooper(parms.Object2, info, indexerCount2);

                CompareParms childParms = new CompareParms
                {
                    Result = parms.Result,
                    Config = parms.Config,
                    ParentObject1 = parms.Object1,
                    ParentObject2 = parms.Object2,
                    Object1 = enumerable1,
                    Object2 = enumerable2,
                    BreadCrumb = parms.BreadCrumb
                };

                IgnoreOrderLogic logic = new IgnoreOrderLogic(_rootComparer);
                logic.CompareEnumeratorIgnoreOrder(childParms, differentCounts);
            }
            else
            {
                string currentCrumb;

                // Run on indexer
                for (int i = 0; i < indexerCount1; i++)
                {
                    currentCrumb = AddBreadCrumb(parms.Config, parms.BreadCrumb, info.Name, string.Empty, i);
                    object objectValue1 = info.GetValue(parms.Object1, new object[] { i });
                    object objectValue2 = null;

                    if (i < indexerCount2)
                        objectValue2 = info.GetValue(parms.Object2, new object[] { i });

                    CompareParms childParms = new CompareParms
                    {
                        Result = parms.Result,
                        Config = parms.Config,
                        ParentObject1 = parms.Object1,
                        ParentObject2 = parms.Object2,
                        Object1 = objectValue1,
                        Object2 = objectValue2,
                        BreadCrumb = currentCrumb
                    };

                    _rootComparer.Compare(childParms);

                    if (parms.Result.ExceededDifferences)
                        return;
                }

                if (indexerCount1 < indexerCount2)
                {
                    for (int j = indexerCount1; j < indexerCount2; j++)
                    {
                        currentCrumb = AddBreadCrumb(parms.Config, parms.BreadCrumb, info.Name, string.Empty, j);
                        object objectValue2 = info.GetValue(parms.Object2, new object[] { j });
                        object objectValue1 = null;

                        CompareParms childParms = new CompareParms
                        {
                            Result = parms.Result,
                            Config = parms.Config,
                            ParentObject1 = parms.Object1,
                            ParentObject2 = parms.Object2,
                            Object1 = objectValue1,
                            Object2 = objectValue2,
                            BreadCrumb = currentCrumb
                        };

                        _rootComparer.Compare(childParms);

                        if (parms.Result.ExceededDifferences)
                            return;
                    }
                }
            }
        }