/// <summary>
        /// Get filters.
        /// </summary>
        /// <param name="data"><see cref="HierarchyDataStructure"/>Copied record structure.</param>
        /// <param name="fromRecordId"><see cref="Guid"/>Record id.</param>
        protected virtual Dictionary <string, object> GetHierarchyDataSimpleFilter(HierarchyDataStructure data, Guid fromRecordId)
        {
            Dictionary <string, object> hierarchyDataFilters = new Dictionary <string, object>();
            var filterKey = string.IsNullOrEmpty(data.ParentColumnName) ? "Id" : data.ParentColumnName;

            hierarchyDataFilters.Add(filterKey, fromRecordId);
            return(hierarchyDataFilters);
        }
        /// <summary>
        /// Get dictionary related new and old record
        /// </summary>
        /// <param name="data"><see cref="HierarchyDataStructure"/>Copied record structure.</param>
        /// <param name="fromRecordId"><see cref="Guid"/>Record id.</param>
        /// <param name="parentSchemaName"><see cref="Guid"/>.</param>
        /// <param name="toRecordId"><see cref="Guid"/>New related record.</param>
        /// <returns><see cref="Dictionary<Guid, Guid>"/>Related record`s id.</returns>
        protected virtual Dictionary <Guid, Guid> CopyHierarchyDataRecord(HierarchyDataStructure data, Guid fromRecordId, Guid toRecordId = default(Guid), string parentSchemaName = default(string))
        {
            Dictionary <string, object> hierarchyDataFilters = GetHierarchyDataSimpleFilter(data, fromRecordId);
            var filterGroup         = GetFilterGroup(hierarchyDataFilters, data.Filters);
            var columns             = GetColumns(data);
            var relatedColumnValues = GetRelatedColumnValues(data.SchemaName, data.ParentColumnName, toRecordId);

            return(EntityCollectionMappingHandler.CopyItems(data.SchemaName, columns, filterGroup, relatedColumnValues));
        }
        /// <summary>
        /// Methods gets HierarchyData and copy records.
        /// </summary>
        /// <param name="schemaName"><see cref="string"/> Entity schema name. </param>
        /// <param name="recordId"><see cref="Guid"/> Main record id. </param>
        /// <returns><see cref="Guid"/> Id of created record.</returns>
        public virtual CopyingResult CopyRecord(string schemaName, Guid recordId)
        {
            if (!HasRightsToCopyRecord(schemaName, recordId))
            {
                var errorMessage = UserConnection.GetLocalizableString("HierarchyDataCopyingController", "RecordRightsErrorMessage");
                return(new CopyingResult(errorMessage));
            }

            HierarchyDataStructure hierarchyData = GetStructure(schemaName);
            var copyRecordId = CopyHierarchyData(hierarchyData, recordId);

            return(new CopyingResult(copyRecordId));
        }
        /// <summary>
        /// Methods saved hierarchy data
        /// </summary>
        /// <param name="HierarchyDataStructure"><see cref="HierarchyDataStructure"/>Copied record structure.</param>
        /// <param name="recordId"><see cref="Guid"/>Main record id.</param>
        /// <returns><see cref="Guid"/> Id of created record.</returns>
        protected virtual Guid CopyHierarchyData(HierarchyDataStructure data, Guid recordId)
        {
            Dictionary <Guid, Guid> mappedCopiedRecords = CopyHierarchyDataRecord(data, recordId);

            if (data.Structures != null && data.Structures.Any())
            {
                CopyHierarchyDataList(new HierarchyDataCopyRecord {
                    MappedRecord     = mappedCopiedRecords,
                    Structures       = data.Structures,
                    ParentSchemaName = data.SchemaName
                });
            }
            return(mappedCopiedRecords.First().Value);
        }
        /// <summary>
        /// Get columns collection with related column
        /// </summary>
        /// <param name="data"><see cref="HierarchyDataStructure"/>Copied record structure.</param>
        /// <returns><see cref="List<string>"/>Columns collection.</returns>
        protected virtual List <string> GetColumns(HierarchyDataStructure data)
        {
            var columns = data.Columns;

            if (!string.IsNullOrEmpty(data.ParentColumnName))
            {
                bool containsItem = columns.Any(item => item == data.ParentColumnName);
                if (!containsItem)
                {
                    columns.Add(data.ParentColumnName);
                }
            }
            return(columns);
        }
        /// <summary>
        /// Obtain structure for entity schema.
        /// </summary>
        /// <param name="entitySchemaName">Entity schema name</param>
        /// <returns>Structure</returns>
        protected HierarchyDataStructure ObtainStructureForEntitySchema(string entitySchemaName)
        {
            var structure = new HierarchyDataStructure {
                SchemaName = entitySchemaName,
                Columns    = new List <string>()
            };
            var entitySchema = UserConnection.EntitySchemaManager.GetInstanceByName(entitySchemaName);

            foreach (var column in entitySchema.Columns)
            {
                if (column.IsVirtual || column.IsSystem || !column.IsValueCloneable)
                {
                    continue;
                }
                structure.Columns.Add(column.Name);
            }
            return(structure);
        }
        /// <summary>
        /// Obtain structure applying base strategy by hierarchical data source name.
        /// </summary>
        /// <returns><see cref="HierarchyDataStructure"/>Structure of hierarchical data.</returns>
        public virtual HierarchyDataStructure ObtainStructure()
        {
            var structure = new HierarchyDataStructure();

            return(structure);
        }