private PhrasingComponent getComponent(
            FormValue formValue, ElementId id, string radioButtonListItemId, DisplaySetup displaySetup, bool isReadOnly, ElementClassSet classes,
            PageModificationValue <bool> pageModificationValue, IReadOnlyCollection <PhrasingComponent> label, FormAction action, FormAction valueChangedAction,
            Func <string> jsClickStatementGetter)
        {
            return(new CustomPhrasingComponent(
                       new DisplayableElement(
                           labelContext => new DisplayableElementData(
                               displaySetup,
                               () => new DisplayableElementLocalData("label"),
                               classes: elementClass.Add(classes ?? ElementClassSet.Empty),
                               children: new DisplayableElement(
                                   context => {
                id.AddId(context.Id);

                if (!isReadOnly)
                {
                    action?.AddToPageIfNecessary();
                    valueChangedAction?.AddToPageIfNecessary();
                }

                return new DisplayableElementData(
                    null,
                    () => {
                    var attributes = new List <Tuple <string, string> >();
                    var radioButtonFormValue = formValue as FormValue <ElementId>;
                    attributes.Add(Tuple.Create("type", radioButtonFormValue != null ? "radio" : "checkbox"));
                    if (radioButtonFormValue != null || !isReadOnly)
                    {
                        attributes.Add(
                            Tuple.Create("name", radioButtonFormValue != null ? ((FormValue)radioButtonFormValue).GetPostBackValueKey() : context.Id));
                    }
                    if (radioButtonFormValue != null)
                    {
                        attributes.Add(Tuple.Create("value", radioButtonListItemId ?? context.Id));
                    }
                    if (pageModificationValue.Value)
                    {
                        attributes.Add(Tuple.Create("checked", "checked"));
                    }
                    if (isReadOnly)
                    {
                        attributes.Add(Tuple.Create("disabled", "disabled"));
                    }

                    var jsInitStatements = StringTools.ConcatenateWithDelimiter(
                        " ",
                        !isReadOnly
                                                                                                        ? SubmitButton.GetImplicitSubmissionKeyPressStatements(action, false)
                        .Surround("$( '#{0}' ).keypress( function( e ) {{ ".FormatWith(context.Id), " } );")
                                                                                                        : "",
                        jsClickStatementGetter().Surround("$( '#{0}' ).click( function() {{ ".FormatWith(context.Id), " } );"));

                    return new DisplayableElementLocalData(
                        "input",
                        new FocusabilityCondition(!isReadOnly),
                        isFocused => {
                        if (isFocused)
                        {
                            attributes.Add(Tuple.Create("autofocus", "autofocus"));
                        }
                        return new DisplayableElementFocusDependentData(
                            attributes: attributes,
                            includeIdAttribute: true,
                            jsInitStatements: jsInitStatements);
                    });
                },
                    classes: elementClass);
            },
                                   formValue: formValue).ToCollection()
                               .Concat(label.Any() ? new GenericPhrasingContainer(label, classes: elementClass).ToCollection() : Enumerable.Empty <FlowComponent>())
                               .Materialize())).ToCollection()));
        }