private void showHideUserdocLink() {
   boolean signupUrlExists = !StringUtils.isEmpty(pageModel.getUserdocUrl());
   if (signupUrlExists) {
     IConnectionFactory factory = pageModel.getConnectionFactory();
     if (factory != null) {
       StyledTextUtils.emulateLinkWidget(
           NLS.bind(
               "New to OpenShift {0}? Explore the <a>getting started documentation</a>.",
               factory.getName()),
           userdocLink);
     }
   }
   UIUtils.setVisibleAndExclude(signupUrlExists, userdocLink);
 }
  @SuppressWarnings({"unchecked", "rawtypes"})
  @Override
  protected void doCreateControls(final Composite parent, DataBindingContext dbc) {
    GridLayoutFactory.fillDefaults().numColumns(3).margins(10, 10).applyTo(parent);

    // userdoc link (JBIDE-20401)
    this.userdocLink = new StyledText(parent, SWT.WRAP); // text set in #showHideUserdocLink
    GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).span(3, 1).applyTo(userdocLink);
    showHideUserdocLink();
    IObservableValue userdocUrlObservable =
        BeanProperties.value(ConnectionWizardPageModel.PROPERTY_USERDOCURL).observe(pageModel);
    StyledTextUtils.emulateLinkAction(userdocLink, r -> onUserdocLinkClicked(userdocUrlObservable));
    userdocUrlObservable.addValueChangeListener(
        new IValueChangeListener() {

          @Override
          public void handleValueChange(ValueChangeEvent event) {
            showHideUserdocLink();
          }
        });

    IObservableValue connectionFactoryObservable =
        BeanProperties.value(ConnectionWizardPageModel.PROPERTY_CONNECTION_FACTORY)
            .observe(pageModel);

    // filler
    Label fillerLabel = new Label(parent, SWT.NONE);
    GridDataFactory.fillDefaults().span(3, 3).hint(SWT.DEFAULT, 6).applyTo(fillerLabel);

    // existing connections combo
    Label connectionLabel = new Label(parent, SWT.NONE);
    connectionLabel.setText("Connection:");
    GridDataFactory.fillDefaults()
        .align(SWT.LEFT, SWT.CENTER)
        .hint(100, SWT.DEFAULT)
        .applyTo(connectionLabel);
    Combo connectionCombo = new Combo(parent, SWT.DEFAULT);
    GridDataFactory.fillDefaults()
        .span(2, 1)
        .align(SWT.FILL, SWT.CENTER)
        .grab(true, false)
        .applyTo(connectionCombo);
    ComboViewer connectionComboViewer = new ComboViewer(connectionCombo);
    connectionComboViewer.setContentProvider(ArrayContentProvider.getInstance());
    connectionComboViewer.setLabelProvider(new ConnectionColumLabelProvider());
    connectionComboViewer.setInput(pageModel.getAllConnections());
    Binding selectedConnectionBinding =
        ValueBindingBuilder.bind(ViewerProperties.singleSelection().observe(connectionComboViewer))
            .validatingAfterGet(
                new IsNotNullValidator(
                    ValidationStatus.cancel("You have to select or create a new connection.")))
            .to(
                BeanProperties.value(
                        ConnectionWizardPageModel.PROPERTY_SELECTED_CONNECTION, IConnection.class)
                    .observe(pageModel))
            .in(dbc);
    ControlDecorationSupport.create(
        selectedConnectionBinding,
        SWT.LEFT | SWT.TOP,
        null,
        new RequiredControlDecorationUpdater());

    // server type
    Label connectionFactoryLabel = new Label(parent, SWT.NONE);
    connectionFactoryLabel.setText("Server type:");
    GridDataFactory.fillDefaults()
        .align(SWT.LEFT, SWT.CENTER)
        .hint(100, SWT.DEFAULT)
        .applyTo(connectionFactoryLabel);
    Combo connectionFactoryCombo = new Combo(parent, SWT.DEFAULT);
    GridDataFactory.fillDefaults()
        .span(2, 1)
        .align(SWT.FILL, SWT.CENTER)
        .grab(true, false)
        .applyTo(connectionFactoryCombo);
    ComboViewer connectionFactoriesViewer = new ComboViewer(connectionFactoryCombo);
    connectionFactoriesViewer.setContentProvider(ArrayContentProvider.getInstance());
    connectionFactoriesViewer.setLabelProvider(
        new ColumnLabelProvider() {

          @Override
          public String getText(Object element) {
            if (!(element instanceof IConnectionFactory)) {
              return element.toString();
            } else {
              return ((IConnectionFactory) element).getName();
            }
          }
        });
    connectionFactoriesViewer.setInput(pageModel.getAllConnectionFactories());
    final IViewerObservableValue selectedServerType =
        ViewerProperties.singleSelection().observe(connectionFactoriesViewer);
    ValueBindingBuilder.bind(selectedServerType).to(connectionFactoryObservable).in(dbc);

    // server
    Button useDefaultServerCheckbox = new Button(parent, SWT.CHECK);
    useDefaultServerCheckbox.setText("Use default server");
    GridDataFactory.fillDefaults()
        .span(3, 1)
        .align(SWT.FILL, SWT.FILL)
        .applyTo(useDefaultServerCheckbox);
    ValueBindingBuilder.bind(WidgetProperties.selection().observe(useDefaultServerCheckbox))
        .to(
            BeanProperties.value(
                    ConnectionWizardPageModel.PROPERTY_USE_DEFAULT_HOST, IConnection.class)
                .observe(pageModel))
        .in(dbc);

    IObservableValue hasDefaultHostObservable =
        BeanProperties.value(ConnectionWizardPageModel.PROPERTY_HAS_DEFAULT_HOST)
            .observe(pageModel);
    ValueBindingBuilder.bind(WidgetProperties.enabled().observe(useDefaultServerCheckbox))
        .notUpdating(hasDefaultHostObservable)
        .in(dbc);

    Label serverLabel = new Label(parent, SWT.NONE);
    serverLabel.setText("Server:");
    GridDataFactory.fillDefaults()
        .align(SWT.LEFT, SWT.CENTER)
        .hint(100, SWT.DEFAULT)
        .applyTo(serverLabel);
    Combo serversCombo = new Combo(parent, SWT.BORDER);
    ComboViewer serversViewer = new ComboViewer(serversCombo);
    serversViewer.setContentProvider(new ObservableListContentProvider());
    serversViewer.setInput(
        BeanProperties.list(ConnectionWizardPageModel.PROPERTY_ALL_HOSTS).observe(pageModel));
    GridDataFactory.fillDefaults()
        .align(SWT.FILL, SWT.FILL)
        .grab(true, false)
        .applyTo(serversCombo);
    final IObservableValue serverUrlObservable = WidgetProperties.text().observe(serversCombo);
    serversCombo.addFocusListener(onServerFocusLost(serverUrlObservable));
    ValueBindingBuilder.bind(serverUrlObservable)
        .converting(new TrimTrailingSlashConverter())
        .to(BeanProperties.value(ConnectionWizardPageModel.PROPERTY_HOST).observe(pageModel))
        .in(dbc);

    MultiValidator serverUrlValidator =
        new MultiValidator() {

          @Override
          protected IStatus validate() {
            Object value = serverUrlObservable.getValue();
            if (!(value instanceof String) || StringUtils.isEmpty((String) value)) {
              return ValidationStatus.cancel("Please provide an OpenShift server url.");
            } else if (!UrlUtils.isValid((String) value)) {
              return ValidationStatus.error("Please provide a valid OpenShift server url.");
            }
            return ValidationStatus.ok();
          }
        };
    ControlDecorationSupport.create(
        serverUrlValidator, SWT.LEFT | SWT.TOP, null, new RequiredControlDecorationUpdater());
    dbc.addValidationStatusProvider(serverUrlValidator);

    ValueBindingBuilder.bind(WidgetProperties.enabled().observe(serversCombo))
        .notUpdatingParticipant()
        .to(
            BeanProperties.value(ConnectionWizardPageModel.PROPERTY_USE_DEFAULT_HOST)
                .observe(pageModel))
        .converting(new InvertingBooleanConverter())
        .in(dbc);

    // connect error
    dbc.addValidationStatusProvider(
        new MultiValidator() {
          IObservableValue observable =
              BeanProperties.value(
                      ConnectionWizardPageModel.PROPERTY_CONNECTED_STATUS, IStatus.class)
                  .observe(pageModel);

          @Override
          protected IStatus validate() {
            return (IStatus) observable.getValue();
          }
        });

    // connection editors
    Group authenticationDetailsGroup = new Group(parent, SWT.NONE);
    authenticationDetailsGroup.setText("Authentication");
    GridDataFactory.fillDefaults()
        .align(SWT.FILL, SWT.FILL)
        .span(3, 1)
        .applyTo(authenticationDetailsGroup);
    GridLayoutFactory.fillDefaults().margins(0, 0).applyTo(authenticationDetailsGroup);
    // additional nesting required because of https://bugs.eclipse.org/bugs/show_bug.cgi?id=478618
    Composite authenticationDetailsContainer = new Composite(authenticationDetailsGroup, SWT.None);
    GridDataFactory.fillDefaults()
        .align(SWT.FILL, SWT.FILL)
        .grab(true, true)
        .applyTo(authenticationDetailsContainer);
    this.connectionEditors =
        new ConnectionEditorsStackedView(
            connectionFactoryObservable, this, authenticationDetailsContainer, dbc);
    connectionEditors.createControls();

    // adv editors
    Composite advEditorContainer = new Composite(parent, SWT.NONE);
    GridLayoutFactory.fillDefaults().margins(0, 0).applyTo(authenticationDetailsGroup);
    GridDataFactory.fillDefaults()
        .align(SWT.FILL, SWT.FILL)
        .span(3, 1)
        .grab(true, true)
        .applyTo(advEditorContainer);
    this.advConnectionEditors =
        new AdvancedConnectionEditorsStackedView(
            connectionFactoryObservable, pageModel, advEditorContainer, dbc);
    advConnectionEditors.createControls();
  }