You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2015/06/18 18:13:11 UTC

[3/4] syncope git commit: [SYNCOPE-156] provided modal content panel + features to add, edit and remove resource/conectors - still missing: 1. the possibility to edit new topology element as soon as created; 2. to show the spinner during ajax calls.

[SYNCOPE-156] provided modal content panel + features to add, edit and remove resource/conectors - still missing: 1. the possibility to edit new topology element  as soon as created; 2. to show the spinner during ajax calls.


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/a2051012
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a2051012
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a2051012

Branch: refs/heads/master
Commit: a20510123b4300150d43ff334335e218a3572c33
Parents: 67c79ab
Author: fmartelli <fa...@gmail.com>
Authored: Thu Jun 18 18:12:25 2015 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu Jun 18 18:12:25 2015 +0200

----------------------------------------------------------------------
 client/console/pom.xml                          |   4 +
 .../console/pages/ConnectorModalPage.java       | 477 -------------------
 .../client/console/pages/ResourceModalPage.java | 204 --------
 .../client/console/panels/ConnectorModal.java   | 476 ++++++++++++++++++
 .../client/console/panels/Connectors.java       | 385 ---------------
 .../client/console/panels/ModalContent.java     |  99 ++++
 .../console/panels/ResourceConnConfPanel.java   |   6 +-
 .../console/panels/ResourceDetailsPanel.java    |  16 +-
 .../client/console/panels/ResourceModal.java    | 204 ++++++++
 .../client/console/topology/Topology.java       | 292 +++++++-----
 .../console/topology/TopologyNodePanel.java     | 177 +++----
 .../topology/TopologyReloadBehavior.java        |  61 ---
 .../META-INF/resources/css/topology.css         |   7 +-
 .../resources/META-INF/resources/js/topology.js | 101 +++-
 .../main/resources/META-INF/web-fragment.xml    |   2 +-
 .../syncope/client/console/pages/BasePage.html  |   2 +-
 .../console/pages/ConnectorModalPage.html       | 161 -------
 .../console/pages/ConnectorModalPage.properties |  43 --
 .../pages/ConnectorModalPage_it.properties      |  43 --
 .../pages/ConnectorModalPage_pt_BR.properties   |  43 --
 .../client/console/panels/ConnectorModal.html   | 161 +++++++
 .../console/panels/ConnectorModal.properties    |  43 ++
 .../console/panels/ConnectorModal_it.properties |  43 ++
 .../panels/ConnectorModal_pt_BR.properties      |  43 ++
 .../client/console/panels/Connectors.html       |  57 ---
 .../client/console/panels/Connectors.properties |  34 --
 .../console/panels/Connectors_it.properties     |  34 --
 .../console/panels/Connectors_pt_BR.properties  |  32 --
 .../client/console/panels/ModalContent.html     |  45 ++
 .../console/panels/ModalContent.properties      |  20 +
 .../console/panels/ModalContent_it.properties   |  20 +
 .../panels/ModalContent_pt_BR.properties        |  20 +
 .../client/console/panels/ResourceModal.html    |  56 +++
 .../console/panels/ResourceModal.properties     |  60 +++
 .../console/panels/ResourceModal_it.properties  |  60 +++
 .../panels/ResourceModal_pt_BR.properties       |  60 +++
 .../client/console/topology/Topology.html       |  19 +-
 .../console/topology/TopologyNodePanel.html     |  14 +-
 pom.xml                                         |   5 +
 39 files changed, 1798 insertions(+), 1831 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/pom.xml
----------------------------------------------------------------------
diff --git a/client/console/pom.xml b/client/console/pom.xml
index 4ef7c9c..2a0f283 100644
--- a/client/console/pom.xml
+++ b/client/console/pom.xml
@@ -74,6 +74,10 @@ under the License.
       <groupId>com.googlecode.wicket-jquery-ui</groupId>
       <artifactId>wicket-jquery-ui</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.wicket</groupId>
+      <artifactId>wicket-native-websocket-javax</artifactId>
+    </dependency>
       
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java
deleted file mode 100644
index f35da6a..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.pages;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.rest.ConnectorRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ConnPoolConfTO;
-import org.apache.syncope.common.lib.types.ConnConfPropSchema;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice;
-import org.apache.wicket.markup.html.form.DropDownChoice;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.ResourceModel;
-import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.apache.wicket.validation.validator.RangeValidator;
-
-/**
- * Modal window with Connector form.
- */
-public class ConnectorModalPage extends BaseModalPage {
-
-    private static final long serialVersionUID = -2025535531121434050L;
-
-    @SpringBean
-    private ConnectorRestClient restClient;
-
-    private final Map<String, Map<String, Map<String, ConnBundleTO>>> mapConnBundleTOs;
-
-    private final List<ConnectorCapability> selectedCapabilities;
-
-    private ConnBundleTO bundleTO;
-
-    private List<ConnConfProperty> properties;
-
-    private final WebMarkupContainer propertiesContainer;
-
-    public ConnectorModalPage(final PageReference pageRef, final ModalWindow window,
-            final ConnInstanceTO connInstanceTO) {
-
-        super();
-
-        this.add(new Label("new", connInstanceTO.getKey() == 0
-                ? new ResourceModel("new")
-                : new Model<>(StringUtils.EMPTY)));
-        this.add(new Label("key", connInstanceTO.getKey() == 0
-                ? StringUtils.EMPTY
-                : connInstanceTO.getKey()));
-
-        // general data setup
-        selectedCapabilities = new ArrayList<>(connInstanceTO.getKey() == 0
-                ? EnumSet.noneOf(ConnectorCapability.class)
-                : connInstanceTO.getCapabilities());
-
-        mapConnBundleTOs = new HashMap<>();
-        for (ConnBundleTO connBundleTO : restClient.getAllBundles()) {
-            // by location
-            if (!mapConnBundleTOs.containsKey(connBundleTO.getLocation())) {
-                mapConnBundleTOs.put(connBundleTO.getLocation(), new HashMap<String, Map<String, ConnBundleTO>>());
-            }
-            final Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connBundleTO.getLocation());
-
-            // by name
-            if (!byLocation.containsKey(connBundleTO.getBundleName())) {
-                byLocation.put(connBundleTO.getBundleName(), new HashMap<String, ConnBundleTO>());
-            }
-            final Map<String, ConnBundleTO> byName = byLocation.get(connBundleTO.getBundleName());
-
-            // by version
-            if (!byName.containsKey(connBundleTO.getVersion())) {
-                byName.put(connBundleTO.getVersion(), connBundleTO);
-            }
-        }
-
-        bundleTO = getSelectedBundleTO(connInstanceTO);
-        properties = fillProperties(bundleTO, connInstanceTO);
-
-        // form - first tab
-        final Form<ConnInstanceTO> connectorForm = new Form<>(FORM);
-        connectorForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
-        connectorForm.setOutputMarkupId(true);
-        add(connectorForm);
-
-        propertiesContainer = new WebMarkupContainer("container");
-        propertiesContainer.setOutputMarkupId(true);
-        connectorForm.add(propertiesContainer);
-
-        final Form<ConnInstanceTO> connectorPropForm = new Form<>("connectorPropForm");
-        connectorPropForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
-        connectorPropForm.setOutputMarkupId(true);
-        propertiesContainer.add(connectorPropForm);
-
-        final AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
-                "displayName", "display name", new PropertyModel<String>(connInstanceTO, "displayName"));
-        displayName.setOutputMarkupId(true);
-        displayName.addRequiredLabel();
-        connectorForm.add(displayName);
-
-        final AjaxDropDownChoicePanel<String> location = new AjaxDropDownChoicePanel<>("location", "location",
-                new Model<>(bundleTO == null ? null : bundleTO.getLocation()));
-        ((DropDownChoice<String>) location.getField()).setNullValid(true);
-        location.setStyleSheet("long_dynamicsize");
-        location.setChoices(new ArrayList<>(mapConnBundleTOs.keySet()));
-        location.setRequired(true);
-        location.addRequiredLabel();
-        location.setOutputMarkupId(true);
-        location.setEnabled(connInstanceTO.getKey() == 0);
-        location.getField().setOutputMarkupId(true);
-        connectorForm.add(location);
-
-        final AjaxDropDownChoicePanel<String> connectorName = new AjaxDropDownChoicePanel<>("connectorName",
-                "connectorName",
-                new Model<>(bundleTO == null ? null : bundleTO.getBundleName()));
-        ((DropDownChoice<String>) connectorName.getField()).setNullValid(true);
-        connectorName.setStyleSheet("long_dynamicsize");
-        connectorName.setChoices(bundleTO == null
-                ? new ArrayList<String>()
-                : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet()));
-        connectorName.setRequired(true);
-        connectorName.addRequiredLabel();
-        connectorName.setEnabled(connInstanceTO.getLocation() != null);
-        connectorName.setOutputMarkupId(true);
-        connectorName.setEnabled(connInstanceTO.getKey() == 0);
-        connectorName.getField().setOutputMarkupId(true);
-        connectorForm.add(connectorName);
-
-        final AjaxDropDownChoicePanel<String> version = new AjaxDropDownChoicePanel<>("version", "version",
-                new Model<>(bundleTO == null ? null : bundleTO.getVersion()));
-        version.setStyleSheet("long_dynamicsize");
-        version.setChoices(bundleTO == null
-                ? new ArrayList<String>()
-                : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).
-                        get(connInstanceTO.getBundleName()).keySet()));
-        version.setRequired(true);
-        version.addRequiredLabel();
-        version.setEnabled(connInstanceTO.getBundleName() != null);
-        version.setOutputMarkupId(true);
-        version.addRequiredLabel();
-        version.getField().setOutputMarkupId(true);
-        connectorForm.add(version);
-
-        final SpinnerFieldPanel<Integer> connRequestTimeout = new SpinnerFieldPanel<>("connRequestTimeout",
-                "connRequestTimeout", Integer.class,
-                new PropertyModel<Integer>(connInstanceTO, "connRequestTimeout"), 0, null);
-        connRequestTimeout.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
-        connectorForm.add(connRequestTimeout);
-
-        if (connInstanceTO.getPoolConf() == null) {
-            connInstanceTO.setPoolConf(new ConnPoolConfTO());
-        }
-        final SpinnerFieldPanel<Integer> poolMaxObjects = new SpinnerFieldPanel<>("poolMaxObjects", "poolMaxObjects",
-                Integer.class,
-                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxObjects"), 0, null);
-        poolMaxObjects.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
-        connectorForm.add(poolMaxObjects);
-        final SpinnerFieldPanel<Integer> poolMinIdle = new SpinnerFieldPanel<>("poolMinIdle", "poolMinIdle",
-                Integer.class,
-                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "minIdle"), 0, null);
-        poolMinIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
-        connectorForm.add(poolMinIdle);
-        final SpinnerFieldPanel<Integer> poolMaxIdle = new SpinnerFieldPanel<>("poolMaxIdle", "poolMaxIdle",
-                Integer.class,
-                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxIdle"), 0, null);
-        poolMaxIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
-        connectorForm.add(poolMaxIdle);
-        final SpinnerFieldPanel<Long> poolMaxWait = new SpinnerFieldPanel<>("poolMaxWait", "poolMaxWait", Long.class,
-                new PropertyModel<Long>(connInstanceTO.getPoolConf(), "maxWait"), 0L, null);
-        poolMaxWait.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
-        connectorForm.add(poolMaxWait);
-        final SpinnerFieldPanel<Long> poolMinEvictableIdleTime = new SpinnerFieldPanel<>("poolMinEvictableIdleTime",
-                "poolMinEvictableIdleTime", Long.class,
-                new PropertyModel<Long>(connInstanceTO.getPoolConf(), "minEvictableIdleTimeMillis"),
-                0L, null);
-        poolMinEvictableIdleTime.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
-        connectorForm.add(poolMinEvictableIdleTime);
-
-        // form - first tab - onchange()
-        location.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                ((DropDownChoice<String>) location.getField()).setNullValid(false);
-                connInstanceTO.setLocation(location.getModelObject());
-                target.add(location);
-
-                connectorName.setChoices(new ArrayList<>(
-                        mapConnBundleTOs.get(location.getModelObject()).keySet()));
-                connectorName.setEnabled(true);
-                connectorName.getField().setModelValue(null);
-                target.add(connectorName);
-
-                version.setChoices(new ArrayList<String>());
-                version.getField().setModelValue(null);
-                version.setEnabled(false);
-                target.add(version);
-
-                properties.clear();
-                target.add(propertiesContainer);
-            }
-        });
-        connectorName.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                ((DropDownChoice<String>) connectorName.getField()).setNullValid(false);
-                connInstanceTO.setBundleName(connectorName.getModelObject());
-                target.add(connectorName);
-
-                List<String> versions = new ArrayList<>(
-                        mapConnBundleTOs.get(location.getModelObject()).get(connectorName.getModelObject()).keySet());
-                version.setChoices(versions);
-                version.setEnabled(true);
-                if (versions.size() == 1) {
-                    selectVersion(target, connInstanceTO, version, versions.get(0));
-                    version.getField().setModelObject(versions.get(0));
-                } else {
-                    version.getField().setModelValue(null);
-                    properties.clear();
-                    target.add(propertiesContainer);
-                }
-                target.add(version);
-            }
-        });
-        version.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                selectVersion(target, connInstanceTO, version, version.getModelObject());
-            }
-        });
-
-        // form - second tab (properties)
-        final ListView<ConnConfProperty> connPropView = new ConnConfPropertyListView("connectorProperties",
-                new PropertyModel<List<ConnConfProperty>>(this, "properties"),
-                true, connInstanceTO.getConfiguration());
-        connPropView.setOutputMarkupId(true);
-        connectorPropForm.add(connPropView);
-
-        final AjaxButton check = new IndicatingAjaxButton("check", new ResourceModel("check")) {
-
-            private static final long serialVersionUID = -7978723352517770644L;
-
-            @Override
-            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
-
-                // ensure that connector bundle information is in sync
-                conn.setBundleName(bundleTO.getBundleName());
-                conn.setVersion(bundleTO.getVersion());
-                conn.setConnectorName(bundleTO.getConnectorName());
-
-                if (restClient.check(conn)) {
-                    info(getString("success_connection"));
-                } else {
-                    error(getString("error_connection"));
-                }
-
-                feedbackPanel.refresh(target);
-            }
-        };
-        connectorPropForm.add(check);
-
-        // form - third tab (capabilities)
-        final IModel<List<ConnectorCapability>> capabilities
-                = new LoadableDetachableModel<List<ConnectorCapability>>() {
-
-                    private static final long serialVersionUID = 5275935387613157437L;
-
-                    @Override
-                    protected List<ConnectorCapability> load() {
-                        return Arrays.asList(ConnectorCapability.values());
-                    }
-                };
-        CheckBoxMultipleChoice<ConnectorCapability> capabilitiesPalette = new CheckBoxMultipleChoice<>(
-                "capabilitiesPalette",
-                new PropertyModel<List<ConnectorCapability>>(this, "selectedCapabilities"), capabilities);
-
-        capabilitiesPalette.add(new AjaxFormChoiceComponentUpdatingBehavior() {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-            }
-        });
-
-        connectorForm.add(capabilitiesPalette);
-
-        // form - submit / cancel buttons
-        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new Model<>(getString(SUBMIT))) {
-
-            private static final long serialVersionUID = -958724007591692537L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
-
-                conn.setConnectorName(bundleTO.getConnectorName());
-                conn.setBundleName(bundleTO.getBundleName());
-                conn.setVersion(bundleTO.getVersion());
-                conn.getConfiguration().clear();
-                conn.getConfiguration().addAll(connPropView.getModelObject());
-
-                // Set the model object's capabilities to capabilitiesPalette's converted Set
-                conn.getCapabilities().clear();
-                conn.getCapabilities().addAll(selectedCapabilities.isEmpty()
-                        ? EnumSet.noneOf(ConnectorCapability.class)
-                        : EnumSet.copyOf(selectedCapabilities));
-
-                // Reset pool configuration if all fields are null
-                if (conn.getPoolConf() != null
-                        && conn.getPoolConf().getMaxIdle() == null
-                        && conn.getPoolConf().getMaxObjects() == null
-                        && conn.getPoolConf().getMaxWait() == null
-                        && conn.getPoolConf().getMinEvictableIdleTimeMillis() == null
-                        && conn.getPoolConf().getMinIdle() == null) {
-
-                    conn.setPoolConf(null);
-                }
-
-                try {
-                    if (connInstanceTO.getKey() == 0) {
-                        restClient.create(conn);
-                    } else {
-                        restClient.update(conn);
-                    }
-
-                    ((BasePage) pageRef.getPage()).setModalResult(true);
-                    window.close(target);
-                } catch (SyncopeClientException e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                    feedbackPanel.refresh(target);
-                    ((BasePage) pageRef.getPage()).setModalResult(false);
-                    LOG.error("While creating or updating connector {}", conn, e);
-                }
-            }
-
-            @Override
-            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
-                feedbackPanel.refresh(target);
-            }
-        };
-        String entitlements = connInstanceTO.getKey() == 0
-                ? Entitlement.CONNECTOR_CREATE : Entitlement.CONNECTOR_UPDATE;
-
-        MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, entitlements);
-        connectorForm.add(submit);
-
-        final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
-
-            private static final long serialVersionUID = -958724007591692537L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                window.close(target);
-            }
-        };
-        cancel.setDefaultFormProcessing(false);
-        connectorForm.add(cancel);
-    }
-
-    private ConnBundleTO getSelectedBundleTO(final ConnInstanceTO connInstanceTO) {
-        ConnBundleTO result = null;
-        if (connInstanceTO != null
-                && StringUtils.isNotBlank(connInstanceTO.getLocation())
-                && StringUtils.isNotBlank(connInstanceTO.getBundleName())
-                && StringUtils.isNotBlank(connInstanceTO.getVersion())
-                && mapConnBundleTOs.containsKey(connInstanceTO.getLocation())) {
-
-            Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connInstanceTO.getLocation());
-            if (byLocation.containsKey(connInstanceTO.getBundleName())) {
-                Map<String, ConnBundleTO> byName = byLocation.get(connInstanceTO.getBundleName());
-                if (byName.containsKey(connInstanceTO.getVersion())) {
-                    result = byName.get(connInstanceTO.getVersion());
-                }
-            }
-        }
-        return result;
-    }
-
-    private List<ConnConfProperty> fillProperties(final ConnBundleTO bundleTO, final ConnInstanceTO connInstanceTO) {
-        final List<ConnConfProperty> props = new ArrayList<>();
-
-        if (bundleTO != null) {
-            for (ConnConfPropSchema key : bundleTO.getProperties()) {
-                final ConnConfProperty property = new ConnConfProperty();
-                property.setSchema(key);
-                if (connInstanceTO.getKey() != 0
-                        && connInstanceTO.getConfigurationMap().containsKey(key.getName())
-                        && connInstanceTO.getConfigurationMap().get(key.getName()).getValues() != null) {
-
-                    property.getValues().addAll(connInstanceTO.getConfigurationMap().get(key.getName()).getValues());
-                    property.setOverridable(connInstanceTO.getConfigurationMap().get(key.getName()).isOverridable());
-                }
-
-                if (property.getValues().isEmpty() && !key.getDefaultValues().isEmpty()) {
-                    property.getValues().addAll(key.getDefaultValues());
-                }
-
-                props.add(property);
-            }
-        }
-
-        // re-order properties (implements Comparable)
-        Collections.sort(props);
-        return props;
-    }
-
-    private void selectVersion(final AjaxRequestTarget target, final ConnInstanceTO connInstanceTO,
-            final AjaxDropDownChoicePanel<String> version, final String versionValue) {
-
-        connInstanceTO.setVersion(versionValue);
-        target.add(version);
-
-        bundleTO = getSelectedBundleTO(connInstanceTO);
-        properties = fillProperties(bundleTO, connInstanceTO);
-        target.add(propertiesContainer);
-    }
-
-    public List<ConnConfProperty> getProperties() {
-        return properties;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
deleted file mode 100644
index e578255..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.pages;
-
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.panels.AnnotatedBeanPanel;
-import org.apache.syncope.client.console.panels.ResourceConnConfPanel;
-import org.apache.syncope.client.console.panels.ResourceDetailsPanel;
-import org.apache.syncope.client.console.panels.ResourceMappingPanel;
-import org.apache.syncope.client.console.panels.ResourceSecurityPanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.ResourceModel;
-
-/**
- * Modal window with Resource form.
- */
-public class ResourceModalPage extends BaseModalPage {
-
-    private static final long serialVersionUID = 1734415311027284221L;
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public ResourceModalPage(final PageReference pageRef, final ModalWindow window, final ResourceTO resourceTO,
-            final boolean createFlag) {
-
-        super();
-
-        final Form<ResourceTO> form = new Form<>(FORM);
-        form.setModel(new CompoundPropertyModel<>(resourceTO));
-
-        //--------------------------------
-        // Resource details panel
-        //--------------------------------
-        form.add(new ResourceDetailsPanel("details", resourceTO,
-                resourceRestClient.getPropagationActionsClasses(), createFlag));
-
-        form.add(new AnnotatedBeanPanel("systeminformation", resourceTO));
-        //--------------------------------
-
-        //--------------------------------
-        // Resource mapping panels
-        //--------------------------------
-        form.add(new ResourceMappingPanel("umapping", resourceTO, AnyTypeKind.USER));
-        form.add(new ResourceMappingPanel("gmapping", resourceTO, AnyTypeKind.GROUP));
-        //--------------------------------
-
-        //--------------------------------
-        // Resource connector configuration panel
-        //--------------------------------
-        ResourceConnConfPanel resourceConnConfPanel = new ResourceConnConfPanel("connconf", resourceTO, createFlag);
-        MetaDataRoleAuthorizationStrategy.authorize(resourceConnConfPanel, ENABLE, Entitlement.CONNECTOR_READ);
-        form.add(resourceConnConfPanel);
-        //--------------------------------
-
-        //--------------------------------
-        // Resource security panel
-        //--------------------------------
-        form.add(new ResourceSecurityPanel("security", resourceTO));
-        //--------------------------------
-
-        AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
-
-            private static final long serialVersionUID = -958724007591692537L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                final ResourceTO resourceTO = (ResourceTO) form.getDefaultModelObject();
-
-                boolean connObjectKeyError = false;
-
-                for (ProvisionTO provision : resourceTO.getProvisions()) {
-                    if (provision != null) {
-                        if (provision.getMapping() == null || provision.getMapping().getItems().isEmpty()) {
-                            resourceTO.getProvisions().remove(provision);
-                        } else {
-                            int uConnObjectKeyCount = CollectionUtils.countMatches(
-                                    provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
-
-                                        @Override
-                                        public boolean evaluate(final MappingItemTO item) {
-                                            return item.isConnObjectKey();
-                                        }
-                                    });
-
-                            connObjectKeyError = uConnObjectKeyCount != 1;
-                        }
-                    }
-                }
-
-                if (connObjectKeyError) {
-                    error(getString("connObjectKeyValidation"));
-                    feedbackPanel.refresh(target);
-                } else {
-                    try {
-                        if (createFlag) {
-                            resourceRestClient.create(resourceTO);
-                        } else {
-                            resourceRestClient.update(resourceTO);
-                        }
-
-                        if (pageRef != null && pageRef.getPage() instanceof AbstractBasePage) {
-                            ((AbstractBasePage) pageRef.getPage()).setModalResult(true);
-                        }
-                        window.close(target);
-                    } catch (Exception e) {
-                        LOG.error("Failure managing resource {}", resourceTO, e);
-                        error(getString(Constants.ERROR) + ": " + e.getMessage());
-                        feedbackPanel.refresh(target);
-                    }
-                }
-            }
-
-            @Override
-
-            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
-                feedbackPanel.refresh(target);
-            }
-        };
-
-        form.add(submit);
-        form.setDefaultButton(submit);
-
-        final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
-
-            private static final long serialVersionUID = -958724007591692537L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                window.close(target);
-            }
-
-            @Override
-            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
-            }
-        };
-
-        cancel.setDefaultFormProcessing(false);
-        form.add(cancel);
-
-        add(form);
-
-        MetaDataRoleAuthorizationStrategy.authorize(
-                submit, ENABLE, createFlag ? Entitlement.RESOURCE_CREATE : Entitlement.RESOURCE_UPDATE);
-
-    }
-
-    /**
-     * Generic resource event.
-     */
-    public static class ResourceEvent {
-
-        /**
-         * Request target.
-         */
-        private final AjaxRequestTarget target;
-
-        /**
-         * Constructor.
-         *
-         * @param target request target.
-         */
-        public ResourceEvent(final AjaxRequestTarget target) {
-            this.target = target;
-        }
-
-        /**
-         * Target getter.
-         *
-         * @return request target.
-         */
-        public AjaxRequestTarget getTarget() {
-            return target;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
new file mode 100644
index 0000000..fee3e06
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
@@ -0,0 +1,476 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import static org.apache.wicket.Component.ENABLE;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.panels.ModalContent;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.validation.validator.RangeValidator;
+
+/**
+ * Modal window with Connector form.
+ */
+public class ConnectorModal extends ModalContent {
+
+    private static final long serialVersionUID = -2025535531121434050L;
+
+    private final Map<String, Map<String, Map<String, ConnBundleTO>>> mapConnBundleTOs;
+
+    private final List<ConnectorCapability> selectedCapabilities;
+
+    private ConnBundleTO bundleTO;
+
+    private List<ConnConfProperty> properties;
+
+    private final WebMarkupContainer propertiesContainer;
+
+    public ConnectorModal(
+            final ModalWindow window, final PageReference pageRef, final ConnInstanceTO connInstanceTO) {
+
+        super(window, pageRef);
+
+        this.add(new Label("new", connInstanceTO.getKey() == 0
+                ? new ResourceModel("new")
+                : new Model<>(StringUtils.EMPTY)));
+        this.add(new Label("key", connInstanceTO.getKey() == 0
+                ? StringUtils.EMPTY
+                : connInstanceTO.getKey()));
+
+        // general data setup
+        selectedCapabilities = new ArrayList<>(connInstanceTO.getKey() == 0
+                ? EnumSet.noneOf(ConnectorCapability.class)
+                : connInstanceTO.getCapabilities());
+
+        mapConnBundleTOs = new HashMap<>();
+        for (ConnBundleTO connBundleTO : connectorRestClient.getAllBundles()) {
+            // by location
+            if (!mapConnBundleTOs.containsKey(connBundleTO.getLocation())) {
+                mapConnBundleTOs.put(connBundleTO.getLocation(), new HashMap<String, Map<String, ConnBundleTO>>());
+            }
+            final Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connBundleTO.getLocation());
+
+            // by name
+            if (!byLocation.containsKey(connBundleTO.getBundleName())) {
+                byLocation.put(connBundleTO.getBundleName(), new HashMap<String, ConnBundleTO>());
+            }
+            final Map<String, ConnBundleTO> byName = byLocation.get(connBundleTO.getBundleName());
+
+            // by version
+            if (!byName.containsKey(connBundleTO.getVersion())) {
+                byName.put(connBundleTO.getVersion(), connBundleTO);
+            }
+        }
+
+        bundleTO = getSelectedBundleTO(connInstanceTO);
+        properties = fillProperties(bundleTO, connInstanceTO);
+
+        // form - first tab
+        final Form<ConnInstanceTO> connectorForm = new Form<>(FORM);
+        connectorForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
+        connectorForm.setOutputMarkupId(true);
+        add(connectorForm);
+
+        propertiesContainer = new WebMarkupContainer("container");
+        propertiesContainer.setOutputMarkupId(true);
+        connectorForm.add(propertiesContainer);
+
+        final Form<ConnInstanceTO> connectorPropForm = new Form<>("connectorPropForm");
+        connectorPropForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
+        connectorPropForm.setOutputMarkupId(true);
+        propertiesContainer.add(connectorPropForm);
+
+        final AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
+                "displayName", "display name", new PropertyModel<String>(connInstanceTO, "displayName"));
+        displayName.setOutputMarkupId(true);
+        displayName.addRequiredLabel();
+        connectorForm.add(displayName);
+
+        final AjaxDropDownChoicePanel<String> location = new AjaxDropDownChoicePanel<>("location", "location",
+                new Model<>(bundleTO == null ? null : bundleTO.getLocation()));
+        ((DropDownChoice<String>) location.getField()).setNullValid(true);
+        location.setStyleSheet("long_dynamicsize");
+        location.setChoices(new ArrayList<>(mapConnBundleTOs.keySet()));
+        location.setRequired(true);
+        location.addRequiredLabel();
+        location.setOutputMarkupId(true);
+        location.setEnabled(connInstanceTO.getKey() == 0);
+        location.getField().setOutputMarkupId(true);
+        connectorForm.add(location);
+
+        final AjaxDropDownChoicePanel<String> connectorName = new AjaxDropDownChoicePanel<>("connectorName",
+                "connectorName",
+                new Model<>(bundleTO == null ? null : bundleTO.getBundleName()));
+        ((DropDownChoice<String>) connectorName.getField()).setNullValid(true);
+        connectorName.setStyleSheet("long_dynamicsize");
+        connectorName.setChoices(bundleTO == null
+                ? new ArrayList<String>()
+                : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet()));
+        connectorName.setRequired(true);
+        connectorName.addRequiredLabel();
+        connectorName.setEnabled(connInstanceTO.getLocation() != null);
+        connectorName.setOutputMarkupId(true);
+        connectorName.setEnabled(connInstanceTO.getKey() == 0);
+        connectorName.getField().setOutputMarkupId(true);
+        connectorForm.add(connectorName);
+
+        final AjaxDropDownChoicePanel<String> version = new AjaxDropDownChoicePanel<>("version", "version",
+                new Model<>(bundleTO == null ? null : bundleTO.getVersion()));
+        version.setStyleSheet("long_dynamicsize");
+        version.setChoices(bundleTO == null
+                ? new ArrayList<String>()
+                : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).
+                        get(connInstanceTO.getBundleName()).keySet()));
+        version.setRequired(true);
+        version.addRequiredLabel();
+        version.setEnabled(connInstanceTO.getBundleName() != null);
+        version.setOutputMarkupId(true);
+        version.addRequiredLabel();
+        version.getField().setOutputMarkupId(true);
+        connectorForm.add(version);
+
+        final SpinnerFieldPanel<Integer> connRequestTimeout = new SpinnerFieldPanel<>("connRequestTimeout",
+                "connRequestTimeout", Integer.class,
+                new PropertyModel<Integer>(connInstanceTO, "connRequestTimeout"), 0, null);
+        connRequestTimeout.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(connRequestTimeout);
+
+        if (connInstanceTO.getPoolConf() == null) {
+            connInstanceTO.setPoolConf(new ConnPoolConfTO());
+        }
+        final SpinnerFieldPanel<Integer> poolMaxObjects = new SpinnerFieldPanel<>("poolMaxObjects", "poolMaxObjects",
+                Integer.class,
+                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxObjects"), 0, null);
+        poolMaxObjects.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(poolMaxObjects);
+        final SpinnerFieldPanel<Integer> poolMinIdle = new SpinnerFieldPanel<>("poolMinIdle", "poolMinIdle",
+                Integer.class,
+                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "minIdle"), 0, null);
+        poolMinIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(poolMinIdle);
+        final SpinnerFieldPanel<Integer> poolMaxIdle = new SpinnerFieldPanel<>("poolMaxIdle", "poolMaxIdle",
+                Integer.class,
+                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxIdle"), 0, null);
+        poolMaxIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE));
+        connectorForm.add(poolMaxIdle);
+        final SpinnerFieldPanel<Long> poolMaxWait = new SpinnerFieldPanel<>("poolMaxWait", "poolMaxWait", Long.class,
+                new PropertyModel<Long>(connInstanceTO.getPoolConf(), "maxWait"), 0L, null);
+        poolMaxWait.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
+        connectorForm.add(poolMaxWait);
+        final SpinnerFieldPanel<Long> poolMinEvictableIdleTime = new SpinnerFieldPanel<>("poolMinEvictableIdleTime",
+                "poolMinEvictableIdleTime", Long.class,
+                new PropertyModel<Long>(connInstanceTO.getPoolConf(), "minEvictableIdleTimeMillis"),
+                0L, null);
+        poolMinEvictableIdleTime.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
+        connectorForm.add(poolMinEvictableIdleTime);
+
+        // form - first tab - onchange()
+        location.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                ((DropDownChoice<String>) location.getField()).setNullValid(false);
+                connInstanceTO.setLocation(location.getModelObject());
+                target.add(location);
+
+                connectorName.setChoices(new ArrayList<>(
+                        mapConnBundleTOs.get(location.getModelObject()).keySet()));
+                connectorName.setEnabled(true);
+                connectorName.getField().setModelValue(null);
+                target.add(connectorName);
+
+                version.setChoices(new ArrayList<String>());
+                version.getField().setModelValue(null);
+                version.setEnabled(false);
+                target.add(version);
+
+                properties.clear();
+                target.add(propertiesContainer);
+            }
+        });
+        connectorName.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                ((DropDownChoice<String>) connectorName.getField()).setNullValid(false);
+                connInstanceTO.setBundleName(connectorName.getModelObject());
+                target.add(connectorName);
+
+                List<String> versions = new ArrayList<>(
+                        mapConnBundleTOs.get(location.getModelObject()).get(connectorName.getModelObject()).keySet());
+                version.setChoices(versions);
+                version.setEnabled(true);
+                if (versions.size() == 1) {
+                    selectVersion(target, connInstanceTO, version, versions.get(0));
+                    version.getField().setModelObject(versions.get(0));
+                } else {
+                    version.getField().setModelValue(null);
+                    properties.clear();
+                    target.add(propertiesContainer);
+                }
+                target.add(version);
+            }
+        });
+        version.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                selectVersion(target, connInstanceTO, version, version.getModelObject());
+            }
+        });
+
+        // form - second tab (properties)
+        final ListView<ConnConfProperty> connPropView = new ConnConfPropertyListView("connectorProperties",
+                new PropertyModel<List<ConnConfProperty>>(this, "properties"),
+                true, connInstanceTO.getConfiguration());
+        connPropView.setOutputMarkupId(true);
+        connectorPropForm.add(connPropView);
+
+        final AjaxButton check = new IndicatingAjaxButton("check", new ResourceModel("check")) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
+
+                // ensure that connector bundle information is in sync
+                conn.setBundleName(bundleTO.getBundleName());
+                conn.setVersion(bundleTO.getVersion());
+                conn.setConnectorName(bundleTO.getConnectorName());
+
+                if (connectorRestClient.check(conn)) {
+                    info(getString("success_connection"));
+                } else {
+                    error(getString("error_connection"));
+                }
+
+                feedbackPanel.refresh(target);
+            }
+        };
+        connectorPropForm.add(check);
+
+        // form - third tab (capabilities)
+        final IModel<List<ConnectorCapability>> capabilities
+                = new LoadableDetachableModel<List<ConnectorCapability>>() {
+
+                    private static final long serialVersionUID = 5275935387613157437L;
+
+                    @Override
+                    protected List<ConnectorCapability> load() {
+                        return Arrays.asList(ConnectorCapability.values());
+                    }
+                };
+        CheckBoxMultipleChoice<ConnectorCapability> capabilitiesPalette = new CheckBoxMultipleChoice<>(
+                "capabilitiesPalette",
+                new PropertyModel<List<ConnectorCapability>>(this, "selectedCapabilities"), capabilities);
+
+        capabilitiesPalette.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+            }
+        });
+
+        connectorForm.add(capabilitiesPalette);
+
+        // form - submit / cancel buttons
+        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new Model<>(getString(SUBMIT))) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
+
+                conn.setConnectorName(bundleTO.getConnectorName());
+                conn.setBundleName(bundleTO.getBundleName());
+                conn.setVersion(bundleTO.getVersion());
+                conn.getConfiguration().clear();
+                conn.getConfiguration().addAll(connPropView.getModelObject());
+
+                // Set the model object's capabilities to capabilitiesPalette's converted Set
+                conn.getCapabilities().clear();
+                conn.getCapabilities().addAll(selectedCapabilities.isEmpty()
+                        ? EnumSet.noneOf(ConnectorCapability.class)
+                        : EnumSet.copyOf(selectedCapabilities));
+
+                // Reset pool configuration if all fields are null
+                if (conn.getPoolConf() != null
+                        && conn.getPoolConf().getMaxIdle() == null
+                        && conn.getPoolConf().getMaxObjects() == null
+                        && conn.getPoolConf().getMaxWait() == null
+                        && conn.getPoolConf().getMinEvictableIdleTimeMillis() == null
+                        && conn.getPoolConf().getMinIdle() == null) {
+
+                    conn.setPoolConf(null);
+                }
+
+                try {
+                    if (connInstanceTO.getKey() == 0) {
+                        connectorRestClient.create(conn);
+                    } else {
+                        connectorRestClient.update(conn);
+                    }
+
+                    ((BasePage) pageRef.getPage()).setModalResult(true);
+                    window.close(target);
+                } catch (SyncopeClientException e) {
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                    ((BasePage) pageRef.getPage()).setModalResult(false);
+                    LOG.error("While creating or updating connector {}", conn, e);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+        String entitlements = connInstanceTO.getKey() == 0
+                ? Entitlement.CONNECTOR_CREATE : Entitlement.CONNECTOR_UPDATE;
+
+        MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, entitlements);
+        connectorForm.add(submit);
+
+        final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                window.close(target);
+            }
+        };
+        cancel.setDefaultFormProcessing(false);
+        connectorForm.add(cancel);
+    }
+
+    private ConnBundleTO getSelectedBundleTO(final ConnInstanceTO connInstanceTO) {
+        ConnBundleTO result = null;
+        if (connInstanceTO != null
+                && StringUtils.isNotBlank(connInstanceTO.getLocation())
+                && StringUtils.isNotBlank(connInstanceTO.getBundleName())
+                && StringUtils.isNotBlank(connInstanceTO.getVersion())
+                && mapConnBundleTOs.containsKey(connInstanceTO.getLocation())) {
+
+            Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connInstanceTO.getLocation());
+            if (byLocation.containsKey(connInstanceTO.getBundleName())) {
+                Map<String, ConnBundleTO> byName = byLocation.get(connInstanceTO.getBundleName());
+                if (byName.containsKey(connInstanceTO.getVersion())) {
+                    result = byName.get(connInstanceTO.getVersion());
+                }
+            }
+        }
+        return result;
+    }
+
+    private List<ConnConfProperty> fillProperties(final ConnBundleTO bundleTO, final ConnInstanceTO connInstanceTO) {
+        final List<ConnConfProperty> props = new ArrayList<>();
+
+        if (bundleTO != null) {
+            for (ConnConfPropSchema key : bundleTO.getProperties()) {
+                final ConnConfProperty property = new ConnConfProperty();
+                property.setSchema(key);
+                if (connInstanceTO.getKey() != 0
+                        && connInstanceTO.getConfigurationMap().containsKey(key.getName())
+                        && connInstanceTO.getConfigurationMap().get(key.getName()).getValues() != null) {
+
+                    property.getValues().addAll(connInstanceTO.getConfigurationMap().get(key.getName()).getValues());
+                    property.setOverridable(connInstanceTO.getConfigurationMap().get(key.getName()).isOverridable());
+                }
+
+                if (property.getValues().isEmpty() && !key.getDefaultValues().isEmpty()) {
+                    property.getValues().addAll(key.getDefaultValues());
+                }
+
+                props.add(property);
+            }
+        }
+
+        // re-order properties (implements Comparable)
+        Collections.sort(props);
+        return props;
+    }
+
+    private void selectVersion(final AjaxRequestTarget target, final ConnInstanceTO connInstanceTO,
+            final AjaxDropDownChoicePanel<String> version, final String versionValue) {
+
+        connInstanceTO.setVersion(versionValue);
+        target.add(version);
+
+        bundleTO = getSelectedBundleTO(connInstanceTO);
+        properties = fillProperties(bundleTO, connInstanceTO);
+        target.add(propertiesContainer);
+    }
+
+    public List<ConnConfProperty> getProperties() {
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
deleted file mode 100644
index 18f28d7..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.panels;
-
-import static org.apache.wicket.Component.ENABLE;
-import static org.apache.wicket.Component.RENDER;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.PreferenceManager;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.pages.ConnectorModalPage;
-import org.apache.syncope.client.console.rest.ConnectorRestClient;
-import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.wicket.Component;
-import org.apache.wicket.Page;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.attributes.AjaxCallListener;
-import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.event.IEvent;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.DropDownChoice;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.markup.repeater.Item;
-import org.apache.wicket.model.AbstractReadOnlyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.StringResourceModel;
-import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Resources WebPage.
- */
-public class Connectors extends Panel {
-
-    private static final long serialVersionUID = -3789252860990261728L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(Connectors.class);
-
-    private static final int WIN_HEIGHT = 600;
-
-    private static final int WIN_WIDTH = 1100;
-
-    @SpringBean
-    private ConnectorRestClient connectorRestClient;
-
-    @SpringBean
-    private PreferenceManager prefMan;
-
-    private final ModalWindow createConnectorWin;
-
-    private final ModalWindow editConnectorWin;
-
-    private final int connectorPaginatorRows;
-
-    private WebMarkupContainer connectorContainer;
-
-    /**
-     * Modal window to be used for user status management.
-     */
-    protected final ModalWindow statusmodal = new ModalWindow("statusModal");
-
-    /**
-     * Schemas to be shown modal window height.
-     */
-    private static final int STATUS_MODAL_WIN_HEIGHT = 500;
-
-    /**
-     * Schemas to be shown modal window width.
-     */
-    private static final int STATUS_MODAL_WIN_WIDTH = 700;
-
-    private final PageReference pageRef;
-
-    public Connectors(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-
-        createConnectorWin = new ModalWindow("createConnectorWin");
-        add(createConnectorWin);
-
-        editConnectorWin = new ModalWindow("editConnectorWin");
-        add(editConnectorWin);
-
-        statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
-        statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
-        statusmodal.setCookieName("status-modal");
-        add(statusmodal);
-
-        AjaxLink<Void> reloadLink = new ClearIndicatingAjaxLink<Void>("reloadLink", pageRef) {
-
-            private static final long serialVersionUID = 3109256773218160485L;
-
-            @Override
-            protected void onClickInternal(final AjaxRequestTarget target) {
-                try {
-                    connectorRestClient.reload();
-                    info(getString(Constants.OPERATION_SUCCEEDED));
-                } catch (Exception e) {
-                    error(getString(Constants.ERROR) + ": " + e.getMessage());
-                }
-                ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
-                target.add(connectorContainer);
-            }
-
-            @Override
-            protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
-                super.updateAjaxAttributes(attributes);
-
-                final AjaxCallListener ajaxCallListener = new AjaxCallListener() {
-
-                    private static final long serialVersionUID = 7160235486520935153L;
-
-                    @Override
-                    public CharSequence getPrecondition(final Component component) {
-                        return "if (!confirm('" + getString("confirmReloadConnectors") + "')) "
-                                + "{return false;} else {return true;}";
-                    }
-                };
-                attributes.getAjaxCallListeners().add(ajaxCallListener);
-            }
-        };
-        MetaDataRoleAuthorizationStrategy.authorize(reloadLink, ENABLE, Entitlement.CONNECTOR_RELOAD);
-        add(reloadLink);
-
-        connectorPaginatorRows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_CONNECTORS_PAGINATOR_ROWS);
-
-        setupConnectors();
-    }
-
-    private void setupConnectors() {
-        List<IColumn<ConnInstanceTO, String>> columns = new ArrayList<>();
-
-        columns.add(new PropertyColumn<ConnInstanceTO, String>(
-                new StringResourceModel("key", this, null), "key", "key"));
-        columns.add(new PropertyColumn<ConnInstanceTO, String>(
-                new StringResourceModel("name", this, null), "connectorName", "connectorName"));
-        columns.add(new PropertyColumn<ConnInstanceTO, String>(
-                new StringResourceModel("displayName", this, null), "displayName", "displayName"));
-        columns.add(new PropertyColumn<ConnInstanceTO, String>(
-                new StringResourceModel("bundleName", this, null), "bundleName", "bundleName"));
-        columns.add(new PropertyColumn<ConnInstanceTO, String>(
-                new StringResourceModel("version", this, null), "version", "version"));
-        columns.add(new AbstractColumn<ConnInstanceTO, String>(new StringResourceModel("actions", this, null, "")) {
-
-            private static final long serialVersionUID = 2054811145491901166L;
-
-            @Override
-            public String getCssClass() {
-                return "action";
-            }
-
-            @Override
-            public void populateItem(final Item<ICellPopulator<ConnInstanceTO>> cellItem, final String componentId,
-                    final IModel<ConnInstanceTO> model) {
-
-                final ConnInstanceTO connectorTO = model.getObject();
-
-                final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, pageRef);
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        editConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new ConnectorModalPage(Connectors.this.pageRef,
-                                        editConnectorWin,
-                                        connectorTO);
-                            }
-                        });
-
-                        editConnectorWin.show(target);
-                    }
-                }, ActionLink.ActionType.EDIT, "Connectors");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        try {
-                            connectorRestClient.delete(connectorTO.getKey());
-                            info(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (SyncopeClientException e) {
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
-
-                            LOG.error("While deleting connector " + connectorTO.getKey(), e);
-                        }
-
-                        target.add(connectorContainer);
-                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
-                    }
-                }, ActionLink.ActionType.DELETE, "Connectors");
-
-                cellItem.add(panel);
-            }
-        });
-
-        final AjaxDataTablePanel<ConnInstanceTO, String> table = new AjaxDataTablePanel<>(
-                "connectorDatatable",
-                columns,
-                (ISortableDataProvider<ConnInstanceTO, String>) new ConnectorsProvider(),
-                connectorPaginatorRows,
-                Arrays.asList(new ActionLink.ActionType[] { ActionLink.ActionType.DELETE }),
-                connectorRestClient,
-                "key",
-                "Connectors",
-                pageRef);
-
-        connectorContainer = new WebMarkupContainer("connectorContainer");
-        connectorContainer.add(table);
-        connectorContainer.setOutputMarkupId(true);
-
-        MetaDataRoleAuthorizationStrategy.authorize(connectorContainer, RENDER, Entitlement.CONNECTOR_LIST);
-
-        add(connectorContainer);
-
-        ((BasePage) pageRef.getPage()).setWindowClosedCallback(createConnectorWin, connectorContainer);
-        ((BasePage) pageRef.getPage()).setWindowClosedCallback(editConnectorWin, connectorContainer);
-
-        createConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        createConnectorWin.setInitialHeight(WIN_HEIGHT);
-        createConnectorWin.setInitialWidth(WIN_WIDTH);
-        createConnectorWin.setCookieName("create-conn-modal");
-
-        editConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        editConnectorWin.setInitialHeight(WIN_HEIGHT);
-        editConnectorWin.setInitialWidth(WIN_WIDTH);
-        editConnectorWin.setCookieName("edit-conn-modal");
-
-        AjaxLink<Void> createConnectorLink
-                = new ClearIndicatingAjaxLink<Void>("createConnectorLink", pageRef) {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
-                        createConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                ConnectorModalPage form = new ConnectorModalPage(
-                                        pageRef, editConnectorWin, new ConnInstanceTO());
-                                return form;
-                            }
-                        });
-
-                        createConnectorWin.show(target);
-                    }
-                };
-
-        MetaDataRoleAuthorizationStrategy.authorize(createConnectorLink, ENABLE, Entitlement.CONNECTOR_CREATE);
-
-        add(createConnectorLink);
-
-        @SuppressWarnings("rawtypes")
-        Form paginatorForm = new Form("connectorPaginatorForm");
-
-        MetaDataRoleAuthorizationStrategy.authorize(paginatorForm, RENDER, Entitlement.CONNECTOR_LIST);
-
-        final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
-                "rowsChooser",
-                new PropertyModel<Integer>(this,
-                        "connectorPaginatorRows"),
-                prefMan.getPaginatorChoices());
-
-        rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                prefMan.set(getRequest(), getResponse(), Constants.PREF_CONNECTORS_PAGINATOR_ROWS,
-                        String.valueOf(connectorPaginatorRows));
-                table.setItemsPerPage(connectorPaginatorRows);
-
-                target.add(connectorContainer);
-            }
-        });
-
-        paginatorForm.add(rowsChooser);
-        add(paginatorForm);
-    }
-
-    private class ConnectorsProvider extends SortableDataProvider<ConnInstanceTO, String> {
-
-        private static final long serialVersionUID = 4445909568349448518L;
-
-        private final SortableDataProviderComparator<ConnInstanceTO> comparator;
-
-        public ConnectorsProvider() {
-            super();
-            //Default sorting
-            setSort("key", SortOrder.ASCENDING);
-            comparator = new SortableDataProviderComparator<>(this);
-        }
-
-        @Override
-        public Iterator<ConnInstanceTO> iterator(final long first, final long count) {
-            List<ConnInstanceTO> list = connectorRestClient.getAllConnectors();
-
-            Collections.sort(list, comparator);
-
-            return list.subList((int) first, (int) first + (int) count).iterator();
-        }
-
-        @Override
-        public long size() {
-            return connectorRestClient.getAllConnectors().size();
-        }
-
-        @Override
-        public IModel<ConnInstanceTO> model(final ConnInstanceTO connector) {
-
-            return new AbstractReadOnlyModel<ConnInstanceTO>() {
-
-                private static final long serialVersionUID = -6033068018293569398L;
-
-                @Override
-                public ConnInstanceTO getObject() {
-                    return connector;
-                }
-            };
-        }
-    }
-
-    @Override
-    public void onEvent(final IEvent<?> event) {
-        if (event.getPayload() instanceof AbstractSearchResultPanel.EventDataWrapper) {
-            ((AbstractSearchResultPanel.EventDataWrapper) event.getPayload()).getTarget().add(connectorContainer);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java
new file mode 100644
index 0000000..fbf8802
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Modal window with Resource form.
+ */
+public class ModalContent extends Panel {
+
+    private static final long serialVersionUID = 8611724965544132636L;
+
+    protected static final Logger LOG = LoggerFactory.getLogger(ModalContent.class);
+
+    protected static final String CANCEL = "cancel";
+
+    protected static final String SUBMIT = "submit";
+
+    protected static final String APPLY = "apply";
+
+    protected static final String FORM = "form";
+
+    @SpringBean
+    protected ResourceRestClient resourceRestClient;
+
+    @SpringBean
+    protected ConnectorRestClient connectorRestClient;
+
+    protected NotificationPanel feedbackPanel;
+
+    private final PageReference pageRef;
+
+    private final ModalWindow window;
+
+    public ModalContent(final ModalWindow window, final PageReference pageRef) {
+        super(window.getContentId());
+        this.pageRef = pageRef;
+        this.window = window;
+
+        feedbackPanel = new NotificationPanel(Constants.FEEDBACK);
+        feedbackPanel.setOutputMarkupId(true);
+        add(feedbackPanel);
+    }
+
+    /**
+     * Generic modal event.
+     */
+    public static class ModalEvent {
+
+        /**
+         * Request target.
+         */
+        private final AjaxRequestTarget target;
+
+        /**
+         * Constructor.
+         *
+         * @param target request target.
+         */
+        public ModalEvent(final AjaxRequestTarget target) {
+            this.target = target;
+        }
+
+        /**
+         * Target getter.
+         *
+         * @return request target.
+         */
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
index 6f2a17b..1b536c4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
@@ -24,7 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.syncope.client.console.pages.BaseModalPage;
-import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent;
+import org.apache.syncope.client.console.panels.ModalContent.ModalEvent;
 import org.apache.syncope.client.console.panels.ResourceDetailsPanel.DetailsModEvent;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel.MultiValueSelectorEvent;
@@ -148,7 +148,7 @@ public class ResourceConnConfPanel extends Panel {
         AjaxRequestTarget target = null;
         if (event.getPayload() instanceof DetailsModEvent) {
             // connector change: update properties and forward event
-            target = ((ResourceEvent) event.getPayload()).getTarget();
+            target = ((ModalEvent) event.getPayload()).getTarget();
 
             connConfProperties = getConnConfProperties();
             check.setEnabled(!connConfProperties.isEmpty());
@@ -167,7 +167,7 @@ public class ResourceConnConfPanel extends Panel {
     /**
      * Connector configuration properties modification event.
      */
-    public static class ConnConfModEvent extends ResourceEvent {
+    public static class ConnConfModEvent extends ModalEvent {
 
         private final List<ConnConfProperty> configuration;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a2051012/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
index 3095b4e..ff5cac3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
@@ -22,7 +22,7 @@ import java.util.Arrays;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent;
+import org.apache.syncope.client.console.panels.ModalContent.ModalEvent;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
@@ -89,9 +89,9 @@ public class ResourceDetailsPanel extends Panel {
                         "propagationPrimary"));
         add(propagationPrimary);
 
-        final SpinnerFieldPanel<Integer> propagationPriority =
-                new SpinnerFieldPanel<>("propagationPriority", "propagationPriority", Integer.class,
-                        new PropertyModel<Integer>(resourceTO, "propagationPriority"), null, null);
+        final SpinnerFieldPanel<Integer> propagationPriority = new SpinnerFieldPanel<>("propagationPriority",
+                "propagationPriority", Integer.class,
+                new PropertyModel<Integer>(resourceTO, "propagationPriority"), null, null);
         add(propagationPriority);
 
         final AjaxDropDownChoicePanel<PropagationMode> propagationMode = new AjaxDropDownChoicePanel<>(
@@ -152,7 +152,7 @@ public class ResourceDetailsPanel extends Panel {
                         actionsClass.setRequired(true);
                         item.add(actionsClass);
 
-                        AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") {
+                        final AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") {
 
                             private static final long serialVersionUID = -7978723352517770644L;
 
@@ -222,7 +222,7 @@ public class ResourceDetailsPanel extends Panel {
                 new ResourceModel("connector", "connector").getObject(),
                 new PropertyModel<ConnInstanceTO>(this, "connInstanceTO"));
         conn.setChoices(connectors.getObject());
-        conn.setChoiceRenderer(new ChoiceRenderer<String>("displayName", "key"));
+        conn.setChoiceRenderer(new ChoiceRenderer<>("displayName", "key"));
 
         conn.getField().setModel(new IModel<ConnInstanceTO>() {
 
@@ -245,7 +245,7 @@ public class ResourceDetailsPanel extends Panel {
         });
 
         conn.addRequiredLabel();
-        conn.setEnabled(createFlag);
+        conn.setEnabled(false);
 
         conn.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
@@ -292,7 +292,7 @@ public class ResourceDetailsPanel extends Panel {
     /**
      * Connector instance modification event.
      */
-    public static class DetailsModEvent extends ResourceEvent {
+    public static class DetailsModEvent extends ModalEvent {
 
         /**
          * Constructor.