protected internal virtual void ParseFormField(Element formField, BpmnParse bpmnParse,
                                                       ExpressionManager expressionManager)
        {
            var formFieldHandler = new FormFieldHandler();

            // parse Id
            var id = formField.GetAttributeValue("id");

            if (ReferenceEquals(id, null) || (id.Length == 0))
            {
                bpmnParse.AddError("attribute id must be set for FormFieldGroup and must have a non-empty value",
                                   formField);
            }
            else
            {
                formFieldHandler.Id = id;
            }

            if (id.Equals(BusinessKeyFieldId))
            {
                formFieldHandler.BusinessKey = true;
            }

            // parse name
            var name = formField.GetAttributeValue("label");

            if (!ReferenceEquals(name, null))
            {
                IExpression nameExpression = (Bpm.Engine.Impl.EL.IExpression)expressionManager.CreateExpression(name);
                formFieldHandler.Label = nameExpression;
            }

            // parse properties
            ParseProperties(formField, formFieldHandler, bpmnParse, expressionManager);

            // parse validation
            ParseValidation(formField, formFieldHandler, bpmnParse, expressionManager);

            // parse type
            var formTypes = FormTypes;
            var formType  = formTypes.ParseFormPropertyType(formField, bpmnParse);

            formFieldHandler.SetType(formType);

            // parse default value
            var defaultValue = formField.GetAttributeValue("defaultValue");

            if (!ReferenceEquals(defaultValue, null))
            {
                IExpression defaultValueExpression = (Bpm.Engine.Impl.EL.IExpression)expressionManager.CreateExpression(defaultValue);
                formFieldHandler.DefaultValueExpression = defaultValueExpression;
            }

            FormFieldHandlers.Add(formFieldHandler);
        }
        protected internal virtual void ParseFormProperties(BpmnParse bpmnParse, ExpressionManager expressionManager,
                                                            Element extensionElement)
        {
            var formTypes = FormTypes;

            var formPropertyElements = extensionElement.ElementsNS(BpmnParse.CamundaBpmnExtensionsNs,
                                                                   FormPropertyElement);

            foreach (var formPropertyElement in formPropertyElements)
            {
                var formPropertyHandler = new FormPropertyHandler();

                var id = formPropertyElement.GetAttributeValue("id");
                if (ReferenceEquals(id, null))
                {
                    bpmnParse.AddError("attribute 'id' is required", formPropertyElement);
                }
                formPropertyHandler.Id = id;

                var name = formPropertyElement.GetAttributeValue("name");
                formPropertyHandler.Name = name;

                var type = formTypes.ParseFormPropertyType(formPropertyElement, bpmnParse);
                formPropertyHandler.SetType(type);

                var requiredText = formPropertyElement.GetAttributeValue("required", "false");
                var required     = bpmnParse.ParseBooleanAttribute(requiredText);
                if (required != null)
                {
                    formPropertyHandler.Required = required.Value;
                }
                else
                {
                    bpmnParse.AddError(
                        "attribute 'required' must be one of {on|yes|true|enabled|active|off|no|false|disabled|inactive}",
                        formPropertyElement);
                }

                var readableText = formPropertyElement.GetAttributeValue("readable", "true");
                var readable     = bpmnParse.ParseBooleanAttribute(readableText);
                if (readable != null)
                {
                    formPropertyHandler.Readable = readable.Value;
                }
                else
                {
                    bpmnParse.AddError(
                        "attribute 'readable' must be one of {on|yes|true|enabled|active|off|no|false|disabled|inactive}",
                        formPropertyElement);
                }

                var writableText = formPropertyElement.GetAttributeValue("writable", "true");
                var writable     = bpmnParse.ParseBooleanAttribute(writableText);
                if (writable != null)
                {
                    formPropertyHandler.Writable = writable.Value;
                }
                else
                {
                    bpmnParse.AddError(
                        "attribute 'writable' must be one of {on|yes|true|enabled|active|off|no|false|disabled|inactive}",
                        formPropertyElement);
                }

                var variableName = formPropertyElement.GetAttributeValue("variable");
                formPropertyHandler.VariableName = variableName;

                var expressionText = formPropertyElement.GetAttributeValue("expression");
                if (!ReferenceEquals(expressionText, null))
                {
                    IExpression expression = (Bpm.Engine.Impl.EL.IExpression)expressionManager.CreateExpression(expressionText);
                    formPropertyHandler.VariableExpression = expression;
                }

                var defaultExpressionText = formPropertyElement.GetAttributeValue("default");
                if (!ReferenceEquals(defaultExpressionText, null))
                {
                    IExpression defaultExpression = (Bpm.Engine.Impl.EL.IExpression)expressionManager.CreateExpression(defaultExpressionText);
                    formPropertyHandler.DefaultExpression = defaultExpression;
                }

                FormPropertyHandlers.Add(formPropertyHandler);
            }
        }