public ActionResult Edit(int id, string category, string type, int sortCriterionId = -1) {
            if (!Services.Authorizer.Authorize(Permissions.ManageQueries, T("Not authorized to manage queries")))
                return new HttpUnauthorizedResult();

            var sortCriterion = _projectionManager.DescribeSortCriteria().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == category && x.Type == type);

            if (sortCriterion == null) {
                return HttpNotFound();
            }

            // if there is no form to edit, save the sort criteria and go back to the query
            if (sortCriterion.Form == null) {
                if (sortCriterionId == -1) {
                    var query = _queryService.GetQuery(id);
                    query.SortCriteria.Add(new SortCriterionRecord {
                        Category = category, 
                        Type = type,
                        Position = query.SortCriteria.Count
                    });
                }

                return RedirectToAction("Edit", "Admin", new { id });
            }

            // build the form, and let external components alter it
            var form = _formManager.Build(sortCriterion.Form);

            var description = String.Empty;

            // bind form with existing values).
            if (sortCriterionId != -1) {
                var query = _queryService.GetQuery(id);
                var sortCriterionRecord = query.SortCriteria.FirstOrDefault(f => f.Id == sortCriterionId);
                if (sortCriterionRecord != null) {
                    description = sortCriterionRecord.Description;
                    var parameters = FormParametersHelper.FromString(sortCriterionRecord.State);
                    _formManager.Bind(form, new DictionaryValueProvider<string>(parameters, CultureInfo.InvariantCulture));
                }
            }

            var viewModel = new SortCriterionEditViewModel { Id = id, Description = description, SortCriterion = sortCriterion, Form = form };
            return View(viewModel);
        }
        public ActionResult EditPost(int id, string category, string type, [DefaultValue(-1)]int sortCriterionId, FormCollection formCollection) {
            var query = _queryService.GetQuery(id);

            var sortCriterion = _projectionManager.DescribeSortCriteria().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == category && x.Type == type);

            var model = new SortCriterionEditViewModel();
            TryUpdateModel(model);

            // validating form values
            _formManager.Validate(new ValidatingContext { FormName = sortCriterion.Form, ModelState = ModelState, ValueProvider = ValueProvider });

            if (ModelState.IsValid) {
                var sortCriterionRecord = query.SortCriteria.FirstOrDefault(f => f.Id == sortCriterionId);

                // add new sort criteria record if it's a newly created one
                if (sortCriterionRecord == null) {
                    sortCriterionRecord = new SortCriterionRecord {
                        Category = category, 
                        Type = type, 
                        Position = query.SortCriteria.Count
                    };
                    query.SortCriteria.Add(sortCriterionRecord);
                }

                var dictionary = formCollection.AllKeys.ToDictionary(key => key, formCollection.Get);

                // save form parameters
                sortCriterionRecord.State = FormParametersHelper.ToString(dictionary);
                sortCriterionRecord.Description = model.Description;

                return RedirectToAction("Edit", "Admin", new { id });
            }

            // model is invalid, display it again
            var form = _formManager.Build(sortCriterion.Form);

            _formManager.Bind(form, formCollection);
            var viewModel = new SortCriterionEditViewModel { Id = id, Description = model.Description, SortCriterion = sortCriterion, Form = form };

            return View(viewModel);
        }