[SYNCOPE-152] Implementations for /ServiceProviderConfig /ResourceTypes and 
/Schemas - still static


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

Branch: refs/heads/master
Commit: f04ab6c26e99ae0a5fe19915e303fa965fcd6332
Parents: 5697a5f
Author: Francesco Chicchiriccò <ilgro...@apache.org>
Authored: Tue Oct 31 15:10:24 2017 +0100
Committer: Francesco Chicchiriccò <ilgro...@apache.org>
Committed: Tue Oct 31 15:16:53 2017 +0100

----------------------------------------------------------------------
 ext/scimv2/logic/pom.xml                        |  62 ++
 .../apache/syncope/core/logic/RootLogic.java    | 143 +++
 .../syncope/core/logic/init/SCIMLoader.java     | 106 ++
 .../logic/src/main/resources/schemas.json       | 960 +++++++++++++++++++
 .../src/main/resources/scimv2-logic.properties  |  21 +
 ext/scimv2/pom.xml                              |   1 +
 .../scimv2/api/data/AuthenticationScheme.java   |  82 ++
 .../api/data/BulkConfigurationOption.java       |  51 +
 .../scimv2/api/data/ConfigurationOption.java    |  39 +
 .../api/data/FilterConfigurationOption.java     |  43 +
 .../ext/scimv2/api/data/ListResponse.java       |   4 +-
 .../syncope/ext/scimv2/api/data/Member.java     |   6 +-
 .../syncope/ext/scimv2/api/data/Meta.java       |  13 +-
 .../ext/scimv2/api/data/ResourceType.java       |  97 ++
 .../ext/scimv2/api/data/SchemaExtension.java    |  49 +
 .../scimv2/api/data/ServiceProviderConfig.java  |  97 ++
 .../ext/scimv2/api/service/GroupService.java    |   2 +-
 .../ext/scimv2/api/service/RootService.java     |  24 +-
 .../ext/scimv2/api/service/UserService.java     |   2 +-
 .../syncope/ext/scimv2/api/type/Resource.java   |  41 +
 .../ext/scimv2/api/type/ResourceType.java       |  37 -
 ext/scimv2/scim-rest-cxf/pom.xml                |   7 +-
 .../syncope/ext/scimv2/cxf/AddETagFilter.java   |  55 ++
 .../scimv2/cxf/service/AbstractSCIMService.java |  22 +-
 .../scimv2/cxf/service/GroupServiceImpl.java    |   4 +-
 .../ext/scimv2/cxf/service/RootServiceImpl.java |  39 +-
 .../ext/scimv2/cxf/service/UserServiceImpl.java |   4 +-
 .../src/main/resources/restSCIMv2CXFContext.xml |   3 +
 .../main/resources/all/scimv2-logic.properties  |  21 +
 .../org/apache/syncope/fit/SCIMDetector.java    |  13 +-
 .../org/apache/syncope/fit/core/SCIMITCase.java |  89 +-
 fit/core-reference/src/test/resources/rebel.xml |   2 +
 32 files changed, 2033 insertions(+), 106 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/logic/pom.xml b/ext/scimv2/logic/pom.xml
new file mode 100644
index 0000000..abc90b1
--- /dev/null
+++ b/ext/scimv2/logic/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.syncope.ext</groupId>
+    <artifactId>syncope-ext-scimv2</artifactId>
+    <version>2.1.0-SNAPSHOT</version>
+  </parent>
+
+  <name>Apache Syncope Ext: SCIMv2 Logic</name>
+  <description>Apache Syncope Ext: SCIMv2 Logic</description>
+  <groupId>org.apache.syncope.ext.scimv2</groupId>
+  <artifactId>syncope-ext-scimv2-logic</artifactId>
+  <packaging>jar</packaging>
+  
+  <properties>
+    <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.syncope.core</groupId>
+      <artifactId>syncope-core-logic</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.syncope.ext.scimv2</groupId>
+      <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java 
b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java
new file mode 100644
index 0000000..75d0ecf
--- /dev/null
+++ 
b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java
@@ -0,0 +1,143 @@
+/*
+ * 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.logic;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.UriBuilder;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.core.logic.init.SCIMLoader;
+import org.apache.syncope.ext.scimv2.api.data.AuthenticationScheme;
+import org.apache.syncope.ext.scimv2.api.data.BulkConfigurationOption;
+import org.apache.syncope.ext.scimv2.api.data.ConfigurationOption;
+import org.apache.syncope.ext.scimv2.api.data.FilterConfigurationOption;
+import org.apache.syncope.ext.scimv2.api.data.Meta;
+import org.apache.syncope.ext.scimv2.api.data.ResourceType;
+import org.apache.syncope.ext.scimv2.api.data.SchemaExtension;
+import org.apache.syncope.ext.scimv2.api.data.ServiceProviderConfig;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RootLogic extends AbstractLogic<AbstractBaseBean> {
+
+    private static final Object MONITOR = new Object();
+
+    private static ServiceProviderConfig SERVICE_PROVIDER_CONFIG;
+
+    private static ResourceType USER;
+
+    private static ResourceType GROUP;
+
+    @Autowired
+    private SCIMLoader loader;
+
+    @PreAuthorize("isAuthenticated()")
+    public ServiceProviderConfig serviceProviderConfig() {
+        synchronized (MONITOR) {
+            if (SERVICE_PROVIDER_CONFIG == null) {
+                SERVICE_PROVIDER_CONFIG = new ServiceProviderConfig(
+                        new ConfigurationOption(true),
+                        new BulkConfigurationOption(
+                                true, loader.getBulkMaxOperations(), 
loader.getBulkMaxPayloadSize()),
+                        new FilterConfigurationOption(true, 
loader.getFilterMaxResults()),
+                        new ConfigurationOption(true),
+                        new ConfigurationOption(true),
+                        new ConfigurationOption(true));
+                SERVICE_PROVIDER_CONFIG.getAuthenticationSchemes().add(new 
AuthenticationScheme(
+                        "JSON Web Token",
+                        "Apache Syncope JWT authentication",
+                        URI.create("http://www.rfc-editor.org/info/rfc6750";),
+                        URI.create("https://syncope.apache.org/docs/";
+                                + 
"reference-guide.html#rest-authentication-and-authorization"),
+                        "oauthbearertoken",
+                        true));
+                SERVICE_PROVIDER_CONFIG.getAuthenticationSchemes().add(new 
AuthenticationScheme(
+                        "HTTP Basic",
+                        "Apache Syncope HTTP Basic authentication",
+                        URI.create("http://www.rfc-editor.org/info/rfc2617";),
+                        URI.create("https://syncope.apache.org/docs/";
+                                + 
"reference-guide.html#rest-authentication-and-authorization"),
+                        "httpbasic",
+                        false));
+            }
+        }
+        return SERVICE_PROVIDER_CONFIG;
+    }
+
+    @PreAuthorize("isAuthenticated()")
+    public List<ResourceType> resourceTypes(final UriBuilder uriBuilder) {
+        synchronized (MONITOR) {
+            if (USER == null) {
+                USER = new ResourceType("User", "User", "/Users", "User 
Account", Resource.User.schema(),
+                        new Meta(Resource.ResourceType,
+                                null, null, null, 
uriBuilder.path("User").build().toASCIIString()));
+                USER.getSchemaExtensions().add(new 
SchemaExtension(Resource.EnterpriseUser.schema(), true));
+            }
+            if (GROUP == null) {
+                GROUP = new ResourceType("Group", "Group", "/Groups", "Group", 
Resource.Group.schema(),
+                        new Meta(Resource.ResourceType,
+                                null, null, null, 
uriBuilder.path("Group").build().toASCIIString()));
+            }
+        }
+
+        return Arrays.asList(USER, GROUP);
+    }
+
+    @PreAuthorize("isAuthenticated()")
+    public ResourceType resourceType(final UriBuilder uriBuilder, final String 
type) {
+        if (Resource.User.name().equals(type)) {
+            resourceTypes(uriBuilder);
+            return USER;
+        } else if (Resource.Group.name().equals(type)) {
+            resourceTypes(uriBuilder);
+            return GROUP;
+        } else {
+            throw new IllegalArgumentException("Unsupported resource type: " + 
type);
+        }
+    }
+
+    @PreAuthorize("isAuthenticated()")
+    public String schemas() {
+        return loader.getSchemas();
+    }
+
+    @PreAuthorize("isAuthenticated()")
+    public String schema(final String schema) {
+        String found = loader.getSchema(schema);
+        if (found == null) {
+            throw new NotFoundException("Schema " + schema);
+        }
+
+        return found;
+    }
+
+    @Override
+    protected AbstractBaseBean resolveReference(final Method method, final 
Object... args)
+            throws UnresolvedReferenceException {
+
+        throw new UnresolvedReferenceException();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java
 
b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java
new file mode 100644
index 0000000..894ba24
--- /dev/null
+++ 
b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java
@@ -0,0 +1,106 @@
+/*
+ * 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.logic.init;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.PropertyUtils;
+import org.apache.syncope.core.persistence.api.SyncopeLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SCIMLoader implements SyncopeLoader {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(SCIMLoader.class);
+
+    private static final String SCIMV2_LOGIC_PROPERTIES = 
"scimv2-logic.properties";
+
+    private static final String SCHEMAS = "schemas.json";
+
+    private int bulkMaxOperations = 0;
+
+    private int bulkMaxPayloadSize = 0;
+
+    private int filterMaxResults = 0;
+
+    private String schemas;
+
+    private final Map<String, String> schemaMap = new HashMap<>();
+
+    @Override
+    public Integer getPriority() {
+        return 1000;
+    }
+
+    @Override
+    public void load() {
+        Pair<Properties, String> init = PropertyUtils.read(getClass(), 
SCIMV2_LOGIC_PROPERTIES, "conf.directory");
+        Properties props = init.getLeft();
+
+        bulkMaxOperations = 
Integer.valueOf(props.getProperty("bulk.maxOperations"));
+        bulkMaxPayloadSize = 
Integer.valueOf(props.getProperty("bulk.maxPayloadSize"));
+        filterMaxResults = 
Integer.valueOf(props.getProperty("filter.maxResults"));
+
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode tree = mapper.readTree(getClass().getResourceAsStream("/" 
+ SCHEMAS));
+            if (!tree.isArray()) {
+                throw new IOException("JSON node is not a tree");
+            }
+
+            ArrayNode schemaArray = (ArrayNode) tree;
+            schemas = 
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(tree);
+
+            for (JsonNode schema : schemaArray) {
+                schemaMap.put(schema.get("id").asText(), 
mapper.writeValueAsString(schema));
+            }
+        } catch (IOException e) {
+            LOG.error("Could not parse the default schema definitions", e);
+        }
+    }
+
+    public int getBulkMaxOperations() {
+        return bulkMaxOperations;
+    }
+
+    public int getBulkMaxPayloadSize() {
+        return bulkMaxPayloadSize;
+    }
+
+    public int getFilterMaxResults() {
+        return filterMaxResults;
+    }
+
+    public String getSchemas() {
+        return schemas;
+    }
+
+    public String getSchema(final String schema) {
+        return schemaMap.get(schema);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/resources/schemas.json
----------------------------------------------------------------------
diff --git a/ext/scimv2/logic/src/main/resources/schemas.json 
b/ext/scimv2/logic/src/main/resources/schemas.json
new file mode 100644
index 0000000..2b9558b
--- /dev/null
+++ b/ext/scimv2/logic/src/main/resources/schemas.json
@@ -0,0 +1,960 @@
+[
+  {
+    "id": "urn:ietf:params:scim:schemas:core:2.0:User",
+    "name": "User",
+    "description": "User Account",
+    "attributes": [
+      {
+        "name": "userName",
+        "type": "string",
+        "multiValued": false,
+        "description": "Unique identifier for the User, typically used by the 
user to directly authenticate to the service provider. Each User MUST include a 
non-empty userName value. This identifier MUST be unique across the service 
provider's entire set of Users. REQUIRED.",
+        "required": true,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "server"
+      },
+      {
+        "name": "name",
+        "type": "complex",
+        "multiValued": false,
+        "description": "The components of the user's real name. Providers MAY 
return just the full name as a single string in the formatted sub-attribute, or 
they MAY return just the individual component attributes using the other 
sub-attributes, or they MAY return both. If both variants are returned, they 
SHOULD be describing the same name, with the formatted name indicating how the 
component attributes should be combined.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "formatted",
+            "type": "string",
+            "multiValued": false,
+            "description": "The full name, including all middle names, titles, 
and suffixes as appropriate, formatted for display 'Ms. Barbara J Jensen, 
III').",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "familyName",
+            "type": "string",
+            "multiValued": false,
+            "description": "The family name of the User, or last name in most 
Western languages (e.g., 'Jensen' given the full name 'Ms. Barbara J Jensen, 
III').",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "givenName",
+            "type": "string",
+            "multiValued": false,
+            "description": "The given name of the User, or first name in most 
Western languages (e.g., 'Barbara' given the full name 'Ms. Barbara J Jensen, 
III').",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "middleName",
+            "type": "string",
+            "multiValued": false,
+            "description": "The middle name(s) of the User (e.g., 'Jane' given 
the full name 'Ms. Barbara J Jensen, III').",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "honorificPrefix",
+            "type": "string",
+            "multiValued": false,
+            "description": "The honorific prefix(es) of the User, or title in 
most Western languages (e.g., 'Ms.' given the full name 'Ms. Barbara J Jensen, 
III').",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "honorificSuffix",
+            "type": "string",
+            "multiValued": false,
+            "description": "The honorific suffix(es) of the User, or suffix in 
most Western languages (e.g., 'III' given the full name 'Ms. Barbara J Jensen, 
III').",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "displayName",
+        "type": "string",
+        "multiValued": false,
+        "description": "The name of the User, suitable for display to 
end-users. The name SHOULD be the full name of the User being described, if 
known.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "nickName",
+        "type": "string",
+        "multiValued": false,
+        "description": "The casual way to address the user in real life, e.g., 
'Bob' or 'Bobby' instead of 'Robert'. This attribute SHOULD NOT be used to 
represent a User's username (e.g., 'bjensen' or 'mpepperidge').",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "profileUrl",
+        "type": "reference",
+        "referenceTypes": ["external"],
+        "multiValued": false,
+        "description": "A fully qualified URL pointing to a page representing 
the User's online profile.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "title",
+        "type": "string",
+        "multiValued": false,
+        "description": "The user's title, such as \"Vice President.\"",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "userType",
+        "type": "string",
+        "multiValued": false,
+        "description": "Used to identify the relationship between the 
organization and the user. Typical values used might be 'Contractor', 
'Employee', 'Intern', 'Temp', 'External', and 'Unknown', but any value may be 
used.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "preferredLanguage",
+        "type": "string",
+        "multiValued": false,
+        "description": "Indicates the User's preferred written or spoken 
language. Generally used for selecting a localized user interface; e.g., 
'en_US' specifies the language English and country US.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "locale",
+        "type": "string",
+        "multiValued": false,
+        "description": "Used to indicate the User's default location for 
purposes of localizing items such as currency, date time format, or numerical 
representations.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "timezone",
+        "type": "string",
+        "multiValued": false,
+        "description": "The User's time zone in the 'Olson' time zone database 
format, e.g., 'America/Los_Angeles'.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "active",
+        "type": "boolean",
+        "multiValued": false,
+        "description": "A Boolean value indicating the User's administrative 
status.",
+        "required": false,
+        "mutability": "readWrite",
+        "returned": "default"
+      },
+      {
+        "name": "password",
+        "type": "string",
+        "multiValued": false,
+        "description": "The User's cleartext password. This attribute is 
intended to be used as a means to specify an initial password when creating a 
new User or to reset an existing User's password.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "writeOnly",
+        "returned": "never",
+        "uniqueness": "none"
+      },
+      {
+        "name": "emails",
+        "type": "complex",
+        "multiValued": true,
+        "description": "Email addresses for the user. The value SHOULD be 
canonicalized by the service provider, e.g., 'bjen...@example.com' instead of 
'bjen...@example.com'. Canonical type values of 'work', 'home', and 'other'.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "Email addresses for the user. The value SHOULD be 
canonicalized by the service provider, e.g., 'bjen...@example.com' instead of 
'bjen...@example.com'. Canonical type values of 'work', 'home', and 'other'.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function, e.g., 
'work' or 'home'.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [
+              "work",
+              "home",
+              "other"
+            ],
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "primary",
+            "type": "boolean",
+            "multiValued": false,
+            "description": "A Boolean value indicating the 'primary' or 
preferred attribute value for this attribute, e.g., the preferred mailing 
address or primary email address. The primary attribute value 'true' MUST 
appear no more than once.",
+            "required": false,
+            "mutability": "readWrite",
+            "returned": "default"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "phoneNumbers",
+        "type": "complex",
+        "multiValued": true,
+        "description": "Phone numbers for the User. The value SHOULD be 
canonicalized by the service provider according to the format specified in RFC 
3966, e.g., 'tel:+1-201-555-0123'. Canonical type values of 'work', 'home', 
'mobile', 'fax', 'pager', and 'other'.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "Phone number of the User.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function, e.g., 
'work', 'home', 'mobile'.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [
+              "work",
+              "home",
+              "mobile",
+              "fax",
+              "pager",
+              "other"
+            ],
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "primary",
+            "type": "boolean",
+            "multiValued": false,
+            "description": "A Boolean value indicating the 'primary' or 
preferred attribute value for this attribute, e.g., the preferred phone number 
or primary phone number. The primary attribute value 'true' MUST appear no more 
than once.",
+            "required": false,
+            "mutability": "readWrite",
+            "returned": "default"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      },
+      {
+        "name": "ims",
+        "type": "complex",
+        "multiValued": true,
+        "description": "Instant messaging addresses for the User.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "Instant messaging address for the User.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function, e.g., 
'aim', 'gtalk', 'xmpp'.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [
+              "aim",
+              "gtalk",
+              "icq",
+              "xmpp",
+              "msn",
+              "skype",
+              "qq",
+              "yahoo"
+            ],
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "primary",
+            "type": "boolean",
+            "multiValued": false,
+            "description": "A Boolean value indicating the 'primary' or 
preferred attribute value for this attribute, e.g., the preferred messenger or 
primary messenger. The primary attribute value 'true' MUST appear no more than 
once.",
+            "required": false,
+            "mutability": "readWrite",
+            "returned": "default"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      },
+      {
+        "name": "photos",
+        "type": "complex",
+        "multiValued": true,
+        "description": "URLs of photos of the User.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "reference",
+            "referenceTypes": ["external"],
+            "multiValued": false,
+            "description": "URL of a photo of the User.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function, i.e., 
'photo' or 'thumbnail'.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [
+              "photo",
+              "thumbnail"
+            ],
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "primary",
+            "type": "boolean",
+            "multiValued": false,
+            "description": "A Boolean value indicating the 'primary' or 
preferred attribute value for this attribute, e.g., the preferred photo or 
thumbnail. The primary attribute value 'true' MUST appear no more than once.",
+            "required": false,
+            "mutability": "readWrite",
+            "returned": "default"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      },
+      {
+        "name": "addresses",
+        "type": "complex",
+        "multiValued": true,
+        "description": "A physical mailing address for this User. Canonical 
type values of 'work', 'home', and 'other'. This attribute is a complex type 
with the following sub-attributes.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "formatted",
+            "type": "string",
+            "multiValued": false,
+            "description": "The full mailing address, formatted for display or 
use with a mailing label. This attribute MAY contain newlines.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "streetAddress",
+            "type": "string",
+            "multiValued": false,
+            "description": "The full street address component, which may 
include house number, street name, P.O. box, and multi-line extended street 
address information. This attribute MAY contain newlines.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "locality",
+            "type": "string",
+            "multiValued": false,
+            "description": "The city or locality component.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "region",
+            "type": "string",
+            "multiValued": false,
+            "description": "The state or region component.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "postalCode",
+            "type": "string",
+            "multiValued": false,
+            "description": "The zip code or postal code component.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "country",
+            "type": "string",
+            "multiValued": false,
+            "description": "The country name component.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function, e.g., 
'work' or 'home'.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [
+              "work",
+              "home",
+              "other"
+            ],
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "groups",
+        "type": "complex",
+        "multiValued": true,
+        "description": "A list of groups to which the user belongs, either 
through direct membership, through nested groups, or dynamically calculated.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "The identifier of the User's group.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readOnly",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "$ref",
+            "type": "reference",
+            "referenceTypes": [
+              "User",
+              "Group"
+            ],
+            "multiValued": false,
+            "description": "The URI of the corresponding 'Group' resource to 
which the user belongs.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readOnly",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readOnly",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function, e.g., 
'direct' or 'indirect'.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [
+              "direct",
+              "indirect"
+            ],
+            "mutability": "readOnly",
+            "returned": "default",
+            "uniqueness": "none"
+          }
+        ],
+        "mutability": "readOnly",
+        "returned": "default"
+      },
+      {
+        "name": "entitlements",
+        "type": "complex",
+        "multiValued": true,
+        "description": "A list of entitlements for the User that represent a 
thing the User has.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "The value of an entitlement.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "primary",
+            "type": "boolean",
+            "multiValued": false,
+            "description": "A Boolean value indicating the 'primary' or 
preferred attribute value for this attribute. The primary attribute value 
'true' MUST appear no more than once.",
+            "required": false,
+            "mutability": "readWrite",
+            "returned": "default"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      },
+      {
+        "name": "roles",
+        "type": "complex",
+        "multiValued": true,
+        "description": "A list of roles for the User that collectively 
represent who the User is, e.g., 'Student', 'Faculty'.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "The value of a role.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [],
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "primary",
+            "type": "boolean",
+            "multiValued": false,
+            "description": "A Boolean value indicating the 'primary' or 
preferred attribute value for this attribute. The primary attribute value 
'true' MUST appear no more than once.",
+            "required": false,
+            "mutability": "readWrite",
+            "returned": "default"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      },
+      {
+        "name": "x509Certificates",
+        "type": "complex",
+        "multiValued": true,
+        "description": "A list of certificates issued to the User.",
+        "required": false,
+        "caseExact": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "binary",
+            "multiValued": false,
+            "description": "The value of an X.509 certificate.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "display",
+            "type": "string",
+            "multiValued": false,
+            "description": "A human-readable name, primarily used for display 
purposes. READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the attribute's function.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [],
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "primary",
+            "type": "boolean",
+            "multiValued": false,
+            "description": "A Boolean value indicating the 'primary' or 
preferred attribute value for this attribute. The primary attribute value 
'true' MUST appear no more than once.",
+            "required": false,
+            "mutability": "readWrite",
+            "returned": "default"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      }
+    ],
+    "meta": {
+      "resourceType": "Schema",
+      "location":
+              "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User"
+    }
+  },
+  {
+    "id": "urn:ietf:params:scim:schemas:core:2.0:Group",
+    "name": "Group",
+    "description": "Group",
+    "attributes": [
+      {
+        "name": "displayName",
+        "type": "string",
+        "multiValued": false,
+        "description": "A human-readable name for the Group. REQUIRED.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "members",
+        "type": "complex",
+        "multiValued": true,
+        "description": "A list of members of the Group.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "Identifier of the member of this Group.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "immutable",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "$ref",
+            "type": "reference",
+            "referenceTypes": [
+              "User",
+              "Group"
+            ],
+            "multiValued": false,
+            "description": "The URI corresponding to a SCIM resource that is a 
member of this Group.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "immutable",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "type",
+            "type": "string",
+            "multiValued": false,
+            "description": "A label indicating the type of resource, e.g., 
'User' or 'Group'.",
+            "required": false,
+            "caseExact": false,
+            "canonicalValues": [
+              "User",
+              "Group"
+            ],
+            "mutability": "immutable",
+            "returned": "default",
+            "uniqueness": "none"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      }
+    ],
+    "meta": {
+      "resourceType": "Schema",
+      "location":
+              "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group"
+    }
+  },
+  {
+    "id": "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
+    "name": "EnterpriseUser",
+    "description": "Enterprise User",
+    "attributes": [
+      {
+        "name": "employeeNumber",
+        "type": "string",
+        "multiValued": false,
+        "description": "Numeric or alphanumeric identifier assigned to a 
person, typically based on order of hire or association with an organization.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "costCenter",
+        "type": "string",
+        "multiValued": false,
+        "description": "Identifies the name of a cost center.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "organization",
+        "type": "string",
+        "multiValued": false,
+        "description": "Identifies the name of an organization.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "division",
+        "type": "string",
+        "multiValued": false,
+        "description": "Identifies the name of a division.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "department",
+        "type": "string",
+        "multiValued": false,
+        "description": "Identifies the name of a department.",
+        "required": false,
+        "caseExact": false,
+        "mutability": "readWrite",
+        "returned": "default",
+        "uniqueness": "none"
+      },
+      {
+        "name": "manager",
+        "type": "complex",
+        "multiValued": false,
+        "description": "The User's manager. A complex type that optionally 
allows service providers to represent organizational hierarchy by referencing 
the 'id' attribute of another User.",
+        "required": false,
+        "subAttributes": [
+          {
+            "name": "value",
+            "type": "string",
+            "multiValued": false,
+            "description": "The id of the SCIM resource representing the 
User's manager. REQUIRED.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "$ref",
+            "type": "reference",
+            "referenceTypes": [
+              "User"
+            ],
+            "multiValued": false,
+            "description": "The URI of the SCIM resource representing the 
User's manager. REQUIRED.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readWrite",
+            "returned": "default",
+            "uniqueness": "none"
+          },
+          {
+            "name": "displayName",
+            "type": "string",
+            "multiValued": false,
+            "description": "The displayName of the User's manager. OPTIONAL 
and READ-ONLY.",
+            "required": false,
+            "caseExact": false,
+            "mutability": "readOnly",
+            "returned": "default",
+            "uniqueness": "none"
+          }
+        ],
+        "mutability": "readWrite",
+        "returned": "default"
+      }
+    ],
+    "meta": {
+      "resourceType": "Schema",
+      "location": 
"/v2/Schemas/urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
+    }
+  }
+]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/resources/scimv2-logic.properties
----------------------------------------------------------------------
diff --git a/ext/scimv2/logic/src/main/resources/scimv2-logic.properties 
b/ext/scimv2/logic/src/main/resources/scimv2-logic.properties
new file mode 100644
index 0000000..2d85a37
--- /dev/null
+++ b/ext/scimv2/logic/src/main/resources/scimv2-logic.properties
@@ -0,0 +1,21 @@
+# 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.
+conf.directory=${conf.directory}
+
+bulk.maxOperations=1000
+bulk.maxPayloadSize=1048576
+filter.maxResults=200

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/pom.xml b/ext/scimv2/pom.xml
index 105853e..bc62e00 100644
--- a/ext/scimv2/pom.xml
+++ b/ext/scimv2/pom.xml
@@ -40,6 +40,7 @@ under the License.
   <modules>
     <module>scim-rest-api</module>
     <module>scim-rest-cxf</module>
+    <module>logic</module>
   </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.java
new file mode 100644
index 0000000..10e3f77
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.java
@@ -0,0 +1,82 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.net.URI;
+
+public class AuthenticationScheme extends SCIMBean {
+
+    private static final long serialVersionUID = -1326661422976856869L;
+
+    private final String name;
+
+    private final String description;
+
+    private final URI specUri;
+
+    private final URI documentationUri;
+
+    private final String type;
+
+    private final boolean primary;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public AuthenticationScheme(
+            @JsonProperty("name") final String name,
+            @JsonProperty("description") final String description,
+            @JsonProperty("specUri") final URI specUri,
+            @JsonProperty("documentationUri") final URI documentationUri,
+            @JsonProperty("type") final String type,
+            @JsonProperty("primary") final boolean primary) {
+
+        this.name = name;
+        this.description = description;
+        this.specUri = specUri;
+        this.documentationUri = documentationUri;
+        this.type = type;
+        this.primary = primary;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public URI getSpecUri() {
+        return specUri;
+    }
+
+    public URI getDocumentationUri() {
+        return documentationUri;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public boolean isPrimary() {
+        return primary;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.java
new file mode 100644
index 0000000..b81b652
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BulkConfigurationOption extends ConfigurationOption {
+
+    private static final long serialVersionUID = 8218541842239260269L;
+
+    private final int maxOperations;
+
+    private final int maxPayloadSize;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public BulkConfigurationOption(
+            @JsonProperty("supported") final boolean supported,
+            @JsonProperty("maxOperations") final int maxOperations,
+            @JsonProperty("maxPayloadSize") final int maxPayloadSize) {
+
+        super(supported);
+        this.maxOperations = maxOperations;
+        this.maxPayloadSize = maxPayloadSize;
+    }
+
+    public int getMaxOperations() {
+        return maxOperations;
+    }
+
+    public int getMaxPayloadSize() {
+        return maxPayloadSize;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java
new file mode 100644
index 0000000..821cae4
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java
@@ -0,0 +1,39 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class ConfigurationOption extends SCIMBean {
+
+    private static final long serialVersionUID = 5165678196717776426L;
+
+    private final boolean supported;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public ConfigurationOption(@JsonProperty("supported") final boolean 
supported) {
+        this.supported = supported;
+    }
+
+    public boolean isSupported() {
+        return supported;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java
new file mode 100644
index 0000000..3eda87e
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java
@@ -0,0 +1,43 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class FilterConfigurationOption extends ConfigurationOption {
+
+    private static final long serialVersionUID = 8218541842239260269L;
+
+    private final int maxResults;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public FilterConfigurationOption(
+            @JsonProperty("supported") final boolean supported,
+            @JsonProperty("maxResults") final int maxResults) {
+
+        super(supported);
+        this.maxResults = maxResults;
+    }
+
+    public int getMaxResults() {
+        return maxResults;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
index 6983631..d20f50a 100644
--- 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
@@ -23,13 +23,13 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
 
 public class ListResponse<R extends SCIMResource> extends SCIMBean {
 
     private static final long serialVersionUID = -776611610457583160L;
 
-    private final List<String> schemas = 
Arrays.asList(ResourceType.ListResponse.getSchema());
+    private final List<String> schemas = 
Arrays.asList(Resource.ListResponse.schema());
 
     private final int totalResults;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
index 73c25eb..aa2f5dd 100644
--- 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
@@ -21,7 +21,7 @@ package org.apache.syncope.ext.scimv2.api.data;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
 
 @JsonPropertyOrder({ "value", "$ref", "display", "type" })
 public class Member extends Reference {
@@ -29,13 +29,13 @@ public class Member extends Reference {
     private static final long serialVersionUID = 75245960461062907L;
 
     @JsonIgnore
-    private final ResourceType type;
+    private final Resource type;
 
     public Member(
             @JsonProperty("value") final String value,
             @JsonProperty("$ref") final String ref,
             @JsonProperty("display") final String display,
-            @JsonProperty("type") final ResourceType type) {
+            @JsonProperty("type") final Resource type) {
 
         super(value, ref, display);
         this.type = type;

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
index 7ecb4af..661ec86 100644
--- 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
@@ -21,16 +21,15 @@ package org.apache.syncope.ext.scimv2.api.data;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import java.io.Serializable;
 import java.util.Date;
 import javax.ws.rs.core.EntityTag;
-import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
 
-public class Meta implements Serializable {
+public class Meta extends SCIMBean {
 
     private static final long serialVersionUID = 8976451652101091915L;
 
-    private final ResourceType resourceType;
+    private final Resource resourceType;
 
     private final Date created;
 
@@ -43,7 +42,7 @@ public class Meta implements Serializable {
 
     @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
     public Meta(
-            @JsonProperty("resourceType") final ResourceType resourceType,
+            @JsonProperty("resourceType") final Resource resourceType,
             @JsonProperty("created") final Date created,
             @JsonProperty("lastModified") final Date lastModified,
             @JsonProperty("version") final String version,
@@ -52,11 +51,11 @@ public class Meta implements Serializable {
         this.resourceType = resourceType;
         this.created = created;
         this.lastModified = lastModified;
-        this.version = new EntityTag(version);
+        this.version = version == null ? null : new EntityTag(version, true);
         this.location = location;
     }
 
-    public ResourceType getResourceType() {
+    public Resource getResourceType() {
         return resourceType;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java
new file mode 100644
index 0000000..19dceac
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java
@@ -0,0 +1,97 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
+
+public class ResourceType extends SCIMBean {
+
+    private static final long serialVersionUID = -6559584102333757279L;
+
+    private final List<String> schemas = 
Arrays.asList(Resource.ResourceType.schema());
+
+    private final String id;
+
+    private final String name;
+
+    private final String endpoint;
+
+    private final String description;
+
+    private final String schema;
+
+    private final List<SchemaExtension> schemaExtensions = new ArrayList<>();
+
+    private final Meta meta;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public ResourceType(
+            @JsonProperty("id") final String id,
+            @JsonProperty("name") final String name,
+            @JsonProperty("endpoint") final String endpoint,
+            @JsonProperty("description") final String description,
+            @JsonProperty("schema") final String schema,
+            @JsonProperty("meta") final Meta meta) {
+
+        this.id = id;
+        this.name = name;
+        this.endpoint = endpoint;
+        this.description = description;
+        this.schema = schema;
+        this.meta = meta;
+    }
+
+    public List<String> getSchemas() {
+        return schemas;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getEndpoint() {
+        return endpoint;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getSchema() {
+        return schema;
+    }
+
+    public List<SchemaExtension> getSchemaExtensions() {
+        return schemaExtensions;
+    }
+
+    public Meta getMeta() {
+        return meta;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java
new file mode 100644
index 0000000..fb2fe2e
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class SchemaExtension extends SCIMBean {
+
+    private static final long serialVersionUID = -2891887818183122384L;
+
+    private final String schema;
+
+    private final boolean required;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public SchemaExtension(
+            @JsonProperty("schema") final String schema,
+            @JsonProperty("required") final boolean required) {
+
+        this.schema = schema;
+        this.required = required;
+    }
+
+    public String getSchema() {
+        return schema;
+    }
+
+    public boolean isRequired() {
+        return required;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java
new file mode 100644
index 0000000..3014a6c
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java
@@ -0,0 +1,97 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
+
+public class ServiceProviderConfig extends SCIMBean {
+
+    private static final long serialVersionUID = 1027738509789460252L;
+
+    private final List<String> schemas = 
Arrays.asList(Resource.ServiceProviderConfig.schema());
+
+    private final ConfigurationOption patch;
+
+    private final BulkConfigurationOption bulk;
+
+    private final FilterConfigurationOption filter;
+
+    private final ConfigurationOption changePassword;
+
+    private final ConfigurationOption sort;
+
+    private final ConfigurationOption etag;
+
+    private final List<AuthenticationScheme> authenticationSchemes = new 
ArrayList<>();
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public ServiceProviderConfig(
+            @JsonProperty("patch") final ConfigurationOption patch,
+            @JsonProperty("bulk") final BulkConfigurationOption bulk,
+            @JsonProperty("filter") final FilterConfigurationOption filter,
+            @JsonProperty("changePassword") final ConfigurationOption 
changePassword,
+            @JsonProperty("sort") final ConfigurationOption sort,
+            @JsonProperty("etag") final ConfigurationOption etag) {
+
+        this.patch = patch;
+        this.bulk = bulk;
+        this.filter = filter;
+        this.changePassword = changePassword;
+        this.sort = sort;
+        this.etag = etag;
+    }
+
+    public List<String> getSchemas() {
+        return schemas;
+    }
+
+    public ConfigurationOption getPatch() {
+        return patch;
+    }
+
+    public BulkConfigurationOption getBulk() {
+        return bulk;
+    }
+
+    public FilterConfigurationOption getFilter() {
+        return filter;
+    }
+
+    public ConfigurationOption getChangePassword() {
+        return changePassword;
+    }
+
+    public ConfigurationOption getSort() {
+        return sort;
+    }
+
+    public ConfigurationOption getEtag() {
+        return etag;
+    }
+
+    public List<AuthenticationScheme> getAuthenticationSchemes() {
+        return authenticationSchemes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
index c1bb82f..8881ec8 100644
--- 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
@@ -32,7 +32,7 @@ import org.apache.cxf.jaxrs.ext.PATCH;
 import org.apache.syncope.ext.scimv2.api.SCIMConstants;
 import org.apache.syncope.ext.scimv2.api.data.SCIMGroup;
 
-@Path("Groups")
+@Path("v2/Groups")
 public interface GroupService extends SCIMService<SCIMGroup> {
 
     @POST

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
index 8de7a0a..6e9b201 100644
--- 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
@@ -18,28 +18,42 @@
  */
 package org.apache.syncope.ext.scimv2.api.service;
 
+import java.util.List;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.ext.scimv2.api.data.ResourceType;
+import org.apache.syncope.ext.scimv2.api.data.SCIMResource;
+import org.apache.syncope.ext.scimv2.api.data.ServiceProviderConfig;
 
-@Path("")
-public interface RootService extends SCIMService {
+@Path("v2")
+public interface RootService extends SCIMService<SCIMResource> {
 
     @GET
-    @Path("ServiceProviderConfigs")
+    @Path("ServiceProviderConfig")
     @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
-    Response serviceProviderConfigs();
+    ServiceProviderConfig serviceProviderConfig();
 
     @GET
     @Path("ResourceTypes")
     @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
-    Response resourceTypes();
+    List<ResourceType> resourceTypes();
+
+    @GET
+    @Path("ResourceTypes/{type}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    ResourceType resourceType(@PathParam("type") String type);
 
     @GET
     @Path("Schemas")
     @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
     Response schemas();
 
+    @GET
+    @Path("Schemas/{schema}")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    Response schema(@PathParam("schema") String schema);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
index 73518b5..8003b66 100644
--- 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
@@ -32,7 +32,7 @@ import org.apache.cxf.jaxrs.ext.PATCH;
 import org.apache.syncope.ext.scimv2.api.SCIMConstants;
 import org.apache.syncope.ext.scimv2.api.data.SCIMUser;
 
-@Path("Users")
+@Path("v2/Users")
 public interface UserService extends SCIMService<SCIMUser> {
 
     @POST

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
new file mode 100644
index 0000000..37b15b6
--- /dev/null
+++ 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ext.scimv2.api.type;
+
+public enum Resource {
+
+    
ServiceProviderConfig("urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"),
+    ResourceType("urn:ietf:params:scim:schemas:core:2.0:ResourceType"),
+    Schema("urn:ietf:params:scim:schemas:core:2.0:Schema"),
+    User("urn:ietf:params:scim:schemas:core:2.0:User"),
+    
EnterpriseUser("urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"),
+    Group("urn:ietf:params:scim:schemas:core:2.0:Group"),
+    ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse");
+
+    private final String schema;
+
+    Resource(final String schema) {
+        this.schema = schema;
+    }
+
+    public String schema() {
+        return schema;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
----------------------------------------------------------------------
diff --git 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
 
b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
deleted file mode 100644
index faf5ccc..0000000
--- 
a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
+++ /dev/null
@@ -1,37 +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.ext.scimv2.api.type;
-
-public enum ResourceType {
-
-    User("urn:ietf:params:scim:schemas:core:2.0:User"),
-    Group("urn:ietf:params:scim:schemas:core:2.0:Group"),
-    ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse");
-
-    private final String schema;
-
-    ResourceType(final String schema) {
-        this.schema = schema;
-    }
-
-    public String getSchema() {
-        return schema;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-cxf/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/pom.xml b/ext/scimv2/scim-rest-cxf/pom.xml
index ffa7483..25a9249 100644
--- a/ext/scimv2/scim-rest-cxf/pom.xml
+++ b/ext/scimv2/scim-rest-cxf/pom.xml
@@ -98,13 +98,8 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-logic</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>org.apache.syncope.ext.scimv2</groupId>
-      <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId>
+      <artifactId>syncope-ext-scimv2-logic</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>

Reply via email to