You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2018/09/25 12:32:14 UTC

[16/34] syncope git commit: [SYNCOPE-1369] Flowable support refactored as extension + code review (now with variable cleanup)

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
deleted file mode 100644
index 24f0e59..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
+++ /dev/null
@@ -1,358 +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.approvals;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.DirectoryDataProvider;
-import org.apache.syncope.client.console.panels.DirectoryPanel;
-import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
-import org.apache.syncope.client.console.approvals.ApprovalDirectoryPanel.ApprovalProvider;
-import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
-import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.rest.AnyTypeRestClient;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
-import org.apache.syncope.client.console.wizards.AjaxWizard;
-import org.apache.syncope.client.console.wizards.any.AnyWrapper;
-import org.apache.syncope.client.console.wizards.any.UserWizardBuilder;
-import org.apache.syncope.common.lib.AnyOperations;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.event.Broadcast;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.ResourceModel;
-
-public class ApprovalDirectoryPanel
-        extends DirectoryPanel<WorkflowFormTO, WorkflowFormTO, ApprovalProvider, UserWorkflowRestClient> {
-
-    private static final long serialVersionUID = -7122136682275797903L;
-
-    protected final BaseModal<WorkflowFormTO> manageApprovalModal = new BaseModal<WorkflowFormTO>("outer") {
-
-        private static final long serialVersionUID = 389935548143327858L;
-
-        @Override
-        protected void onConfigure() {
-            super.onConfigure();
-            addSubmitButton();
-            size(Modal.Size.Large);
-        }
-
-    };
-
-    public ApprovalDirectoryPanel(final String id, final PageReference pageReference) {
-        super(id, pageReference, true);
-        disableCheckBoxes();
-        setFooterVisibility(false);
-        modal.size(Modal.Size.Large);
-
-        addOuterObject(manageApprovalModal);
-
-        manageApprovalModal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
-
-            private static final long serialVersionUID = 8804221891699487139L;
-
-            @Override
-            public void onClose(final AjaxRequestTarget target) {
-                updateResultTable(target);
-                ((BasePage) pageReference.getPage()).getApprovalsWidget().refreshLatestAlerts(target);
-                manageApprovalModal.show(false);
-            }
-        });
-
-        restClient = new UserWorkflowRestClient();
-
-        initResultTable();
-
-        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, StandardEntitlement.WORKFLOW_FORM_SUBMIT);
-    }
-
-    @Override
-    protected List<IColumn<WorkflowFormTO, String>> getColumns() {
-        List<IColumn<WorkflowFormTO, String>> columns = new ArrayList<>();
-
-        columns.add(new PropertyColumn<>(
-                new ResourceModel("taskId"), "taskId", "taskId"));
-        columns.add(new PropertyColumn<>(
-                new ResourceModel("key"), "key"));
-        columns.add(new PropertyColumn<>(
-                new ResourceModel("username"), "username"));
-        columns.add(new DatePropertyColumn<>(
-                new ResourceModel("createTime"), "createTime", "createTime"));
-        columns.add(new DatePropertyColumn<>(
-                new ResourceModel("dueDate"), "dueDate", "dueDate"));
-        columns.add(new PropertyColumn<>(
-                new ResourceModel("owner"), "owner", "owner"));
-
-        return columns;
-    }
-
-    @Override
-    public ActionsPanel<WorkflowFormTO> getActions(final IModel<WorkflowFormTO> model) {
-        final ActionsPanel<WorkflowFormTO> panel = super.getActions(model);
-
-        panel.add(new ActionLink<WorkflowFormTO>() {
-
-            private static final long serialVersionUID = -3722207913631435501L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
-                claimForm(model.getObject().getTaskId());
-                SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                target.add(container);
-            }
-        }, ActionLink.ActionType.CLAIM, StandardEntitlement.WORKFLOW_FORM_CLAIM);
-
-        panel.add(new ActionLink<WorkflowFormTO>() {
-
-            private static final long serialVersionUID = -3722207913631435501L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
-                manageApprovalModal.setFormModel(new CompoundPropertyModel<>(model.getObject()));
-
-                target.add(manageApprovalModal.setContent(
-                        new ApprovalModal(manageApprovalModal, pageRef, model.getObject()) {
-
-                    private static final long serialVersionUID = 5546519445061007248L;
-
-                    @Override
-                    public void onSubmit(final AjaxRequestTarget target) {
-                        try {
-                            super.onSubmit(target);
-
-                            ApprovalDirectoryPanel.this.getTogglePanel().close(target);
-                        } catch (SyncopeClientException e) {
-                            SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + e.getMessage());
-                        }
-                        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                    }
-
-                }));
-
-                manageApprovalModal.header(new Model<>(getString("approval.manage", new Model<>(model.getObject()))));
-                manageApprovalModal.show(true);
-            }
-
-            @Override
-            protected boolean statusCondition(final WorkflowFormTO modelObject) {
-                return SyncopeConsoleSession.get().getSelfTO().getUsername().
-                        equals(model.getObject().getOwner());
-            }
-
-        }, ActionLink.ActionType.MANAGE_APPROVAL, StandardEntitlement.WORKFLOW_FORM_READ);
-
-        // SYNCOPE-1200 edit user while in approval state
-        panel.add(new ActionLink<WorkflowFormTO>() {
-
-            private static final long serialVersionUID = -3722207913631435501L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
-                modal.setFormModel(new CompoundPropertyModel<>(model.getObject()));
-
-                WorkflowFormTO formTO = model.getObject();
-                UserTO newUserTO;
-                UserTO previousUserTO;
-                if (formTO.getUserPatch() == null) {
-                    newUserTO = formTO.getUserTO();
-                    previousUserTO = null;
-                } else if (formTO.getUserTO() == null) {
-                    // make it stronger by handling possible NPE
-                    previousUserTO = new UserTO();
-                    previousUserTO.setKey(formTO.getUserPatch().getKey());
-                    newUserTO = AnyOperations.patch(previousUserTO, formTO.getUserPatch());
-                } else {
-                    previousUserTO = formTO.getUserTO();
-                    formTO.getUserTO().setKey(formTO.getUserPatch().getKey());
-                    formTO.getUserTO().setPassword(null);
-                    newUserTO = AnyOperations.patch(formTO.getUserTO(), formTO.getUserPatch());
-                }
-
-                AjaxWizard.EditItemActionEvent<UserTO> editItemActionEvent =
-                        new AjaxWizard.EditItemActionEvent<>(newUserTO, target);
-                editItemActionEvent.forceModalPanel(new ApprovalUserWizardBuilder(
-                        model.getObject(),
-                        previousUserTO,
-                        newUserTO,
-                        new AnyTypeRestClient().read(AnyTypeKind.USER.name()).getClasses(),
-                        FormLayoutInfoUtils.fetch(Collections.singletonList(AnyTypeKind.USER.name())).getLeft(),
-                        pageRef
-                ).build(BaseModal.CONTENT_ID, AjaxWizard.Mode.EDIT));
-
-                send(ApprovalDirectoryPanel.this, Broadcast.EXACT, editItemActionEvent);
-            }
-
-            @Override
-            protected boolean statusCondition(final WorkflowFormTO modelObject) {
-                return SyncopeConsoleSession.get().getSelfTO().getUsername().
-                        equals(model.getObject().getOwner());
-            }
-
-        }, ActionLink.ActionType.EDIT_APPROVAL, StandardEntitlement.WORKFLOW_FORM_SUBMIT);
-
-        return panel;
-    }
-
-    @Override
-    protected ApprovalProvider dataProvider() {
-        return new ApprovalProvider(rows);
-    }
-
-    @Override
-    protected String paginatorRowsKey() {
-        return Constants.PREF_WORKFLOW_FORM_PAGINATOR_ROWS;
-    }
-
-    public static class ApprovalProvider extends DirectoryDataProvider<WorkflowFormTO> {
-
-        private static final long serialVersionUID = -2311716167583335852L;
-
-        private final UserWorkflowRestClient restClient = new UserWorkflowRestClient();
-
-        public ApprovalProvider(final int paginatorRows) {
-            super(paginatorRows);
-
-            setSort("createTime", SortOrder.ASCENDING);
-        }
-
-        @Override
-        public Iterator<WorkflowFormTO> iterator(final long first, final long count) {
-            int page = ((int) first / paginatorRows);
-            return restClient.getForms((page < 0 ? 0 : page) + 1, paginatorRows, getSort()).iterator();
-        }
-
-        @Override
-        public long size() {
-            return restClient.countForms();
-        }
-
-        @Override
-        public IModel<WorkflowFormTO> model(final WorkflowFormTO form) {
-            return new IModel<WorkflowFormTO>() {
-
-                private static final long serialVersionUID = -2566070996511906708L;
-
-                @Override
-                public WorkflowFormTO getObject() {
-                    return form;
-                }
-            };
-        }
-    }
-
-    @Override
-    protected Collection<ActionLink.ActionType> getBatches() {
-        return Collections.<ActionLink.ActionType>emptyList();
-    }
-
-    private void claimForm(final String taskId) {
-        try {
-            restClient.claimForm(taskId);
-        } catch (SyncopeClientException scee) {
-            SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + scee.getMessage());
-        }
-    }
-
-    private class ApprovalUserWizardBuilder extends UserWizardBuilder {
-
-        private static final long serialVersionUID = 1854981134836384069L;
-
-        private final WorkflowFormTO formTO;
-
-        ApprovalUserWizardBuilder(
-                final WorkflowFormTO formTO,
-                final UserTO previousUserTO,
-                final UserTO userTO,
-                final List<String> anyTypeClasses,
-                final UserFormLayoutInfo formLayoutInfo,
-                final PageReference pageRef) {
-
-            super(previousUserTO, userTO, anyTypeClasses, formLayoutInfo, pageRef);
-            this.formTO = formTO;
-        }
-
-        @Override
-        protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
-            UserTO inner = modelObject.getInnerObject();
-
-            ProvisioningResult<UserTO> result;
-
-            if (formTO.getUserPatch() == null) {
-                result = new ProvisioningResult<>();
-                UserTO user = new UserWorkflowRestClient().executeTask("default", inner);
-                result.setEntity(user);
-                claimForm(restClient.getFormForUser(result.getEntity().getKey()).getTaskId());
-            } else {
-                UserPatch patch = AnyOperations.diff(inner, formTO.getUserTO(), false);
-
-                if (StringUtils.isNotBlank(inner.getPassword())) {
-                    PasswordPatch passwordPatch = new PasswordPatch.Builder().
-                            value(inner.getPassword()).onSyncope(true).resources(inner.
-                            getResources()).
-                            build();
-                    patch.setPassword(passwordPatch);
-                }
-                // update just if it is changed
-                if (patch.isEmpty()) {
-                    result = new ProvisioningResult<>();
-                    result.setEntity(inner);
-                } else {
-                    result = userRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
-                    WorkflowFormTO workFlowTO = restClient.getFormForUser(result.getEntity().getKey());
-                    if (workFlowTO != null) {
-                        claimForm(workFlowTO.getTaskId());
-                    }
-                }
-
-            }
-
-            return result;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java
deleted file mode 100644
index 1b1ce48..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java
+++ /dev/null
@@ -1,82 +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.approvals;
-
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.syncope.client.console.panels.SubmitableModalPanel;
-import org.apache.syncope.client.console.panels.WizardModalPanel;
-
-public class ApprovalModal extends Panel implements SubmitableModalPanel, WizardModalPanel<WorkflowFormTO> {
-
-    private static final long serialVersionUID = -8847854414429745216L;
-
-    private final UserWorkflowRestClient restClient = new UserWorkflowRestClient();
-
-    private final BaseModal<?> modal;
-
-    private final WorkflowFormTO formTO;
-
-    private final PageReference pageRef;
-
-    public ApprovalModal(final BaseModal<?> modal, final PageReference pageRef, final WorkflowFormTO formTO) {
-        super(BaseModal.CONTENT_ID);
-        this.modal = modal;
-        this.formTO = formTO;
-        this.pageRef = pageRef;
-
-        MultilevelPanel mlp = new MultilevelPanel("approval");
-        mlp.setFirstLevel(new Approval(pageRef, formTO) {
-
-            private static final long serialVersionUID = -2195387360323687302L;
-
-            @Override
-            protected void viewDetails(final AjaxRequestTarget target) {
-                mlp.next(getString("approval.details"), new ApprovalDetails(pageRef, formTO), target);
-            }
-        });
-        add(mlp);
-    }
-
-    @Override
-    public void onSubmit(final AjaxRequestTarget target) {
-        this.restClient.submitForm(formTO);
-        this.modal.show(false);
-        this.modal.close(target);
-        SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-    }
-
-    @Override
-    public void onError(final AjaxRequestTarget target) {
-        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-    }
-
-    @Override
-    public WorkflowFormTO getItem() {
-        return this.formTO;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
index 2bfd9ed..48b58137 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
@@ -37,8 +37,6 @@ public final class Constants {
 
     public static final String VEIL_INDICATOR_MARKUP_ID = "veil";
 
-    public static final String FLOWABLE_MODELER_CONTEXT = "flowable-modeler";
-
     public static final String MODELER_CONTEXT = "modelerContext";
 
     public static final String MODEL_ID_PARAM = "modelId";

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java b/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
index 876d299..edb7b61 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
@@ -34,10 +34,12 @@ import org.apache.syncope.client.console.pages.BaseExtPage;
 import org.apache.syncope.client.console.annotations.BinaryPreview;
 import org.apache.syncope.client.console.annotations.ExtPage;
 import org.apache.syncope.client.console.annotations.ExtWidget;
+import org.apache.syncope.client.console.annotations.Resource;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.SSOLoginFormPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.preview.AbstractBinaryPreviewer;
 import org.apache.syncope.client.console.widgets.BaseExtWidget;
+import org.apache.syncope.client.console.widgets.ExtAlertWidget;
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
 import org.apache.syncope.common.lib.policy.PasswordRuleConf;
 import org.apache.syncope.common.lib.policy.PullCorrelationRuleConf;
@@ -46,6 +48,7 @@ import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.request.resource.AbstractResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
@@ -93,6 +96,8 @@ public class ClassPathScanImplementationLookup {
 
     private List<Class<? extends BaseExtWidget>> extWidgets;
 
+    private List<Class<? extends ExtAlertWidget<?>>> extAlertWidgets;
+
     private List<Class<? extends SSOLoginFormPanel>> ssoLoginFormPanels;
 
     private Map<String, Class<? extends ReportletConf>> reportletConfs;
@@ -105,6 +110,8 @@ public class ClassPathScanImplementationLookup {
 
     private Map<String, Class<? extends PushCorrelationRuleConf>> pushCorrelationRuleConfs;
 
+    private List<Class<? extends AbstractResource>> resources;
+
     /**
      * This method can be overridden by subclasses to customize classpath scan.
      *
@@ -120,24 +127,28 @@ public class ClassPathScanImplementationLookup {
         previewers = new ArrayList<>();
         extPages = new ArrayList<>();
         extWidgets = new ArrayList<>();
+        extAlertWidgets = new ArrayList<>();
         ssoLoginFormPanels = new ArrayList<>();
         reportletConfs = new HashMap<>();
         accountRuleConfs = new HashMap<>();
         passwordRuleConfs = new HashMap<>();
         pullCorrelationRuleConfs = new HashMap<>();
         pushCorrelationRuleConfs = new HashMap<>();
+        resources = new ArrayList<>();
 
         ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
         scanner.addIncludeFilter(new AssignableTypeFilter(BasePage.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(AbstractBinaryPreviewer.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(BaseExtPage.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(BaseExtWidget.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(ExtAlertWidget.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SSOLoginFormPanel.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(ReportletConf.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(AccountRuleConf.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PasswordRuleConf.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PullCorrelationRuleConf.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PushCorrelationRuleConf.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(AbstractResource.class));
 
         scanner.findCandidateComponents(getBasePackage()).forEach(bd -> {
             try {
@@ -160,6 +171,13 @@ public class ClassPathScanImplementationLookup {
                             LOG.error("Could not find annotation {} in {}, ignoring",
                                     ExtWidget.class.getName(), clazz.getName());
                         }
+                    } else if (ExtAlertWidget.class.isAssignableFrom(clazz)) {
+                        if (clazz.isAnnotationPresent(ExtWidget.class)) {
+                            extAlertWidgets.add((Class<? extends ExtAlertWidget<?>>) clazz);
+                        } else {
+                            LOG.error("Could not find annotation {} in {}, ignoring",
+                                    ExtWidget.class.getName(), clazz.getName());
+                        }
                     } else if (BasePage.class.isAssignableFrom(clazz)) {
                         pages.add((Class<? extends BasePage>) clazz);
                     } else if (AbstractBinaryPreviewer.class.isAssignableFrom(clazz)) {
@@ -176,6 +194,13 @@ public class ClassPathScanImplementationLookup {
                         pullCorrelationRuleConfs.put(clazz.getName(), (Class<? extends PullCorrelationRuleConf>) clazz);
                     } else if (PushCorrelationRuleConf.class.isAssignableFrom(clazz)) {
                         pushCorrelationRuleConfs.put(clazz.getName(), (Class<? extends PushCorrelationRuleConf>) clazz);
+                    } else if (AbstractResource.class.isAssignableFrom(clazz)) {
+                        if (clazz.isAnnotationPresent(Resource.class)) {
+                            resources.add((Class<? extends AbstractResource>) clazz);
+                        } else {
+                            LOG.error("Could not find annotation {} in {}, ignoring",
+                                    Resource.class.getName(), clazz.getName());
+                        }
                     }
                 }
             } catch (Throwable t) {
@@ -185,18 +210,21 @@ public class ClassPathScanImplementationLookup {
         pages = Collections.unmodifiableList(pages);
         previewers = Collections.unmodifiableList(previewers);
 
-        Collections.sort(extPages, (o1, o2)
-                -> ObjectUtils.compare(
-                        o1.getAnnotation(ExtPage.class).priority(),
-                        o2.getAnnotation(ExtPage.class).priority()));
+        extPages.sort((o1, o2) -> ObjectUtils.compare(
+                o1.getAnnotation(ExtPage.class).priority(),
+                o2.getAnnotation(ExtPage.class).priority()));
         extPages = Collections.unmodifiableList(extPages);
 
-        Collections.sort(extWidgets, (o1, o2)
-                -> ObjectUtils.compare(
-                        o1.getAnnotation(ExtWidget.class).priority(),
-                        o2.getAnnotation(ExtWidget.class).priority()));
+        extWidgets.sort((o1, o2) -> ObjectUtils.compare(
+                o1.getAnnotation(ExtWidget.class).priority(),
+                o2.getAnnotation(ExtWidget.class).priority()));
         extWidgets = Collections.unmodifiableList(extWidgets);
 
+        extAlertWidgets.sort((o1, o2) -> ObjectUtils.compare(
+                o1.getAnnotation(ExtWidget.class).priority(),
+                o2.getAnnotation(ExtWidget.class).priority()));
+        extAlertWidgets = Collections.unmodifiableList(extAlertWidgets);
+
         ssoLoginFormPanels = Collections.unmodifiableList(ssoLoginFormPanels);
 
         reportletConfs = Collections.unmodifiableMap(reportletConfs);
@@ -205,15 +233,19 @@ public class ClassPathScanImplementationLookup {
         pullCorrelationRuleConfs = Collections.unmodifiableMap(pullCorrelationRuleConfs);
         pushCorrelationRuleConfs = Collections.unmodifiableMap(pushCorrelationRuleConfs);
 
+        resources = Collections.unmodifiableList(resources);
+
         LOG.debug("Binary previewers found: {}", previewers);
         LOG.debug("Extension pages found: {}", extPages);
         LOG.debug("Extension widgets found: {}", extWidgets);
+        LOG.debug("Extension alert widgets found: {}", extAlertWidgets);
         LOG.debug("SSO Login pages found: {}", ssoLoginFormPanels);
         LOG.debug("Reportlet configurations found: {}", reportletConfs);
         LOG.debug("Account Rule configurations found: {}", accountRuleConfs);
         LOG.debug("Password Rule configurations found: {}", passwordRuleConfs);
         LOG.debug("Pull Correlation Rule configurations found: {}", pullCorrelationRuleConfs);
         LOG.debug("Push Correlation Rule configurations found: {}", pushCorrelationRuleConfs);
+        LOG.debug("Resources found: {}", resources);
     }
 
     public Class<? extends AbstractBinaryPreviewer> getPreviewerClass(final String mimeType) {
@@ -242,6 +274,10 @@ public class ClassPathScanImplementationLookup {
         return extWidgets;
     }
 
+    public List<Class<? extends ExtAlertWidget<?>>> getExtAlertWidgetClasses() {
+        return extAlertWidgets;
+    }
+
     public List<Class<? extends SSOLoginFormPanel>> getSSOLoginFormPanels() {
         return ssoLoginFormPanels;
     }
@@ -265,4 +301,8 @@ public class ClassPathScanImplementationLookup {
     public Map<String, Class<? extends PushCorrelationRuleConf>> getPushCorrelationRuleConfs() {
         return pushCorrelationRuleConfs;
     }
+
+    public List<Class<? extends AbstractResource>> getResources() {
+        return resources;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
deleted file mode 100644
index 0dbc4db..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
+++ /dev/null
@@ -1,41 +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.syncope.client.console.BookmarkablePageLinkBuilder;
-import org.apache.syncope.client.console.approvals.ApprovalDirectoryPanel;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-
-public class Approvals extends BasePage {
-
-    private static final long serialVersionUID = -1100228004207271271L;
-
-    public Approvals(final PageParameters parameters) {
-        super(parameters);
-
-        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
-
-        WebMarkupContainer content = new WebMarkupContainer("content");
-        content.setOutputMarkupId(true);
-        body.add(content);
-
-        content.add(new ApprovalDirectoryPanel("wfPanel", getPageReference()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index d79cec7..a4ef3f0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.pages;
 
 import java.io.Serializable;
+import java.lang.reflect.Constructor;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
@@ -34,7 +35,7 @@ import org.apache.syncope.client.console.rest.ConfRestClient;
 import org.apache.syncope.client.console.topology.Topology;
 import org.apache.syncope.client.console.wicket.markup.head.MetaHeaderItem;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.widgets.ApprovalsWidget;
+import org.apache.syncope.client.console.widgets.ExtAlertWidget;
 import org.apache.syncope.client.console.widgets.RemediationsWidget;
 import org.apache.syncope.common.lib.info.PlatformInfo;
 import org.apache.syncope.common.lib.info.SystemInfo;
@@ -42,6 +43,7 @@ import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.AttributeModifier;
 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.IAjaxIndicatorAware;
 import org.apache.wicket.ajax.attributes.AjaxCallListener;
@@ -81,8 +83,6 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
 
     protected NotificationPanel notificationPanel;
 
-    protected ApprovalsWidget approvalsWidget;
-
     protected RemediationsWidget remediationWidget;
 
     public BasePage() {
@@ -108,9 +108,6 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
         remediationWidget = new RemediationsWidget("remediationWidget", getPageReference());
         body.add(remediationWidget.setRenderBodyOnly(true));
 
-        approvalsWidget = new ApprovalsWidget("approvalsWidget", getPageReference());
-        body.add(approvalsWidget.setRenderBodyOnly(true));
-
         // right sidebar
         PlatformInfo platformInfo = SyncopeConsoleSession.get().getPlatformInfo();
         Label version = new Label("version", platformInfo.getVersion());
@@ -187,14 +184,6 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
         WebMarkupContainer confULContainer = new WebMarkupContainer(getULContainerId("configuration"));
         confLIContainer.add(confULContainer);
 
-        liContainer = new WebMarkupContainer(getLIContainerId("workflow"));
-        liContainer.setOutputMarkupPlaceholderTag(true);
-        liContainer.setVisible(platformInfo.getUserWorkflowAdapter().contains("Flowable"));
-        confULContainer.add(liContainer);
-        link = BookmarkablePageLinkBuilder.build("workflow", Workflow.class);
-        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.RENDER, StandardEntitlement.WORKFLOW_DEF_GET);
-        liContainer.add(link);
-
         liContainer = new WebMarkupContainer(getLIContainerId("audit"));
         confULContainer.add(liContainer);
         link = BookmarkablePageLinkBuilder.build("audit", Audit.class);
@@ -331,10 +320,33 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
         }
 
         // Extensions
-        ClassPathScanImplementationLookup classPathScanImplementationLookup =
-                (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
-                        getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
-        List<Class<? extends BaseExtPage>> extPageClasses = classPathScanImplementationLookup.getExtPageClasses();
+        ClassPathScanImplementationLookup lookup = (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
+                getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
+
+        List<Class<? extends ExtAlertWidget<?>>> extAlertWidgetClasses = lookup.getExtAlertWidgetClasses();
+        ListView<Class<? extends ExtAlertWidget<?>>> extAlertWidgets = new ListView<Class<? extends ExtAlertWidget<?>>>(
+                "extAlertWidgets", extAlertWidgetClasses) {
+
+            private static final long serialVersionUID = -9112553137618363167L;
+
+            @Override
+            protected void populateItem(final ListItem<Class<? extends ExtAlertWidget<?>>> item) {
+                try {
+                    Constructor<? extends ExtAlertWidget<?>> constructor =
+                            item.getModelObject().getDeclaredConstructor(String.class, PageReference.class);
+                    ExtAlertWidget<?> widget = constructor.newInstance("extAlertWidget", getPageReference());
+
+                    SyncopeConsoleSession.get().setAttribute(widget.getClass().getName(), widget);
+
+                    item.add(widget.setRenderBodyOnly(true));
+                } catch (Exception e) {
+                    LOG.error("Could not instantiate {}", item.getModelObject().getName(), e);
+                }
+            }
+        };
+        body.add(extAlertWidgets);
+
+        List<Class<? extends BaseExtPage>> extPageClasses = lookup.getExtPageClasses();
 
         WebMarkupContainer extensionsLI = new WebMarkupContainer(getLIContainerId("extensions"));
         extensionsLI.setOutputMarkupPlaceholderTag(true);
@@ -431,10 +443,6 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
         return remediationWidget;
     }
 
-    public ApprovalsWidget getApprovalsWidget() {
-        return approvalsWidget;
-    }
-
     /**
      * Set a WindowClosedCallback for a Modal instance.
      *

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/pages/FlowableModelerPopupPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/FlowableModelerPopupPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/FlowableModelerPopupPage.java
deleted file mode 100644
index b55d2b5..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/FlowableModelerPopupPage.java
+++ /dev/null
@@ -1,27 +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.wicket.markup.html.WebPage;
-
-public class FlowableModelerPopupPage extends WebPage {
-
-    private static final long serialVersionUID = -7031206743629422898L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/pages/Workflow.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Workflow.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Workflow.java
deleted file mode 100644
index 5ab09c3..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/Workflow.java
+++ /dev/null
@@ -1,64 +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.syncope.client.console.BookmarkablePageLinkBuilder;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.panels.WorkflowDirectoryPanel;
-import org.apache.syncope.client.console.wizards.WizardMgtPanel;
-import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-
-public class Workflow extends BasePage {
-
-    private static final long serialVersionUID = -8781434495150074529L;
-
-    public Workflow(final PageParameters parameters) {
-        super(parameters);
-
-        body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
-
-        WebMarkupContainer content = new WebMarkupContainer("content");
-        content.setOutputMarkupId(true);
-        body.add(content);
-
-        WebMarkupContainer disabled = new WebMarkupContainer("disabled");
-        disabled.setOutputMarkupPlaceholderTag(true);
-        content.add(disabled);
-
-        WizardMgtPanel<WorkflowDefinitionTO> workflowsPanel = new WorkflowDirectoryPanel.Builder(getPageReference()) {
-
-            private static final long serialVersionUID = -5960765294082359003L;
-
-        }.disableCheckBoxes().build("workflowsPanel");
-        workflowsPanel.setOutputMarkupPlaceholderTag(true);
-        MetaDataRoleAuthorizationStrategy.authorize(workflowsPanel, ENABLE, StandardEntitlement.WORKFLOW_DEF_LIST);
-
-        content.add(workflowsPanel);
-
-        if (SyncopeConsoleSession.get().getPlatformInfo().getUserWorkflowAdapter().contains("Flowable")) {
-            disabled.setVisible(false);
-        } else {
-            workflowsPanel.setVisible(false);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/panels/NewWorkflowProcess.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/NewWorkflowProcess.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/NewWorkflowProcess.java
deleted file mode 100644
index f0971c6..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/NewWorkflowProcess.java
+++ /dev/null
@@ -1,87 +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 java.io.Serializable;
-import javax.ws.rs.core.MediaType;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.pdfbox.util.Charsets;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.rest.WorkflowRestClient;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.model.Model;
-
-public class NewWorkflowProcess extends TogglePanel<Serializable> {
-
-    private static final long serialVersionUID = -4886361549305302161L;
-
-    private final WorkflowRestClient restClient = new WorkflowRestClient();
-
-    private final Form<?> form;
-
-    public NewWorkflowProcess(final String id, final WebMarkupContainer container, final PageReference pageRef) {
-        super(id, pageRef);
-
-        form = new Form<>("form");
-        addInnerObject(form);
-
-        final TextField<String> key = new TextField<>("key", new Model<>());
-        key.setRequired(true);
-        form.add(key);
-
-        form.add(new AjaxSubmitLink("submit", form) {
-
-            private static final long serialVersionUID = 4947613489823025052L;
-
-            @Override
-            protected void onSubmit(final AjaxRequestTarget target) {
-                try {
-                    restClient.setDefinition(MediaType.APPLICATION_XML_TYPE, key.getModelObject(),
-                            IOUtils.toString(
-                                    getClass().getResourceAsStream("empty.bpmn20.xml"),
-                                    Charsets.UTF_8.name()).replaceAll("%KEY%", key.getModelObject()));
-
-                    key.getModel().setObject(null);
-                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                    toggle(target, false);
-                    target.add(container);
-                } catch (Exception e) {
-                    LOG.error("While creating new workflow process", e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
-                }
-                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-            }
-
-            @Override
-            protected void onError(final AjaxRequestTarget target) {
-                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
index 9bce309..8cd3fb8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
@@ -166,7 +166,6 @@ public class ParametersDirectoryPanel
                     super.populateItem(item, componentId, rowModel);
                 }
             }
-
         });
         return columns;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
index e9f8029..fb8047c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
@@ -42,8 +42,6 @@ import org.apache.syncope.common.lib.to.ReportTO;
 import org.apache.syncope.common.lib.to.ProvisioningTaskTO;
 import org.apache.syncope.common.lib.to.SecurityQuestionTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.PageReference;
@@ -202,12 +200,8 @@ public abstract class TogglePanel<T extends Serializable> extends WizardMgtPanel
             key = ((AccessTokenTO) modelObject).getKey();
         } else if (modelObject instanceof ExecTO) {
             key = ((ExecTO) modelObject).getKey();
-        } else if (modelObject instanceof WorkflowDefinitionTO) {
-            key = ((WorkflowDefinitionTO) modelObject).getKey();
         } else if (modelObject instanceof ProvisioningTaskTO) {
             key = ((ProvisioningTaskTO) modelObject).getKey();
-        } else if (modelObject instanceof WorkflowFormTO) {
-            key = ((WorkflowFormTO) modelObject).getKey();
         } else if (modelObject instanceof EntityTO) {
             key = ((EntityTO) modelObject).getKey();
         } else if (modelObject instanceof StatusBean) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/panels/WorkflowDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/WorkflowDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/WorkflowDirectoryPanel.java
deleted file mode 100644
index a640367..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/WorkflowDirectoryPanel.java
+++ /dev/null
@@ -1,333 +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 de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import javax.ws.rs.core.MediaType;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleApplication;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.DirectoryDataProvider;
-import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.pages.ModelerPopupPage;
-import org.apache.syncope.client.console.panels.WorkflowDirectoryPanel.WorkflowDefinitionDataProvider;
-import org.apache.syncope.client.console.rest.WorkflowRestClient;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.ImageModalPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
-import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
-import org.apache.syncope.client.console.wizards.WizardMgtPanel;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.Page;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.extensions.wizard.WizardModel;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.ResourceModel;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.wicket.util.io.IOUtils;
-
-public class WorkflowDirectoryPanel extends DirectoryPanel<
-        WorkflowDefinitionTO, WorkflowDefinitionTO, WorkflowDefinitionDataProvider, WorkflowRestClient> {
-
-    private static final long serialVersionUID = 2705668831139984998L;
-
-    private final BaseModal<String> utility;
-
-    private String modelerCtx;
-
-    protected WorkflowDirectoryPanel(final String id, final Builder builder) {
-        super(id, builder);
-
-        this.addNewItemPanelBuilder(new AjaxWizardBuilder<WorkflowDefinitionTO>(new WorkflowDefinitionTO(), pageRef) {
-
-            private static final long serialVersionUID = 1633859795677053912L;
-
-            @Override
-            protected WizardModel buildModelSteps(
-                    final WorkflowDefinitionTO modelObject, final WizardModel wizardModel) {
-
-                return wizardModel;
-            }
-        }, false);
-        final NewWorkflowProcess newWorkflowProcess = new NewWorkflowProcess("newWorkflowProcess", container, pageRef);
-        addInnerObject(newWorkflowProcess);
-        AjaxLink<Void> newWorkflowProcessLink = new AjaxLink<Void>("add") {
-
-            private static final long serialVersionUID = -7978723352517770644L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target) {
-                newWorkflowProcess.toggle(target, true);
-            }
-        };
-        ((WebMarkupContainer) get("container:content")).addOrReplace(newWorkflowProcessLink);
-
-        setShowResultPage(true);
-
-        modal.size(Modal.Size.Large);
-
-        utility = new BaseModal<>("outer");
-        addOuterObject(utility);
-        utility.size(Modal.Size.Large);
-        AjaxSubmitLink xmlEditorSubmit = utility.addSubmitButton();
-        MetaDataRoleAuthorizationStrategy.authorize(xmlEditorSubmit, RENDER, StandardEntitlement.WORKFLOW_DEF_SET);
-        utility.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
-
-            private static final long serialVersionUID = 8804221891699487139L;
-
-            @Override
-            public void onClose(final AjaxRequestTarget target) {
-                utility.show(false);
-                utility.close(target);
-            }
-        });
-        initResultTable();
-
-        // Check if Flowable Modeler directory is found
-        modelerCtx = null;
-        try {
-            if (SyncopeConsoleApplication.get().getFlowableModelerDirectory() != null) {
-                File baseDir = new File(SyncopeConsoleApplication.get().getFlowableModelerDirectory());
-                if (baseDir.exists() && baseDir.canRead() && baseDir.isDirectory()) {
-                    modelerCtx = Constants.FLOWABLE_MODELER_CONTEXT;
-                }
-            }
-        } catch (Exception e) {
-            LOG.error("Could not check for Modeler directory", e);
-        }
-    }
-
-    @Override
-    protected WorkflowDefinitionDataProvider dataProvider() {
-        return new WorkflowDefinitionDataProvider(rows);
-    }
-
-    @Override
-    protected String paginatorRowsKey() {
-        return Constants.PREF_WORKFLOW_PAGINATOR_ROWS;
-    }
-
-    @Override
-    protected List<IColumn<WorkflowDefinitionTO, String>> getColumns() {
-        List<IColumn<WorkflowDefinitionTO, String>> columns = new ArrayList<>();
-
-        columns.add(new KeyPropertyColumn<>(new ResourceModel("key"), "key"));
-        columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
-        columns.add(new BooleanPropertyColumn<>(new ResourceModel("main"), null, "main"));
-
-        return columns;
-    }
-
-    @Override
-    public ActionsPanel<WorkflowDefinitionTO> getActions(final IModel<WorkflowDefinitionTO> model) {
-        final ActionsPanel<WorkflowDefinitionTO> panel = super.getActions(model);
-
-        panel.add(new ActionLink<WorkflowDefinitionTO>() {
-
-            private static final long serialVersionUID = -184018732772021627L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target, final WorkflowDefinitionTO ignore) {
-                final IModel<String> wfDefinition = new Model<>();
-                try {
-                    wfDefinition.setObject(IOUtils.toString(restClient.getDefinition(
-                            MediaType.APPLICATION_XML_TYPE, model.getObject().getKey())));
-                } catch (IOException e) {
-                    LOG.error("Could not get workflow definition", e);
-                }
-
-                utility.header(Model.of(model.getObject().getKey()));
-                utility.setContent(new XMLEditorPanel(utility, wfDefinition, false, pageRef) {
-
-                    private static final long serialVersionUID = -7688359318035249200L;
-
-                    @Override
-                    public void onSubmit(final AjaxRequestTarget target) {
-                        if (StringUtils.isNotBlank(wfDefinition.getObject())) {
-                            try {
-                                restClient.setDefinition(MediaType.APPLICATION_XML_TYPE,
-                                        model.getObject().getKey(), wfDefinition.getObject());
-                                SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-
-                                target.add(container);
-                                utility.show(false);
-                                utility.close(target);
-                            } catch (SyncopeClientException e) {
-                                SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                        ? e.getClass().getName() : e.getMessage());
-                            }
-                            ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-                        }
-                    }
-                });
-                utility.show(target);
-                target.add(utility);
-            }
-        }, ActionLink.ActionType.EDIT, StandardEntitlement.WORKFLOW_DEF_SET);
-
-        panel.add(new ActionLink<WorkflowDefinitionTO>() {
-
-            private static final long serialVersionUID = 3109256773218160485L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target, final WorkflowDefinitionTO ignore) {
-                modal.header(Model.of(model.getObject().getKey()));
-                modal.setContent(new ImageModalPanel<>(
-                        modal, restClient.getDiagram(model.getObject().getKey()), pageRef));
-                modal.show(target);
-                target.add(modal);
-            }
-        }, ActionLink.ActionType.VIEW, StandardEntitlement.WORKFLOW_DEF_GET);
-
-        panel.add(new ActionLink<WorkflowDefinitionTO>() {
-
-            private static final long serialVersionUID = -184018732772021627L;
-
-            @Override
-            public Class<? extends Page> getPageClass() {
-                return ModelerPopupPage.class;
-            }
-
-            @Override
-            public PageParameters getPageParameters() {
-                PageParameters parameters = new PageParameters();
-                if (modelerCtx != null) {
-                    parameters.add(Constants.MODELER_CONTEXT, modelerCtx);
-                }
-                parameters.add(Constants.MODEL_ID_PARAM, model.getObject().getModelId());
-
-                return parameters;
-            }
-
-            @Override
-            protected boolean statusCondition(final WorkflowDefinitionTO modelObject) {
-                return modelerCtx != null;
-            }
-
-            @Override
-            public void onClick(final AjaxRequestTarget target, final WorkflowDefinitionTO ignore) {
-                // do nothing
-            }
-        }, ActionLink.ActionType.WORKFLOW_MODELER, StandardEntitlement.WORKFLOW_DEF_SET);
-
-        panel.add(new ActionLink<WorkflowDefinitionTO>() {
-
-            private static final long serialVersionUID = -7978723352517770644L;
-
-            @Override
-            protected boolean statusCondition(final WorkflowDefinitionTO modelObject) {
-                return !modelObject.isMain();
-            }
-
-            @Override
-            public void onClick(final AjaxRequestTarget target, final WorkflowDefinitionTO ignore) {
-                try {
-                    restClient.deleteDefinition(model.getObject().getKey());
-                    SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                    target.add(container);
-                } catch (SyncopeClientException e) {
-                    LOG.error("While deleting workflow definition {}", model.getObject().getName(), e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
-                }
-                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-            }
-        }, ActionLink.ActionType.DELETE, StandardEntitlement.WORKFLOW_DEF_DELETE, true);
-
-        return panel;
-    }
-
-    @Override
-    protected Collection<ActionLink.ActionType> getBatches() {
-        return Collections.emptyList();
-    }
-
-    public abstract static class Builder
-            extends DirectoryPanel.Builder<WorkflowDefinitionTO, WorkflowDefinitionTO, WorkflowRestClient> {
-
-        private static final long serialVersionUID = 5088962796986706805L;
-
-        public Builder(final PageReference pageRef) {
-            super(new WorkflowRestClient(), pageRef);
-        }
-
-        @Override
-        protected WizardMgtPanel<WorkflowDefinitionTO> newInstance(final String id, final boolean wizardInModal) {
-            return new WorkflowDirectoryPanel(id, this);
-        }
-    }
-
-    protected class WorkflowDefinitionDataProvider extends DirectoryDataProvider<WorkflowDefinitionTO> {
-
-        private static final long serialVersionUID = 1764153405387687592L;
-
-        private final SortableDataProviderComparator<WorkflowDefinitionTO> comparator;
-
-        private final WorkflowRestClient restClient = new WorkflowRestClient();
-
-        public WorkflowDefinitionDataProvider(final int paginatorRows) {
-            super(paginatorRows);
-            this.comparator = new SortableDataProviderComparator<>(this);
-            setSort("main", SortOrder.DESCENDING);
-        }
-
-        @Override
-        public Iterator<WorkflowDefinitionTO> iterator(final long first, final long count) {
-            List<WorkflowDefinitionTO> result = restClient.getDefinitions();
-            Collections.sort(result, comparator);
-            return result.subList((int) first, (int) first + (int) count).iterator();
-        }
-
-        @Override
-        public long size() {
-            return restClient.getDefinitions().size();
-        }
-
-        @Override
-        public IModel<WorkflowDefinitionTO> model(final WorkflowDefinitionTO object) {
-            return new CompoundPropertyModel<>(object);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/resources/AbstractWorkflowResource.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/AbstractWorkflowResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/AbstractWorkflowResource.java
deleted file mode 100644
index b76bd9e..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/resources/AbstractWorkflowResource.java
+++ /dev/null
@@ -1,51 +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.resources;
-
-import javax.ws.rs.NotFoundException;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.rest.WorkflowRestClient;
-import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.util.string.StringValue;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-abstract class AbstractWorkflowResource extends AbstractResource {
-
-    private static final long serialVersionUID = 5163553843196539019L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractWorkflowResource.class);
-
-    protected final WorkflowRestClient restClient = new WorkflowRestClient();
-
-    protected WorkflowDefinitionTO getWorkflowDefinition(final Attributes attributes) {
-        final StringValue modelId =
-                attributes.getRequest().getQueryParameters().getParameterValue(Constants.MODEL_ID_PARAM);
-
-        WorkflowDefinitionTO workflowDefinition = modelId == null || modelId.isNull() ? null
-                : restClient.getDefinitions().stream().
-                        filter(object -> modelId.toString().equals(object.getModelId())).findAny().orElse(null);
-        if (workflowDefinition == null) {
-            throw new NotFoundException("Workflow definition with modelId " + modelId);
-        }
-
-        return workflowDefinition;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java
deleted file mode 100644
index f8dc13d..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java
+++ /dev/null
@@ -1,79 +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.resources;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import org.apache.wicket.request.resource.AbstractResource;
-import org.apache.wicket.util.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Mounts directory on local filesystem as subcontext.
- */
-public class FilesystemResource extends AbstractResource {
-
-    private static final long serialVersionUID = -4791087117785935198L;
-
-    private static final Logger LOG = LoggerFactory.getLogger(FilesystemResource.class);
-
-    private final String baseCtx;
-
-    private final String basePath;
-
-    public FilesystemResource(final String baseCtx, final String basePath) {
-        this.baseCtx = baseCtx;
-        this.basePath = basePath;
-    }
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        ResourceResponse response = new ResourceResponse();
-
-        final File baseDir = new File(basePath);
-        if (baseDir.exists() && baseDir.canRead() && baseDir.isDirectory()) {
-            String reqPath = attributes.getRequest().getUrl().getPath();
-            final String subPath = reqPath.substring(reqPath.indexOf(baseCtx) + baseCtx.length()).
-                    replace('/', File.separatorChar);
-            LOG.debug("Request for {}", subPath);
-
-            response.setTextEncoding(StandardCharsets.UTF_8.name());
-            response.setWriteCallback(new WriteCallback() {
-
-                @Override
-                public void writeData(final Attributes attributes) throws IOException {
-                    try (InputStream resourceIS = Files.newInputStream(new File(baseDir, subPath).toPath())) {
-                        IOUtils.copy(resourceIS, attributes.getResponse().getOutputStream());
-                    } catch (IOException e) {
-                        LOG.error("Could not read from {}", baseDir.getAbsolutePath() + subPath, e);
-                    }
-                }
-            });
-        } else {
-            LOG.error("{} not found, not readable or not a directory", basePath);
-        }
-
-        return response;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java
deleted file mode 100644
index 46fb22a..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java
+++ /dev/null
@@ -1,58 +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.resources;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import javax.ws.rs.core.MediaType;
-import org.apache.syncope.client.console.rest.WorkflowRestClient;
-import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
-import org.apache.wicket.util.io.IOUtils;
-
-/**
- * Mirror REST resource for obtaining user workflow definition in JSON (used by Flowable Modeler).
- *
- * @see org.apache.syncope.common.rest.api.service.WorkflowService#get
- */
-public class WorkflowDefGETResource extends AbstractWorkflowResource {
-
-    private static final long serialVersionUID = 4637304868056148970L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        final WorkflowDefinitionTO toGet = getWorkflowDefinition(attributes);
-
-        ResourceResponse response = new ResourceResponse();
-        response.disableCaching();
-        response.setContentType(MediaType.APPLICATION_JSON);
-        response.setTextEncoding(StandardCharsets.UTF_8.name());
-        response.setWriteCallback(new WriteCallback() {
-
-            @Override
-            public void writeData(final Attributes attributes) throws IOException {
-                IOUtils.copy(
-                        new WorkflowRestClient().getDefinition(MediaType.APPLICATION_JSON_TYPE, toGet.getKey()),
-                        attributes.getResponse().getOutputStream());
-            }
-        });
-
-        return response;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java
deleted file mode 100644
index 84ec3e5..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java
+++ /dev/null
@@ -1,74 +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.resources;
-
-import java.io.IOException;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.cxf.common.util.UrlUtils;
-import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
-import org.apache.wicket.util.io.IOUtils;
-
-/**
- * Mirror REST resource for putting user workflow definition in JSON (used by Flowable Modeler).
- *
- * @see org.apache.syncope.common.rest.api.service.WorkflowService#set
- */
-public class WorkflowDefPUTResource extends AbstractWorkflowResource {
-
-    private static final long serialVersionUID = 2964542005207297944L;
-
-    @Override
-    protected ResourceResponse newResourceResponse(final Attributes attributes) {
-        String definition = null;
-        try {
-            HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
-            String requestBody = IOUtils.toString(request.getInputStream());
-            String[] split = requestBody.split("&");
-            for (int i = 0; i < split.length && definition == null; i++) {
-                String keyValue = split[i];
-                if (keyValue.startsWith("json_xml=")) {
-                    definition = UrlUtils.urlDecode(keyValue.split("=")[1]);
-                }
-            }
-        } catch (IOException e) {
-            LOG.error("Could not extract workflow definition", e);
-        }
-
-        WorkflowDefinitionTO toSet = getWorkflowDefinition(attributes);
-
-        if (definition == null || toSet == null) {
-            return new ResourceResponse().setStatusCode(Response.Status.BAD_REQUEST.getStatusCode()).
-                    setError(Response.Status.BAD_REQUEST.getStatusCode(),
-                            "Could not extract workflow model id and / or definition");
-        }
-
-        try {
-            restClient.setDefinition(MediaType.APPLICATION_JSON_TYPE, toSet.getKey(), definition);
-            return new ResourceResponse().setStatusCode(Response.Status.NO_CONTENT.getStatusCode());
-        } catch (Exception e) {
-            LOG.error("While updating workflow definition", e);
-            return new ResourceResponse().setStatusCode(Response.Status.BAD_REQUEST.getStatusCode()).
-                    setError(Response.Status.BAD_REQUEST.getStatusCode(),
-                            "While updating workflow definition: " + e.getMessage());
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java
deleted file mode 100644
index 8ccf057..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java
+++ /dev/null
@@ -1,59 +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.rest;
-
-import java.util.List;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.rest.api.beans.WorkflowFormQuery;
-import org.apache.syncope.common.rest.api.service.UserWorkflowService;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
-
-public class UserWorkflowRestClient extends BaseRestClient {
-
-    private static final long serialVersionUID = -4785231164900813921L;
-
-    public int countForms() {
-        return getService(UserWorkflowService.class).
-                getForms(new WorkflowFormQuery.Builder().page(1).size(1).build()).
-                getTotalCount();
-    }
-
-    public List<WorkflowFormTO> getForms(final int page, final int size, final SortParam<String> sort) {
-        return getService(UserWorkflowService.class).
-                getForms(new WorkflowFormQuery.Builder().page(page).size(size).orderBy(toOrderBy(sort)).build()).
-                getResult();
-    }
-
-    public WorkflowFormTO getFormForUser(final String userKey) {
-        return getService(UserWorkflowService.class).getFormForUser(userKey);
-    }
-
-    public WorkflowFormTO claimForm(final String taskKey) {
-        return getService(UserWorkflowService.class).claimForm(taskKey);
-    }
-
-    public void submitForm(final WorkflowFormTO form) {
-        getService(UserWorkflowService.class).submitForm(form);
-    }
-
-    public UserTO executeTask(final String taskId, final UserTO form) {
-        return getService(UserWorkflowService.class).executeTask(taskId, form);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java
deleted file mode 100644
index 14711a4..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java
+++ /dev/null
@@ -1,73 +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.rest;
-
-import java.io.InputStream;
-import java.util.List;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.cxf.helpers.IOUtils;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.common.lib.to.WorkflowDefinitionTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.service.WorkflowService;
-
-public class WorkflowRestClient extends BaseRestClient {
-
-    private static final long serialVersionUID = 5049285686167071017L;
-
-    private WorkflowService getService(final MediaType mediaType) {
-        return SyncopeConsoleSession.get().getService(mediaType, WorkflowService.class);
-    }
-
-    public List<WorkflowDefinitionTO> getDefinitions() {
-        return getService(WorkflowService.class).list(AnyTypeKind.USER.name());
-    }
-
-    public InputStream getDefinition(final MediaType mediaType, final String key) {
-        Response response = getService(mediaType).get(AnyTypeKind.USER.name(), key);
-
-        return (InputStream) response.getEntity();
-    }
-
-    public byte[] getDiagram(final String key) {
-        WorkflowService service = getService(WorkflowService.class);
-        WebClient.client(service).accept(RESTHeaders.MEDIATYPE_IMAGE_PNG);
-        Response response = service.exportDiagram(AnyTypeKind.USER.name(), key);
-
-        byte[] diagram;
-        try {
-            diagram = IOUtils.readBytesFromStream((InputStream) response.getEntity());
-        } catch (Exception e) {
-            LOG.error("Could not get workflow diagram", e);
-            diagram = new byte[0];
-        }
-        return diagram;
-    }
-
-    public void setDefinition(final MediaType mediaType, final String key, final String definition) {
-        getService(mediaType).set(AnyTypeKind.USER.name(), key, definition);
-    }
-
-    public void deleteDefinition(final String key) {
-        getService(WorkflowService.class).delete(AnyTypeKind.USER.name(), key);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3cabe08a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index d8e8f77..7f8ade0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -98,11 +98,11 @@ public abstract class ActionLink<T extends Serializable> implements Serializable
         NOTIFICATION_TASKS("read"),
         ZOOM_IN("zoomin"),
         ZOOM_OUT("zoomout"),
-        WORKFLOW_MODELER("workflowModeler"),
         VIEW_EXECUTIONS("read"),
         VIEW_DETAILS("read"),
         MANAGE_APPROVAL("edit"),
-        EDIT_APPROVAL("edit");
+        EDIT_APPROVAL("edit"),
+        EXTERNAL_EDITOR("externalEditor");
 
         private final String actionId;