/// <summary>
        /// Adds a result to the list and returns the state.
        /// </summary>
        /// <param name="expected">The expected <see cref="ObjectField"/> to set the result for.</param>
        /// <param name="current">The current <see cref="ObjectField"/> to set the result for.</param>
        /// <param name="state">The state of the result.</param>
        /// <param name="percent">The percentage of equal fields.</param>
        /// <returns>The <see cref="CompareResult"/> added to the list.</returns>
        private CompareResult AddResult(ObjectField expected, ObjectField current, ResultState state, double percent)
        {
            CompareResult compareResult = new CompareResult(state, percent);

            return(AddResult(expected, current, compareResult));
        }
        private CompareResult CompareRecur(ObjectField expected, ObjectField current)
        {
            CompareFieldsEventArgs eventArgs = new CompareFieldsEventArgs(expected, current);

            OnCompareFields(eventArgs);
            if (eventArgs.CompareResult != null)
            {
                AddResult(expected, current, eventArgs.CompareResult);
                return(eventArgs.CompareResult);
            }

            if (expected == null || current == null)
            {
                return(new CompareResult(ResultState.Unknown, 0));
            }
            if (expected.GetType() != current.GetType())
            {
                // Type is different.
                return(AddResult(expected, current, ResultState.NotEqual, 0));
            }

            if (expected.Value != null && current.Value == null)
            {
                // The field is missing.
                return(AddResult(expected, current, ResultState.Missing, 0));
            }
            if (expected.Value == null && current.Value != null)
            {
                // The field is new.
                return(AddResult(expected, current, ResultState.New, 0));
            }

            ObjectFieldValue expectedValue = expected as ObjectFieldValue;
            ObjectFieldValue currentValue  = current as ObjectFieldValue;

            if (expectedValue != null && currentValue != null)
            {
                if (expectedValue.Name != currentValue.Name)
                {
                    // Fields are different
                    return(AddResult(expected, current, ResultState.NotEqual, 0));
                }
                if (expectedValue.Value != null && currentValue.Value != null && !expectedValue.Value.Equals(currentValue.Value))
                {
                    // Value is different
                    return(AddResult(expected, current, ResultState.NotEqual, 0));
                }
                return(AddResult(expected, current, ResultState.Equal, 1));
            }

            IEnumerator <ObjectField> expectedEnumerator = expected.Childs.GetEnumerator();
            IEnumerator <ObjectField> currentEnumerator  = current.Childs.GetEnumerator();
            ResultState resultState   = ResultState.Equal;
            double      resultPercent = 0;
            int         count         = 0;

            while (expectedEnumerator.MoveNext() & currentEnumerator.MoveNext())
            {
                CompareResult currentResult = CompareRecur(expectedEnumerator.Current, currentEnumerator.Current);
                if (currentResult.State != ResultState.Equal && currentResult.State != ResultState.Ignored)
                {
                    resultState = ResultState.NotEqual;
                }
                if (currentResult.State != ResultState.Ignored)
                {
                    resultPercent += currentResult.Percent;
                    count++;
                }
            }

            if (expectedEnumerator.Current != null)
            {
                do
                {
                    AddResult(expectedEnumerator.Current, null, ResultState.Missing, 0);
                    count++;
                } while (expectedEnumerator.MoveNext());
            }
            if (currentEnumerator.Current != null)
            {
                do
                {
                    AddResult(null, currentEnumerator.Current, ResultState.New, 0);
                    count++;
                } while (currentEnumerator.MoveNext());
            }
            resultPercent = count != 0 ? resultPercent / count : 1;

            return(AddResult(expected, current, resultState, resultPercent));
        }