protected virtual void OnDuplicateKeyFound(DuplicateKeyEventArg e)
        {
            var handler = DuplicateKeyFound;

            if (handler != null)
            {
                handler(this, e);
            }
        }
        protected virtual void FetchContentTranslationKeys(Dictionary <string, string> translationKeyToPropertyPathMap,
                                                           Dictionary <string, string> propertyPathToTranslationKeyMap,
                                                           Type contentType,
                                                           IEnumerable <string> parentTranslationPaths,
                                                           string contentTypePath)
        {
            if (contentType.IsPrimitive || contentType == typeof(string))
            {
                return;
            }

            var processedTypes = new HashSet <Type>();

            var localContentTranslationPaths   = GetTranslationPaths(contentType);
            var currentContentTranslationPaths = BuildKeyPaths(parentTranslationPaths, localContentTranslationPaths).ToList();

            var translationProps = GetTranslationProperties(contentType).ToList();

            processedTypes.Add(contentType);

            foreach (var translationProp in translationProps)
            {
                var propertyTranslationKeys = GetTranslationPropertyKeys(translationProp);
                var keyList      = BuildKeyPaths(currentContentTranslationPaths, propertyTranslationKeys).ToList();
                var propertyPath = CombineTypePropertyPath(contentTypePath, translationProp.Name);

                foreach (var propertyKey in keyList)
                {
                    var translationKey = PrepareTranslationKey(propertyKey);

                    if (translationKeyToPropertyPathMap.ContainsKey(translationKey))
                    {
                        var e = new DuplicateKeyEventArg
                        {
                            TranslationKeyToPropertyPathMap = translationKeyToPropertyPathMap.OrEmpty(),
                            PropertyPathToTranslationKeyMap = propertyPathToTranslationKeyMap.OrEmpty(),
                            TranslationKey = translationKey,
                            PropertyKey    = propertyKey
                        };
                        OnDuplicateKeyFound(e);
                    }
                    translationKeyToPropertyPathMap[translationKey] = propertyPath;
                }

                if (keyList.Count > 0)
                {
                    propertyPathToTranslationKeyMap[propertyPath] = PrepareTranslationKey(keyList.First());
                }
            }

            var childContentTypeProps = GetChildTranslationContentTypeProperties(contentType);

            foreach (var childContentTypeProp in childContentTypeProps)
            {
                if (processedTypes.Contains(childContentTypeProp.PropertyType))
                {
                    continue;
                }

                processedTypes.Add(childContentTypeProp.PropertyType);

                FetchContentTranslationKeys(translationKeyToPropertyPathMap, propertyPathToTranslationKeyMap,
                                            childContentTypeProp.PropertyType, currentContentTranslationPaths,
                                            CombineTypePropertyPath(contentTypePath, childContentTypeProp.Name));
            }
        }