private static IDictionaryDifference <TKey, TVal> GetDifference <TKey, TVal>(
            IDictionaryAccessor <TKey, TVal> left,
            IDictionaryAccessor <TKey, TVal> right)
        {
            IDictionary <TKey, TVal> entriesOnlyOnLeft  = new Dictionary <TKey, TVal>();
            IDictionary <TKey, TVal> entriesOnlyOnRight = new Dictionary <TKey, TVal>();
            var entriesInCommon  = new Dictionary <TKey, TVal>();
            var entriesDiffering = new Dictionary <TKey, IDictionaryValueDifference <TVal> >();
            int leftSize         = left.Count;
            int rightSize        = right.Count;

            if (leftSize != 0 && rightSize != 0)
            {
                foreach (KeyValuePair <TKey, TVal> leftKeyVal in left)
                {
                    TKey key     = leftKeyVal.Key;
                    TVal leftVal = leftKeyVal.Value;
                    if (right.TryGetValue(key, out TVal rightVal))
                    {
                        if (Equals(leftVal, rightVal))
                        {
                            entriesInCommon[key] = leftVal;
                        }
                        else
                        {
                            entriesDiffering[key] = new DictionaryValueDifference <TVal>(leftVal, rightVal);
                        }
                    }
                    else
                    {
                        entriesOnlyOnLeft[key] = leftVal;
                    }
                }

                foreach (KeyValuePair <TKey, TVal> rightKeyVal in right)
                {
                    TKey key = rightKeyVal.Key;
                    if (!entriesOnlyOnLeft.ContainsKey(key) && !entriesInCommon.ContainsKey(key) &&
                        !entriesDiffering.ContainsKey(key))
                    {
                        entriesOnlyOnRight[key] = rightKeyVal.Value;
                    }
                }
            }
            else if (leftSize != 0)
            {
                entriesOnlyOnLeft = left.ToDictionary();
            }
            else if (rightSize != 0)
            {
                entriesOnlyOnRight = right.ToDictionary();
            }

            return(new DictionaryDifference <TKey, TVal>(entriesOnlyOnLeft, entriesOnlyOnRight, entriesInCommon,
                                                         entriesDiffering));
        }