public ActionResult SafePositionEdit(FormCollection formCollection)
        {
            var openPositionChangedPropertyList = new List<SystemProperty>();
            var closePositionChangedPropertyList = new List<SystemProperty>();

            var strOpenId = String.Empty; // содержит, перечисленные через запятую, уникальные идентификаторы открытых позиций, которые нужно обновить
            var strCloseId = String.Empty; // -- закрытых позиций, которые нужно обновить

            //Список ошибок валидации. Формат: Поле - коментарий к ошибке
            var validationErrorList = new List<Tuple<string, string>>();

            // Мапим коллекцию 'FormCollection' в списоки из элементов 'SystemProperty'
            // Элемент item имеет тут знаения типа "Open_Side", "Open_StopLoss" и т.п.
            foreach (var item in formCollection)
            {
                if (String.IsNullOrEmpty(formCollection[item.ToString()]))
                    continue;  //Если строка оставлена пользователем пустой, тогда НЕ вносим это поле в список на редактирование

                string type;
                string systemName;

                #region парсим тип свойства и его системное имя
                try
                {
                    type = ((string) item).Split('_')[0];
                    systemName = ((string)item).Split('_')[1];
                }
                catch (Exception ex)
                {
                    Logger.Error(String.Format("SafePositionEdit() - не {0}", item), ex);
                    continue;
                }
                #endregion

                var prop = new SystemProperty
                    {
                        SystemName = systemName,
                        Value = formCollection[item.ToString()]
                    };

                if (!prop.Validation())
                {
                    validationErrorList.Add(new Tuple<string, string>(systemName, Resource.ErrorMessageInvalid));
                    continue;
                }

                // Поскольку в следующем switch нет случаев 'OpenDanger_', 'CloseDanger_' и 'OtherDanger_' то в выборку на
                // редактирование попадут только "безопасные" поля сделок
                #region в зависимости от состояния сделки (открыта / закрыта), запихиваем её свойство в соответствующий список из 'SystemProperty'
                switch (type)
                {
                    case "Open":
                        openPositionChangedPropertyList.Add(prop);
                        break;
                    case "Close":
                        closePositionChangedPropertyList.Add(prop);
                        break;
                    case "ItemsId":
                        if (systemName == "Open") strOpenId = formCollection[item.ToString()];
                        if (systemName == "Close") strCloseId = formCollection[item.ToString()];
                        break;
                }
                #endregion
            }

            var mess = string.Empty;

            mess += positionRepository.UpdateSavePositionItem(strOpenId, openPositionChangedPropertyList, PositionState.Opened) ?
                 string.Format("{0}: {1}", Resource.MessageMarketOrderUpdate, strOpenId) :
                 string.Format("{0}: {1} - {2}.",Resource.ErrorMessage, Resource.ErrorMessageUnableMarketOrderUpdate, strOpenId);
            mess += "   ";
            mess += positionRepository.UpdateSavePositionItem(strCloseId, closePositionChangedPropertyList, PositionState.Closed) ?
                string.Format("{0}: {1}", Resource.MessageMarketOrderUpdate, strCloseId) :
                string.Format("{0}: {1} - {2}.", Resource.ErrorMessage, Resource.ErrorMessageUnableMarketOrderUpdate, strCloseId);

            #region Если были найдены ошибки валидации возвращаем на ту же самую страницу редактирования, но уже со списком ошибок
            if (validationErrorList.Count > 0)
            {
                var idArray = String.Empty;
                if (!String.IsNullOrEmpty(strOpenId)) idArray += strOpenId;
                if (!String.IsNullOrEmpty(strCloseId)) idArray += "," + strCloseId;

                var positions = positionRepository.GetPositionsById(idArray.ToIntArrayUniform());
                var model = new PositionsEditModel(positions) { validationErrorList = validationErrorList };
                return View("SafePositionEdit", model);
            }
            #endregion

            return RedirectToAction("PositionList", new { message = mess, accountId = -1 });
        }
        /// <summary>
        /// Вспомогательный метод заполнения кортежей OpenPositionValues, ClosePositionValues и OtherPositionValues данными
        /// </summary>
        /// <param name="positions"></param>
        /// <param name="currentProp"></param>
        /// <param name="isDanger">Дополнительный параметр, указывает 'опасено' ли это поле для редактирования</param>
        /// <param name="valueList">Список свойст из таблици представления 'SafePositionEdit'. В этом методе в 'valueList' добавляется всегда
        /// однин элемент (новая строка в таблице представления 'SafePositionEdit'). Но при этом считается статистика</param>
        private static void FillProrertyList(IEnumerable<PositionItem> positions, PropertyInfo currentProp, bool isDanger,  List<SystemProperty> valueList)
        {
            var positionItems = positions as PositionItem[] ?? positions.ToArray();

            //Содержит человеко-понятное имя свойства из атрибута
            var propTitle = currentProp.Name;
            try
            {
                var attrDisplName = currentProp.CustomAttributes.SingleOrDefault(x => x.AttributeType == typeof (DisplayNameAttribute));
                if (attrDisplName != null) propTitle = (string) attrDisplName.ConstructorArguments[0].Value;
            }
            catch (Exception ex)
            {
                Logger.Error(string.Format("FillProrertyList() - {0} {1}", Resource.TextUnableReadAttributeDisplayName, propTitle), ex);
            }

            if (positionItems.Count() == 1)
            {
                var propObj = currentProp.GetValue(positionItems.Single());
                var propObjStr = propObj == null ? string.Empty : Converter.GetStringFromObject(propObj);

                var newRow = new SystemProperty
                    {
                        #region
                        PropertyType = currentProp.PropertyType,
                        SystemName = currentProp.Name,
                        PropertyTypeName = Utils.GetTypeDescription(currentProp.PropertyType).Item1,
                        PropertyTypeComment = Utils.GetTypeDescription(currentProp.PropertyType).Item2,
                        Title = propTitle,
                        IsDanger = isDanger,
                        Value = propObjStr,
                        Comment = Resource.TextSameInAllSelectedItems,
                        Tag = propObjStr
                        #endregion
                    };

                newRow.SetDescription();
                valueList.Add(newRow);
                return;
            }

            //=============   В случае, если для редактирования было выбрано больше двух строк  ==============
            //сюда будем складывать статистику
            var differentValues = new List<string>(); // примеры значений текущего свойства
            const string strNull = "null";
            const string strEmpty = " - ";

            // собираем статистику по текущему свойству
            foreach (var item in positionItems)
            {
                var propObj = currentProp.GetValue(item);
                var currentValues = propObj == null ? strNull : string.IsNullOrEmpty(propObj.ToString()) ? strEmpty : Converter.GetStringFromObject(propObj);
                if (differentValues.Contains(currentValues)) continue;
                differentValues.Add(currentValues);
            }

            var newMultiRow = new SystemProperty
            {
                #region
                PropertyType = currentProp.PropertyType,
                SystemName = currentProp.Name,
                PropertyTypeName = Utils.GetTypeDescription(currentProp.PropertyType).Item1,
                PropertyTypeComment = Utils.GetTypeDescription(currentProp.PropertyType).Item2,
                Title = propTitle,
                IsDanger = isDanger,
                Value = string.Format("{0}", string.Join(", ", differentValues)),
                Comment = (differentValues.Count < 2) ? Resource.TextSameInAllSelectedItems : string.Format("{0} {1}", Resource.TextNumberDistinctValues, +differentValues.Count),
                Tag = (differentValues.Count == 1) ? differentValues[0].Replace(strNull, string.Empty).Replace(strEmpty, string.Empty) : string.Empty
                #endregion
            };

            newMultiRow.SetDescription();
            valueList.Add(newMultiRow);
        }