http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Login.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Login.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Login.java
new file mode 100644
index 0000000..deaa359
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Login.java
@@ -0,0 +1,365 @@
+/*
+ * 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.security.AccessControlException;
+import java.util.List;
+import java.util.Locale;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.NotificationPanel;
+import org.apache.syncope.client.console.rest.UserSelfRestClient;
+import 
org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.LinkPanel;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.wrap.EntitlementTO;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.EntitlementService;
+import org.apache.wicket.Component;
+import org.apache.wicket.Page;
+import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.markup.html.form.StatelessForm;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.panel.Fragment;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+/**
+ * Syncope Login page.
+ */
+public class Login extends WebPage {
+
+    private static final long serialVersionUID = -3744389270366566218L;
+
+    private final static int SELF_REG_WIN_HEIGHT = 550;
+
+    private final static int SELF_REG_WIN_WIDTH = 800;
+
+    private final static int PWD_RESET_WIN_HEIGHT = 300;
+
+    private final static int PWD_RESET_WIN_WIDTH = 800;
+
+    @SpringBean(name = "version")
+    private String version;
+
+    @SpringBean(name = "anonymousUser")
+    private String anonymousUser;
+
+    @SpringBean(name = "anonymousKey")
+    private String anonymousKey;
+
+    @SpringBean
+    private UserSelfRestClient userSelfRestClient;
+
+    private final StatelessForm<Void> form;
+
+    private final TextField<String> userIdField;
+
+    private final TextField<String> passwordField;
+
+    private final DropDownChoice<Locale> languageSelect;
+
+    private final NotificationPanel feedbackPanel;
+
+    public Login(final PageParameters parameters) {
+        super(parameters);
+        setStatelessHint(true);
+
+        feedbackPanel = new NotificationPanel(Constants.FEEDBACK);
+        add(feedbackPanel);
+
+        form = new StatelessForm<Void>("login");
+
+        userIdField = new TextField<String>("userId", new Model<String>());
+        userIdField.setMarkupId("userId");
+        form.add(userIdField);
+
+        passwordField = new PasswordTextField("password", new Model<String>());
+        passwordField.setMarkupId("password");
+        form.add(passwordField);
+
+        languageSelect = new LocaleDropDown("language");
+
+        form.add(languageSelect);
+
+        AjaxButton submitButton = new AjaxButton("submit", new 
Model<String>(getString("submit"))) {
+
+            private static final long serialVersionUID = 429178684321093953L;
+
+            @Override
+            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
+                try {
+                    if (anonymousUser.equals(userIdField.getRawInput())) {
+                        throw new AccessControlException("Illegal username");
+                    }
+
+                    authenticate(userIdField.getRawInput(), 
passwordField.getRawInput());
+
+                    setResponsePage(WelcomePage.class, parameters);
+                } catch (AccessControlException e) {
+                    error(getString("login-error"));
+                    feedbackPanel.refresh(target);
+                    SyncopeSession.get().resetClients();
+                }
+            }
+        };
+
+        submitButton.setDefaultFormProcessing(false);
+        form.add(submitButton);
+
+        add(form);
+
+        // Modal window for self registration
+        final ModalWindow selfRegModalWin = new ModalWindow("selfRegModal");
+        selfRegModalWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        selfRegModalWin.setInitialHeight(SELF_REG_WIN_HEIGHT);
+        selfRegModalWin.setInitialWidth(SELF_REG_WIN_WIDTH);
+        selfRegModalWin.setCookieName("self-reg-modal");
+        add(selfRegModalWin);
+
+        Fragment selfRegFrag;
+        if (userSelfRestClient.isSelfRegistrationAllowed()) {
+            selfRegFrag = new Fragment("selfRegistration", "selfRegAllowed", 
this);
+
+            final AjaxLink<Void> selfRegLink = new 
ClearIndicatingAjaxLink<Void>("link", getPageReference()) {
+
+                private static final long serialVersionUID = 
-7978723352517770644L;
+
+                @Override
+                protected void onClickInternal(final AjaxRequestTarget target) 
{
+                    selfRegModalWin.setPageCreator(new 
ModalWindow.PageCreator() {
+
+                        private static final long serialVersionUID = 
-7834632442532690940L;
+
+                        @Override
+                        public Page createPage() {
+                            // anonymous authentication needed for 
self-registration
+                            authenticate(anonymousUser, anonymousKey);
+
+                            return new 
UserSelfModalPage(Login.this.getPageReference(), selfRegModalWin, new UserTO());
+                        }
+                    });
+
+                    selfRegModalWin.setWindowClosedCallback(new 
ModalWindow.WindowClosedCallback() {
+
+                        private static final long serialVersionUID = 
251794406325329768L;
+
+                        @Override
+                        public void onClose(final AjaxRequestTarget target) {
+                            SyncopeSession.get().invalidate();
+                        }
+                    });
+
+                    selfRegModalWin.show(target);
+                }
+            };
+            selfRegLink.add(new Label("linkTitle", 
getString("selfRegistration")));
+
+            Panel panel = new LinkPanel("selfRegistration", new 
ResourceModel("selfRegistration"));
+            panel.add(selfRegLink);
+            selfRegFrag.add(panel);
+        } else {
+            selfRegFrag = new Fragment("selfRegistration", 
"selfRegNotAllowed", this);
+        }
+        add(selfRegFrag);
+
+        // Modal window for password reset request
+        final ModalWindow pwdResetReqModalWin = new 
ModalWindow("pwdResetReqModal");
+        pwdResetReqModalWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        pwdResetReqModalWin.setInitialHeight(PWD_RESET_WIN_HEIGHT);
+        pwdResetReqModalWin.setInitialWidth(PWD_RESET_WIN_WIDTH);
+        pwdResetReqModalWin.setCookieName("pwd-reset-req-modal");
+        add(pwdResetReqModalWin);
+
+        Fragment pwdResetFrag;
+        if (userSelfRestClient.isPasswordResetAllowed()) {
+            pwdResetFrag = new Fragment("passwordReset", "pwdResetAllowed", 
this);
+
+            final AjaxLink<Void> pwdResetLink = new 
ClearIndicatingAjaxLink<Void>("link", getPageReference()) {
+
+                private static final long serialVersionUID = 
-6957616042924610290L;
+
+                @Override
+                protected void onClickInternal(final AjaxRequestTarget target) 
{
+                    pwdResetReqModalWin.setPageCreator(new 
ModalWindow.PageCreator() {
+
+                        private static final long serialVersionUID = 
-7834632442532690940L;
+
+                        @Override
+                        public Page createPage() {
+                            // anonymous authentication needed for password 
reset request
+                            authenticate(anonymousUser, anonymousKey);
+
+                            return new 
RequestPasswordResetModalPage(pwdResetReqModalWin);
+                        }
+                    });
+
+                    pwdResetReqModalWin.setWindowClosedCallback(new 
ModalWindow.WindowClosedCallback() {
+
+                        private static final long serialVersionUID = 
8804221891699487139L;
+
+                        @Override
+                        public void onClose(final AjaxRequestTarget target) {
+                            SyncopeSession.get().invalidate();
+                            setResponsePage(Login.class);
+                        }
+                    });
+
+                    pwdResetReqModalWin.show(target);
+                }
+            };
+            pwdResetLink.add(new Label("linkTitle", 
getString("passwordReset")));
+
+            Panel panel = new LinkPanel("passwordReset", new 
ResourceModel("passwordReset"));
+            panel.add(pwdResetLink);
+            pwdResetFrag.add(panel);
+        } else {
+            pwdResetFrag = new Fragment("passwordReset", "pwdResetNotAllowed", 
this);
+        }
+        add(pwdResetFrag);
+
+        // Modal window for password reset confirm - automatically shown when 
token is available as request parameter
+        final String pwdResetToken = 
RequestCycle.get().getRequest().getRequestParameters().
+                
getParameterValue(Constants.PARAM_PASSWORD_RESET_TOKEN).toOptionalString();
+        final ModalWindow pwdResetConfModalWin = new 
ModalWindow("pwdResetConfModal");
+        if (StringUtils.isNotBlank(pwdResetToken)) {
+            pwdResetConfModalWin.add(new AbstractDefaultAjaxBehavior() {
+
+                private static final long serialVersionUID = 
3109256773218160485L;
+
+                @Override
+                protected void respond(final AjaxRequestTarget target) {
+                    ModalWindow window = (ModalWindow) getComponent();
+                    window.show(target);
+                }
+
+                @Override
+                public void renderHead(final Component component, final 
IHeaderResponse response) {
+                    
response.render(JavaScriptHeaderItem.forScript(getCallbackScript(), null));
+                }
+            });
+        }
+        pwdResetConfModalWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        pwdResetConfModalWin.setInitialHeight(PWD_RESET_WIN_HEIGHT);
+        pwdResetConfModalWin.setInitialWidth(PWD_RESET_WIN_WIDTH);
+        pwdResetConfModalWin.setCookieName("pwd-reset-conf-modal");
+        pwdResetConfModalWin.setPageCreator(new ModalWindow.PageCreator() {
+
+            private static final long serialVersionUID = -7834632442532690940L;
+
+            @Override
+            public Page createPage() {
+                // anonymous authentication needed for password reset confirm
+                authenticate(anonymousUser, anonymousKey);
+
+                return new ConfirmPasswordResetModalPage(pwdResetConfModalWin, 
pwdResetToken);
+            }
+        });
+        pwdResetConfModalWin.setWindowClosedCallback(new 
ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                SyncopeSession.get().invalidate();
+                setResponsePage(Login.class);
+            }
+        });
+        add(pwdResetConfModalWin);
+    }
+
+    private void authenticate(final String username, final String password) {
+        List<EntitlementTO> entitlements = SyncopeSession.get().
+                getService(EntitlementService.class, username, 
password).getOwnEntitlements();
+
+        SyncopeSession.get().setUsername(username);
+        SyncopeSession.get().setPassword(password);
+        
SyncopeSession.get().setEntitlements(CollectionWrapper.unwrap(entitlements).toArray(new
 String[0]));
+        SyncopeSession.get().setVersion(version);
+    }
+
+    /**
+     * Inner class which implements (custom) Locale DropDownChoice component.
+     */
+    private class LocaleDropDown extends DropDownChoice<Locale> {
+
+        private static final long serialVersionUID = 2349382679992357202L;
+
+        private class LocaleRenderer extends ChoiceRenderer<Locale> {
+
+            private static final long serialVersionUID = -3657529581555164741L;
+
+            @Override
+            public String getDisplayValue(final Locale locale) {
+                return locale.getDisplayName(getLocale());
+            }
+        }
+
+        public LocaleDropDown(final String id) {
+            super(id, SyncopeSession.SUPPORTED_LOCALES);
+
+            setChoiceRenderer(new LocaleRenderer());
+            setModel(new IModel<Locale>() {
+
+                private static final long serialVersionUID = 
-6985170095629312963L;
+
+                @Override
+                public Locale getObject() {
+                    return getSession().getLocale();
+                }
+
+                @Override
+                public void setObject(final Locale object) {
+                    getSession().setLocale(object);
+                }
+
+                @Override
+                public void detach() {
+                    // Empty.
+                }
+            });
+
+            // set default value to English
+            getModel().setObject(Locale.ENGLISH);
+        }
+
+        @Override
+        protected boolean wantOnSelectionChangedNotifications() {
+            return true;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Logout.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Logout.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Logout.java
new file mode 100644
index 0000000..acf313b
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Logout.java
@@ -0,0 +1,38 @@
+/*
+ * 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.syncope.client.console.SyncopeSession;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+/**
+ * Syncope Logout.
+ */
+public class Logout extends BasePage {
+
+    private static final long serialVersionUID = -2143007520243939450L;
+
+    public Logout(final PageParameters parameters) {
+        super(parameters);
+
+        SyncopeSession.get().invalidate();
+
+        setResponsePage(getApplication().getHomePage());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/MembershipModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/MembershipModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/MembershipModalPage.java
new file mode 100644
index 0000000..f2e2189
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/MembershipModalPage.java
@@ -0,0 +1,114 @@
+/*
+ * 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.syncope.client.console.commons.Mode;
+import org.apache.syncope.client.console.panels.AnnotatedBeanPanel;
+import org.apache.syncope.client.console.panels.DerAttrsPanel;
+import org.apache.syncope.client.console.panels.PlainAttrsPanel;
+import org.apache.syncope.client.console.panels.VirAttrsPanel;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+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;
+
+public class MembershipModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = -4360802478081432549L;
+
+    private final AjaxButton submit;
+
+    public MembershipModalPage(final PageReference pageRef, final ModalWindow 
window, final MembershipTO membershipTO,
+            final Mode mode) {
+
+        final Form<MembershipTO> form = new 
Form<MembershipTO>("MembershipForm");
+
+        final UserTO userTO = ((UserModalPage) pageRef.getPage()).getUserTO();
+
+        form.setModel(new CompoundPropertyModel<MembershipTO>(membershipTO));
+
+        submit = new AjaxButton(SUBMIT, new ResourceModel(SUBMIT)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form 
form) {
+                userTO.getMemberships().remove(membershipTO);
+                userTO.getMemberships().add(membershipTO);
+
+                ((UserModalPage) pageRef.getPage()).setUserTO(userTO);
+
+                window.close(target);
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+
+        form.add(submit);
+        form.setDefaultButton(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) {
+                ((UserModalPage) pageRef.getPage()).setUserTO(userTO);
+                window.close(target);
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
+            }
+        };
+
+        cancel.setDefaultFormProcessing(false);
+        form.add(cancel);
+
+        //--------------------------------
+        // Attributes panel
+        //--------------------------------
+        form.add(new PlainAttrsPanel("plainAttrs", membershipTO, form, mode));
+        form.add(new AnnotatedBeanPanel("systeminformation", membershipTO));
+        //--------------------------------
+
+        //--------------------------------
+        // Derived attributes container
+        //--------------------------------
+        form.add(new DerAttrsPanel("derAttrs", membershipTO));
+        //--------------------------------
+
+        //--------------------------------
+        // Virtual attributes container
+        //--------------------------------
+        form.add(new VirAttrsPanel("virAttrs", membershipTO, mode == 
Mode.TEMPLATE));
+        //--------------------------------
+
+        add(form);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationModalPage.java
new file mode 100644
index 0000000..98d8862
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationModalPage.java
@@ -0,0 +1,441 @@
+/*
+ * 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.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.LoggerCategoryPanel;
+import org.apache.syncope.client.console.panels.GroupSearchPanel;
+import org.apache.syncope.client.console.panels.UserSearchPanel;
+import org.apache.syncope.client.console.rest.LoggerRestClient;
+import org.apache.syncope.client.console.rest.NotificationRestClient;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+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.MultiFieldPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+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.form.Form;
+import org.apache.wicket.model.CompoundPropertyModel;
+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.EmailAddressValidator;
+
+class NotificationModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = -1975312550059578553L;
+
+    @SpringBean
+    private NotificationRestClient restClient;
+
+    @SpringBean
+    private LoggerRestClient loggerRestClient;
+
+    public NotificationModalPage(final PageReference pageRef, final 
ModalWindow window,
+            final NotificationTO notificationTO, final boolean createFlag) {
+
+        final Form<NotificationTO> form =
+                new Form<NotificationTO>(FORM, new 
CompoundPropertyModel<NotificationTO>(notificationTO));
+
+        final AjaxTextFieldPanel sender = new AjaxTextFieldPanel("sender", 
getString("sender"),
+                new PropertyModel<String>(notificationTO, "sender"));
+        sender.addRequiredLabel();
+        sender.addValidator(EmailAddressValidator.getInstance());
+        form.add(sender);
+
+        final AjaxTextFieldPanel subject = new AjaxTextFieldPanel("subject", 
getString("subject"),
+                new PropertyModel<String>(notificationTO, "subject"));
+        subject.addRequiredLabel();
+        form.add(subject);
+
+        final AjaxDropDownChoicePanel<String> template = new 
AjaxDropDownChoicePanel<String>(
+                "template", getString("template"),
+                new PropertyModel<String>(notificationTO, "template"));
+        template.setChoices(confRestClient.getMailTemplates());
+        template.addRequiredLabel();
+        form.add(template);
+
+        final AjaxDropDownChoicePanel<TraceLevel> traceLevel = new 
AjaxDropDownChoicePanel<TraceLevel>(
+                "traceLevel", getString("traceLevel"),
+                new PropertyModel<TraceLevel>(notificationTO, "traceLevel"));
+        traceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+        traceLevel.addRequiredLabel();
+        form.add(traceLevel);
+
+        final AjaxCheckBoxPanel isActive = new AjaxCheckBoxPanel("isActive",
+                getString("isActive"), new 
PropertyModel<Boolean>(notificationTO, "active"));
+        if (createFlag) {
+            isActive.getField().setDefaultModelObject(Boolean.TRUE);
+        }
+        form.add(isActive);
+
+        final WebMarkupContainer aboutContainer = new 
WebMarkupContainer("aboutContainer");
+        aboutContainer.setOutputMarkupId(true);
+
+        form.add(aboutContainer);
+
+        final AjaxCheckBoxPanel checkAbout = new 
AjaxCheckBoxPanel("checkAbout", "checkAbout", new Model<Boolean>(
+                notificationTO.getUserAbout() == null && 
notificationTO.getGroupAbout() == null));
+        aboutContainer.add(checkAbout);
+
+        final AjaxCheckBoxPanel checkUserAbout = new 
AjaxCheckBoxPanel("checkUserAbout", "checkUserAbout",
+                new Model<Boolean>(notificationTO.getUserAbout() != null));
+        aboutContainer.add(checkUserAbout);
+
+        final AjaxCheckBoxPanel checkGroupAbout = new 
AjaxCheckBoxPanel("checkGroupAbout", "checkGroupAbout",
+                new Model<Boolean>(notificationTO.getGroupAbout() != null));
+        aboutContainer.add(checkGroupAbout);
+
+        final UserSearchPanel userAbout =
+                new 
UserSearchPanel.Builder("userAbout").fiql(notificationTO.getUserAbout()).build();
+        aboutContainer.add(userAbout);
+        userAbout.setEnabled(checkUserAbout.getModelObject());
+
+        final GroupSearchPanel groupAbout =
+                new 
GroupSearchPanel.Builder("groupAbout").fiql(notificationTO.getGroupAbout()).build();
+        aboutContainer.add(groupAbout);
+        groupAbout.setEnabled(checkGroupAbout.getModelObject());
+
+        checkAbout.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                if (checkAbout.getModelObject()) {
+                    checkUserAbout.setModelObject(Boolean.FALSE);
+                    checkGroupAbout.setModelObject(Boolean.FALSE);
+                    userAbout.setEnabled(Boolean.FALSE);
+                    groupAbout.setEnabled(Boolean.FALSE);
+                } else {
+                    checkAbout.setModelObject(Boolean.TRUE);
+                }
+                target.add(aboutContainer);
+            }
+        });
+
+        checkUserAbout.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                if (checkUserAbout.getModelObject()) {
+                    
checkAbout.setModelObject(!checkUserAbout.getModelObject());
+                    
checkGroupAbout.setModelObject(!checkUserAbout.getModelObject());
+                    groupAbout.setEnabled(Boolean.FALSE);
+                } else {
+                    checkUserAbout.setModelObject(Boolean.TRUE);
+                }
+                userAbout.setEnabled(Boolean.TRUE);
+                target.add(aboutContainer);
+            }
+        });
+
+        checkGroupAbout.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                if (checkGroupAbout.getModelObject()) {
+                    checkAbout.setModelObject(Boolean.FALSE);
+                    checkUserAbout.setModelObject(Boolean.FALSE);
+                    userAbout.setEnabled(Boolean.FALSE);
+                } else {
+                    checkGroupAbout.setModelObject(Boolean.TRUE);
+                }
+                groupAbout.setEnabled(Boolean.TRUE);
+                target.add(aboutContainer);
+            }
+        });
+
+        final AjaxDropDownChoicePanel<IntMappingType> recipientAttrType = new 
AjaxDropDownChoicePanel<IntMappingType>(
+                "recipientAttrType", new ResourceModel("recipientAttrType", 
"recipientAttrType").getObject(),
+                new PropertyModel<IntMappingType>(notificationTO, 
"recipientAttrType"));
+        recipientAttrType.setChoices(new ArrayList<IntMappingType>(
+                IntMappingType.getAttributeTypes(AttributableType.USER,
+                        EnumSet.of(IntMappingType.UserId, 
IntMappingType.Password))));
+        recipientAttrType.addRequiredLabel();
+        form.add(recipientAttrType);
+
+        final AjaxDropDownChoicePanel<String> recipientAttrName = new 
AjaxDropDownChoicePanel<String>(
+                "recipientAttrName", new ResourceModel("recipientAttrName", 
"recipientAttrName").getObject(),
+                new PropertyModel<String>(notificationTO, 
"recipientAttrName"));
+        
recipientAttrName.setChoices(getSchemaNames(recipientAttrType.getModelObject()));
+        recipientAttrName.addRequiredLabel();
+        form.add(recipientAttrName);
+
+        recipientAttrType.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                
recipientAttrName.setChoices(getSchemaNames(recipientAttrType.getModelObject()));
+                target.add(recipientAttrName);
+            }
+        });
+
+        form.add(new LoggerCategoryPanel(
+                "eventSelection",
+                loggerRestClient.listEvents(),
+                new PropertyModel<List<String>>(notificationTO, "events"),
+                getPageReference(),
+                "Notification") {
+
+                    private static final long serialVersionUID = 
6429053774964787735L;
+
+                    @Override
+                    protected String[] getListRoles() {
+                        return new String[] {};
+                    }
+
+                    @Override
+                    protected String[] getChangeRoles() {
+                        return new String[] {};
+                    }
+                });
+
+        final WebMarkupContainer recipientsContainer = new 
WebMarkupContainer("recipientsContainer");
+        recipientsContainer.setOutputMarkupId(true);
+
+        form.add(recipientsContainer);
+
+        final AjaxCheckBoxPanel checkStaticRecipients = new 
AjaxCheckBoxPanel("checkStaticRecipients",
+                "recipients", new 
Model<Boolean>(!notificationTO.getStaticRecipients().isEmpty()));
+        form.add(checkStaticRecipients);
+
+        if (createFlag) {
+            
checkStaticRecipients.getField().setDefaultModelObject(Boolean.FALSE);
+        }
+
+        final AjaxTextFieldPanel staticRecipientsFieldPanel =
+                new AjaxTextFieldPanel("panel", "staticRecipients", new 
Model<String>(null));
+        
staticRecipientsFieldPanel.addValidator(EmailAddressValidator.getInstance());
+        
staticRecipientsFieldPanel.setRequired(checkStaticRecipients.getModelObject());
+
+        if (notificationTO.getStaticRecipients().isEmpty()) {
+            notificationTO.getStaticRecipients().add(null);
+        }
+
+        final MultiFieldPanel<String> staticRecipients = new 
MultiFieldPanel<String>("staticRecipients",
+                new PropertyModel<List<String>>(notificationTO, 
"staticRecipients"), staticRecipientsFieldPanel);
+        staticRecipients.setEnabled(checkStaticRecipients.getModelObject());
+        form.add(staticRecipients);
+
+        final AjaxCheckBoxPanel checkRecipients =
+                new AjaxCheckBoxPanel("checkRecipients", "checkRecipients",
+                        new Model<Boolean>(notificationTO.getRecipients() == 
null ? false : true));
+        recipientsContainer.add(checkRecipients);
+
+        if (createFlag) {
+            checkRecipients.getField().setDefaultModelObject(Boolean.TRUE);
+        }
+
+        final UserSearchPanel recipients =
+                new 
UserSearchPanel.Builder("recipients").fiql(notificationTO.getRecipients()).build();
+
+        recipients.setEnabled(checkRecipients.getModelObject());
+        recipientsContainer.add(recipients);
+
+        final AjaxCheckBoxPanel selfAsRecipient = new 
AjaxCheckBoxPanel("selfAsRecipient",
+                getString("selfAsRecipient"), new 
PropertyModel<Boolean>(notificationTO, "selfAsRecipient"));
+        form.add(selfAsRecipient);
+
+        if (createFlag) {
+            selfAsRecipient.getField().setDefaultModelObject(Boolean.FALSE);
+        }
+
+        selfAsRecipient.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                if (!selfAsRecipient.getModelObject()
+                        && !checkRecipients.getModelObject()
+                        && !checkStaticRecipients.getModelObject()) {
+
+                    
checkRecipients.getField().setDefaultModelObject(Boolean.TRUE);
+                    target.add(checkRecipients);
+                    recipients.setEnabled(checkRecipients.getModelObject());
+                    target.add(recipients);
+                    target.add(recipientsContainer);
+                }
+            }
+        });
+
+        checkRecipients.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                if (!checkRecipients.getModelObject()
+                        && !selfAsRecipient.getModelObject()
+                        && !checkStaticRecipients.getModelObject()) {
+
+                    
checkStaticRecipients.getField().setDefaultModelObject(Boolean.TRUE);
+                    target.add(checkStaticRecipients);
+                    staticRecipients.setEnabled(Boolean.TRUE);
+                    target.add(staticRecipients);
+                    staticRecipientsFieldPanel.setRequired(Boolean.TRUE);
+                    target.add(staticRecipientsFieldPanel);
+                }
+                recipients.setEnabled(checkRecipients.getModelObject());
+                target.add(recipients);
+                target.add(recipientsContainer);
+            }
+        });
+
+        checkStaticRecipients.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                if (!checkStaticRecipients.getModelObject()
+                        && !selfAsRecipient.getModelObject()
+                        && !checkRecipients.getModelObject()) {
+                    
checkRecipients.getField().setDefaultModelObject(Boolean.TRUE);
+                    checkRecipients.setEnabled(Boolean.TRUE);
+                    target.add(checkRecipients);
+                }
+                
staticRecipients.setEnabled(checkStaticRecipients.getModelObject());
+                
staticRecipientsFieldPanel.setRequired(checkStaticRecipients.getModelObject());
+                recipients.setEnabled(checkRecipients.getModelObject());
+                target.add(staticRecipientsFieldPanel);
+                target.add(staticRecipients);
+                target.add(recipients);
+                target.add(recipientsContainer);
+            }
+        });
+
+        AjaxButton submit = new IndicatingAjaxButton(APPLY, new 
Model<String>(getString(SUBMIT))) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
+                notificationTO.setUserAbout(
+                        !checkAbout.getModelObject() && 
checkUserAbout.getModelObject() ? userAbout.buildFIQL() : null);
+                notificationTO.setGroupAbout(
+                        !checkAbout.getModelObject()
+                        && checkGroupAbout.getModelObject() ? 
groupAbout.buildFIQL() : null);
+                notificationTO.setRecipients(checkRecipients.getModelObject() 
? recipients.buildFIQL() : null);
+                
notificationTO.getStaticRecipients().removeAll(Collections.singleton(null));
+
+                try {
+                    if (createFlag) {
+                        restClient.create(notificationTO);
+                    } else {
+                        restClient.update(notificationTO);
+                    }
+                    info(getString(Constants.OPERATION_SUCCEEDED));
+
+                    Configuration callerPage = (Configuration) 
pageRef.getPage();
+                    callerPage.setModalResult(true);
+
+                    window.close(target);
+                } catch (SyncopeClientException scee) {
+                    error(getString(Constants.ERROR) + ": " + 
scee.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+
+        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);
+            }
+        };
+
+        cancel.setDefaultFormProcessing(false);
+
+        String allowedRoles = createFlag
+                ? xmlRolesReader.getEntitlement("Notification", "create")
+                : xmlRolesReader.getEntitlement("Notification", "update");
+        MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, 
allowedRoles);
+
+        form.add(submit);
+        form.setDefaultButton(submit);
+
+        form.add(cancel);
+
+        add(form);
+    }
+
+    private List<String> getSchemaNames(final IntMappingType type) {
+        final List<String> result;
+
+        if (type == null) {
+            result = Collections.<String>emptyList();
+        } else {
+            switch (type) {
+                case UserPlainSchema:
+                    result = 
schemaRestClient.getPlainSchemaNames(AttributableType.USER);
+                    break;
+
+                case UserDerivedSchema:
+                    result = 
schemaRestClient.getDerSchemaNames(AttributableType.USER);
+                    break;
+
+                case UserVirtualSchema:
+                    result = 
schemaRestClient.getVirSchemaNames(AttributableType.USER);
+                    break;
+
+                case Username:
+                    result = Collections.singletonList("Username");
+                    break;
+
+                default:
+                    result = Collections.<String>emptyList();
+            }
+        }
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationTaskModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationTaskModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationTaskModalPage.java
new file mode 100644
index 0000000..70f63d6
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/NotificationTaskModalPage.java
@@ -0,0 +1,69 @@
+/*
+ * 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 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.wicket.markup.html.form.ListMultipleChoice;
+import org.apache.wicket.markup.html.form.TextArea;
+import org.apache.wicket.model.PropertyModel;
+
+public class NotificationTaskModalPage extends TaskModalPage {
+
+    private static final long serialVersionUID = -4399606755452034216L;
+
+    public NotificationTaskModalPage(final AbstractTaskTO taskTO) {
+        super(taskTO);
+
+        final AjaxTextFieldPanel sender = new AjaxTextFieldPanel("sender", 
getString("sender"),
+                new PropertyModel<String>(taskTO, "sender"));
+        sender.setEnabled(false);
+        profile.add(sender);
+
+        if (taskTO instanceof NotificationTaskTO) {
+            final ListMultipleChoice<String> recipients = new 
ListMultipleChoice<>("recipients",
+                    new ArrayList<>(((NotificationTaskTO) 
taskTO).getRecipients()));
+            recipients.setMaxRows(5);
+            recipients.setEnabled(false);
+            profile.add(recipients);
+        }
+
+        final AjaxTextFieldPanel subject = new AjaxTextFieldPanel("subject", 
getString("subject"),
+                new PropertyModel<String>(taskTO, "subject"));
+        subject.setEnabled(false);
+        profile.add(subject);
+
+        final TextArea<String> textBody = new TextArea<String>("textBody",
+                new PropertyModel<String>(taskTO, "textBody"));
+        textBody.setEnabled(false);
+        profile.add(textBody);
+
+        final TextArea<String> htmlBody = new TextArea<String>("htmlBody",
+                new PropertyModel<String>(taskTO, "htmlBody"));
+        htmlBody.setEnabled(false);
+        profile.add(htmlBody);
+
+        final AjaxTextFieldPanel traceLevel = new 
AjaxTextFieldPanel("traceLevel", getString("traceLevel"),
+                new PropertyModel<String>(taskTO, "traceLevel"));
+        traceLevel.setEnabled(false);
+        profile.add(traceLevel);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PlainSchemaModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PlainSchemaModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PlainSchemaModalPage.java
new file mode 100644
index 0000000..3adba7d
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PlainSchemaModalPage.java
@@ -0,0 +1,456 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.JexlHelpUtils;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+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.MultiFieldPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+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.autocomplete.AutoCompleteTextField;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+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.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.util.string.Strings;
+
+/**
+ * Modal window with Schema form.
+ */
+public class PlainSchemaModalPage extends 
AbstractSchemaModalPage<PlainSchemaTO> {
+
+    private static final long serialVersionUID = -5991561277287424057L;
+
+    public PlainSchemaModalPage(final AttributableType kind) {
+        super(kind);
+    }
+
+    @Override
+    public void setSchemaModalPage(final PageReference pageRef, final 
ModalWindow window,
+            final PlainSchemaTO schemaTO, final boolean createFlag) {
+
+        final PlainSchemaTO schema = schemaTO == null
+                ? new PlainSchemaTO()
+                : schemaTO;
+
+        final Form<PlainSchemaTO> schemaForm = new Form<>(FORM);
+
+        schemaForm.setModel(new CompoundPropertyModel<>(schema));
+        schemaForm.setOutputMarkupId(true);
+
+        final AjaxTextFieldPanel name =
+                new AjaxTextFieldPanel("key", getString("key"), new 
PropertyModel<String>(schema, "key"));
+        name.addRequiredLabel();
+        name.setEnabled(createFlag);
+        schemaForm.add(name);
+
+        final AjaxDropDownChoicePanel<AttrSchemaType> type = new 
AjaxDropDownChoicePanel<>(
+                "type", getString("type"), new 
PropertyModel<AttrSchemaType>(schema, "type"));
+        type.setChoices(Arrays.asList(AttrSchemaType.values()));
+        type.addRequiredLabel();
+        schemaForm.add(type);
+
+        // -- long, double, date
+        final AjaxTextFieldPanel conversionPattern = new 
AjaxTextFieldPanel("conversionPattern",
+                getString("conversionPattern"), new 
PropertyModel<String>(schema, "conversionPattern"));
+        schemaForm.add(conversionPattern);
+
+        final WebMarkupContainer conversionParams = new 
WebMarkupContainer("conversionParams");
+        conversionParams.setOutputMarkupPlaceholderTag(true);
+        conversionParams.add(conversionPattern);
+        schemaForm.add(conversionParams);
+
+        final WebMarkupContainer typeParams = new 
WebMarkupContainer("typeParams");
+        typeParams.setOutputMarkupPlaceholderTag(true);
+        // -- enum
+        final AjaxTextFieldPanel enumerationValuesPanel =
+                new AjaxTextFieldPanel("panel", "enumerationValues", new 
Model<String>(null));
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        final MultiFieldPanel<String> enumerationValues = new 
MultiFieldPanel<>("enumerationValues",
+                new Model(),
+                enumerationValuesPanel);
+        
enumerationValues.setModelObject(getEnumValuesAsList(schema.getEnumerationValues()));
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        final MultiFieldPanel<String> enumerationKeys = new 
MultiFieldPanel<>("enumerationKeys",
+                new Model(),
+                new AjaxTextFieldPanel("panel", "enumerationKeys", new 
Model<String>(null)));
+        
enumerationKeys.setModelObject(getEnumValuesAsList(schema.getEnumerationKeys()));
+
+        final WebMarkupContainer enumParams = new 
WebMarkupContainer("enumParams");
+        enumParams.setOutputMarkupPlaceholderTag(true);
+        enumParams.add(enumerationValues);
+        enumParams.add(enumerationKeys);
+        typeParams.add(enumParams);
+
+        // -- encrypted
+        final AjaxTextFieldPanel secretKey = new 
AjaxTextFieldPanel("secretKey",
+                getString("secretKey"), new PropertyModel<String>(schema, 
"secretKey"));
+
+        final AjaxDropDownChoicePanel<CipherAlgorithm> cipherAlgorithm = new 
AjaxDropDownChoicePanel<>(
+                "cipherAlgorithm", getString("cipherAlgorithm"),
+                new PropertyModel<CipherAlgorithm>(schema, "cipherAlgorithm"));
+        cipherAlgorithm.setChoices(Arrays.asList(CipherAlgorithm.values()));
+
+        final WebMarkupContainer encryptedParams = new 
WebMarkupContainer("encryptedParams");
+        encryptedParams.setOutputMarkupPlaceholderTag(true);
+        encryptedParams.add(secretKey);
+        encryptedParams.add(cipherAlgorithm);
+        typeParams.add(encryptedParams);
+
+        // -- binary
+        final AjaxTextFieldPanel mimeType = new AjaxTextFieldPanel("mimeType",
+                getString("mimeType"), new PropertyModel<String>(schema, 
"mimeType"));
+        mimeType.setChoices(mimeTypesInitializer.getMimeTypes());
+
+        final WebMarkupContainer binaryParams = new 
WebMarkupContainer("binaryParams");
+        binaryParams.setOutputMarkupPlaceholderTag(true);
+        binaryParams.add(mimeType);
+        typeParams.add(binaryParams);
+
+        schemaForm.add(typeParams);
+
+        // -- show or hide
+        showHide(schema, type,
+                conversionParams, conversionPattern,
+                enumParams, enumerationValuesPanel, enumerationValues, 
enumerationKeys,
+                encryptedParams, secretKey, cipherAlgorithm,
+                binaryParams, mimeType);
+        type.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                PlainSchemaModalPage.this.showHide(schema, type,
+                        conversionParams, conversionPattern,
+                        enumParams, enumerationValuesPanel, enumerationValues, 
enumerationKeys,
+                        encryptedParams, secretKey, cipherAlgorithm,
+                        binaryParams, mimeType);
+                target.add(typeParams);
+            }
+        });
+
+        final IModel<List<String>> validatorsList = new 
LoadableDetachableModel<List<String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<String> load() {
+                return schemaRestClient.getAllValidatorClasses();
+            }
+        };
+        final AjaxDropDownChoicePanel<String> validatorClass = new 
AjaxDropDownChoicePanel<>("validatorClass",
+                getString("validatorClass"), new PropertyModel<String>(schema, 
"validatorClass"));
+        ((DropDownChoice) validatorClass.getField()).setNullValid(true);
+        validatorClass.setChoices(validatorsList.getObject());
+        schemaForm.add(validatorClass);
+
+        final AutoCompleteTextField<String> mandatoryCondition =
+                new AutoCompleteTextField<String>("mandatoryCondition") {
+
+                    private static final long serialVersionUID = 
-2428903969518079100L;
+
+                    @Override
+                    protected Iterator<String> getChoices(final String input) {
+                        List<String> choices = new ArrayList<String>();
+
+                        if (Strings.isEmpty(input)) {
+                            choices = Collections.emptyList();
+                        } else if ("true".startsWith(input.toLowerCase())) {
+                            choices.add("true");
+                        } else if ("false".startsWith(input.toLowerCase())) {
+                            choices.add("false");
+                        }
+
+                        return choices.iterator();
+                    }
+                };
+        mandatoryCondition.add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+            }
+        });
+        schemaForm.add(mandatoryCondition);
+
+        final WebMarkupContainer pwdJexlHelp = 
JexlHelpUtils.getJexlHelpWebContainer("jexlHelp");
+
+        final AjaxLink<Void> pwdQuestionMarkJexlHelp = 
JexlHelpUtils.getAjaxLink(pwdJexlHelp, "questionMarkJexlHelp");
+        schemaForm.add(pwdQuestionMarkJexlHelp);
+        pwdQuestionMarkJexlHelp.add(pwdJexlHelp);
+
+        final AjaxCheckBoxPanel multivalue = new 
AjaxCheckBoxPanel("multivalue", getString("multivalue"),
+                new PropertyModel<Boolean>(schema, "multivalue"));
+        schemaForm.add(multivalue);
+
+        final AjaxCheckBoxPanel readonly = new AjaxCheckBoxPanel("readonly", 
getString("readonly"),
+                new PropertyModel<Boolean>(schema, "readonly"));
+        schemaForm.add(readonly);
+
+        final AjaxCheckBoxPanel uniqueConstraint = new 
AjaxCheckBoxPanel("uniqueConstraint",
+                getString("uniqueConstraint"), new 
PropertyModel<Boolean>(schema, "uniqueConstraint"));
+        schemaForm.add(uniqueConstraint);
+
+        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new 
ResourceModel(SUBMIT)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
+                final PlainSchemaTO schemaTO = (PlainSchemaTO) 
form.getDefaultModelObject();
+
+                
schemaTO.setEnumerationValues(getEnumValuesAsString(enumerationValues.getView().getModelObject()));
+                
schemaTO.setEnumerationKeys(getEnumValuesAsString(enumerationKeys.getView().getModelObject()));
+
+                if (schemaTO.isMultivalue() && schemaTO.isUniqueConstraint()) {
+                    error(getString("multivalueAndUniqueConstr.validation"));
+                    feedbackPanel.refresh(target);
+                    return;
+                }
+
+                try {
+                    if (createFlag) {
+                        schemaRestClient.createPlainSchema(kind, schemaTO);
+                    } else {
+                        schemaRestClient.updatePlainSchema(kind, schemaTO);
+                    }
+                    if (pageRef.getPage() instanceof BasePage) {
+                        ((BasePage) pageRef.getPage()).setModalResult(true);
+                    }
+
+                    window.close(target);
+                } catch (SyncopeClientException e) {
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+        schemaForm.add(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);
+            }
+        };
+        cancel.setDefaultFormProcessing(false);
+        schemaForm.add(cancel);
+
+        String allowedRoles = createFlag
+                ? xmlRolesReader.getEntitlement("Schema", "create")
+                : xmlRolesReader.getEntitlement("Schema", "update");
+
+        MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, 
allowedRoles);
+
+        add(schemaForm);
+    }
+
+    private void showHide(final PlainSchemaTO schema, final 
AjaxDropDownChoicePanel<AttrSchemaType> type,
+            final WebMarkupContainer conversionParams, final 
AjaxTextFieldPanel conversionPattern,
+            final WebMarkupContainer enumParams, final AjaxTextFieldPanel 
enumerationValuesPanel,
+            final MultiFieldPanel<String> enumerationValues, final 
MultiFieldPanel<String> enumerationKeys,
+            final WebMarkupContainer encryptedParams,
+            final AjaxTextFieldPanel secretKey, final 
AjaxDropDownChoicePanel<CipherAlgorithm> cipherAlgorithm,
+            final WebMarkupContainer binaryParams, final AjaxTextFieldPanel 
mimeType) {
+
+        final int typeOrdinal = Integer.parseInt(type.getField().getValue());
+        if (AttrSchemaType.Long.ordinal() == typeOrdinal
+                || AttrSchemaType.Double.ordinal() == typeOrdinal
+                || AttrSchemaType.Date.ordinal() == typeOrdinal) {
+
+            conversionParams.setVisible(true);
+
+            enumParams.setVisible(false);
+            if (enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.removeRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(null));
+            enumerationKeys.setModelObject(getEnumValuesAsList(null));
+
+            encryptedParams.setVisible(false);
+            if (secretKey.isRequired()) {
+                secretKey.removeRequiredLabel();
+            }
+            secretKey.setModelObject(null);
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.removeRequiredLabel();
+            }
+            cipherAlgorithm.setModelObject(null);
+
+            binaryParams.setVisible(false);
+            mimeType.setModelObject(null);
+        } else if (AttrSchemaType.Enum.ordinal() == typeOrdinal) {
+            conversionParams.setVisible(false);
+            conversionPattern.setModelObject(null);
+
+            enumParams.setVisible(true);
+            if (!enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.addRequiredLabel();
+            }
+            
enumerationValues.setModelObject(getEnumValuesAsList(schema.getEnumerationValues()));
+            
enumerationKeys.setModelObject(getEnumValuesAsList(schema.getEnumerationKeys()));
+
+            encryptedParams.setVisible(false);
+            if (secretKey.isRequired()) {
+                secretKey.removeRequiredLabel();
+            }
+            secretKey.setModelObject(null);
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.removeRequiredLabel();
+            }
+            cipherAlgorithm.setModelObject(null);
+
+            binaryParams.setVisible(false);
+            mimeType.setModelObject(null);
+        } else if (AttrSchemaType.Encrypted.ordinal() == typeOrdinal) {
+            conversionParams.setVisible(false);
+            conversionPattern.setModelObject(null);
+
+            enumParams.setVisible(false);
+            if (enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.removeRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(null));
+            enumerationKeys.setModelObject(getEnumValuesAsList(null));
+
+            encryptedParams.setVisible(true);
+            if (!secretKey.isRequired()) {
+                secretKey.addRequiredLabel();
+            }
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.addRequiredLabel();
+            }
+
+            binaryParams.setVisible(false);
+            mimeType.setModelObject(null);
+        } else if (AttrSchemaType.Binary.ordinal() == typeOrdinal) {
+            conversionParams.setVisible(false);
+            conversionPattern.setModelObject(null);
+
+            enumParams.setVisible(false);
+            if (enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.removeRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(null));
+            enumerationKeys.setModelObject(getEnumValuesAsList(null));
+
+            encryptedParams.setVisible(false);
+            if (secretKey.isRequired()) {
+                secretKey.removeRequiredLabel();
+            }
+            secretKey.setModelObject(null);
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.removeRequiredLabel();
+            }
+            cipherAlgorithm.setModelObject(null);
+
+            binaryParams.setVisible(true);
+        } else {
+            conversionParams.setVisible(false);
+            conversionPattern.setModelObject(null);
+
+            enumParams.setVisible(false);
+            if (enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.removeRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(null));
+            enumerationKeys.setModelObject(getEnumValuesAsList(null));
+
+            encryptedParams.setVisible(false);
+            if (secretKey.isRequired()) {
+                secretKey.removeRequiredLabel();
+            }
+            secretKey.setModelObject(null);
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.removeRequiredLabel();
+            }
+            cipherAlgorithm.setModelObject(null);
+
+            binaryParams.setVisible(false);
+            mimeType.setModelObject(null);
+        }
+    }
+
+    private String getEnumValuesAsString(final List<String> enumerationValues) 
{
+        final StringBuilder builder = new StringBuilder();
+
+        for (String str : enumerationValues) {
+            if (StringUtils.isNotBlank(str)) {
+                if (builder.length() > 0) {
+                    builder.append(SyncopeConstants.ENUM_VALUES_SEPARATOR);
+                }
+
+                builder.append(str.trim());
+            }
+        }
+
+        return builder.toString();
+    }
+
+    private List<String> getEnumValuesAsList(final String enumerationValues) {
+        final List<String> values = new ArrayList<String>();
+
+        if (StringUtils.isNotBlank(enumerationValues)) {
+            for (String value : 
enumerationValues.split(SyncopeConstants.ENUM_VALUES_SEPARATOR)) {
+                values.add(value.trim());
+            }
+        } else {
+            values.add(StringUtils.EMPTY);
+        }
+
+        return values;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PolicyModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PolicyModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PolicyModalPage.java
new file mode 100644
index 0000000..ead376a
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PolicyModalPage.java
@@ -0,0 +1,450 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.NotificationPanel;
+import org.apache.syncope.client.console.panels.PolicyBeanPanel;
+import org.apache.syncope.client.console.rest.PolicyRestClient;
+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.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.AccountPolicyTO;
+import org.apache.syncope.common.lib.to.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.SyncPolicyTO;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.common.lib.types.PolicySpec;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import 
org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import 
org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+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.basic.Label;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Fragment;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
+import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+/**
+ * Modal window with Resource form.
+ */
+public class PolicyModalPage<T extends AbstractPolicyTO<?>> extends 
BaseModalPage {
+
+    private static final long serialVersionUID = -7325772767481076679L;
+
+    private static final int WIN_HEIGHT = 600;
+
+    private static final int WIN_WIDTH = 1100;
+
+    @SpringBean
+    private PolicyRestClient policyRestClient;
+
+    public PolicyModalPage(final PageReference pageRef, final ModalWindow 
window, final T policyTO) {
+        super();
+
+        final Form<?> form = new Form<>(FORM);
+        form.setOutputMarkupId(true);
+        add(form);
+
+        final AjaxTextFieldPanel policyid =
+                new AjaxTextFieldPanel("key", "key", new 
PropertyModel<String>(policyTO, "key"));
+        policyid.setEnabled(false);
+        policyid.setStyleSheet("ui-widget-content ui-corner-all 
short_fixedsize");
+        form.add(policyid);
+
+        final AjaxTextFieldPanel description = new 
AjaxTextFieldPanel("description", "description",
+                new PropertyModel<String>(policyTO, "description"));
+        description.addRequiredLabel();
+        description.setStyleSheet("ui-widget-content ui-corner-all 
medium_dynamicsize");
+        form.add(description);
+
+        final AjaxDropDownChoicePanel<PolicyType> type =
+                new AjaxDropDownChoicePanel<>("type", "type", new 
PropertyModel<PolicyType>(policyTO, "type"));
+        switch (policyTO.getType()) {
+            case GLOBAL_ACCOUNT:
+            case ACCOUNT:
+                type.setChoices(Arrays.asList(new PolicyType[] { 
PolicyType.GLOBAL_ACCOUNT, PolicyType.ACCOUNT }));
+                break;
+
+            case GLOBAL_PASSWORD:
+            case PASSWORD:
+                type.setChoices(Arrays.asList(new PolicyType[] { 
PolicyType.GLOBAL_PASSWORD, PolicyType.PASSWORD }));
+                break;
+
+            case GLOBAL_SYNC:
+            case SYNC:
+                type.setChoices(Arrays.asList(new PolicyType[] { 
PolicyType.GLOBAL_SYNC, PolicyType.SYNC }));
+
+            default:
+        }
+        type.setChoiceRenderer(new PolicyTypeRenderer());
+        type.addRequiredLabel();
+        form.add(type);
+
+        // Authentication resources - only for AccountPolicyTO
+        Fragment fragment;
+        if (policyTO instanceof AccountPolicyTO) {
+            fragment = new Fragment("forAccountOnly", "authResourcesFragment", 
form);
+
+            final List<String> resourceNames = new ArrayList<>();
+            for (ResourceTO resource : resourceRestClient.getAll()) {
+                resourceNames.add(resource.getKey());
+            }
+            fragment.add(new AjaxPalettePanel<>("authResources",
+                    new PropertyModel<List<String>>(policyTO, "resources"),
+                    new ListModel<>(resourceNames)));
+        } else {
+            fragment = new Fragment("forAccountOnly", "emptyFragment", form);
+        }
+        form.add(fragment);
+        //
+
+        final PolicySpec policy = getPolicySpecification(policyTO);
+
+        form.add(new PolicyBeanPanel("panel", policy));
+
+        final ModalWindow mwindow = new ModalWindow("metaEditModalWin");
+        mwindow.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        mwindow.setInitialHeight(WIN_HEIGHT);
+        mwindow.setInitialWidth(WIN_WIDTH);
+        mwindow.setCookieName("meta-edit-modal");
+        add(mwindow);
+
+        List<IColumn<String, String>> resColumns = new ArrayList<>();
+        resColumns.add(new AbstractColumn<String, String>(new 
StringResourceModel("name", this, null, "")) {
+
+            private static final long serialVersionUID = 2054811145491901166L;
+
+            @Override
+            public void populateItem(final Item<ICellPopulator<String>> 
cellItem,
+                    final String componentId, final IModel<String> rowModel) {
+
+                cellItem.add(new Label(componentId, rowModel.getObject()));
+            }
+        });
+        resColumns.add(new AbstractColumn<String, 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<String>> 
cellItem, final String componentId,
+                    final IModel<String> model) {
+
+                final String resource = model.getObject();
+
+                final ActionLinksPanel panel = new 
ActionLinksPanel(componentId, model, getPageReference());
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        mwindow.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = 
-7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new 
ResourceModalPage(PolicyModalPage.this.getPageReference(),
+                                        mwindow, 
resourceRestClient.read(resource), false);
+                            }
+                        });
+
+                        mwindow.show(target);
+                    }
+                }, ActionLink.ActionType.EDIT, "Resources");
+
+                cellItem.add(panel);
+            }
+        });
+        ISortableDataProvider<String, String> resDataProvider = new 
SortableDataProvider<String, String>() {
+
+            private static final long serialVersionUID = 8263758912838836438L;
+
+            @Override
+            public Iterator<? extends String> iterator(final long first, final 
long count) {
+                return policyTO.getKey() == 0
+                        ? Collections.<String>emptyList().iterator()
+                        : policyRestClient.getPolicy(policyTO.getKey()).
+                        getUsedByResources().subList((int) first, (int) first 
+ (int) count).iterator();
+            }
+
+            @Override
+            public long size() {
+                return policyTO.getKey() == 0
+                        ? 0
+                        : policyRestClient.getPolicy(policyTO.getKey()).
+                        getUsedByResources().size();
+            }
+
+            @Override
+            public IModel<String> model(final String object) {
+                return new Model<>(object);
+            }
+        };
+        final AjaxFallbackDefaultDataTable<String, String> resources =
+                new AjaxFallbackDefaultDataTable<>("resources", resColumns, 
resDataProvider, 10);
+        form.add(resources);
+
+        List<IColumn<GroupTO, String>> groupColumns = new ArrayList<>();
+        groupColumns.add(new PropertyColumn<GroupTO, String>(new 
ResourceModel("key", "key"), "key", "key"));
+        groupColumns.add(new PropertyColumn<GroupTO, String>(new 
ResourceModel("name", "name"), "name", "name"));
+        groupColumns.add(new AbstractColumn<GroupTO, 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<GroupTO>> 
cellItem, final String componentId,
+                    final IModel<GroupTO> model) {
+
+                final GroupTO group = model.getObject();
+
+                final ActionLinksPanel panel = new 
ActionLinksPanel(componentId, model, getPageReference());
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        mwindow.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = 
-7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new 
GroupModalPage(PolicyModalPage.this.getPageReference(), mwindow, group);
+                            }
+                        });
+
+                        mwindow.show(target);
+                    }
+                }, ActionLink.ActionType.EDIT, "Groups");
+
+                cellItem.add(panel);
+            }
+        });
+        ISortableDataProvider<GroupTO, String> groupDataProvider = new 
SortableDataProvider<GroupTO, String>() {
+
+            private static final long serialVersionUID = 8263758912838836438L;
+
+            @Override
+            public Iterator<? extends GroupTO> iterator(final long first, 
final long count) {
+                List<GroupTO> groups = new ArrayList<>();
+
+                if (policyTO.getKey() > 0) {
+                    for (Long groupId : 
policyRestClient.getPolicy(policyTO.getKey()).getUsedByGroups().
+                            subList((int) first, (int) first + (int) count)) {
+
+                        groups.add(groupRestClient.read(groupId));
+                    }
+                }
+
+                return groups.iterator();
+            }
+
+            @Override
+            public long size() {
+                return policyTO.getKey() == 0
+                        ? 0
+                        : 
policyRestClient.getPolicy(policyTO.getKey()).getUsedByGroups().size();
+            }
+
+            @Override
+            public IModel<GroupTO> model(final GroupTO object) {
+                return new Model<>(object);
+            }
+        };
+        final AjaxFallbackDefaultDataTable<GroupTO, String> groups =
+                new AjaxFallbackDefaultDataTable<>("groups", groupColumns, 
groupDataProvider, 10);
+        form.add(groups);
+
+        mwindow.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() 
{
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                target.add(resources);
+                target.add(groups);
+                if (isModalResult()) {
+                    info(getString(Constants.OPERATION_SUCCEEDED));
+                    feedbackPanel.refresh(target);
+                    setModalResult(false);
+                }
+            }
+        });
+
+        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new 
ResourceModel(APPLY)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
+                setPolicySpecification(policyTO, policy);
+
+                try {
+                    if (policyTO.getKey() > 0) {
+                        policyRestClient.updatePolicy(policyTO);
+                    } else {
+                        policyRestClient.createPolicy(policyTO);
+                    }
+                    ((BasePage) pageRef.getPage()).setModalResult(true);
+
+                    window.close(target);
+                } catch (Exception e) {
+                    LOG.error("While creating policy", e);
+
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    ((NotificationPanel) 
getPage().get(Constants.FEEDBACK)).refresh(target);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
+                ((NotificationPanel) 
getPage().get(Constants.FEEDBACK)).refresh(target);
+            }
+        };
+        form.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);
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
+            }
+        };
+        cancel.setDefaultFormProcessing(false);
+        form.add(cancel);
+    }
+
+    private PolicySpec getPolicySpecification(final AbstractPolicyTO policyTO) 
{
+        PolicySpec spec;
+
+        switch (policyTO.getType()) {
+            case GLOBAL_ACCOUNT:
+            case ACCOUNT:
+                spec = ((AccountPolicyTO) policyTO).getSpecification() != null
+                        ? ((AccountPolicyTO) policyTO).getSpecification()
+                        : new AccountPolicySpec();
+                break;
+
+            case GLOBAL_PASSWORD:
+            case PASSWORD:
+                spec = ((PasswordPolicyTO) policyTO).getSpecification() != null
+                        ? ((PasswordPolicyTO) policyTO).getSpecification()
+                        : new PasswordPolicySpec();
+                break;
+
+            case GLOBAL_SYNC:
+            case SYNC:
+            default:
+                spec = ((SyncPolicyTO) policyTO).getSpecification() != null
+                        ? ((SyncPolicyTO) policyTO).getSpecification()
+                        : new SyncPolicySpec();
+        }
+
+        return spec;
+    }
+
+    private void setPolicySpecification(final AbstractPolicyTO policyTO, final 
PolicySpec specification) {
+        switch (policyTO.getType()) {
+            case GLOBAL_ACCOUNT:
+            case ACCOUNT:
+                if (!(specification instanceof AccountPolicySpec)) {
+                    throw new ClassCastException("policy is type Account, but 
spec is not: "
+                            + specification.getClass().getName());
+                }
+                ((AccountPolicyTO) 
policyTO).setSpecification((AccountPolicySpec) specification);
+                break;
+
+            case GLOBAL_PASSWORD:
+            case PASSWORD:
+                if (!(specification instanceof PasswordPolicySpec)) {
+                    throw new ClassCastException("policy is type Password, but 
spec is not: "
+                            + specification.getClass().getName());
+                }
+                ((PasswordPolicyTO) 
policyTO).setSpecification((PasswordPolicySpec) specification);
+                break;
+
+            case GLOBAL_SYNC:
+            case SYNC:
+                if (!(specification instanceof SyncPolicySpec)) {
+                    throw new ClassCastException("policy is type Sync, but 
spec is not: "
+                            + specification.getClass().getName());
+                }
+                ((SyncPolicyTO) policyTO).setSpecification((SyncPolicySpec) 
specification);
+
+            default:
+        }
+    }
+
+    private class PolicyTypeRenderer extends ChoiceRenderer<PolicyType> {
+
+        private static final long serialVersionUID = -8993265421104002134L;
+
+        @Override
+        public Object getDisplayValue(final PolicyType object) {
+            return getString(object.name());
+        }
+    };
+}

Reply via email to