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 2017/08/28 15:42:20 UTC

[3/3] syncope git commit: [SYNCOPE-1054] Now migrated to Flowable 6.1

[SYNCOPE-1054] Now migrated to Flowable 6.1


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

Branch: refs/heads/master
Commit: f27e1bb4a6cc9281a0e157ba6cda06ccc06e1807
Parents: 7098ca9
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Aug 28 15:44:52 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Aug 28 17:42:05 2017 +0200

----------------------------------------------------------------------
 .../archetype-resources/console/pom.xml         |   33 +-
 .../client/console/pages/ModelerPopupPage.java  |    2 +-
 .../flowable/FlowableDefinitionLoader.java      |    6 +-
 .../workflow/flowable/FlowableDeployUtils.java  |   20 +-
 .../flowable/FlowableUserWorkflowAdapter.java   |   66 +-
 .../flowable/SyncopeEntitiesVariableType.java   |    2 +-
 .../workflow/flowable/SyncopeGroupManager.java  |  122 --
 .../flowable/SyncopeGroupQueryImpl.java         |  136 +-
 .../flowable/SyncopeIdmIdentityService.java     |   51 +
 .../core/workflow/flowable/SyncopeSession.java  |    2 +-
 .../flowable/SyncopeSessionFactory.java         |    7 +-
 .../workflow/flowable/SyncopeUserManager.java   |  166 --
 .../workflow/flowable/SyncopeUserQueryImpl.java |  167 +-
 .../flowable/spring/DomainProcessEngine.java    |   26 +-
 .../spring/DomainProcessEngineFactoryBean.java  |   58 +-
 .../task/AbstractFlowableServiceTask.java       |    2 +-
 .../src/main/resources/workflow.properties      |    1 -
 .../main/resources/workflowFlowableContext.xml  |   26 +-
 fit/console-reference/pom.xml                   |   33 +-
 .../src/main/resources/app-cfg.js               |   29 +
 .../src/main/resources/save-model.html          |   93 +-
 .../src/main/resources/stencilset.json          | 1627 ++++++++++++++++++
 .../src/main/resources/url-config.js            |   21 +-
 .../src/main/resources/all/workflow.properties  |    1 -
 .../src/main/resources/log4j2.xml               |    2 +-
 .../syncope/installer/files/ConsolePom.java     |   44 +-
 pom.xml                                         |    4 +-
 27 files changed, 2021 insertions(+), 726 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/archetype/src/main/resources/archetype-resources/console/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/src/main/resources/archetype-resources/console/pom.xml b/archetype/src/main/resources/archetype-resources/console/pom.xml
index 52de63a..de901be 100644
--- a/archetype/src/main/resources/archetype-resources/console/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/console/pom.xml
@@ -142,7 +142,7 @@ under the License.
         
         <dependency>
           <groupId>org.flowable</groupId>
-          <artifactId>flowable-webapp-explorer2</artifactId>            
+          <artifactId>flowable-ui-modeler-app</artifactId>            
           <type>war</type>
           <scope>test</scope>
         </dependency>
@@ -160,34 +160,25 @@ under the License.
                 <phase>process-resources</phase>
                 <configuration>
                   <target>
-                    <unzip src="${settings.localRepository}/org/flowable/flowable-webapp-explorer2/${flowable.version}/flowable-webapp-explorer2-${flowable.version}.war" 
-                           dest="${project.build.directory}/flowable-webapp-explorer2"/>
+                    <unzip src="${settings.localRepository}/org/flowable/flowable-ui-modeler-app/${flowable.version}/flowable-ui-modeler-app-${flowable.version}.war" 
+                           dest="${flowable-modeler.directory}"/>
                 
-                    <mkdir dir="${flowable-modeler.directory}"/>
-                    <copy file="${project.build.directory}/flowable-webapp-explorer2/modeler.html" 
-                          todir="${flowable-modeler.directory}"/>
-                    <replace file="${flowable-modeler.directory}/modeler.html"
+                    <replace file="${flowable-modeler.directory}/index.html"
                              token="&lt;/head&gt;"
                              value="&lt;script type=&quot;text/javascript&quot;&gt;window.onunload = refreshParent; function refreshParent() { window.opener.location.reload(); }&lt;/script&gt;&lt;/head&gt;"/>
-                    <copy file="${project.build.directory}/flowable-webapp-explorer2/WEB-INF/classes/stencilset.json" 
-                          todir="${flowable-modeler.directory}"/>
-
-                    <mkdir dir="${flowable-modeler.directory}/editor-app"/>
-                    <copy todir="${flowable-modeler.directory}/editor-app">
-                      <fileset dir="${project.build.directory}/flowable-webapp-explorer2/editor-app"/>                  
-                    </copy>
-                    <replace file="${flowable-modeler.directory}/editor-app/editor/oryx.debug.js"
-                             token="return this.changeDifference !== 0 || (this.facade.getModelMetaData()['new'] &amp;&amp; this.facade.getCanvas().getChildShapes().size() &gt; 0);"
-                             value="return this.changeDifference !== 0 
-              || (typeof this.facade.getModelMetaData() != 'undefined' 
-              &amp;&amp; this.facade.getModelMetaData()['new'] &amp;&amp; this.facade.getCanvas().getChildShapes().size() &gt; 0);"/>
                     <replace file="${flowable-modeler.directory}/editor-app/configuration/toolbar-default-actions.js"
-                             token="window.location.href = &quot;./&quot;;"
+                             token="$location.path('/processes');"
                              value="window.close();"/>
-                                               
+
+                    <copy file="${basedir}/src/main/resources/app-cfg.js" 
+                          todir="${flowable-modeler.directory}/scripts"
+                          overwrite="true"/>
                     <copy file="${basedir}/src/main/resources/url-config.js" 
                           todir="${flowable-modeler.directory}/editor-app/configuration"
                           overwrite="true"/>
+                    <copy file="${basedir}/src/main/resources/stencilset.json" 
+                          todir="${flowable-modeler.directory}"
+                          overwrite="true"/>
                     <copy file="${basedir}/src/main/resources/save-model.html" 
                           todir="${flowable-modeler.directory}/editor-app/popups"
                           overwrite="true"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/client/console/src/main/java/org/apache/syncope/client/console/pages/ModelerPopupPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ModelerPopupPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ModelerPopupPage.java
index 3b3ed84..42a599c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ModelerPopupPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ModelerPopupPage.java
@@ -38,7 +38,7 @@ public class ModelerPopupPage extends WebPage {
         // properly parameterize ?modelId=5 with SYNCOPE-1020
         refresh.add(new AttributeModifier(
                 "content", "0; url=../../" + parameters.get(Constants.MODELER_CONTEXT)
-                + "/modeler.html?modelId=" + modelId.toString()));
+                + "/index.html#/editor/" + modelId.toString()));
         add(refresh);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDefinitionLoader.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDefinitionLoader.java
index a387c30..9ed5760 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDefinitionLoader.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDefinitionLoader.java
@@ -24,13 +24,13 @@ import java.io.InputStream;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.Resource;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.spring.SpringProcessEngineConfiguration;
 import org.apache.commons.io.IOUtils;
 import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.workflow.flowable.spring.DomainProcessEngine;
+import org.flowable.engine.ProcessEngine;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.spring.SpringProcessEngineConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDeployUtils.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDeployUtils.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDeployUtils.java
index 4d28cd2..eafc050 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDeployUtils.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableDeployUtils.java
@@ -26,17 +26,17 @@ import java.io.InputStreamReader;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
-import org.activiti.bpmn.converter.BpmnXMLConverter;
-import org.activiti.bpmn.model.BpmnModel;
-import org.activiti.editor.constants.ModelDataJsonConstants;
-import org.activiti.editor.language.json.converter.BpmnJsonConverter;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.repository.Deployment;
-import org.activiti.engine.repository.Model;
-import org.activiti.engine.repository.ProcessDefinition;
 import org.apache.commons.io.IOUtils;
 import org.apache.syncope.core.workflow.api.WorkflowException;
+import org.flowable.bpmn.converter.BpmnXMLConverter;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.editor.constants.ModelDataJsonConstants;
+import org.flowable.editor.language.json.converter.BpmnJsonConverter;
+import org.flowable.engine.ProcessEngine;
+import org.flowable.engine.common.api.FlowableException;
+import org.flowable.engine.repository.Deployment;
+import org.flowable.engine.repository.Model;
+import org.flowable.engine.repository.ProcessDefinition;
 
 public final class FlowableDeployUtils {
 
@@ -48,7 +48,7 @@ public final class FlowableDeployUtils {
         try {
             return engine.getRepositoryService().createDeployment().
                     addInputStream(resourceName, new ByteArrayInputStream(definition)).deploy();
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new WorkflowException("While importing " + resourceName, e);
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
index 82d1add..0b32990 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
@@ -33,23 +33,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 import javax.annotation.Resource;
-import org.activiti.bpmn.converter.BpmnXMLConverter;
-import org.activiti.bpmn.model.BpmnModel;
-import org.activiti.editor.constants.ModelDataJsonConstants;
-import org.activiti.editor.language.json.converter.BpmnJsonConverter;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.form.FormProperty;
-import org.activiti.engine.form.FormType;
-import org.activiti.engine.form.TaskFormData;
-import org.activiti.engine.history.HistoricActivityInstance;
-import org.activiti.engine.history.HistoricTaskInstance;
-import org.activiti.engine.impl.persistence.entity.HistoricFormPropertyEntity;
-import org.activiti.engine.query.Query;
-import org.activiti.engine.repository.Deployment;
-import org.activiti.engine.repository.Model;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.activiti.engine.task.Task;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -75,6 +58,23 @@ import org.apache.syncope.core.workflow.flowable.spring.DomainProcessEngine;
 import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat;
 import org.apache.syncope.core.workflow.api.WorkflowException;
 import org.apache.syncope.core.workflow.java.AbstractUserWorkflowAdapter;
+import org.flowable.bpmn.converter.BpmnXMLConverter;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.editor.constants.ModelDataJsonConstants;
+import org.flowable.editor.language.json.converter.BpmnJsonConverter;
+import org.flowable.engine.common.api.FlowableException;
+import org.flowable.engine.common.api.query.Query;
+import org.flowable.engine.form.FormProperty;
+import org.flowable.engine.form.FormType;
+import org.flowable.engine.form.TaskFormData;
+import org.flowable.engine.history.HistoricActivityInstance;
+import org.flowable.engine.history.HistoricTaskInstance;
+import org.flowable.engine.impl.persistence.entity.HistoricFormPropertyEntity;
+import org.flowable.engine.repository.Deployment;
+import org.flowable.engine.repository.Model;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.engine.task.Task;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -134,7 +134,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         return "ACT_";
     }
 
-    protected void throwException(final ActivitiException e, final String defaultMessage) {
+    protected void throwException(final FlowableException e, final String defaultMessage) {
         if (e.getCause() != null) {
             if (e.getCause().getCause() instanceof SyncopeClientException) {
                 throw (SyncopeClientException) e.getCause().getCause();
@@ -169,7 +169,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 if (formData != null && !formData.getFormProperties().isEmpty()) {
                     result = tasks.get(0).getId();
                 }
-            } catch (ActivitiException e) {
+            } catch (FlowableException e) {
                 LOG.warn("Could not get task form data", e);
             }
         }
@@ -227,7 +227,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         ProcessInstance processInstance = null;
         try {
             processInstance = engine.getRuntimeService().startProcessInstanceByKey(WF_PROCESS_ID, variables);
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throwException(e, "While starting " + WF_PROCESS_ID + " instance");
         }
 
@@ -288,7 +288,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         if (tasks.size() == 1) {
             try {
                 engine.getTaskService().complete(tasks.get(0).getId(), variables);
-            } catch (ActivitiException e) {
+            } catch (FlowableException e) {
                 throwException(e, "While completing task '" + tasks.get(0).getName() + "' for " + user);
             }
         } else {
@@ -617,10 +617,10 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 } else if (obj instanceof Task) {
                     forms.add(getFormTO((Task) obj));
                 } else {
-                    throw new ActivitiException(
+                    throw new FlowableException(
                             "Failure retrieving form", new IllegalArgumentException("Invalid task type"));
                 }
-            } catch (ActivitiException e) {
+            } catch (FlowableException e) {
                 LOG.debug("No form found for task {}", obj, e);
             }
         });
@@ -633,14 +633,14 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         Task task;
         try {
             task = engine.getTaskService().createTaskQuery().processInstanceId(workflowId).singleResult();
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new WorkflowException("While reading form for workflow instance " + workflowId, e);
         }
 
         TaskFormData formData;
         try {
             formData = engine.getFormService().getTaskFormData(task.getId());
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             LOG.debug("No form found for task {}", task.getId(), e);
             formData = null;
         }
@@ -658,16 +658,16 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         try {
             task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
             if (task == null) {
-                throw new ActivitiException("NULL result");
+                throw new FlowableException("NULL result");
             }
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new NotFoundException("Flowable Task " + taskId, e);
         }
 
         TaskFormData formData;
         try {
             formData = engine.getFormService().getTaskFormData(task.getId());
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new NotFoundException("Form for Flowable Task " + taskId, e);
         }
 
@@ -699,7 +699,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         try {
             engine.getTaskService().setOwner(taskId, authUser);
             task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new WorkflowException("While reading task " + taskId, e);
         }
 
@@ -736,7 +736,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         try {
             engine.getFormService().submitTaskFormData(form.getTaskId(), getPropertiesForSubmit(form));
             engine.getRuntimeService().setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throwException(e, "While submitting form for task " + form.getTaskId());
         }
 
@@ -807,7 +807,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
                         return defTO;
                     }).collect(Collectors.toList());
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new WorkflowException("While listing available process definitions", e);
         }
     }
@@ -816,7 +816,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         try {
             return engine.getRepositoryService().createProcessDefinitionQuery().
                     processDefinitionKey(key).latestVersion().singleResult();
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new WorkflowException("While accessing process " + key, e);
         }
 
@@ -826,7 +826,7 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         try {
             return engine.getRepositoryService().createProcessDefinitionQuery().
                     deploymentId(deploymentId).latestVersion().singleResult();
-        } catch (ActivitiException e) {
+        } catch (FlowableException e) {
             throw new WorkflowException("While accessing deployment " + deploymentId, e);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeEntitiesVariableType.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeEntitiesVariableType.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeEntitiesVariableType.java
index 88b43ac..7fd0faa 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeEntitiesVariableType.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeEntitiesVariableType.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.core.workflow.flowable;
 
-import org.activiti.engine.impl.variable.SerializableType;
 import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.flowable.engine.impl.variable.SerializableType;
 
 /**
  * Flowable variable type for handling Syncope entities as Flowable variables.

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupManager.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupManager.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupManager.java
deleted file mode 100644
index f73e45d..0000000
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupManager.java
+++ /dev/null
@@ -1,122 +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.core.workflow.flowable;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.activiti.engine.identity.Group;
-import org.activiti.engine.identity.GroupQuery;
-import org.activiti.engine.impl.GroupQueryImpl;
-import org.activiti.engine.impl.Page;
-import org.activiti.engine.impl.persistence.entity.GroupEntity;
-import org.activiti.engine.impl.persistence.entity.GroupIdentityManager;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class SyncopeGroupManager implements GroupIdentityManager, SyncopeSession {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Override
-    public Class<?> getType() {
-        return GroupIdentityManager.class;
-    }
-
-    @Override
-    public Group createNewGroup(final String groupId) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public GroupQuery createNewGroupQuery() {
-        return new SyncopeGroupQueryImpl(groupDAO);
-    }
-
-    @Override
-    public void deleteGroup(final String groupId) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<Group> findGroupsByUser(final String userId) {
-        List<Group> result = Collections.emptyList();
-        User user = userDAO.findByUsername(userId);
-        if (user != null) {
-            result = new ArrayList<>();
-            for (String groupName : userDAO.findAllGroupNames(user)) {
-                result.add(new GroupEntity(groupName));
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<Group> findGroupByQueryCriteria(final GroupQueryImpl query, final Page page) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findGroupCountByQueryCriteria(final GroupQueryImpl query) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<Group> findGroupsByNativeQuery(final Map<String, Object> parameterMap, final int firstResult,
-            final int maxResults) {
-
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findGroupCountByNativeQuery(final Map<String, Object> parameterMap) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void insertGroup(final Group group) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void updateGroup(final Group updatedGroup) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isNewGroup(final Group group) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void flush() {
-    }
-
-    @Override
-    public void close() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupQueryImpl.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupQueryImpl.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupQueryImpl.java
index 035b1a0..b2387e5 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupQueryImpl.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeGroupQueryImpl.java
@@ -18,142 +18,72 @@
  */
 package org.apache.syncope.core.workflow.flowable;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.identity.Group;
-import org.activiti.engine.identity.GroupQuery;
-import org.activiti.engine.impl.persistence.entity.GroupEntity;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.flowable.idm.api.Group;
+import org.flowable.idm.engine.impl.GroupQueryImpl;
+import org.flowable.idm.engine.impl.persistence.entity.GroupEntity;
+import org.flowable.idm.engine.impl.persistence.entity.GroupEntityImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
-public class SyncopeGroupQueryImpl implements GroupQuery {
+public class SyncopeGroupQueryImpl extends GroupQueryImpl {
 
-    private final GroupDAO groupDAO;
+    private static final long serialVersionUID = -2595069675443343682L;
 
-    private String groupId;
+    @Autowired
+    private UserDAO userDAO;
 
-    private List<Group> result;
-
-    public SyncopeGroupQueryImpl(final GroupDAO groupDAO) {
-        this.groupDAO = groupDAO;
-    }
-
-    @Override
-    public GroupQuery groupId(final String groupId) {
-        try {
-            this.groupId = groupId;
-        } catch (NumberFormatException e) {
-            // ignore
-        }
-
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupName(final String groupName) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupNameLike(final String groupNameLike) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupType(final String groupType) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery groupMember(final String groupMemberUserId) {
-        return this;
-    }
-
-    @Override
-    public GroupQuery orderByGroupId() {
-        return this;
-    }
-
-    @Override
-    public GroupQuery orderByGroupName() {
-        return this;
-    }
-
-    @Override
-    public GroupQuery orderByGroupType() {
-        return this;
-    }
+    @Autowired
+    private GroupDAO groupDAO;
 
-    @Override
-    public GroupQuery asc() {
-        return this;
-    }
-
-    @Override
-    public GroupQuery desc() {
-        return this;
-    }
+    private List<Group> result;
 
-    private Group fromSyncopeGroup(final org.apache.syncope.core.persistence.api.entity.group.Group group) {
-        return new GroupEntity(group.getKey());
+    private Group fromSyncopeGroup(final String name) {
+        GroupEntity group = new GroupEntityImpl();
+        group.setId(name);
+        return group;
     }
 
     private void execute() {
-        if (groupId != null) {
-            org.apache.syncope.core.persistence.api.entity.group.Group syncopeGroup = groupDAO.findByName(groupId);
+        if (id != null) {
+            org.apache.syncope.core.persistence.api.entity.group.Group syncopeGroup = groupDAO.findByName(id);
             if (syncopeGroup == null) {
                 result = Collections.emptyList();
             } else {
-                result = Collections.singletonList(fromSyncopeGroup(syncopeGroup));
-            }
-        }
-        if (result == null) {
-            result = new ArrayList<>();
-            for (int page = 1; page <= (groupDAO.count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
-                result.addAll(groupDAO.findAll(page, AnyDAO.DEFAULT_PAGE_SIZE).stream().
-                        map(group -> fromSyncopeGroup(group)).collect(Collectors.toList()));
+                result = Collections.singletonList(fromSyncopeGroup(syncopeGroup.getName()));
             }
+        } else if (userId != null) {
+            result = userDAO.findAllGroupNames(userDAO.findByUsername(userId)).stream().
+                    map(groupName -> fromSyncopeGroup(groupName)).
+                    collect(Collectors.toList());
         }
     }
 
+    @Transactional(readOnly = true)
     @Override
     public long count() {
-        if (result == null) {
-            execute();
-        }
-        return result.size();
-    }
+        checkQueryOk();
 
-    @Override
-    public Group singleResult() {
+        this.resultType = ResultType.COUNT;
         if (result == null) {
             execute();
         }
-        if (result.isEmpty()) {
-            throw new ActivitiException("Empty result");
-        }
-
-        return result.get(0);
+        return result.size();
     }
 
+    @Transactional(readOnly = true)
     @Override
     public List<Group> list() {
+        checkQueryOk();
+
+        this.resultType = ResultType.LIST;
         if (result == null) {
             execute();
         }
         return result;
     }
-
-    @Override
-    public List<Group> listPage(final int firstResult, final int maxResults) {
-        return list();
-    }
-
-    @Override
-    public GroupQuery potentialStarter(final String procDefId) {
-        throw new UnsupportedOperationException();
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeIdmIdentityService.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeIdmIdentityService.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeIdmIdentityService.java
new file mode 100644
index 0000000..7e0dff9
--- /dev/null
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeIdmIdentityService.java
@@ -0,0 +1,51 @@
+/*
+ * 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.core.workflow.flowable;
+
+import org.flowable.idm.api.GroupQuery;
+import org.flowable.idm.api.UserQuery;
+import org.flowable.idm.engine.impl.IdmIdentityServiceImpl;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class SyncopeIdmIdentityService extends IdmIdentityServiceImpl implements ApplicationContextAware {
+
+    private ConfigurableApplicationContext ctx;
+
+    @Override
+    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+        this.ctx = (ConfigurableApplicationContext) ctx;
+    }
+
+    @Override
+    public UserQuery createUserQuery() {
+        return (UserQuery) ctx.getBeanFactory().
+                createBean(SyncopeUserQueryImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+    }
+
+    @Override
+    public GroupQuery createGroupQuery() {
+        return (GroupQuery) ctx.getBeanFactory().
+                createBean(SyncopeGroupQueryImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSession.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSession.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSession.java
index f15d18d..709a61d 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSession.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSession.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.workflow.flowable;
 
-import org.activiti.engine.impl.interceptor.Session;
+import org.flowable.engine.common.impl.interceptor.Session;
 
 public interface SyncopeSession extends Session {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSessionFactory.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSessionFactory.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSessionFactory.java
index 4758d4e..a0420c3 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSessionFactory.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeSessionFactory.java
@@ -18,8 +18,9 @@
  */
 package org.apache.syncope.core.workflow.flowable;
 
-import org.activiti.engine.impl.interceptor.Session;
-import org.activiti.engine.impl.interceptor.SessionFactory;
+import org.flowable.engine.common.impl.interceptor.CommandContext;
+import org.flowable.engine.common.impl.interceptor.Session;
+import org.flowable.engine.common.impl.interceptor.SessionFactory;
 
 public class SyncopeSessionFactory implements SessionFactory {
 
@@ -31,7 +32,7 @@ public class SyncopeSessionFactory implements SessionFactory {
     }
 
     @Override
-    public Session openSession() {
+    public Session openSession(final CommandContext cc) {
         return syncopeSession;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserManager.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserManager.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserManager.java
deleted file mode 100644
index a6cc201..0000000
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserManager.java
+++ /dev/null
@@ -1,166 +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.core.workflow.flowable;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.activiti.engine.identity.Group;
-import org.activiti.engine.identity.Picture;
-import org.activiti.engine.identity.User;
-import org.activiti.engine.identity.UserQuery;
-import org.activiti.engine.impl.Page;
-import org.activiti.engine.impl.UserQueryImpl;
-import org.activiti.engine.impl.persistence.entity.GroupEntity;
-import org.activiti.engine.impl.persistence.entity.IdentityInfoEntity;
-import org.activiti.engine.impl.persistence.entity.UserEntity;
-import org.activiti.engine.impl.persistence.entity.UserIdentityManager;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class SyncopeUserManager implements UserIdentityManager, SyncopeSession {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Override
-    public Class<?> getType() {
-        return UserIdentityManager.class;
-    }
-
-    @Override
-    public Boolean checkPassword(final String userKey, final String password) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public User createNewUser(final String userKey) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public UserQuery createNewUserQuery() {
-        return new SyncopeUserQueryImpl(userDAO, groupDAO);
-    }
-
-    @Override
-    public void deleteUser(final String userKey) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<Group> findGroupsByUser(final String username) {
-        List<Group> result = Collections.emptyList();
-        org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.findByUsername(username);
-        if (user != null) {
-            result = new ArrayList<>();
-            for (String groupName : userDAO.findAllGroupNames(user)) {
-                result.add(new GroupEntity(groupName));
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public UserEntity findUserById(final String username) {
-        UserEntity result = null;
-        org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.findByUsername(username);
-        if (user != null) {
-            result = new UserEntity(username);
-        }
-
-        return result;
-    }
-
-    @Override
-    public void flush() {
-    }
-
-    @Override
-    public void close() {
-    }
-
-    @Override
-    public void insertUser(final User user) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isNewUser(final User user) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void updateUser(final User updatedUser) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Picture getUserPicture(final String string) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setUserPicture(final String string, final Picture pctr) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<User> findUserByQueryCriteria(final UserQueryImpl query, final Page page) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findUserCountByQueryCriteria(final UserQueryImpl query) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public IdentityInfoEntity findUserInfoByUserIdAndKey(final String userKey, final String key) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<String> findUserInfoKeysByUserIdAndType(final String userKey, final String type) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<User> findPotentialStarterUsers(final String proceDefId) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<User> findUsersByNativeQuery(final Map<String, Object> parameterMap,
-            final int firstResult, final int maxResults) {
-
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long findUserCountByNativeQuery(final Map<String, Object> parameterMap) {
-        throw new UnsupportedOperationException();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserQueryImpl.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserQueryImpl.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserQueryImpl.java
index 1e73f99..6e8f0c7c7 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserQueryImpl.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/SyncopeUserQueryImpl.java
@@ -21,186 +21,81 @@ package org.apache.syncope.core.workflow.flowable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.stream.Collectors;
-import org.activiti.engine.ActivitiException;
-import org.activiti.engine.identity.User;
-import org.activiti.engine.identity.UserQuery;
-import org.activiti.engine.impl.persistence.entity.UserEntity;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.flowable.idm.api.User;
+import org.flowable.idm.engine.impl.UserQueryImpl;
+import org.flowable.idm.engine.impl.persistence.entity.UserEntity;
+import org.flowable.idm.engine.impl.persistence.entity.UserEntityImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
-public class SyncopeUserQueryImpl implements UserQuery {
+public class SyncopeUserQueryImpl extends UserQueryImpl {
 
-    private final UserDAO userDAO;
+    private static final long serialVersionUID = 4403344392227706318L;
 
-    private final GroupDAO groupDAO;
+    @Autowired
+    private UserDAO userDAO;
 
-    private String username;
-
-    private String memberOf;
+    @Autowired
+    private GroupDAO groupDAO;
 
     private List<User> result;
 
-    public SyncopeUserQueryImpl(final UserDAO userDAO, final GroupDAO groupDAO) {
-        this.userDAO = userDAO;
-        this.groupDAO = groupDAO;
-    }
-
-    @Override
-    public UserQuery userId(final String id) {
-        this.username = id;
-        return this;
-    }
-
-    @Override
-    public UserQuery userFirstName(final String firstName) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userFirstNameLike(final String firstNameLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userLastName(final String lastName) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userLastNameLike(final String lastNameLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userFullNameLike(final String fullNameLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userEmail(final String email) {
-        return this;
-    }
-
-    @Override
-    public UserQuery userEmailLike(final String emailLike) {
-        return this;
-    }
-
-    @Override
-    public UserQuery memberOfGroup(final String groupId) {
-        memberOf = groupId;
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserId() {
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserFirstName() {
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserLastName() {
-        return this;
-    }
-
-    @Override
-    public UserQuery orderByUserEmail() {
-        return this;
-    }
-
-    @Override
-    public UserQuery asc() {
-        return this;
-    }
-
-    @Override
-    public UserQuery desc() {
-        return this;
-    }
-
-    private User fromSyncopeUser(final org.apache.syncope.core.persistence.api.entity.user.User user) {
-        return new UserEntity(user.getUsername());
+    private User fromSyncopeUser(final org.apache.syncope.core.persistence.api.entity.user.User syncopeUser) {
+        UserEntity user = new UserEntityImpl();
+        user.setId(syncopeUser.getUsername());
+        return user;
     }
 
     private void execute() {
-        if (username != null) {
-            org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.findByUsername(username);
+        if (id != null) {
+            org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.findByUsername(id);
             if (user == null) {
                 result = Collections.<User>emptyList();
-            } else if (memberOf == null || userDAO.findAllGroupNames(user).contains(memberOf)) {
+            } else if (groupId == null || userDAO.findAllGroupNames(user).contains(groupId)) {
                 result = Collections.singletonList(fromSyncopeUser(user));
             }
-        }
-        if (memberOf != null) {
-            Group group = groupDAO.findByName(memberOf);
+        } else if (groupId != null) {
+            Group group = groupDAO.findByName(groupId);
             if (group == null) {
                 result = Collections.<User>emptyList();
             } else {
                 result = new ArrayList<>();
                 List<UMembership> memberships = groupDAO.findUMemberships(group);
                 memberships.stream().map(membership -> fromSyncopeUser(membership.getLeftEnd())).
-                        filter((user) -> (!result.contains(user))).
-                        forEachOrdered((user) -> {
+                        filter(user -> (!result.contains(user))).
+                        forEachOrdered(user -> {
                             result.add(user);
                         });
             }
         }
-        // THIS CAN BE *VERY* DANGEROUS
-        if (result == null) {
-            result = new ArrayList<>();
-            for (int page = 1; page <= (userDAO.count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
-                result.addAll(userDAO.findAll(page, AnyDAO.DEFAULT_PAGE_SIZE).stream().
-                        map(user -> fromSyncopeUser(user)).collect(Collectors.toList()));
-            }
-        }
     }
 
+    @Transactional(readOnly = true)
     @Override
     public long count() {
-        if (result == null) {
-            execute();
-        }
-        return result.size();
-    }
+        checkQueryOk();
 
-    @Override
-    public User singleResult() {
+        this.resultType = ResultType.COUNT;
         if (result == null) {
             execute();
         }
-        if (result.isEmpty()) {
-            throw new ActivitiException("Empty result");
-        }
-
-        return result.get(0);
+        return result.size();
     }
 
+    @Transactional(readOnly = true)
     @Override
     public List<User> list() {
-        if (result == null) {
-            execute();
-        }
-        return result;
-    }
+        checkQueryOk();
 
-    @Override
-    public List<User> listPage(final int firstResult, final int maxResults) {
+        this.resultType = ResultType.LIST;
         if (result == null) {
             execute();
         }
-        return result.subList(firstResult, firstResult + maxResults - 1);
+        return result;
     }
 
-    @Override
-    public UserQuery potentialStarter(final String string) {
-        throw new UnsupportedOperationException();
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngine.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngine.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngine.java
index c8e9141..92e9aff 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngine.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngine.java
@@ -21,18 +21,18 @@ package org.apache.syncope.core.workflow.flowable.spring;
 import java.util.Collections;
 import java.util.Map;
 import javax.sql.DataSource;
-import org.activiti.engine.DynamicBpmnService;
-import org.activiti.engine.FormService;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.IdentityService;
-import org.activiti.engine.ManagementService;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.ProcessEngineConfiguration;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.TaskService;
-import org.activiti.engine.impl.ProcessEngineImpl;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.flowable.engine.DynamicBpmnService;
+import org.flowable.engine.FormService;
+import org.flowable.engine.HistoryService;
+import org.flowable.engine.IdentityService;
+import org.flowable.engine.ManagementService;
+import org.flowable.engine.ProcessEngine;
+import org.flowable.engine.ProcessEngineConfiguration;
+import org.flowable.engine.RepositoryService;
+import org.flowable.engine.RuntimeService;
+import org.flowable.engine.TaskService;
+import org.flowable.engine.impl.ProcessEngineImpl;
 
 /**
  * {@link ProcessEngine} delegating actual method invocation to the inner map of {@link ProcessEngine} instances,
@@ -57,9 +57,9 @@ public class DomainProcessEngine implements ProcessEngine {
 
     @Override
     public void close() {
-        for (ProcessEngine engine : engines.values()) {
+        engines.values().forEach(engine -> {
             engine.close();
-        }
+        });
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngineFactoryBean.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngineFactoryBean.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngineFactoryBean.java
index 620d6b9..fbd0f22 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngineFactoryBean.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/spring/DomainProcessEngineFactoryBean.java
@@ -21,11 +21,14 @@ package org.apache.syncope.core.workflow.flowable.spring;
 import java.util.HashMap;
 import java.util.Map;
 import javax.sql.DataSource;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.impl.cfg.SpringBeanFactoryProxyMap;
-import org.activiti.spring.SpringExpressionManager;
-import org.activiti.spring.SpringProcessEngineConfiguration;
 import org.apache.commons.lang3.StringUtils;
+import org.flowable.engine.ProcessEngine;
+import org.flowable.engine.common.impl.cfg.SpringBeanFactoryProxyMap;
+import org.flowable.engine.common.impl.interceptor.EngineConfigurationConstants;
+import org.flowable.engine.impl.util.EngineServiceUtil;
+import org.flowable.idm.spring.SpringIdmEngineConfiguration;
+import org.flowable.spring.SpringExpressionManager;
+import org.flowable.spring.SpringProcessEngineConfiguration;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.FactoryBean;
@@ -54,29 +57,34 @@ public class DomainProcessEngineFactoryBean
         if (engine == null) {
             Map<String, ProcessEngine> engines = new HashMap<>();
 
-            for (Map.Entry<String, DataSource> entry : ctx.getBeansOfType(DataSource.class).entrySet()) {
-                if (!entry.getKey().startsWith("local")) {
-                    String domain = StringUtils.substringBefore(entry.getKey(), DataSource.class.getSimpleName());
-                    DataSource dataSource = entry.getValue();
-                    PlatformTransactionManager transactionManager = ctx.getBean(
-                            domain + "TransactionManager", PlatformTransactionManager.class);
-                    Object entityManagerFactory = ctx.getBean(domain + "EntityManagerFactory");
+            ctx.getBeansOfType(DataSource.class).entrySet().stream().
+                    filter(entry -> (!entry.getKey().startsWith("local"))).
+                    forEachOrdered(entry -> {
+                        String domain = StringUtils.substringBefore(entry.getKey(), DataSource.class.getSimpleName());
+                        DataSource dataSource = entry.getValue();
+                        PlatformTransactionManager transactionManager = ctx.getBean(
+                                domain + "TransactionManager", PlatformTransactionManager.class);
+                        Object entityManagerFactory = ctx.getBean(domain + "EntityManagerFactory");
 
-                    SpringProcessEngineConfiguration conf = ctx.getBean(SpringProcessEngineConfiguration.class);
-                    conf.setDataSource(dataSource);
-                    conf.setTransactionManager(transactionManager);
-                    conf.setTransactionsExternallyManaged(true);
-                    conf.setJpaEntityManagerFactory(entityManagerFactory);
-                    if (conf.getBeans() == null) {
-                        conf.setBeans(new SpringBeanFactoryProxyMap(ctx));
-                    }
-                    if (conf.getExpressionManager() == null) {
-                        conf.setExpressionManager(new SpringExpressionManager(ctx, conf.getBeans()));
-                    }
+                        SpringProcessEngineConfiguration conf = ctx.getBean(SpringProcessEngineConfiguration.class);
+                        conf.setDataSource(dataSource);
+                        conf.setTransactionManager(transactionManager);
+                        conf.setTransactionsExternallyManaged(true);
+                        conf.setJpaEntityManagerFactory(entityManagerFactory);
+                        if (conf.getBeans() == null) {
+                            conf.setBeans(new SpringBeanFactoryProxyMap(ctx));
+                        }
+                        if (conf.getExpressionManager() == null) {
+                            conf.setExpressionManager(new SpringExpressionManager(ctx, conf.getBeans()));
+                        }
+                        if (EngineServiceUtil.getIdmEngineConfiguration(conf) == null) {
+                            conf.addEngineConfiguration(
+                                    EngineConfigurationConstants.KEY_IDM_ENGINE_CONFIG,
+                                    ctx.getBean(SpringIdmEngineConfiguration.class));
+                        }
 
-                    engines.put(domain, conf.buildProcessEngine());
-                }
-            }
+                        engines.put(domain, conf.buildProcessEngine());
+                    });
 
             engine = new DomainProcessEngine(engines);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/task/AbstractFlowableServiceTask.java
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/task/AbstractFlowableServiceTask.java b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/task/AbstractFlowableServiceTask.java
index c3a5ba1..b9f87ca 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/task/AbstractFlowableServiceTask.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/task/AbstractFlowableServiceTask.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.workflow.flowable.task;
 
-import org.activiti.engine.ProcessEngine;
+import org.flowable.engine.ProcessEngine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/resources/workflow.properties b/core/workflow-flowable/src/main/resources/workflow.properties
index 50c42fc..36af01c 100644
--- a/core/workflow-flowable/src/main/resources/workflow.properties
+++ b/core/workflow-flowable/src/main/resources/workflow.properties
@@ -16,7 +16,6 @@
 # under the License.
 wf.directory=${conf.directory}
 historyLevel=activity
-jobExecutorActivate=true
 uwfAdapter=org.apache.syncope.core.workflow.flowable.FlowableUserWorkflowAdapter
 gwfAdapter=org.apache.syncope.core.workflow.java.DefaultGroupWorkflowAdapter
 awfAdapter=org.apache.syncope.core.workflow.java.DefaultAnyObjectWorkflowAdapter

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/core/workflow-flowable/src/main/resources/workflowFlowableContext.xml
----------------------------------------------------------------------
diff --git a/core/workflow-flowable/src/main/resources/workflowFlowableContext.xml b/core/workflow-flowable/src/main/resources/workflowFlowableContext.xml
index 517b8d7..aed5e2e 100644
--- a/core/workflow-flowable/src/main/resources/workflowFlowableContext.xml
+++ b/core/workflow-flowable/src/main/resources/workflowFlowableContext.xml
@@ -32,29 +32,23 @@ under the License.
 
   <bean id="flowableUtils" class="org.apache.syncope.core.workflow.flowable.FlowableUtils"/>
 
-  <bean id="syncopeFlowableUserManager" class="org.apache.syncope.core.workflow.flowable.SyncopeUserManager"/>
-  <bean id="syncopeFlowableGroupManager" class="org.apache.syncope.core.workflow.flowable.SyncopeGroupManager"/>
-
-  <bean class="org.activiti.spring.SpringProcessEngineConfiguration" scope="prototype">
-    <property name="transactionsExternallyManaged" value="true"/>
+  <bean id="syncopeIdmIdentityService" class="org.apache.syncope.core.workflow.flowable.SyncopeIdmIdentityService"/>
+  <bean id="syncopeIdmEngineConfiguration" class="org.flowable.idm.spring.SpringIdmEngineConfiguration">
+    <property name="idmIdentityService" ref="syncopeIdmIdentityService"/> 
+  </bean>
+  <bean id="syncopeIdmEngineConfigurator" class="org.flowable.spring.configurator.SpringIdmEngineConfigurator">
+    <property name="idmEngineConfiguration" ref="syncopeIdmEngineConfiguration"/> 
+  </bean>
+  
+  <bean class="org.flowable.spring.SpringProcessEngineConfiguration" scope="prototype">
     <property name="databaseSchemaUpdate" value="true"/>
 
     <property name="jpaHandleTransaction" value="true"/>
     <property name="jpaCloseEntityManager" value="false"/>
 
     <property name="history" value="${historyLevel}"/>
-    <property name="jobExecutorActivate" value="${jobExecutorActivate}"/>
 
-    <property name="customSessionFactories">
-      <list>
-        <bean class="org.apache.syncope.core.workflow.flowable.SyncopeSessionFactory">
-          <property name="syncopeSession" ref="syncopeFlowableUserManager"/>
-        </bean>
-        <bean class="org.apache.syncope.core.workflow.flowable.SyncopeSessionFactory">
-          <property name="syncopeSession" ref="syncopeFlowableGroupManager"/>
-        </bean>
-      </list>
-    </property>
+    <property name="idmProcessEngineConfigurator" ref="syncopeIdmEngineConfigurator"/>
     <property name="customPreVariableTypes">
       <list>
         <bean class="org.apache.syncope.core.workflow.flowable.SyncopeEntitiesVariableType"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/fit/console-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml
index f46136e..2c64c2d 100644
--- a/fit/console-reference/pom.xml
+++ b/fit/console-reference/pom.xml
@@ -111,7 +111,7 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.flowable</groupId>
-      <artifactId>flowable-webapp-explorer2</artifactId>
+      <artifactId>flowable-ui-modeler-app</artifactId>
       <type>war</type>
       <scope>test</scope>
     </dependency>
@@ -144,34 +144,25 @@ under the License.
             <phase>process-resources</phase>
             <configuration>
               <target>
-                <unzip src="${settings.localRepository}/org/flowable/flowable-webapp-explorer2/${flowable.version}/flowable-webapp-explorer2-${flowable.version}.war" 
-                       dest="${project.build.directory}/flowable-webapp-explorer2"/>
+                <unzip src="${settings.localRepository}/org/flowable/flowable-ui-modeler-app/${flowable.version}/flowable-ui-modeler-app-${flowable.version}.war" 
+                       dest="${flowable-modeler.directory}"/>
                 
-                <mkdir dir="${flowable-modeler.directory}"/>
-                <copy file="${project.build.directory}/flowable-webapp-explorer2/modeler.html" 
-                      todir="${flowable-modeler.directory}"/>
-                <replace file="${flowable-modeler.directory}/modeler.html"
+                <replace file="${flowable-modeler.directory}/index.html"
                          token="&lt;/head&gt;"
                          value="&lt;script type=&quot;text/javascript&quot;&gt;window.onunload = refreshParent; function refreshParent() { window.opener.location.reload(); }&lt;/script&gt;&lt;/head&gt;"/>
-                <copy file="${project.build.directory}/flowable-webapp-explorer2/WEB-INF/classes/stencilset.json" 
-                      todir="${flowable-modeler.directory}"/>
-
-                <mkdir dir="${flowable-modeler.directory}/editor-app"/>
-                <copy todir="${flowable-modeler.directory}/editor-app">
-                  <fileset dir="${project.build.directory}/flowable-webapp-explorer2/editor-app"/>                  
-                </copy>
-                <replace file="${flowable-modeler.directory}/editor-app/editor/oryx.debug.js"
-                         token="return this.changeDifference !== 0 || (this.facade.getModelMetaData()['new'] &amp;&amp; this.facade.getCanvas().getChildShapes().size() &gt; 0);"
-                         value="return this.changeDifference !== 0 
-              || (typeof this.facade.getModelMetaData() != 'undefined' 
-              &amp;&amp; this.facade.getModelMetaData()['new'] &amp;&amp; this.facade.getCanvas().getChildShapes().size() &gt; 0);"/>
                 <replace file="${flowable-modeler.directory}/editor-app/configuration/toolbar-default-actions.js"
-                         token="window.location.href = &quot;./&quot;;"
+                         token="$location.path('/processes');"
                          value="window.close();"/>
-                                               
+
+                <copy file="${basedir}/src/main/resources/app-cfg.js" 
+                      todir="${flowable-modeler.directory}/scripts"
+                      overwrite="true"/>
                 <copy file="${basedir}/src/main/resources/url-config.js" 
                       todir="${flowable-modeler.directory}/editor-app/configuration"
                       overwrite="true"/>
+                <copy file="${basedir}/src/main/resources/stencilset.json" 
+                      todir="${flowable-modeler.directory}"
+                      overwrite="true"/>
                 <copy file="${basedir}/src/main/resources/save-model.html" 
                       todir="${flowable-modeler.directory}/editor-app/popups"
                       overwrite="true"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/fit/console-reference/src/main/resources/app-cfg.js
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/main/resources/app-cfg.js b/fit/console-reference/src/main/resources/app-cfg.js
new file mode 100644
index 0000000..ec812b4
--- /dev/null
+++ b/fit/console-reference/src/main/resources/app-cfg.js
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+'use strict';
+
+var FLOWABLE = FLOWABLE || {};
+
+FLOWABLE.CONFIG = {
+  'onPremise': true,
+  'contextRoot': window.location.toString().substr(0, window.location.toString().indexOf('/flowable-modeler')),
+  'webContextRoot': window.location.toString().substr(0, window.location.toString().indexOf('/flowable-modeler')),
+  'datesLocalization': false
+};

http://git-wip-us.apache.org/repos/asf/syncope/blob/f27e1bb4/fit/console-reference/src/main/resources/save-model.html
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/main/resources/save-model.html b/fit/console-reference/src/main/resources/save-model.html
index 4c6173d..abd5ecf 100644
--- a/fit/console-reference/src/main/resources/save-model.html
+++ b/fit/console-reference/src/main/resources/save-model.html
@@ -23,28 +23,101 @@ under the License.
         <h2>{{'MODEL.SAVE.TITLE'| translate}}</h2>
       </div>
       <div class="modal-body">
-
+        <div ng-if="saveDialog.errorMessage && saveDialog.errorMessage.length > 0" class="alert error" style="font-size: 14px; margin-top:20px">
+          <div class="popup-error" style="font-size: 14px">
+            <span class="glyphicon glyphicon-remove-circle"></span>
+            <span>{{saveDialog.errorMessage}}</span>
+          </div>
+        </div>
         <div class="form-group">
           <label for="nameField">{{'MODEL.NAME'| translate}}</label>
           <input type="text"
-                 ng-disabled="status.loading"
+                 ng-disabled="status.loading || (error && error.conflictResolveAction == 'saveAs')"
                  id="nameField"
                  class="form-control"
-                 ng-model="saveDialog.name"
-                 ui-keypress="{13:'save()'}"
-                 auto-focus readonly/>
+                 ng-model="saveDialog.name" readonly="readonly"
+                 auto-focus />
         </div>
-        <div class="form-group">
+        <div class="form-group" style="display: none">
+          <label for="keyField">{{'MODEL.KEY'| translate}}</label>
+          <input type="text"
+                 ng-disabled="status.loading || (error && error.conflictResolveAction == 'saveAs')"
+                 id="keyField"
+                 class="form-control"
+                 ng-model="saveDialog.key" ng-init="saveDialog.key = saveDialog.name"/>
+        </div>
+        <div class="form-group" style="display: none">
           <label for="docTextArea">{{'MODEL.DESCRIPTION'| translate}}</label>
-          <textarea id="docTextArea" ng-disabled="status.loading" class="form-control" 
-                    ng-model="saveDialog.description" readonly></textarea>
+          <textarea id="docTextArea" ng-disabled="status.loading" class="form-control" ng-model="saveDialog.description"></textarea>
+        </div>
+        <div class="checkbox" ng-show="!error && !error.isConflict" style="display: none">
+          <label>
+            <input type="checkbox" ng-disabled="status.loading" ng-model="saveDialog.newVersion" >
+            {{'MODEL.SAVE.NEWVERSION'| translate}}
+          </label>
+        </div>
+        <div class="form-group" ng-if="saveDialog.newVersion">
+          <label for="commentTextArea">{{'MODEL.SAVE.COMMENT'| translate}}</label>
+          <textarea id="commentTextArea" class="form-control" ng-model="saveDialog.comment" ng-disabled="status.loading"></textarea>
         </div>
+
+        <div ng-if="saveDialog.validationErrors" class="alert error" style="font-size: 14px; margin-top:20px">
+
+          <div class="popup-error" style="font-size: 14px">
+            <span class="glyphicon glyphicon-remove-circle"></span>
+            <span>{{'MODEL.VALIDATIONERRORS'| translate:error}}</span>
+          </div>
+        </div>
+
+        <div ng-if="error && error.isConflict && !status.loading" class="alert error" style="font-size: 14px; margin-top:20px">
+
+          <div class="popup-error" style="font-size: 14px">
+            <span class="glyphicon glyphicon-remove-circle"></span>
+            <span>{{'MODEL.CONFLICT.WRITE'| translate:error}}</span>
+          </div>
+
+          <div>
+
+            <div style="font-size: 14px; margin-bottom: 10px">{{'MODEL.CONFLICT.WRITE.OPTIONS'| translate}}</div>
+            <div class="btn-group" data-toggle="buttons">
+              <label class="btn btn-danger"
+                     ng-click="error.conflictResolveAction = 'overwrite'">
+                <input type="radio" name="options" id="option1">
+                {{'MODEL.CONFLICT.WRITE.OPTION.OVERWRITE'| translate}}
+              </label>
+              <label class="btn btn-danger"
+                     ng-click="error.conflictResolveAction = 'discardChanges'">
+                <input type="radio" name="options" id="option2">
+                {{'MODEL.CONFLICT.WRITE.OPTION.DISCARDCHANGES'| translate}}
+              </label>
+              <label class="btn btn-danger"
+                     ng-click="error.conflictResolveAction = 'saveAs'">
+                <input type="radio" name="options" id="option3" ng-disabled="account.type != 'enterprise'">
+                {{'MODEL.CONFLICT.WRITE.OPTION.SAVEAS'| translate}}
+              </label>
+              <label class="btn btn-danger"
+                     ng-click="error.conflictResolveAction = 'newVersion'">
+                <input type="radio" name="options" id="optio43">
+                {{'MODEL.CONFLICT.WRITE.OPTION.NEWVERSION'| translate}}
+              </label>
+            </div>
+
+            <div ng-if="error.conflictResolveAction == 'saveAs'" style="margin-top: 10px">
+              <span>{{'MODEL.CONFLICT.SAVEAS'| translate}}</span>
+              <input type="text" ng-model="error.saveAs" style="width: 300px" auto-focus>
+            </div>
+          </div>
+
+        </div>
+
       </div>
       <div class="modal-footer">
 
         <div class="pull-right">
           <button type="button" class="btn" ng-click="close()" ng-disabled="status.loading" translate>ACTION.CANCEL</button>
-          <button class="btn btn-primary" ng-click="saveAndClose()" ng-disabled="status.loading" ng-show="!error" translate>ACTION.SAVE-AND-CLOSE</button>
+          <button class="btn btn-primary" ng-click="saveAndClose()" ng-disabled="status.loading || saveDialog.name.length == 0 || saveDialog.key.length == 0" ng-show="!error && !error.isConflict" translate>ACTION.SAVE-AND-CLOSE</button>
+          <button class="btn btn-primary" ng-click="save()" ng-disabled="status.loading || saveDialog.name.length == 0 || saveDialog.key.length == 0" ng-show="!error && !error.isConflict" style="display: none" translate>ACTION.SAVE</button>
+          <button class="btn btn-primary" ng-click="okClicked()" ng-disabled="isOkButtonDisabled()" ng-show="error && error.isConflict" translate>ACTION.OK</button>
         </div>
 
         <div class="pull-right popup-error" ng-if="error && !error.isConflict">
@@ -56,4 +129,4 @@ under the License.
       </div>
     </div>
   </div>
-</div>
\ No newline at end of file
+</div>