class ClientResource implements CollectionResourceProvider {

    public Promise<ResourceResponse, ResourceException> createInstance(Context context,
            CreateRequest createRequest) {

        String principal = PrincipalRestUtils.getPrincipalNameFromServerContext(context);

        Map< String, String> responseVal = new HashMap< String, String>();
        try {
            if (serviceSchema == null || serviceSchemaManager == null){
                if (debug.errorEnabled()) {
                    debug.error("ClientResource :: CREATE by " + principal + ": No serviceSchema available.");
                }
                throw new PermanentException(ResourceException.INTERNAL_ERROR, "", null);
            }

            Map<String, ArrayList<String>> client =
                    (Map<String, ArrayList<String>>) createRequest.getContent().getObject();
            String realm = null;
            if (client == null || client.isEmpty()){
                if (debug.errorEnabled()) {
                    debug.error("ClientResource :: CREATE by " + principal + ": No client definition.");
                }
                throw new PermanentException(ResourceException.BAD_REQUEST, "Missing client definition", null);
            }

            //check for id
            String id = createRequest.getNewResourceId();
            if (client.containsKey(OAuth2Constants.OAuth2Client.CLIENT_ID)){
                ArrayList<String> idList = client.remove(OAuth2Constants.OAuth2Client.CLIENT_ID);
                if (idList != null && !idList.isEmpty()){
                    id = idList.iterator().next();
                }
            }

            if (id == null || id.isEmpty()){
                debug.error("ClientResource :: CREATE by " + principal + ": No client ID.");
                throw new PermanentException(ResourceException.BAD_REQUEST, "Missing client id", null);
            }

            //get realm
            if (client.containsKey(OAuth2Constants.OAuth2Client.REALM)){
                ArrayList<String> realmList = client.remove(OAuth2Constants.OAuth2Client.REALM);
                if (realmList != null && !realmList.isEmpty()){
                    realm = realmList.iterator().next();
                }
            }

            //check for required parameters
            if (!client.containsKey(OAuth2Constants.OAuth2Client.USERPASSWORD) ||
                    client.get(OAuth2Constants.OAuth2Client.USERPASSWORD).iterator().next().isEmpty()){
                if (debug.errorEnabled()) {
                    debug.error("ClientResource :: CREATE by " + principal + ": " +
                            "Resource ID: " + id + ": No user password.");
                }
                throw new PermanentException(ResourceException.BAD_REQUEST, "Missing user password", null);
            }

            if (client.containsKey(OAuth2Constants.OAuth2Client.CLIENT_TYPE)) {
                String type = client.get(OAuth2Constants.OAuth2Client.CLIENT_TYPE).iterator().next();
                if (!(type.equals("Confidential") || type.equals("Public"))){
                    debug.error("ClientResource :: CREATE by " + principal + ": " +
                            "Resource ID: " + id + ": No client type.");
                    throw new PermanentException(ResourceException.BAD_REQUEST, "Missing client type", null);
                }
            } else {
                debug.error("ClientResource :: CREATE by" + principal + ": " +
                        "Resource ID: " + id + ": No client type.");
                throw new PermanentException(ResourceException.BAD_REQUEST, "Missing client type", null);
            }

            Map<String, Set<String>> attrs = new HashMap<String, Set<String>>();
            for (Map.Entry mapEntry : client.entrySet()){
                List<String> list = (ArrayList) mapEntry.getValue();
                Set<String> set = new HashSet<String>();
                if (isSingle((String) mapEntry.getKey())){
                    set.add((String)((ArrayList)mapEntry.getValue()).get(0));
                    } else {
                    for (int i = 0; i < list.size(); i++) {
                        set.add("[" + i + "]=" + list.get(i));
                    }
                }
                attrs.put((String)mapEntry.getKey(), set);
            }

            Set<String> temp = new HashSet<String>();
            temp.add("OAuth2Client");
            attrs.put("AgentType", temp);

            temp = new HashSet<String>();
            temp.add("Active");
            attrs.put("sunIdentityServerDeviceStatus", temp);

            manager.createIdentity(realm, id, attrs);
            responseVal.put("success", "true");

            JsonValue response = new JsonValue(responseVal);

            ResourceResponse resource = newResourceResponse("results", String.valueOf(System.currentTimeMillis()), response);
            if (auditLogger.isAuditLogEnabled()) {
                String[] obs = {"CREATED_CLIENT", responseVal.toString()};
                auditLogger.logAccessMessage("CREATED_CLIENT", obs, null);
            }
            return newResultPromise(resource);
        } catch(IdRepoException e){
            responseVal.put("success", "false");
            if (auditLogger.isAuditLogEnabled()) {
                String[] obs = {"FAILED_CREATE_CLIENT", responseVal.toString()};
                auditLogger.logErrorMessage("FAILED_CREATE_CLIENT", obs, null);
            }

            if (debug.errorEnabled()) {
                debug.error("ClientResource :: CREATE by " + principal + ": Unable to create client due to " +
                        "IdRepo exception.", e);
            }
            return new InternalServerErrorException("Unable to create client", e).asPromise();
        } catch (SSOException e){
            responseVal.put("success", "false");
            if (auditLogger.isAuditLogEnabled()) {
                String[] obs = {"FAILED_CREATE_CLIENT", responseVal.toString()};
                auditLogger.logErrorMessage("FAILED_CREATE_CLIENT", obs, null);
            }
            if (debug.errorEnabled()) {
                debug.error("ClientResource :: CREATE by " + principal + ": Unable to create client due to " +
                        "SSO exception.", e);
            }
            return new InternalServerErrorException("Unable to create client", e).asPromise();
        } catch (PermanentException e){
            responseVal.put("success", "false");
            if (auditLogger.isAuditLogEnabled()) {
                String[] obs = {"FAILED_CREATE_CLIENT", responseVal.toString()};
                auditLogger.logErrorMessage("FAILED_CREATE_CLIENT", obs, null);
            }
            if (debug.errorEnabled()) {
                debug.error("ClientResource :: CREATE by " + principal +
                        ": Unable to create client due to exception.", e);
            }
            return e.asPromise();
        } catch (org.forgerock.json.resource.BadRequestException e) {
            responseVal.put("success", "false");
            if (auditLogger.isAuditLogEnabled()) {
                String[] obs = {"FAILED_CREATE_CLIENT", responseVal.toString()};
                auditLogger.logErrorMessage("FAILED_CREATE_CLIENT", obs, null);
            }
            debug.error("ClientResource :: CREATE : Unable to create client due to Bad Request.", e);
            return e.asPromise();
        }
    }

    @Inject public  ClientResource(ClientResourceManager manager, CTSPersistentStore store, OAuth2AuditLogger auditLogger,
                          @Named("frRest") Debug debug);
    public  ClientResource(ClientResourceManager manager, CTSPersistentStore store, ServiceSchemaManager mgr,
            OAuth2AuditLogger auditLogger, Debug debug);

}