public ActionResult Edit(int id, string category, string type, int actionId = -1) {
            if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage rules")))
                return new HttpUnauthorizedResult();

            var action = _rulesManager.DescribeActions().SelectMany(x => x.Descriptors).Where(x => x.Category == category && x.Type == type).FirstOrDefault();

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

            // if there is no form to edit, save the action and go back to the rule
            if (action.Form == null) {
                if (actionId == -1) {
                    var rule = _rulesServices.GetRule(id);
                    rule.Actions.Add(new ActionRecord { Category = category, Type = type, Position = rule.Actions.Count + 1 });
                }

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

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

            // generate an anti forgery token
            var viewContext = new ViewContext { HttpContext = HttpContext, Controller = this };
            var siteSalt = Services.WorkContext.CurrentSite.SiteSalt;
            var token = new HtmlHelper(viewContext, new ViewDataContainer()).AntiForgeryToken(siteSalt);

            // add a submit button to the form
            form
                ._Actions(Shape.Fieldset(
                    _RequestAntiForgeryToken: Shape.Markup(
                        Value: token.ToString()),
                    _Save: Shape.Submit(
                        Name: "op",
                        Value: T("Save"))
                    )
                );

            // bind form with existing values).
            if (actionId != -1) {
                var rule = _rulesServices.GetRule(id);
                var actionRecord = rule.Actions.Where(a => a.Id == actionId).FirstOrDefault();
                if (actionRecord != null) {
                    var parameters = FormParametersHelper.FromString(actionRecord.Parameters);
                    _formManager.Bind(form, new DictionaryValueProvider<string>(parameters, CultureInfo.InvariantCulture));
                }
            }

            var viewModel = new EditActionViewModel { Id = id, Action = action, Form = form };
            return View(viewModel);
        }
        public ActionResult EditPost(int id, string category, string type, [DefaultValue(-1)]int actionId, FormCollection formCollection) {
            var rule = _rulesServices.GetRule(id);

            var actionRecord = rule.Actions.Where(a => a.Id == actionId).FirstOrDefault();

            // add new action record if it's a newly created action
            if (actionRecord == null) {
                actionRecord = new ActionRecord { Category = category, Type = type, Position = rule.Actions.Count };
                rule.Actions.Add(actionRecord);
            }

            var action = _rulesManager.DescribeActions().SelectMany(x => x.Descriptors).Where(x => x.Category == category && x.Type == type).FirstOrDefault();

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

            if (ModelState.IsValid) {
                var dictionary = formCollection.AllKeys.ToDictionary(key => key, formCollection.Get);

                // save form parameters
                actionRecord.Parameters = FormParametersHelper.ToString(dictionary);

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

            // model is invalid, display it again
            var form = _formManager.Build(action.Form);
            AddSubmitButton(form);
            _formManager.Bind(form, formCollection);
            var viewModel = new EditActionViewModel { Id = id, Action = action, Form = form };

            return View(viewModel);
        }