/// <summary>
        /// Создание представление с добавление свойств из ограничения, которые используются в ограничении, но отсутствуют в указанном в качестве параметра ограничении. При поиске отсутствующих в представлении свойств учитываются также и выражения для вычислимых свойств.
        /// </summary>
        /// <param name="view">Представление, но основе которого создается новое представление, возвращаемое в качестве результата метода.</param>
        /// <param name="function">Функция, среди параметров которой происходит поиск неиспользуемых в представлении свойств.</param>
        /// <param name="dataService">Сервис данных необходим для правильного выбора выражения для вычислимиого свойства.</param>
        /// <returns>Представление, в которое добавлены необходимые свойства.</returns>
        public static View GetViewWithPropertiesUsedInFunction(View view, Function function, IDataService dataService)
        {
            if (view == null)
            {
                throw new ArgumentNullException("view");
            }

            if (function == null)
            {
                throw new ArgumentNullException("function");
            }

            SQLWhereLanguageDef langdef = ExternalLangDef.LanguageDef;

            // Создадим копию представления.
            // ToDo: При текущей реализации клонирования происходят аномалии, т.к. вложенные объекты не копируются полностью, копируются только ссылки. В TFS создана ошибка №30700.
            var enrichedView = view.Clone();

            var variableList = enrichedView.Properties.Select(propertyInView => propertyInView.Name).ToList();

            var detailList = new List <DetailVariableDef>();

            // ToDo: Для расширения представлений детейлов необходимо раскомментировать следую строку.  На данный момент этот вызов приводит к появлению пустых свойств в представлении детейла. Явление, видимо, как-то связанное с клонированием представлений (см. №30700.).
            // var detailList = enrichedView.Details.Select(detailInView => new DetailVariableDef(langdef.GetObjectType(detailInView.Name), detailInView.Name, detailInView.View, string.Empty, null)).ToList();

            FindPropertiesUsedInFunction(
                function, variableList, DetailVariableDefContainer.CreateDetailVariableDefContainersList(detailList));

            // Просмотрим все найденные в органичении свойства
            foreach (var property in variableList)
            {
                if (!enrichedView.CheckPropname(property))
                {
                    enrichedView.AddProperty(property, property, false, string.Empty);
                }

                // Проверим нет ли у свойства выражения для вычисления.
                var propertiesUsedInExpression = GetPropertiesUsedInExpression(
                    property, enrichedView.DefineClassType, dataService);

                foreach (var propertyUsedInExpression in propertiesUsedInExpression)
                {
                    if (!enrichedView.CheckPropname(propertyUsedInExpression) &&
                        !string.Equals(propertyUsedInExpression, SQLWhereLanguageDef.StormMainObjectKey, StringComparison.OrdinalIgnoreCase))
                    {
                        enrichedView.AddProperty(propertyUsedInExpression, propertyUsedInExpression, false, string.Empty);
                    }
                }
            }

            // Добавление описания детейлов: раскоментировать при ненеобходимости.
            // Пока в добавлении детейлов нет необходимости.
            // foreach (var detail in detailList)
            // {
            //    if (enrichedView.Details.Count(dvd => dvd.Name == detail.StringedView) == 0)
            //        enrichedView.AddDetailInView(detail.StringedView, detail.View, true);
            // }

            return(enrichedView);
        }
        /// <summary>
        /// Метод поиска всех используемых в параметрах функции свойств (включая описание детейлов).
        /// </summary>
        /// <param name="function">Функция, в которой производится поиск свойств.</param>
        /// <param name="variableList">Список найденных в функции свойств.</param>
        /// <param name="detailList">Список найденных описаний детейлов.</param>
        public static void FindPropertiesUsedInFunction(Function function, List <string> variableList, List <DetailVariableDefContainer> detailList)
        {
            if (function == null)
            {
                return;
            }

            DetailVariableDefContainer currentDetailContainer = null;

            foreach (var parameter in function.Parameters)
            {
                if (parameter is DetailVariableDef)
                { // это детейл
                    var detailVariableDef = parameter as DetailVariableDef;
                    currentDetailContainer =
                        detailList.FirstOrDefault(
                            dvd => dvd.DetailVariableDefValue.StringedView == detailVariableDef.StringedView);
                    if (currentDetailContainer == null)
                    {
                        detailList.Add(currentDetailContainer = new DetailVariableDefContainer()
                        {
                            DetailVariableDefValue = detailVariableDef
                        });
                    }
                }
                else if (parameter is VariableDef)
                { // это имя свойства
                    var variableDef = parameter as VariableDef;
                    if (!variableList.Contains(variableDef.StringedView) &&
                        variableDef.StringedView != SQLWhereLanguageDef.StormMainObjectKey)
                    {
                        variableList.Add(variableDef.StringedView);
                    }
                }
                else if (parameter is Function)
                { // спускаемся вниз
                    if (currentDetailContainer == null)
                    {
                        FindPropertiesUsedInFunction(parameter as Function, variableList, detailList);
                    }
                    else
                    {
                        FindPropertiesUsedInFunction(
                            parameter as Function, currentDetailContainer.DetailVariablesList, currentDetailContainer.DetailDetailsList);
                    }
                }
            }
        }