/*
 * 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.usergrid.management.cassandra;


import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;

import com.google.common.base.Optional;
import org.apache.usergrid.corepersistence.util.CpNamingUtils;
import org.apache.usergrid.exception.ConflictException;
import org.apache.usergrid.management.exceptions.*;
import org.apache.usergrid.persistence.*;
import org.apache.usergrid.persistence.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.text.StrSubstitutor;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.usergrid.locking.Lock;
import org.apache.usergrid.locking.LockManager;
import org.apache.usergrid.management.AccountCreationProps;
import org.apache.usergrid.management.ActivationState;
import org.apache.usergrid.management.ApplicationInfo;
import org.apache.usergrid.management.ManagementService;
import org.apache.usergrid.management.OrganizationInfo;
import org.apache.usergrid.management.OrganizationOwnerInfo;
import org.apache.usergrid.management.UserInfo;
import org.apache.usergrid.persistence.exceptions.ApplicationAlreadyExistsException;
import org.apache.usergrid.persistence.index.query.Identifier;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.persistence.entities.Group;
import org.apache.usergrid.persistence.entities.User;
import org.apache.usergrid.persistence.exceptions.DuplicateUniquePropertyExistsException;
import org.apache.usergrid.persistence.exceptions.EntityNotFoundException;
import org.apache.usergrid.security.AuthPrincipalInfo;
import org.apache.usergrid.security.AuthPrincipalType;
import org.apache.usergrid.security.crypto.EncryptionService;
import org.apache.usergrid.security.oauth.AccessInfo;
import org.apache.usergrid.security.oauth.ClientCredentialsInfo;
import org.apache.usergrid.security.salt.SaltProvider;
import org.apache.usergrid.security.shiro.PrincipalCredentialsToken;
import org.apache.usergrid.security.shiro.credentials.ApplicationClientCredentials;
import org.apache.usergrid.security.shiro.credentials.OrganizationClientCredentials;
import org.apache.usergrid.security.shiro.principals.ApplicationPrincipal;
import org.apache.usergrid.security.shiro.principals.OrganizationPrincipal;
import org.apache.usergrid.security.shiro.utils.SubjectUtils;
import org.apache.usergrid.security.tokens.TokenCategory;
import org.apache.usergrid.security.tokens.TokenInfo;
import org.apache.usergrid.security.tokens.TokenService;
import org.apache.usergrid.security.tokens.exceptions.TokenException;
import org.apache.usergrid.services.ServiceAction;
import org.apache.usergrid.services.ServiceManager;
import org.apache.usergrid.services.ServiceManagerFactory;
import org.apache.usergrid.services.ServiceRequest;
import org.apache.usergrid.services.ServiceResults;
import org.apache.usergrid.utils.ConversionUtils;
import org.apache.usergrid.utils.JsonUtils;
import org.apache.usergrid.utils.MailUtils;
import org.apache.usergrid.utils.StringUtils;
import org.apache.usergrid.utils.UUIDUtils;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString;
import static org.apache.commons.codec.digest.DigestUtils.sha;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.usergrid.locking.LockHelper.getUniqueUpdateLock;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_ADMIN_ACTIVATION_URL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_ADMIN_CONFIRMATION_URL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_ADMIN_RESETPW_URL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ADMIN_ACTIVATED;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ADMIN_CONFIRMATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ADMIN_CONFIRMED_AWAITING_ACTIVATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ADMIN_INVITED;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ADMIN_PASSWORD_RESET;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ADMIN_USER_ACTIVATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_FOOTER;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ORGANIZATION_ACTIVATED;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ORGANIZATION_CONFIRMATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_ORGANIZATION_CONFIRMED_AWAITING_ACTIVATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_SYSADMIN_ADMIN_ACTIVATED;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_SYSADMIN_ADMIN_ACTIVATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_SYSADMIN_ORGANIZATION_ACTIVATED;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_SYSADMIN_ORGANIZATION_ACTIVATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_USER_ACTIVATED;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_USER_CONFIRMATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_USER_CONFIRMED_AWAITING_ACTIVATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_USER_PASSWORD_RESET;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_EMAIL_USER_PIN_REQUEST;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_MAILER_EMAIL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_ORGANIZATION_ACTIVATION_URL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SETUP_TEST_ACCOUNT;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SYSADMIN_EMAIL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SYSADMIN_LOGIN_ALLOWED;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SYSADMIN_LOGIN_EMAIL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SYSADMIN_LOGIN_NAME;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SYSADMIN_LOGIN_PASSWORD;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_TEST_ACCOUNT_ADMIN_USER_EMAIL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_TEST_ACCOUNT_ADMIN_USER_NAME;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_TEST_ACCOUNT_ADMIN_USER_PASSWORD;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_TEST_ACCOUNT_ADMIN_USER_USERNAME;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_TEST_ACCOUNT_APP;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_TEST_ACCOUNT_ORGANIZATION;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_USER_ACTIVATION_URL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_USER_CONFIRMATION_URL;
import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_USER_RESETPW_URL;
import static org.apache.usergrid.persistence.CredentialsInfo.getCredentialsSecret;
import static org.apache.usergrid.persistence.Schema.*;
import static org.apache.usergrid.persistence.Schema.PROPERTY_UUID;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_ACTOR;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_ACTOR_NAME;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_CATEGORY;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_CONTENT;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_DISPLAY_NAME;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_ENTITY_TYPE;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_OBJECT;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_OBJECT_ENTITY_TYPE;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_OBJECT_NAME;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_OBJECT_TYPE;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_TITLE;
import static org.apache.usergrid.persistence.entities.Activity.PROPERTY_VERB;
import org.apache.usergrid.persistence.Query.Level;
import static org.apache.usergrid.security.AuthPrincipalType.ADMIN_USER;
import static org.apache.usergrid.security.AuthPrincipalType.APPLICATION;
import static org.apache.usergrid.security.AuthPrincipalType.APPLICATION_USER;
import static org.apache.usergrid.security.AuthPrincipalType.ORGANIZATION;
import static org.apache.usergrid.security.oauth.ClientCredentialsInfo.getTypeFromClientId;
import static org.apache.usergrid.security.oauth.ClientCredentialsInfo.getUUIDFromClientId;
import static org.apache.usergrid.security.tokens.TokenCategory.ACCESS;
import static org.apache.usergrid.security.tokens.TokenCategory.EMAIL;
import static org.apache.usergrid.services.ServiceParameter.parameters;
import static org.apache.usergrid.services.ServicePayload.payload;
import static org.apache.usergrid.services.ServiceResults.genericServiceResults;
import static org.apache.usergrid.utils.ClassUtils.cast;
import static org.apache.usergrid.utils.ConversionUtils.bytes;
import static org.apache.usergrid.utils.ConversionUtils.uuid;
import static org.apache.usergrid.utils.ListUtils.anyNull;
import static org.apache.usergrid.utils.MapUtils.hashMap;
import static org.apache.usergrid.utils.PasswordUtils.mongoPassword;

import static java.lang.Boolean.parseBoolean;


public class ManagementServiceImpl implements ManagementService {
    private static final Logger logger = LoggerFactory.getLogger( ManagementServiceImpl.class );

    /** Key for the user's pin */
    protected static final String USER_PIN = "pin";

    /** Key for the user's oauth secret */
    protected static final String USER_TOKEN = "secret";

    /** Key for the user's mongo password */
    protected static final String USER_MONGO_PASSWORD = "mongo_pwd";

    /** Key for the user's password */
    protected static final String USER_PASSWORD = "password";

    protected static final String USER_PASSWORD_HISTORY = "password_history";

    private static final String TOKEN_TYPE_ACTIVATION = "activate";

    private static final String TOKEN_TYPE_PASSWORD_RESET = "resetpw";

    private static final String TOKEN_TYPE_CONFIRM = "confirm";

    public static final String OAUTH_SECRET_SALT = "super secret oauth value";

    private static final String ORGANIZATION_PROPERTIES_DICTIONARY = "orgProperties";
    public static final String REGISTRATION_REQUIRES_ADMIN_APPROVAL = "registration_requires_admin_approval";
    public static final String REGISTRATION_REQUIRES_EMAIL_CONFIRMATION = "registration_requires_email_confirmation";
    public static final String NOTIFY_ADMIN_OF_NEW_USERS = "notify_admin_of_new_users";

    protected ServiceManagerFactory smf;

    protected EntityManagerFactory emf;

    protected AccountCreationPropsImpl properties;

    protected LockManager lockManager;

    protected TokenService tokens;

    protected SaltProvider saltProvider;

    @Autowired
    protected MailUtils mailUtils;

    protected EncryptionService encryptionService;


    /** Must be constructed with a CassandraClientPool. */
    public ManagementServiceImpl() {
    }


    @Autowired
    public void setEntityManagerFactory( EntityManagerFactory emf ) {
        logger.info( "ManagementServiceImpl.setEntityManagerFactory" );
        this.emf = emf;
    }


    @Autowired
    public void setProperties( Properties properties ) {
        this.properties = new AccountCreationPropsImpl( properties );
    }


    /** For testing purposes only */
    public Properties getProperties() {
        return properties.properties;
    }

   @Autowired
    public void setTokenService( TokenService tokens ) {
        this.tokens = tokens;
    }


    @Autowired
    public void setServiceManagerFactory( ServiceManagerFactory smf ) {
        this.smf = smf;
    }


    public LockManager getLockManager() {
        return lockManager;
    }


    @Autowired
    public void setLockManager( LockManager lockManager ) {
        this.lockManager = lockManager;
    }


    /** @param encryptionService the encryptionService to set */
    @Autowired
    public void setEncryptionService( EncryptionService encryptionService ) {
        this.encryptionService = encryptionService;
    }


    @Override
    public void setup() throws Exception {

        if ( getBooleanProperty( PROPERTIES_SETUP_TEST_ACCOUNT ) ) {
            String test_app_name = properties.getProperty( PROPERTIES_TEST_ACCOUNT_APP );
            String test_organization_name = properties.getProperty( PROPERTIES_TEST_ACCOUNT_ORGANIZATION );
            String test_admin_username = properties.getProperty( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_USERNAME );
            String test_admin_name = properties.getProperty( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_NAME );
            String test_admin_email = properties.getProperty( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_EMAIL );
            String test_admin_password = properties.getProperty( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_PASSWORD );

            if ( anyNull( test_app_name, test_organization_name, test_admin_username, test_admin_name, test_admin_email,
                    test_admin_password ) ) {
                logger.warn( "Missing values for test app, check properties.  Skipping test app setup..." );
                return;
            }

            OrganizationInfo organization = getOrganizationByName( test_organization_name );

            if ( organization == null ) {
                OrganizationOwnerInfo created =
                        createOwnerAndOrganization( test_organization_name, test_admin_username, test_admin_name,
                                test_admin_email, test_admin_password, true, false );
                organization = created.getOrganization();
            }

            if ( !getApplicationsForOrganization( organization.getUuid() ).containsValue( test_app_name ) ) {
                try {
                    createApplication( organization.getUuid(), test_app_name );
                }catch(ApplicationAlreadyExistsException aaee){
                    logger.debug("The database setup already found an existing application");
                }
            }
        }
        else {
            logger.warn( "Test app creation disabled" );
        }

        if ( superuserEnabled() ) {
            provisionSuperuser();
        }
    }


    public boolean superuserEnabled() {
        boolean superuser_enabled = getBooleanProperty( PROPERTIES_SYSADMIN_LOGIN_ALLOWED );
        String superuser_username = properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_NAME );
        String superuser_email = properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_EMAIL );
        String superuser_password = properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_PASSWORD );

        return superuser_enabled && !anyNull( superuser_username, superuser_email, superuser_password );
    }


    @Override
    public void provisionSuperuser() throws Exception {
        boolean superuser_enabled = getBooleanProperty( PROPERTIES_SYSADMIN_LOGIN_ALLOWED );
        String superuser_username = properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_NAME );
        String superuser_email = properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_EMAIL );
        String superuser_password = properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_PASSWORD );

        if ( !anyNull( superuser_username, superuser_email, superuser_password ) ) {
            UserInfo user = this.getAdminUserByUsername( superuser_username );
            if ( user == null ) {
                createAdminUser( superuser_username, "Super User", superuser_email, superuser_password,
                        superuser_enabled, !superuser_enabled );
            }
            else {
                this.setAdminUserPassword( user.getUuid(), superuser_password );
            }
        }
        else {
            System.out.println(
                    "Missing values for superuser account, check properties.  Skipping superuser account setup..." );
        }
    }


    @Override
    public void resetSuperUser(String username, String password, String email) throws Exception {
        //final AccountCreationProps.SuperUser superUser = properties.getSuperUser();
        //this.getAdminUser
        UserInfo user = this.getAdminUserByUsername( username );
        if ( user == null ) {
            try {
                createAdminUser( username, "Super User", email, password, true, false );
            }catch(Exception e){

            }
        }
        else {
            this.setAdminUserPassword( user.getUuid(), password );
        }
    }


    public String generateOAuthSecretKey( AuthPrincipalType type ) {
        long timestamp = System.currentTimeMillis();
        ByteBuffer bytes = ByteBuffer.allocate( 20 );
        bytes.put( sha( timestamp + OAUTH_SECRET_SALT + UUID.randomUUID() ) );
        String secret = type.getBase64Prefix() + encodeBase64URLSafeString( bytes.array() );
        return secret;
    }


    @SuppressWarnings( "serial" )
    @Override
    public void postOrganizationActivity( UUID organizationId, final UserInfo user, String verb, final EntityRef object,
                                          final String objectType, final String objectName, String title,
                                          String content ) throws Exception {
        ServiceManager sm = smf.getServiceManager( smf.getManagementAppId() );

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put( PROPERTY_VERB, verb );
        properties.put( PROPERTY_CATEGORY, "admin" );
        if ( content != null ) {
            properties.put( PROPERTY_CONTENT, content );
        }
        if ( title != null ) {
            properties.put( PROPERTY_TITLE, title );
        }
        properties.put( PROPERTY_ACTOR, new HashMap<String, Object>() {
            {
                put( PROPERTY_DISPLAY_NAME, user.getName() );
                put( PROPERTY_OBJECT_TYPE, "person" );
                put( PROPERTY_ENTITY_TYPE, "user" );
                put( PROPERTY_UUID, user.getUuid() );
            }
        } );
        properties.put( PROPERTY_OBJECT, new HashMap<String, Object>() {
            {
                put( PROPERTY_DISPLAY_NAME, objectName );
                put( PROPERTY_OBJECT_TYPE, objectType );
                put( PROPERTY_ENTITY_TYPE, object.getType() );
                put( PROPERTY_UUID, object.getUuid() );
            }
        } );

        sm.newRequest( ServiceAction.POST, parameters( Schema.COLLECTION_GROUPS, organizationId, "activities" ), payload( properties ) )
          .execute().getEntity();
    }


    @Override
    public ServiceResults getOrganizationActivity( OrganizationInfo organization ) throws Exception {
        ServiceManager sm = smf.getServiceManager( smf.getManagementAppId() );
        return sm.newRequest( ServiceAction.GET, parameters( Schema.COLLECTION_GROUPS, organization.getUuid(), "feed" ) ).execute();
    }


    @Override
    public ServiceResults getOrganizationActivityForAdminUser( OrganizationInfo organization, UserInfo user )
            throws Exception {
        ServiceManager sm = smf.getServiceManager( smf.getManagementAppId() );
        return sm.newRequest( ServiceAction.GET,
                parameters( Schema.COLLECTION_GROUPS, organization.getUuid(), "users", user.getUuid(), "feed" ) ).execute();
    }


    @Override
    public ServiceResults getAdminUserActivity( UserInfo user ) throws Exception {
        ServiceManager sm = smf.getServiceManager( smf.getManagementAppId() );
        return sm.newRequest( ServiceAction.GET, parameters( "users", user.getUuid(), "feed" ) ).execute();
    }


    @Override
    public OrganizationOwnerInfo createOwnerAndOrganization( String organizationName, String username, String name,
                                                             String email, String password ) throws Exception {

        logger.debug("createOwnerAndOrganization1");
        boolean activated = !newAdminUsersNeedSysAdminApproval() && !newOrganizationsNeedSysAdminApproval();
        boolean disabled = newAdminUsersRequireConfirmation();
        // if we are active and enabled, skip the send email step

        return createOwnerAndOrganization( organizationName, username, name, email, password, activated, disabled, null,
                null );
    }


    @Override
    public OrganizationOwnerInfo createOwnerAndOrganization( String organizationName, String username, String name,
                                                             String email, String password, boolean activated,
                                                             boolean disabled ) throws Exception {
        logger.debug("createOwnerAndOrganization2");
        return createOwnerAndOrganization( organizationName, username, name, email, password,
                activated, disabled, null, null );
    }


    @Override
    public OrganizationOwnerInfo createOwnerAndOrganization( String organizationName, String username, String name,
                                                             String email, String password, boolean activated,
                                                             boolean disabled, Map<String, Object> userProperties,
                                                             Map<String, Object> organizationProperties )
            throws Exception {

        logger.debug("createOwnerAndOrganization3");

        /**
         * Only lock on the target values. We don't want lock contention if another
         * node is trying to set the property do a different value
         */
        Lock groupLock =
                getUniqueUpdateLock( lockManager, smf.getManagementAppId(), organizationName, Schema.COLLECTION_GROUPS, PROPERTY_PATH );

        Lock userLock = getUniqueUpdateLock( lockManager, smf.getManagementAppId(), username, "users", "username" );

        Lock emailLock = getUniqueUpdateLock( lockManager, smf.getManagementAppId(), email, "users", "email" );

        UserInfo user = null;
        OrganizationInfo organization = null;

        try {

            groupLock.lock();
            userLock.lock();
            emailLock.lock();
            EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
            if ( !em.isPropertyValueUniqueForEntity( Group.ENTITY_TYPE, PROPERTY_PATH, organizationName ) ) {
                throw new DuplicateUniquePropertyExistsException( Group.ENTITY_TYPE, PROPERTY_PATH, organizationName );
            }
            if ( !validateAdminInfo( username, name, email, password ) ) {
                return null;
            }
            if ( areActivationChecksDisabled() ) {
                user = createAdminUserInternal( username, name, email, password, true, false, userProperties );
            }
            else {
                user = createAdminUserInternal( username, name, email, password, activated, disabled, userProperties );
            }

            logger.debug("User created");
            organization = createOrganizationInternal( null, organizationName, user, true, organizationProperties );
        }
        finally {
            emailLock.unlock();
            userLock.unlock();
            groupLock.unlock();
        }

        return new OrganizationOwnerInfo( user, organization );
    }


    private OrganizationInfo createOrganizationInternal( UUID orgUuid, String organizationName, UserInfo user, boolean activated )
            throws Exception {
        logger.debug("createOrganizationInternal1");
        return createOrganizationInternal( orgUuid, organizationName, user, activated, null );
    }


    private OrganizationInfo createOrganizationInternal( UUID orgUuid, String organizationName, UserInfo user, boolean activated,
                                                         Map<String, Object> properties ) throws Exception {

        logger.info( "createOrganizationInternal2: {}", organizationName );

        if (  organizationName == null ) {
            logger.debug("organizationName = null");
            return null;
        }
        if ( user == null ) {
            logger.debug("user = null");
            return null;
        }

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        Group organizationEntity = new Group();
        organizationEntity.setPath( organizationName );

        if ( orgUuid == null ) {
            organizationEntity = em.create( organizationEntity );
        } else {
            em.create( orgUuid, Group.ENTITY_TYPE, organizationEntity.getProperties() );
            organizationEntity = em.get( orgUuid, Group.class );
        }

        em.addToCollection( organizationEntity, "users", new SimpleEntityRef( User.ENTITY_TYPE, user.getUuid() ) );
//        em.addToCollection( new SimpleEntityRef( User.ENTITY_TYPE, user.getUuid() ), Schema.COLLECTION_GROUPS, organizationEntity );

        writeUserToken( smf.getManagementAppId(), organizationEntity, encryptionService
                .plainTextCredentials( generateOAuthSecretKey( AuthPrincipalType.ORGANIZATION ), user.getUuid(),
                        smf.getManagementAppId() ) );

        OrganizationInfo organization =
                new OrganizationInfo( organizationEntity.getUuid(), organizationName, properties );
        updateOrganization( organization );

        if ( orgUuid == null ) { // no import ID specified, so do the activation email flow stuff

            logger.info( "createOrganizationInternal: {}", organizationName );
            postOrganizationActivity( organization.getUuid(), user, "create", organizationEntity, "Organization",
                    organization.getName(),
                    "<a href=\"mailto:" + user.getEmail() + "\">" + user.getName() + " (" + user.getEmail()
                            + ")</a> created a new organization account named " + organizationName, null );

            startOrganizationActivationFlow( organization );
        }



        return organization;
    }


    @Override
    public OrganizationInfo createOrganization(String organizationName, UserInfo user, boolean activated)
            throws Exception {
        return createOrganization( null, organizationName, user, activated );
    }

    @Override
    public OrganizationInfo createOrganization(UUID orgUuid, String organizationName, UserInfo user, boolean activated)
            throws Exception {

        if (  organizationName == null ) {
            logger.debug("organizationName = null");
            return null;
        }
        if ( user == null ) {
            logger.debug("user = null");
            return null;
        }

        Lock groupLock = getUniqueUpdateLock(
            lockManager, smf.getManagementAppId(), organizationName, Schema.COLLECTION_GROUPS, PROPERTY_PATH );

        EntityManager em = emf.getEntityManager(smf.getManagementAppId());
        if ( !em.isPropertyValueUniqueForEntity( Group.ENTITY_TYPE, PROPERTY_PATH, organizationName ) ) {
            throw new DuplicateUniquePropertyExistsException( Group.ENTITY_TYPE, PROPERTY_PATH, organizationName );
        }
        try {
            groupLock.lock();
            return createOrganizationInternal( orgUuid, organizationName, user, activated );
        }
        finally {
            groupLock.unlock();
        }
    }


    /** currently only affects properties */
    public void updateOrganization( OrganizationInfo organizationInfo ) throws Exception {
        Map<String, Object> properties = organizationInfo.getProperties();
        if ( properties != null ) {
            EntityRef organizationEntity = new SimpleEntityRef( Group.ENTITY_TYPE, organizationInfo.getUuid() );
            EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
            for ( Map.Entry<String, Object> entry : properties.entrySet() ) {
                if ( "".equals( entry.getValue() ) ) {
                    properties.remove( entry.getKey() );
                    em.removeFromDictionary( organizationEntity, ORGANIZATION_PROPERTIES_DICTIONARY, entry.getKey() );
                }
                else {
                    em.addToDictionary( organizationEntity, ORGANIZATION_PROPERTIES_DICTIONARY, entry.getKey(),
                            entry.getValue() );
                }
            }
        }
    }


    @Override
    public OrganizationInfo importOrganization( UUID organizationId, OrganizationInfo organizationInfo,
                                                Map<String, Object> properties ) throws Exception {

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        if ( !em.isPropertyValueUniqueForEntity( Group.ENTITY_TYPE, PROPERTY_PATH, organizationInfo.getName() ) ) {
            throw new DuplicateUniquePropertyExistsException( Group.ENTITY_TYPE, PROPERTY_PATH, organizationInfo.getName() );
        }
        if ( properties == null ) {
            properties = new HashMap<String, Object>();
        }

        String organizationName = null;
        if ( organizationInfo != null ) {
            organizationName = organizationInfo.getName();
        }
        if ( organizationName == null ) {
            organizationName = ( String ) properties.get( PROPERTY_PATH );
        }
        if ( organizationName == null ) {
            organizationName = ( String ) properties.get( PROPERTY_NAME );
        }
        if ( organizationName == null ) {
            return null;
        }

        if ( organizationId == null ) {
            if ( organizationInfo != null ) {
                organizationId = organizationInfo.getUuid();
            }
        }
        if ( organizationId == null ) {
            organizationId = uuid( properties.get( PROPERTY_UUID ) );
        }
        if ( organizationId == null ) {
            return null;
        }

        properties.put( PROPERTY_PATH, organizationName );
        properties.put( PROPERTY_SECRET, generateOAuthSecretKey( AuthPrincipalType.ORGANIZATION ) );
        Entity organization = em.create( organizationId, Group.ENTITY_TYPE, properties );
        // em.addToCollection(organization, "users", new SimpleEntityRef(
        // User.ENTITY_TYPE, userId));
        return new OrganizationInfo( organization.getUuid(), organizationName );
    }


    @Override
    public UUID importApplication( UUID organizationId, final Application application ) throws Exception {
        throw new UnsupportedOperationException("Import application not supported");
    }


    /**
     * Test if the applicationName contains a '/' character, prepend with orgName if it does not, assume it is complete
     * (and that organization is needed) if so.
     */
    private String buildAppName( String applicationName, OrganizationInfo organization ) {
        return applicationName.contains( "/" ) ? applicationName : organization.getName() + "/" + applicationName;
    }


    @Override
    public List<OrganizationInfo> getOrganizations( UUID startResult, int count ) throws Exception {
        // still need the bimap to search for existing
        BiMap<UUID, String> organizations = HashBiMap.create();
        EntityManager em = emf.getEntityManager(smf.getManagementAppId());
        Results results =
                em.getCollection(em.getApplicationRef(), Schema.COLLECTION_GROUPS, startResult, count, Level.ALL_PROPERTIES, false);
        List<OrganizationInfo> orgs = new ArrayList<OrganizationInfo>( results.size() );
        OrganizationInfo orgInfo;
        for ( Entity entity : results.getEntities() ) {
            // TODO T.N. temporary hack to deal with duplicate orgs. Revert this
            // commit after migration
            String path = ( String ) entity.getProperty( PROPERTY_PATH );

            if ( organizations.containsValue( path ) ) {
                path += "DUPLICATE";
            }
            orgInfo = new OrganizationInfo( entity.getUuid(), path );
            orgs.add( orgInfo );
            organizations.put( entity.getUuid(), path );
        }
        return orgs;
    }


    @Override
    public BiMap<UUID, String> getOrganizations() throws Exception {
        List<OrganizationInfo> orgs = getOrganizations( null, 10000 );
        return buildOrgBiMap( orgs );
    }


    private BiMap<UUID, String> buildOrgBiMap( List<OrganizationInfo> orgs ) {
        BiMap<UUID, String> organizations = HashBiMap.create();
        for ( OrganizationInfo orgInfo : orgs ) {
            organizations.put( orgInfo.getUuid(), orgInfo.getName() );
        }
        return organizations;
    }


    @Override
    public OrganizationInfo getOrganizationInfoFromAccessToken( String token ) throws Exception {
        Entity entity = getEntityFromAccessToken( token, null, ORGANIZATION );
        if ( entity == null ) {
            return null;
        }
        return new OrganizationInfo( entity.getProperties() );
    }


    @Override
    public OrganizationInfo getOrganizationByName( String organizationName ) throws Exception {

        if ( organizationName == null ) {
            return null;
        }

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        EntityRef ref = em.getAlias( Group.ENTITY_TYPE, organizationName );
        if ( ref == null ) {
            return null;
        }
        return getOrganizationByUuid( ref.getUuid() );
    }


    @Override
    public OrganizationInfo getOrganizationByUuid( UUID id ) throws Exception {

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        Entity entity = em.get( new SimpleEntityRef( Group.ENTITY_TYPE, id ) );
        if ( entity == null ) {
            return null;
        }
        Map properties = em.getDictionaryAsMap( entity, ORGANIZATION_PROPERTIES_DICTIONARY );
        OrganizationInfo orgInfo = new OrganizationInfo( entity.getProperties() );
        orgInfo.setProperties( properties );
        return orgInfo;
    }


    @Override
    public OrganizationInfo getOrganizationByIdentifier( Identifier id ) throws Exception {
        if ( id.isUUID() ) {
            return getOrganizationByUuid( id.getUUID() );
        }
        if ( id.isName() ) {
            return getOrganizationByName( id.getName() );
        }
        return null;
    }


    public void postUserActivity( UserInfo user, String verb, EntityRef object, String objectType, String objectName,
                                  String title, String content ) throws Exception {
        ServiceManager sm = smf.getServiceManager( smf.getManagementAppId() );

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put( PROPERTY_VERB, verb );
        properties.put( PROPERTY_CATEGORY, "admin" );
        if ( content != null ) {
            properties.put( PROPERTY_CONTENT, content );
        }
        if ( title != null ) {
            properties.put( PROPERTY_TITLE, title );
        }
        properties.put( PROPERTY_ACTOR, user.getUuid() );
        properties.put( PROPERTY_ACTOR_NAME, user.getName() );
        properties.put( PROPERTY_OBJECT, object.getUuid() );
        properties.put( PROPERTY_OBJECT_ENTITY_TYPE, object.getType() );
        properties.put( PROPERTY_OBJECT_TYPE, objectType );
        properties.put( PROPERTY_OBJECT_NAME, objectName );

        sm.newRequest( ServiceAction.POST, parameters( "users", user.getUuid(), "activities" ), payload( properties ) )
          .execute().getEntity();
    }


    @Override
    public ServiceResults getAdminUserActivities( UserInfo user ) throws Exception {
        ServiceManager sm = smf.getServiceManager( smf.getManagementAppId() );
        ServiceRequest request = sm.newRequest( ServiceAction.GET, parameters( "users", user.getUuid(), "feed" ) );
        ServiceResults results = request.execute();
        return results;
    }


    private UserInfo doCreateAdmin( User user, CredentialsInfo userPassword, CredentialsInfo mongoPassword )
            throws Exception {

        writeUserToken( smf.getManagementAppId(), user, encryptionService
                .plainTextCredentials( generateOAuthSecretKey( AuthPrincipalType.ADMIN_USER ), user.getUuid(),
                        smf.getManagementAppId() ) );

        writeUserPassword( smf.getManagementAppId(), user, userPassword );

        writeUserMongoPassword( smf.getManagementAppId(), user, mongoPassword );

        UserInfo userInfo = new UserInfo(
            smf.getManagementAppId(), user.getUuid(), user.getUsername(), user.getName(),
            user.getEmail(), user.getConfirmed(), user.getActivated(), user.getDisabled(),
            user.getDynamicProperties(), true );

        // special case for sysadmin and test account only
        if (    !user.getEmail().equals( properties.getProperty( PROPERTIES_SYSADMIN_LOGIN_EMAIL ) )
             && !user.getEmail().equals( properties .getProperty( PROPERTIES_TEST_ACCOUNT_ADMIN_USER_EMAIL ) ) ) {
            this.startAdminUserActivationFlow( userInfo );
        }

        return userInfo;
    }


    @Override
    public UserInfo createAdminFromPrexistingPassword( User user, CredentialsInfo ci ) throws Exception {

        return doCreateAdmin( user, ci,
                // we can't actually set the mongo password. We never have the plain text in
                // this path
                encryptionService.plainTextCredentials( mongoPassword( user.getUsername(), "" ), user.getUuid(),
                        smf.getManagementAppId() ) );
    }


    @Override
    public UserInfo createAdminFrom( User user, String password ) throws Exception {
        return doCreateAdmin( user,
                encryptionService.defaultEncryptedCredentials( password, user.getUuid(), smf.getManagementAppId() ),
                encryptionService.plainTextCredentials( mongoPassword( user.getUsername(), password ), user.getUuid(),
                        smf.getManagementAppId() ) );
    }


    @Override
    public UserInfo createAdminUser( String username, String name, String email, String password, boolean activated,
                                     boolean disabled ) throws Exception {
        return createAdminUser( username, name, email, password, activated, disabled, null );
    }


    @Override
    public UserInfo createAdminUser( String username, String name, String email, String password, boolean activated,
                                     boolean disabled, Map<String, Object> userProperties ) throws Exception {

        if ( !validateAdminInfo( username, name, email, password ) ) {
            return null;
        }
        return createAdminUserInternal( username, name, email, password, activated, disabled, userProperties );
    }


    private boolean validateAdminInfo( String username, String name, String email, String password ) throws Exception {
        if ( email == null ) {
            return false;
        }
        if ( username == null ) {
            username = email;
        }
        if ( name == null ) {
            name = email;
        }

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        if ( !em.isPropertyValueUniqueForEntity( "user", "username", username ) ) {
            throw new DuplicateUniquePropertyExistsException( "user", "username", username );
        }

        if ( !em.isPropertyValueUniqueForEntity( "user", "email", email ) ) {
            throw new DuplicateUniquePropertyExistsException( "user", "email", email );
        }
        return true;
    }


    private UserInfo createAdminUserInternal( String username, String name, String email, String password,
                                              boolean activated, boolean disabled, Map<String, Object> userProperties )
            throws Exception {
        logger.info( "createAdminUserInternal: {}", username );

        if ( isBlank( password ) ) {
            password = encodeBase64URLSafeString( bytes( UUID.randomUUID() ) );
        }
        if ( username == null ) {
            username = email;
        }
        if ( name == null ) {
            name = email;
        }
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        User user = new User();
        user.setUsername( username );
        user.setName( name );
        user.setEmail( email );
        user.setActivated( activated );
        user.setConfirmed( !newAdminUsersRequireConfirmation() ); // only
        user.setDisabled( disabled );
        if ( userProperties != null ) {
            // double check no 'password' property just to be safe
            userProperties.remove( "password" );
            user.setProperties( userProperties );
        }
        user = em.create( user );

        return createAdminFrom( user, password );
    }


    public UserInfo getUserInfo( UUID applicationId, Entity entity ) {

        if ( entity == null ) {
            return null;
        }
        return new UserInfo( applicationId, entity.getUuid(), ( String ) entity.getProperty( "username" ),
                entity.getName(), ( String ) entity.getProperty( "email" ),
                ConversionUtils.getBoolean( entity.getProperty( "confirmed" ) ),
                ConversionUtils.getBoolean( entity.getProperty( "activated" ) ),
                ConversionUtils.getBoolean( entity.getProperty( "disabled" ) ),
                entity.getDynamicProperties(),
                ConversionUtils.getBoolean( entity.getProperty( "admin" )));
    }


    public UserInfo getUserInfo( UUID applicationId, Map<String, Object> properties ) {

        if ( properties == null ) {
            return null;
        }
        return new UserInfo( applicationId, properties );
    }


    @Override
    public List<UserInfo> getAdminUsersForOrganization( UUID organizationId ) throws Exception {

        if ( organizationId == null ) {
            return null;
        }

        List<UserInfo> users = new ArrayList<UserInfo>();

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        Results results =
                em.getCollection( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "users", null, 10000,
                        Level.ALL_PROPERTIES, false );
        for ( Entity entity : results.getEntities() ) {
            users.add( getUserInfo( smf.getManagementAppId(), entity ) );
        }

        return users;
    }


    @Override
    public UserInfo updateAdminUser( UserInfo user, String username, String name, String email,
                                     Map<String, Object> json ) throws Exception {

        /**
         * Only lock on the target values. We don't want lock contention if another
         * node is trying to set the property do a different value
         */
        Lock usernameLock =
                getUniqueUpdateLock( lockManager, smf.getManagementAppId(), username, "users", "username" );

        Lock emailLock = getUniqueUpdateLock( lockManager, smf.getManagementAppId(), email, "users", "email" );

        try {

            usernameLock.lock();
            emailLock.lock();

            EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

            SimpleEntityRef entityRef = new SimpleEntityRef( User.ENTITY_TYPE, user.getUuid() );
            if ( !isBlank( username ) ) {
                em.setProperty( entityRef, "username", username );
            }
            if ( !isBlank( name ) ) {
                em.setProperty( entityRef, "name", name );
            }
            if ( !isBlank( email ) ) {
                em.setProperty( entityRef, "email", email );
            }
            if ( json != null ) {
                json.remove( "password" );
                json.remove( "oldpassword" );
                json.remove( "newpassword" );
                Map<String, Object> userProperties = user.getProperties();
                userProperties.putAll( json );
                em.updateProperties( entityRef, userProperties );
            }

            user = getAdminUserByUuid( user.getUuid() );
        }
        finally {
            emailLock.unlock();
            usernameLock.unlock();
        }

        return user;
    }


    public User getAdminUserEntityByEmail( String email ) throws Exception {

        if ( email == null ) {
            return null;
        }

        return getUserEntityByIdentifier( smf.getManagementAppId(), Identifier.fromEmail( email ) );
    }


    @Override
    public UserInfo getAdminUserByEmail( String email ) throws Exception {
        if ( email == null ) {
            return null;
        }
        return getUserInfo( smf.getManagementAppId(),
                getUserEntityByIdentifier( smf.getManagementAppId(), Identifier.fromEmail( email ) ) );
    }


    public User getUserEntityByIdentifier( UUID applicationId, Identifier identifier ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        return em.get( em.getUserByIdentifier( identifier ), User.class );
    }


    @Override
    public UserInfo getAdminUserByUsername( String username ) throws Exception {
        if ( username == null ) {
            return null;
        }
        return getUserInfo( smf.getManagementAppId(),
                getUserEntityByIdentifier( smf.getManagementAppId(), Identifier.fromName( username ) ) );
    }


    @Override
    public User getAdminUserEntityByUuid( UUID id ) throws Exception {
        if ( id == null ) {
            return null;
        }
        return getUserEntityByIdentifier( smf.getManagementAppId(), Identifier.fromUUID( id ) );
    }


    @Override
    public UserInfo getAdminUserByUuid( UUID id ) throws Exception {
        return getUserInfo( smf.getManagementAppId(),
                getUserEntityByIdentifier( smf.getManagementAppId(), Identifier.fromUUID( id ) ) );
    }


    @Override
    public User getAdminUserEntityByIdentifier( Identifier id ) throws Exception {
        return getUserEntityByIdentifier( smf.getManagementAppId(), id );
    }


    @Override
    public UserInfo getAdminUserByIdentifier( Identifier id ) throws Exception {
        if ( id.isUUID() ) {
            return getAdminUserByUuid( id.getUUID() );
        }
        if ( id.isName() ) {
            return getAdminUserByUsername( id.getName() );
        }
        if ( id.isEmail() ) {
            return getAdminUserByEmail( id.getEmail() );
        }
        return null;
    }


    public User findUserEntity( UUID applicationId, String identifierString ) {

        User user = null;
        if ( UUIDUtils.isUUID( identifierString ) ) {
            try {
                Entity entity = getUserEntityByIdentifier( applicationId,
                        Identifier.fromUUID( UUID.fromString( identifierString ) ) );
                if ( entity != null ) {
                    user = ( User ) entity.toTypedEntity();
                    logger.info( "Found user {} as a UUID", identifierString );
                }
            }
            catch ( Exception e ) {
                logger.warn( "Unable to get user " + identifierString + " as a UUID, trying username..." );
            }
            return user;
        }
        // now we are either an email or a username. Let Indentifier handle the parsing of such.
        Identifier identifier = Identifier.from( identifierString );

        try {
            Entity entity = getUserEntityByIdentifier( applicationId, identifier );
            if ( entity != null ) {
                user = ( User ) entity.toTypedEntity();
                logger.info( "Found user {} as an {}", identifierString, identifier.getType() );
            }
        }
        catch ( Exception e ) {
            logger.warn( "Unable to get user {} as a {}", identifierString, identifier.getType());
            logger.warn( "Exception", e);
        }
        if ( user != null ) {
            return user;
        }

        return null;
    }


    @Override
    public UserInfo findAdminUser( String identifier ) {
        return getUserInfo( smf.getManagementAppId(), findUserEntity( smf.getManagementAppId(), identifier ) );
    }


    @Override
    public void setAdminUserPassword( UUID userId, String oldPassword, String newPassword ) throws Exception {

        if ( ( userId == null ) || ( oldPassword == null ) || ( newPassword == null ) ) {
            return;
        }
        User user = emf.getEntityManager( smf.getManagementAppId() ).get( userId, User.class );

        if ( !verify( smf.getManagementAppId(), user.getUuid(), oldPassword ) ) {
            throw new IncorrectPasswordException( "Old password does not match" );
        }

        setAdminUserPassword( userId, newPassword );
    }


    private static final String CREDENTIALS_HISTORY = "credentialsHistory";


    @Override
    public void setAdminUserPassword( UUID userId, String newPassword ) throws Exception {

        if ( ( userId == null ) || ( newPassword == null ) ) {
            return;
        }

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        User user = em.get( userId, User.class );

        CredentialsInfo newCredentials =
                encryptionService.defaultEncryptedCredentials( newPassword, user.getUuid(), smf.getManagementAppId() );

        int passwordHistorySize = calculatePasswordHistorySizeForUser( user.getUuid() );
        Map<String, CredentialsInfo> credsMap = cast( em.getDictionaryAsMap( user, CREDENTIALS_HISTORY ) );

        CredentialsInfo currentCredentials = null;
        if ( passwordHistorySize > 0 ) {
            ArrayList<CredentialsInfo> oldCreds = new ArrayList<CredentialsInfo>( credsMap.values() );
            Collections.sort( oldCreds );

            currentCredentials = readUserPasswordCredentials( smf.getManagementAppId(), user.getUuid(), user.getType() );

            // check credential history
            if ( encryptionService.verify( newPassword, currentCredentials, userId, smf.getManagementAppId() ) ) {
                throw new RecentlyUsedPasswordException();
            }
            for ( int i = 0; i < oldCreds.size() && i < passwordHistorySize; i++ ) {
                CredentialsInfo ci = oldCreds.get( i );
                if ( encryptionService.verify( newPassword, ci, userId, smf.getManagementAppId() ) ) {
                    throw new RecentlyUsedPasswordException();
                }
            }
        }

        // remove excess history
        if ( credsMap.size() > passwordHistorySize ) {
            ArrayList<UUID> oldUUIDs = new ArrayList<UUID>( credsMap.size() );
            for ( String uuid : credsMap.keySet() ) {
                oldUUIDs.add( UUID.fromString( uuid ) );
            }
            UUIDUtils.sort( oldUUIDs );
            for ( int i = 0; i < oldUUIDs.size() - passwordHistorySize; i++ ) {
                em.removeFromDictionary( user, CREDENTIALS_HISTORY, oldUUIDs.get( i ).toString() );
            }
        }

        if ( passwordHistorySize > 0 ) {
            UUID uuid = UUIDUtils.newTimeUUID();
            em.addToDictionary( user, CREDENTIALS_HISTORY, uuid.toString(), currentCredentials );
        }

        writeUserPassword( smf.getManagementAppId(), user, newCredentials );
        writeUserMongoPassword( smf.getManagementAppId(), user, encryptionService
                .plainTextCredentials( mongoPassword( ( String ) user.getProperty( "username" ), newPassword ),
                        user.getUuid(), smf.getManagementAppId() ) );

    }


    public int calculatePasswordHistorySizeForUser( UUID userId ) throws Exception {

        logger.debug( "calculatePasswordHistorySizeForUser " + userId.toString() );

        int size = 0;
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        Results orgResults = em.getCollection( new SimpleEntityRef( User.ENTITY_TYPE, userId ),
                Schema.COLLECTION_GROUPS, null, 10000, Level.REFS, false );

        logger.debug( "    orgResults.size() = " +  orgResults.size() );

        for ( EntityRef orgRef : orgResults.getRefs() ) {
            Map properties = em.getDictionaryAsMap( orgRef, ORGANIZATION_PROPERTIES_DICTIONARY );
            if ( properties != null ) {
                OrganizationInfo orgInfo = new OrganizationInfo( null, null, properties );
                logger.debug( "    orgInfo.getPasswordHistorySize() = " +  orgInfo.getPasswordHistorySize() );
                size = Math.max( orgInfo.getPasswordHistorySize(), size );
            }
        }

        return size;
    }


    @Override
    public boolean verifyAdminUserPassword( UUID userId, String password ) throws Exception {
        if ( ( userId == null ) || ( password == null ) ) {
            return false;
        }
        User user = emf.getEntityManager( smf.getManagementAppId() ).get( userId, User.class );

        return verify( smf.getManagementAppId(), user.getUuid(), password );
    }


    @Override
    public UserInfo verifyAdminUserPasswordCredentials( String name, String password ) throws Exception {
        UserInfo userInfo = null;

        logger.debug("verifyAdminUserPasswordCredentials for {}/{}", name, password);

        User user = findUserEntity( smf.getManagementAppId(), name );
        if ( user == null ) {
            return null;
        }

        if ( verify( smf.getManagementAppId(), user.getUuid(), password ) ) {
            userInfo = getUserInfo( smf.getManagementAppId(), user );

            boolean userIsSuperAdmin = properties.getSuperUser().isEnabled() && properties.getSuperUser().getEmail().equals(userInfo.getEmail());

            boolean testUserEnabled = parseBoolean( properties.getProperty( PROPERTIES_SETUP_TEST_ACCOUNT ) );
            boolean userIsTestUser = testUserEnabled && properties.getProperty(PROPERTIES_SYSADMIN_LOGIN_EMAIL)
                    .equals(userInfo.getEmail());

            if ( !userIsSuperAdmin && !userIsTestUser ) {

                if ( !userInfo.isConfirmed() && newAdminUsersRequireConfirmation() ) {
                    throw new UnconfirmedAdminUserException();
                }
                if ( !userInfo.isActivated() ) {
                    throw new UnactivatedAdminUserException();
                }
                if ( userInfo.isDisabled() ) {
                    throw new DisabledAdminUserException();
                }
            }
            return userInfo;
        }
        logger.info( "password compare fail for {}", name );
        return null;
    }


    @Override
    public UserInfo verifyMongoCredentials( String name, String nonce, String key ) throws Exception {

        Entity user = findUserEntity( smf.getManagementAppId(), name );

        if ( user == null ) {
            return null;
        }

        String mongo_pwd = readUserMongoPassword( smf.getManagementAppId(), user.getUuid(), user.getType() ).getSecret();

        if ( mongo_pwd == null ) {
            throw new IncorrectPasswordException( "Your mongo password has not be set" );
        }

        String expected_key = DigestUtils.md5Hex( nonce + user.getProperty( "username" ) + mongo_pwd );

        if ( !expected_key.equalsIgnoreCase( key ) ) {
            throw new IncorrectPasswordException();
        }

        UserInfo userInfo = new UserInfo( smf.getManagementAppId(), user.getProperties() );

        if ( !userInfo.isActivated() ) {
            throw new UnactivatedAdminUserException();
        }
        if ( userInfo.isDisabled() ) {
            throw new DisabledAdminUserException();
        }

        return userInfo;
    }


    // TokenType tokenType, String type, AuthPrincipalInfo principal,
    // Map<String, Object> state
    public String getTokenForPrincipal( TokenCategory token_category, String token_type, UUID applicationId,
                                        AuthPrincipalType principal_type, UUID id, long duration ) throws Exception {

        if ( anyNull( token_category, applicationId, principal_type, id ) ) {
            return null;
        }

        return tokens
                .createToken( token_category, token_type, new AuthPrincipalInfo( principal_type, id, applicationId ),
                        null, duration );
    }


    public void revokeTokensForPrincipal( AuthPrincipalType principalType, UUID applicationId, UUID id )
            throws Exception {

        if ( anyNull( applicationId, principalType, id ) ) {
            throw new IllegalArgumentException( "applicationId, principal_type and id are required" );
        }

        AuthPrincipalInfo principal = new AuthPrincipalInfo( principalType, id, applicationId );

        tokens.removeTokens( principal );
    }


    public AuthPrincipalInfo getPrincipalFromAccessToken( String token, String expected_token_type,
                                                          AuthPrincipalType expected_principal_type ) throws Exception {

        TokenInfo tokenInfo = tokens.getTokenInfo( token );

        if ( tokenInfo == null ) {
            return null;
        }

        if ( ( expected_token_type != null ) && !expected_token_type.equals( tokenInfo.getType() ) ) {
            return null;
        }

        AuthPrincipalInfo principal = tokenInfo.getPrincipal();
        if ( principal == null ) {
            return null;
        }

        if ( ( expected_principal_type != null ) && !expected_principal_type.equals( principal.getType() ) ) {
            return null;
        }

        return principal;
    }


    public Entity getEntityFromAccessToken( String token, String expected_token_type,
                                            AuthPrincipalType expected_principal_type ) throws Exception {

        AuthPrincipalInfo principal =
                getPrincipalFromAccessToken( token, expected_token_type, expected_principal_type );
        if ( principal == null ) {
            return null;
        }

        return getEntityFromPrincipal( principal );
    }


    public Entity getEntityFromPrincipal( AuthPrincipalInfo principal ) throws Exception {

        EntityManager em = emf.getEntityManager(
            principal.getApplicationId() != null
                ? principal.getApplicationId() : smf.getManagementAppId() );

        Entity entity = em.get( new SimpleEntityRef(
                principal.getType().getEntityType(), principal.getUuid()));

        return entity;
    }


    @Override
    public String getAccessTokenForAdminUser( UUID userId, long duration ) throws Exception {

        return getTokenForPrincipal( ACCESS, null, smf.getManagementAppId(), ADMIN_USER, userId, duration );
    }


    @Override
    public void importTokenForAdminUser(UUID userId, String token, long ttl) throws Exception {
        tokens.importToken( token, TokenCategory.ACCESS, null,
                new AuthPrincipalInfo( ADMIN_USER, userId, smf.getManagementAppId() ), null, ttl );
    }


    /*
   * (non-Javadoc)
   *
   * @see
   * org.apache.usergrid.management.ManagementService#revokeAccessTokensForAdminUser
   * (java.util.UUID)
   */
    @Override
    public void revokeAccessTokensForAdminUser( UUID userId ) throws Exception {
        revokeTokensForPrincipal( ADMIN_USER, smf.getManagementAppId(), userId );
    }


    @Override
    public void revokeAccessTokenForAdminUser( UUID userId, String token ) throws Exception {
        if ( anyNull( userId, token ) ) {
            throw new IllegalArgumentException( "token is required" );
        }

        Entity user = getAdminUserEntityFromAccessToken( token );
        if ( !user.getUuid().equals( userId ) ) {
            throw new TokenException( "Could not match token : " + token );
        }

        tokens.revokeToken( token );
    }


    @Override
    public Entity getAdminUserEntityFromAccessToken( String token ) throws Exception {

        Entity user = getEntityFromAccessToken( token, null, ADMIN_USER );
        return user;
    }


    @Override
    public UserInfo getAdminUserInfoFromAccessToken( String token ) throws Exception {
        Entity user = getAdminUserEntityFromAccessToken( token );
        return new UserInfo( smf.getManagementAppId(), user.getProperties() );
    }


    @Override
    public BiMap<UUID, String> getOrganizationsForAdminUser( UUID userId ) throws Exception {

        if ( userId == null ) {
            return null;
        }

        BiMap<UUID, String> organizations = HashBiMap.create();
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        Results results = em.getCollection(  new SimpleEntityRef( User.ENTITY_TYPE, userId ),
            Schema.COLLECTION_GROUPS, null, 1000, Level.ALL_PROPERTIES, false );

        String path = null;

        do {
            for ( Entity entity : results.getEntities() ) {

                path = ( String ) entity.getProperty( PROPERTY_PATH );

                if ( path != null ) {
                    path = path.toLowerCase();
                }

                try {
                    organizations.put( entity.getUuid(), path );
                } catch (IllegalArgumentException e) {
                    logger.warn("Error adding " + entity.getUuid() + ":" + path + " to BiMap: " + e.getMessage() );
                }
            }

            results = results.hasMoreResults() ? results.getNextPageResults() : null ;

        } while (results != null);

        return organizations;
    }


    @Override
    public Map<String, Object> getAdminUserOrganizationData( UUID userId ) throws Exception {
        UserInfo user = getAdminUserByUuid( userId );
        return getAdminUserOrganizationData( user, true );
    }


    @Override
    public Long getLastAdminPasswordChange( UUID userId ) throws Exception {
        CredentialsInfo ci = readUserPasswordCredentials( smf.getManagementAppId(), userId, User.ENTITY_TYPE );
        return ci.getCreated();
    }


    @Override
    public Map<String, Object> getAdminUserOrganizationData( UserInfo user, boolean deep ) throws Exception {

        Map<String, Object> json = new HashMap<String, Object>();

        json.putAll( JsonUtils.toJsonMap( user ) );

        Map<String, Map<String, Object>> jsonOrganizations = new HashMap<String, Map<String, Object>>();
        json.put( "organizations", jsonOrganizations );

        Map<UUID, String> organizations;

        AccountCreationProps.SuperUser superUser = properties.getSuperUser();
        if ( superUser.isEnabled() && superUser.getUsername().equals( user.getUsername() ) ) {
            int maxOrganizations = this.getAccountCreationProps().getMaxOrganizationsForSuperUserLogin();
            organizations = buildOrgBiMap( getOrganizations( null, maxOrganizations ) );
        }
        else {
            organizations = getOrganizationsForAdminUser( user.getUuid() );
        }

        for ( Entry<UUID, String> organization : organizations.entrySet() ) {
            Map<String, Object> jsonOrganization = new HashMap<String, Object>();

            jsonOrganizations.put( organization.getValue(), jsonOrganization );

            jsonOrganization.put( PROPERTY_NAME, organization.getValue() );
            jsonOrganization.put( PROPERTY_UUID, organization.getKey() );
            jsonOrganization.put( "properties", getOrganizationByUuid( organization.getKey() ).getProperties() );

            if ( deep ) {
                BiMap<UUID, String> applications = getApplicationsForOrganization( organization.getKey() );
                jsonOrganization.put( "applications", applications.inverse() );

                List<UserInfo> users = getAdminUsersForOrganization( organization.getKey() );
                Map<String, Object> jsonUsers = new HashMap<String, Object>();
                for ( UserInfo u : users ) {
                    jsonUsers.put( u.getUsername(), u );
                }
                jsonOrganization.put( "users", jsonUsers );
            }
        }

        return json;
    }


    @Override
    public Map<String, Object> getOrganizationData( OrganizationInfo organization ) throws Exception {

        Map<String, Object> jsonOrganization = new HashMap<>();
        jsonOrganization.putAll( JsonUtils.toJsonMap( organization ) );

        BiMap<UUID, String> applications = getApplicationsForOrganization( organization.getUuid() );
        jsonOrganization.put( "applications", applications.inverse() );

        List<UserInfo> users = getAdminUsersForOrganization( organization.getUuid() );
        Map<String, Object> jsonUsers = new HashMap<>();
        for ( UserInfo u : users ) {
            jsonUsers.put( u.getUsername(), u );
        }
        jsonOrganization.put( "users", jsonUsers );

        return jsonOrganization;
    }


    @Override
    public void addAdminUserToOrganization( UserInfo user, OrganizationInfo organization, boolean email )
            throws Exception {

        if ( ( user == null ) || ( organization == null ) ) {
            return;
        }

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.addToCollection( new SimpleEntityRef( Group.ENTITY_TYPE, organization.getUuid() ), "users",
                new SimpleEntityRef( User.ENTITY_TYPE, user.getUuid() ) );

        if ( email ) {
            sendAdminUserInvitedEmail( user, organization );
        }
    }


    @Override
    public void removeAdminUserFromOrganization( UUID userId, UUID organizationId ) throws Exception {

        if ( ( userId == null ) || ( organizationId == null ) ) {
            return;
        }

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        try {
            if ( em.getCollection( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "users", null, 2,
                    Level.IDS, false ).size() <= 1 ) {
                throw new Exception();
            }
        }
        catch ( Exception e ) {
            throw new UnableToLeaveOrganizationException( "Organizations must have at least one member." );
        }

        em.removeFromCollection( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "users",
                new SimpleEntityRef( User.ENTITY_TYPE, userId ) );
    }


    @Override
    public ApplicationInfo createApplication( UUID organizationId, String applicationName ) throws Exception {

        return createApplication( organizationId, applicationName, null );
    }


    @Override
    public ApplicationInfo createApplication( UUID organizationId, String applicationName,
                                              Map<String, Object> properties ) throws Exception {

        if ( ( organizationId == null ) || ( applicationName == null ) ) {
            return null;
        }

        if ( properties == null ) {
            properties = new HashMap<>();
        }

        OrganizationInfo organizationInfo = getOrganizationByUuid( organizationId );
        Entity appInfo = emf.createApplicationV2(
            organizationInfo.getName(), applicationName, properties);

        writeUserToken( smf.getManagementAppId(), appInfo,
            encryptionService.plainTextCredentials(
                generateOAuthSecretKey( AuthPrincipalType.APPLICATION ),
                null,
                smf.getManagementAppId() ) );

        UUID applicationId = addApplicationToOrganization( organizationId, appInfo );

        UserInfo user = null;
        try {
            user = SubjectUtils.getUser();
        }
        catch ( UnavailableSecurityManagerException e ) {
            // occurs in the rare case that this is called before the full stack is initialized
            logger.warn("Error getting user, application created activity will not be created", e);
        }
        if ( ( user != null ) && user.isAdminUser() ) {
            postOrganizationActivity( organizationId, user, "create", appInfo, "Application", applicationName,
                "<a href=\"mailto:" + user.getEmail() + "\">" + user.getName() + " (" + user.getEmail()
                    + ")</a> created a new application named " + applicationName, null );
        }



        return new ApplicationInfo( applicationId, appInfo.getName() );
    }


    @Override
    public void deleteApplication(UUID applicationId) throws Exception {
        emf.deleteApplication( applicationId );
    }


    @Override
    public ApplicationInfo restoreApplication(UUID applicationId) throws Exception {

        ApplicationInfo app = getDeletedApplicationInfo( applicationId );
        if ( app == null ) {
            throw new EntityNotFoundException("Deleted application ID " + applicationId + " not found");
        }

        if ( emf.lookupApplication( app.getName() ).isPresent()) {
            throw new ConflictException("Cannot restore application, one with that name already exists.");
        }

        // restore application_info entity

        EntityManager em = emf.getEntityManager( emf.getManagementAppId() );
        Entity appInfo = emf.restoreApplication(applicationId);

        // restore token

        writeUserToken( smf.getManagementAppId(), appInfo,
            encryptionService.plainTextCredentials(
                generateOAuthSecretKey( AuthPrincipalType.APPLICATION ),
                null,
                smf.getManagementAppId() ) );

        String orgName = appInfo.getName().split("/")[0];
        EntityRef alias = em.getAlias( Group.ENTITY_TYPE, orgName );
        Entity orgEntity = em.get( alias );

        addApplicationToOrganization( orgEntity.getUuid(), appInfo );

        // create activity

        UserInfo user = null;
        try {
            user = SubjectUtils.getUser();
        }
        catch ( UnavailableSecurityManagerException e ) {
            // occurs in the rare case that this is called before the full stack is initialized
            logger.warn("Error getting user, application restored created activity will not be created", e);
        }
        if ( ( user != null ) && user.isAdminUser() ) {
            postOrganizationActivity( orgEntity.getUuid(), user, "restore", appInfo, "Application", appInfo.getName(),
                "<a href=\"mailto:" + user.getEmail() + "\">" + user.getName() + " (" + user.getEmail()
                    + ")</a> restored an application named " + appInfo.getName(), null );
        }



        return new ApplicationInfo( applicationId, appInfo.getName() );
    }


    @Override
    public OrganizationInfo getOrganizationForApplication( UUID applicationInfoId ) throws Exception {

        if ( applicationInfoId == null ) {
            return null;
        }

        final EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        Results r = em.getSourceEntities(
            new SimpleEntityRef(CpNamingUtils.APPLICATION_INFO, applicationInfoId),
            "owns", Group.ENTITY_TYPE, Level.ALL_PROPERTIES);

        Entity entity = r.getEntity();
        if ( entity != null ) {
            return new OrganizationInfo( entity.getUuid(), ( String ) entity.getProperty( "path" ) );
        }

        return null;
    }


    @Override
    public BiMap<UUID, String> getApplicationsForOrganization( UUID organizationGroupId ) throws Exception {

        if ( organizationGroupId == null ) {
            return null;
        }
        final BiMap<UUID, String> applications = HashBiMap.create();
        final EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        // query for application_info entities
        final Results results = em.getTargetEntities(
            new SimpleEntityRef(Group.ENTITY_TYPE, organizationGroupId),
            "owns", CpNamingUtils.APPLICATION_INFO, Level.ALL_PROPERTIES);

        final PagingResultsIterator itr = new PagingResultsIterator( results );

        String entityName;

        while ( itr.hasNext() ) {

            final Entity entity = ( Entity ) itr.next();

            entityName = entity.getName();

            if ( entityName != null ) {
                entityName = entityName.toLowerCase();
            }

            // make sure we return applicationId and not the application_info UUID
            UUID applicationId = UUIDUtils.tryExtractUUID(
                entity.getProperty( PROPERTY_APPLICATION_ID ).toString() );

            applications.put( applicationId, entityName );
        }


        return applications;
    }


    @Override
    public BiMap<UUID, String> getApplicationsForOrganizations( Set<UUID> organizationIds ) throws Exception {
        if ( organizationIds == null ) {
            return null;
        }
        BiMap<UUID, String> applications = HashBiMap.create();
        for ( UUID organizationId : organizationIds ) {
            BiMap<UUID, String> organizationApplications = getApplicationsForOrganization( organizationId );
            applications.putAll( organizationApplications );
        }
        return applications;
    }


    /**
     * @return UUID of the application itself (NOT the application_info entity).
     */
    @Override
    public UUID addApplicationToOrganization(UUID organizationId, Entity appInfo) throws Exception {

        UUID applicationId = appInfo.getUuid();

        if ( ( organizationId == null ) || ( applicationId == null ) ) {
            return null;
        }

        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.createConnection( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "owns", appInfo );

        return applicationId;
    }


    @Override
    public void deleteOrganizationApplication( UUID organizationId, UUID applicationId ) throws Exception {
        // TODO Auto-generated method stub

    }


    @Override
    public void removeOrganizationApplication( UUID organizationId, UUID applicationId ) throws Exception {
        // TODO Auto-generated method stub

    }


    @Override
    public ApplicationInfo getApplicationInfo( String applicationName ) throws Exception {
        if ( applicationName == null ) {
            return null;
        }
        Optional<UUID> applicationId = emf.lookupApplication(applicationName);
        if ( !applicationId.isPresent() ) {
            return null;
        }
        return new ApplicationInfo( applicationId.get(), applicationName.toLowerCase() );
    }


    @Override
    public ApplicationInfo getApplicationInfo( UUID applicationId ) throws Exception {
        if ( applicationId == null ) {
            return null;
        }
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        Entity entity = em.get( new SimpleEntityRef(CpNamingUtils.APPLICATION_INFO, applicationId) );

        if ( entity != null ) {
            return new ApplicationInfo( applicationId, entity.getName() );
        }
        return null;
    }


    @Override
    public ApplicationInfo getDeletedApplicationInfo(UUID applicationId) throws Exception {
        if ( applicationId == null ) {
            return null;
        }
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        final Entity entity = em.get( new SimpleEntityRef( CpNamingUtils.DELETED_APPLICATION_INFO, applicationId ) );

        if ( entity != null ) {
            return new ApplicationInfo( applicationId, entity.getName() );
        }
        return null;
    }


    @Override
    public ApplicationInfo getApplicationInfo( Identifier id ) throws Exception {
        if ( id == null ) {
            return null;
        }
        if ( id.isUUID() ) {
            return getApplicationInfo( id.getUUID() );
        }
        if ( id.isName() ) {
            return getApplicationInfo( id.getName() );
        }
        return null;
    }


    @Override
    public ApplicationInfo getApplicationInfoFromAccessToken( String token ) throws Exception {
        Entity entity = getEntityFromAccessToken( token, null, APPLICATION );
        if ( entity == null ) {
            throw new TokenException( "Could not find an entity for that access token: " + token );
        }
        return new ApplicationInfo( entity.getProperties() );
    }


    @Override
    public ServiceResults getApplicationMetadata( UUID applicationId ) throws Exception {

        if ( applicationId == null ) {
            return ServiceResults.genericServiceResults();
        }

        EntityManager em = emf.getEntityManager( applicationId );
        Entity entity = em.get( em.getApplicationRef() );

        Results r = Results.fromEntity( entity );

        Map<String, Object> collections = em.getApplicationCollectionMetadata();
        if ( collections.size() > 0 ) {
            r.setMetadata( em.getApplicationRef().getUuid(), "collections", collections );
        }
        return genericServiceResults( r );
    }


    public String getSecret( UUID applicationId, AuthPrincipalType type, UUID entityId ) throws Exception {

        if ( AuthPrincipalType.ORGANIZATION.equals( type )) {
            UUID ownerId = smf.getManagementAppId();
            return getCredentialsSecret( readUserToken( ownerId, entityId, Group.ENTITY_TYPE ) );

        } else if ( AuthPrincipalType.APPLICATION.equals( type ) ) {
            UUID ownerId = smf.getManagementAppId();
            return getCredentialsSecret( readUserToken( ownerId, entityId, Application.ENTITY_TYPE ) );

        }
        else if ( AuthPrincipalType.ADMIN_USER.equals( type ) || AuthPrincipalType.APPLICATION_USER.equals( type ) ) {
            return getCredentialsSecret( readUserPasswordCredentials( applicationId, entityId, User.ENTITY_TYPE ) );
        }

        throw new IllegalArgumentException( "Must specify an admin user, organization or application principal" );
    }


    @Override
    public String getClientIdForOrganization( UUID organizationId ) {
        return ClientCredentialsInfo.getClientIdForTypeAndUuid( AuthPrincipalType.ORGANIZATION, organizationId );
    }


    @Override
    public String getClientSecretForOrganization( UUID organizationId ) throws Exception {
        return getSecret( smf.getManagementAppId(), AuthPrincipalType.ORGANIZATION, organizationId );
    }


    @Override
    public String getClientIdForApplication( UUID applicationId ) {
        return ClientCredentialsInfo.getClientIdForTypeAndUuid( AuthPrincipalType.APPLICATION, applicationId );
    }


    @Override
    public String getClientSecretForApplication( UUID applicationId ) throws Exception {
        return getSecret( smf.getManagementAppId(), AuthPrincipalType.APPLICATION, applicationId );
    }


    public String newSecretKey( AuthPrincipalType type, UUID id ) throws Exception {
        String secret = generateOAuthSecretKey( type );

        writeUserToken( smf.getManagementAppId(), new SimpleEntityRef( type.getEntityType(), id ),
                encryptionService.plainTextCredentials( secret, id, smf.getManagementAppId() ) );

        return secret;
    }


    @Override
    public String newClientSecretForOrganization( UUID organizationId ) throws Exception {
        return newSecretKey( AuthPrincipalType.ORGANIZATION, organizationId );
    }


    @Override
    public String newClientSecretForApplication( UUID applicationId ) throws Exception {
        return newSecretKey( AuthPrincipalType.APPLICATION, applicationId );
    }


    @Override
    public AccessInfo authorizeClient( String clientId, String clientSecret, long ttl ) throws Exception {
        if ( ( clientId == null ) || ( clientSecret == null ) ) {
            return null;
        }
        UUID uuid = getUUIDFromClientId( clientId );
        if ( uuid == null ) {
            return null;
        }
        AuthPrincipalType type = getTypeFromClientId( clientId );
        if ( type == null ) {
            return null;
        }
        AccessInfo access_info = null;

        if ( clientSecret.equals( getSecret( smf.getManagementAppId(), type, uuid ) ) ) {

            String token = getTokenForPrincipal( ACCESS, null, smf.getManagementAppId(), type, uuid, ttl );

            long duration = tokens.getMaxTokenAgeInSeconds( token );

            access_info = new AccessInfo().withExpiresIn( duration ).withAccessToken( token );

            if ( type.equals( AuthPrincipalType.APPLICATION ) ) {
                ApplicationInfo app = getApplicationInfo( uuid );
                access_info = access_info.withProperty( "application", app.getId() );
            }
            else if ( type.equals( AuthPrincipalType.ORGANIZATION ) ) {
                OrganizationInfo organization = getOrganizationByUuid( uuid );
                access_info = access_info.withProperty( "organization", getOrganizationData( organization ) );
            }
        }
        return access_info;
    }


    @Override
    public PrincipalCredentialsToken getPrincipalCredentialsTokenForClientCredentials( String clientId,
                                                                                       String clientSecret )
            throws Exception {
        if ( ( clientId == null ) || ( clientSecret == null ) ) {
            return null;
        }
        UUID uuid = getUUIDFromClientId( clientId );
        if ( uuid == null ) {
            return null;
        }
        AuthPrincipalType type = getTypeFromClientId( clientId );
        if ( type == null ) {
            return null;
        }

        PrincipalCredentialsToken token = null;
        if ( clientSecret.equals( getSecret( smf.getManagementAppId(), type, uuid))) {
            if ( type.equals( AuthPrincipalType.APPLICATION ) ) {
                ApplicationInfo app = getApplicationInfo( uuid );
                token = new PrincipalCredentialsToken( new ApplicationPrincipal( app ),
                        new ApplicationClientCredentials( clientId, clientSecret ) );
            }
            else if ( type.equals( AuthPrincipalType.ORGANIZATION ) ) {
                OrganizationInfo organization = getOrganizationByUuid( uuid );
                token = new PrincipalCredentialsToken( new OrganizationPrincipal( organization ),
                        new OrganizationClientCredentials( clientId, clientSecret ) );
            }
        }
        return token;
    }


    public AccessInfo authorizeAppUser( String clientType, String clientId, String clientSecret ) throws Exception {

        return null;
    }


    @Override
    public String getPasswordResetTokenForAdminUser( UUID userId, long ttl ) throws Exception {
        return getTokenForPrincipal( EMAIL, TOKEN_TYPE_PASSWORD_RESET, smf.getManagementAppId(), ADMIN_USER, userId,
                ttl );
    }


    @Override
    public boolean checkPasswordResetTokenForAdminUser( UUID userId, String token ) throws Exception {
        AuthPrincipalInfo principal = null;
        try {
            principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_PASSWORD_RESET, ADMIN_USER );
        }
        catch ( Exception e ) {
            logger.error( "Unable to verify token", e );
        }
        return ( principal != null ) && userId.equals( principal.getUuid() );
    }


    @Override
    public String getActivationTokenForAdminUser( UUID userId, long ttl ) throws Exception {
        return getTokenForPrincipal( EMAIL, TOKEN_TYPE_ACTIVATION, smf.getManagementAppId(), ADMIN_USER, userId, ttl );
    }


    @Override
    public String getConfirmationTokenForAdminUser( UUID userId, long ttl ) throws Exception {
        return getTokenForPrincipal( EMAIL, TOKEN_TYPE_CONFIRM, smf.getManagementAppId(), ADMIN_USER, userId, ttl );
    }


    @Override
    public void activateAdminUser( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "activated", true );
    }


    @Override
    public User deactivateUser( UUID applicationId, UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );

        User user = em.get( userId, User.class );

        if ( user == null ) {
            throw new ManagementException(
                    String.format( "User with id %s does not exist in app %s", userId, applicationId ) );
        }

        user.setActivated( false );
        user.setDeactivated( System.currentTimeMillis() );

        em.update( user );

        // revoke all access tokens for the app
        revokeAccessTokensForAppUser( applicationId, userId );

        return user;
    }


    @Override
    public boolean isAdminUserActivated( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        return Boolean.TRUE.equals( em.getProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "activated" ) );
    }


    @Override
    public void confirmAdminUser( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "confirmed", true );
    }


    @Override
    public void unconfirmAdminUser( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "confirmed", false );
    }


    @Override
    public boolean isAdminUserConfirmed( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        return Boolean.TRUE.equals( em.getProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "confirmed" ) );
    }


    @Override
    public void enableAdminUser( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "disabled", false );
    }


    @Override
    public void disableAdminUser( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "disabled", true );

        revokeAccessTokensForAdminUser( userId );
    }


    @Override
    public boolean isAdminUserEnabled( UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        return !Boolean.TRUE.equals( em.getProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "disabled" ) );
    }


    public String emailMsg( Map<String, String> values, String propertyName ) {
        return new StrSubstitutor( values ).replace( properties.getProperty( propertyName ) );
    }


    private String appendEmailFooter( String msg ) {
        return msg + "\n" + properties.getProperty( PROPERTIES_EMAIL_FOOTER );
    }


    @Override
    public void startAdminUserPasswordResetFlow( UserInfo user ) throws Exception {
        String token = getPasswordResetTokenForAdminUser( user.getUuid(), 0 );

        String reset_url =
                String.format( properties.getProperty( PROPERTIES_ADMIN_RESETPW_URL ), user.getUuid().toString() )
                        + "?token=" + token;

        Map<String, String> pageContext = hashMap( "reset_url", reset_url )
                .map( "reset_url_base", properties.getProperty( PROPERTIES_ADMIN_RESETPW_URL ) )
                .map( "user_uuid", user.getUuid().toString() ).map( "raw_token", token );


        sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                "Password Reset", appendEmailFooter( emailMsg( pageContext, PROPERTIES_EMAIL_ADMIN_PASSWORD_RESET ) ) );
    }


    @Override
    public String getActivationTokenForOrganization( UUID organizationId, long ttl ) throws Exception {
        return getTokenForPrincipal( EMAIL, TOKEN_TYPE_ACTIVATION, smf.getManagementAppId(), ORGANIZATION,
                organizationId, ttl );
    }


    @Override
    public void startOrganizationActivationFlow( OrganizationInfo organization ) throws Exception {
        logger.info( "startOrganizationActivationFlow: {}", organization.getName() );

        try {
            String token = getActivationTokenForOrganization( organization.getUuid(), 0 );
            String activation_url = String.format( properties.getProperty( PROPERTIES_ORGANIZATION_ACTIVATION_URL ),
                    organization.getUuid().toString() ) + "?token=" + token;
            List<UserInfo> users = getAdminUsersForOrganization( organization.getUuid() );
            String organization_owners = null;
            for ( UserInfo user : users ) {
                organization_owners = ( organization_owners == null ) ? user.getHTMLDisplayEmailAddress() :
                                      organization_owners + ", " + user.getHTMLDisplayEmailAddress();
            }
            if ( newOrganizationsNeedSysAdminApproval() ) {
                logger.info( "sending SysAdminApproval confirmation email: {}", organization.getName() );
                sendHtmlMail( properties, properties.getProperty( PROPERTIES_SYSADMIN_EMAIL ),
                        properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                        "Request For Organization Account Activation " + organization.getName(), appendEmailFooter(
                        emailMsg( hashMap( "organization_name", organization.getName() )
                                .map( "activation_url", activation_url )
                                .map( "organization_owners", organization_owners ),
                                PROPERTIES_EMAIL_SYSADMIN_ORGANIZATION_ACTIVATION ) ) );
                sendOrganizationEmail( organization, "Organization Account Confirmed",
                        emailMsg( hashMap( "organization_name", organization.getName() ),
                                PROPERTIES_EMAIL_ORGANIZATION_CONFIRMED_AWAITING_ACTIVATION ) );
            }
            else if ( properties.newOrganizationsRequireConfirmation() ) {
                logger.info( "sending account confirmation email: {}", organization.getName() );
                sendOrganizationEmail( organization, "Organization Account Confirmation", emailMsg(
                        hashMap( "organization_name", organization.getName() )
                                .map( "confirmation_url", activation_url ),
                        PROPERTIES_EMAIL_ORGANIZATION_CONFIRMATION ) );
                sendSysAdminNewOrganizationActivatedNotificationEmail( organization );
            }
            else {
                logger.info( "activating organization (no confirmation): {}", organization.getName() );
                activateOrganization( organization, false );
                sendSysAdminNewOrganizationActivatedNotificationEmail( organization );
            }
        }
        catch ( Exception e ) {
            logger.error( "Unable to send activation emails to " + organization.getName(), e );
        }
    }


    @Override
    public ActivationState handleActivationTokenForOrganization( UUID organizationId, String token ) throws Exception {
        AuthPrincipalInfo principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_ACTIVATION, ORGANIZATION );
        if ( ( principal != null ) && organizationId.equals( principal.getUuid() ) ) {
            OrganizationInfo organization = this.getOrganizationByUuid( organizationId );
            sendOrganizationActivatedEmail( organization );
            sendSysAdminNewOrganizationActivatedNotificationEmail( organization );

            activateOrganization( organization, false );

            return ActivationState.ACTIVATED;
        }
        return ActivationState.UNKNOWN;
    }


    public void sendOrganizationActivatedEmail( OrganizationInfo organization ) throws Exception {
        sendOrganizationEmail( organization, "Organization Account Activated: " + organization.getName(),
                emailMsg( hashMap( "organization_name", organization.getName() ),
                        PROPERTIES_EMAIL_ORGANIZATION_ACTIVATED ) );
    }


    public void sendSysAdminNewOrganizationActivatedNotificationEmail( OrganizationInfo organization )
            throws Exception {
        if ( properties.notifySysAdminOfNewOrganizations() ) {
            List<UserInfo> users = getAdminUsersForOrganization( organization.getUuid() );
            String organization_owners = null;
            for ( UserInfo user : users ) {
                organization_owners = ( organization_owners == null ) ? user.getHTMLDisplayEmailAddress() :
                                      organization_owners + ", " + user.getHTMLDisplayEmailAddress();
            }
            sendHtmlMail( properties, properties.getProperty( PROPERTIES_SYSADMIN_EMAIL ),
                    properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                    "Organization Account Activated " + organization.getName(), appendEmailFooter( emailMsg(
                    hashMap( "organization_name", organization.getName() )
                            .map( "organization_owners", organization_owners ),
                    PROPERTIES_EMAIL_SYSADMIN_ORGANIZATION_ACTIVATED ) ) );
        }
    }


    @Override
    public void sendOrganizationEmail( OrganizationInfo organization, String subject, String html ) throws Exception {
        List<UserInfo> users = getAdminUsersForOrganization( organization.getUuid() );
        for ( UserInfo user : users ) {
            sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                    subject, appendEmailFooter( html ) );
        }
    }


    @Override
    public void startAdminUserActivationFlow( UserInfo user ) throws Exception {
        if ( user.isActivated() ) {
            sendAdminUserConfirmationEmail( user );
            sendAdminUserActivatedEmail( user );
            sendSysAdminNewAdminActivatedNotificationEmail( user );
        }
        else {
            if ( newAdminUsersRequireConfirmation() ) {
                sendAdminUserConfirmationEmail( user );
            }
            else if ( newAdminUsersNeedSysAdminApproval() ) {
                sendSysAdminRequestAdminActivationEmail( user );
            }
            else {
                // sdg: There seems to be a hole in the logic. The user has been
                // created
                // in an inactive state but nobody is being notified.
                activateAdminUser( user.getUuid() );
            }
        }
    }


    @Override
    public ActivationState handleConfirmationTokenForAdminUser( UUID userId, String token ) throws Exception {
        AuthPrincipalInfo principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_CONFIRM, ADMIN_USER );
        if ( ( principal != null ) && userId.equals( principal.getUuid() ) ) {
            UserInfo user = getAdminUserByUuid( principal.getUuid() );
            confirmAdminUser( user.getUuid() );
            if ( newAdminUsersNeedSysAdminApproval() ) {
                sendAdminUserConfirmedAwaitingActivationEmail( user );
                sendSysAdminRequestAdminActivationEmail( user );
                return ActivationState.CONFIRMED_AWAITING_ACTIVATION;
            }
            else {
                activateAdminUser( principal.getUuid() );
                sendAdminUserActivatedEmail( user );
                sendSysAdminNewAdminActivatedNotificationEmail( user );
                return ActivationState.ACTIVATED;
            }
        }
        return ActivationState.UNKNOWN;
    }


    @Override
    public ActivationState handleActivationTokenForAdminUser( UUID userId, String token ) throws Exception {
        AuthPrincipalInfo principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_ACTIVATION, ADMIN_USER );
        if ( ( principal != null ) && userId.equals( principal.getUuid() ) ) {
            activateAdminUser( principal.getUuid() );
            UserInfo user = getAdminUserByUuid( principal.getUuid() );
            sendAdminUserActivatedEmail( user );
            sendSysAdminNewAdminActivatedNotificationEmail( user );
            return ActivationState.ACTIVATED;
        }
        return ActivationState.UNKNOWN;
    }


    public void sendAdminUserConfirmationEmail( UserInfo user ) throws Exception {
        String token = getConfirmationTokenForAdminUser( user.getUuid(), 0 );
        String confirmation_url =
                String.format( properties.getProperty( PROPERTIES_ADMIN_CONFIRMATION_URL ), user.getUuid().toString() )
                        + "?token=" + token;
        sendAdminUserEmail( user, "User Account Confirmation: " + user.getEmail(),
                emailMsg( hashMap( "user_email", user.getEmail() ).map( "confirmation_url", confirmation_url ),
                        PROPERTIES_EMAIL_ADMIN_CONFIRMATION ) );
    }


    public void sendSysAdminRequestAdminActivationEmail( UserInfo user ) throws Exception {
        String token = getActivationTokenForAdminUser( user.getUuid(), 0 );
        String activation_url =
                String.format( properties.getProperty( PROPERTIES_ADMIN_ACTIVATION_URL ), user.getUuid().toString() )
                        + "?token=" + token;
        sendHtmlMail( properties, properties.getProperty( PROPERTIES_SYSADMIN_EMAIL ),
                properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                "Request For Admin User Account Activation " + user.getEmail(), appendEmailFooter(
                emailMsg( hashMap( "user_email", user.getEmail() ).map( "activation_url", activation_url ),
                        PROPERTIES_EMAIL_SYSADMIN_ADMIN_ACTIVATION ) ) );
    }


    public void sendSysAdminNewAdminActivatedNotificationEmail( UserInfo user ) throws Exception {
        if ( properties.notifySysAdminOfNewAdminUsers() ) {
            sendHtmlMail( properties, properties.getProperty( PROPERTIES_SYSADMIN_EMAIL ),
                    properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                    "Admin User Account Activated " + user.getEmail(), appendEmailFooter(
                    emailMsg( hashMap( "user_email", user.getEmail() ), PROPERTIES_EMAIL_SYSADMIN_ADMIN_ACTIVATED ) ) );
        }
    }


    public void sendAdminUserConfirmedAwaitingActivationEmail( UserInfo user ) throws Exception {
        sendAdminUserEmail(user, "User Account Confirmed",
                emailMsg( hashMap("confirmed_email",user.getEmail() ),PROPERTIES_EMAIL_ADMIN_CONFIRMED_AWAITING_ACTIVATION ) );
    }


    public void sendAdminUserActivatedEmail( UserInfo user ) throws Exception {
        if ( properties.notifyAdminOfActivation() ) {
            sendAdminUserEmail( user, "User Account Activated",
                    properties.getProperty( PROPERTIES_EMAIL_ADMIN_ACTIVATED ) );
        }
    }


    public void sendAdminUserInvitedEmail( UserInfo user, OrganizationInfo organization ) throws Exception {
        sendAdminUserEmail( user, "User Invited To Organization",
                emailMsg( hashMap( "organization_name", organization.getName() ), PROPERTIES_EMAIL_ADMIN_INVITED ) );
    }


    @Override
    public void sendAdminUserEmail( UserInfo user, String subject, String html ) throws Exception {
        sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                subject, appendEmailFooter( html ) );
    }


    @Override
    public void activateOrganization( OrganizationInfo organization ) throws Exception {
        activateOrganization( organization, true );
    }


    private void activateOrganization( OrganizationInfo organization, boolean sendEmail ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( Group.ENTITY_TYPE, organization.getUuid() ), "activated", true );
        List<UserInfo> users = getAdminUsersForOrganization( organization.getUuid() );
        for ( UserInfo user : users ) {
            boolean confirmed = user.isConfirmed() || !newAdminUsersRequireConfirmation();
            boolean shouldActivate = confirmed && !newAdminUsersRequireConfirmation();
            if ( shouldActivate ) {
                activateAdminUser( user.getUuid() );
            }
        }
        if ( sendEmail ) {
            startOrganizationActivationFlow( organization );
        }

    }


    @Override
    public void deactivateOrganization( UUID organizationId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "activated", false );
    }


    @Override
    public boolean isOrganizationActivated( UUID organizationId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        return Boolean.TRUE.equals(
                em.getProperty( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "activated" ) );
    }


    @Override
    public void enableOrganization( UUID organizationId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "disabled", false );
    }


    @Override
    public void disableOrganization( UUID organizationId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.setProperty( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "disabled", true );
    }


    @Override
    public boolean isOrganizationEnabled( UUID organizationId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        return !Boolean.TRUE.equals(
                em.getProperty( new SimpleEntityRef( Group.ENTITY_TYPE, organizationId ), "disabled" ) );
    }


    @Override
    public boolean checkPasswordResetTokenForAppUser( UUID applicationId, UUID userId, String token ) throws Exception {
        AuthPrincipalInfo principal = null;
        try {
            principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_PASSWORD_RESET, APPLICATION_USER );
        }
        catch ( Exception e ) {
            logger.error( "Unable to verify token", e );
        }
        return ( principal != null ) && userId.equals( principal.getUuid() );
    }


    @Override
    public String getAccessTokenForAppUser( UUID applicationId, UUID userId, long duration ) throws Exception {
        return getTokenForPrincipal( ACCESS, null, applicationId, APPLICATION_USER, userId, duration );
    }


    /*
   * (non-Javadoc)
   *
   * @see
   * org.apache.usergrid.management.ManagementService#revokeAccessTokensForAappUser
   * (java.util.UUID, java.util.UUID)
   */
    @Override
    public void revokeAccessTokensForAppUser( UUID applicationId, UUID userId ) throws Exception {
        revokeTokensForPrincipal( APPLICATION_USER, applicationId, userId );
    }


    @Override
    public void revokeAccessTokenForAppUser( String token ) throws Exception {
        if ( anyNull( token ) ) {
            throw new IllegalArgumentException( "token is required" );
        }

        UserInfo userInfo = getAppUserFromAccessToken( token );
        if ( userInfo == null ) {
            throw new TokenException( "Could not match token : " + token );
        }

        tokens.revokeToken( token );
    }


    @Override
    public UserInfo getAppUserFromAccessToken( String token ) throws Exception {
        AuthPrincipalInfo auth_principal = getPrincipalFromAccessToken( token, null, APPLICATION_USER );
        if ( auth_principal == null ) {
            return null;
        }
        UUID appId = auth_principal.getApplicationId();
        if ( appId != null ) {
            Entity user = getAppUserByIdentifier( appId, Identifier.fromUUID( auth_principal.getUuid() ) );
            if ( user != null ) {
                return new UserInfo( appId, user.getProperties() );
            }
        }
        return null;
    }


    @Override
    public User getAppUserByIdentifier( UUID applicationId, Identifier identifier ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        return em.get( em.getUserByIdentifier( identifier ), User.class );
    }


    @Override
    public void startAppUserPasswordResetFlow( UUID applicationId, User user ) throws Exception {
        String token = getPasswordResetTokenForAppUser( applicationId, user.getUuid() );
        String reset_url =
                buildUserAppUrl( applicationId, properties.getProperty( PROPERTIES_USER_RESETPW_URL ), user, token );
        Map<String, String> pageContext = hashMap( "reset_url", reset_url )
                .map( "reset_url_base", properties.getProperty( PROPERTIES_ADMIN_RESETPW_URL ) )
                .map( "user_uuid", user.getUuid().toString() ).map( "raw_token", token )
                .map( "application_id", applicationId.toString() );
    /*
     * String reset_url = String.format(
     * properties.getProperty(PROPERTIES_USER_RESETPW_URL), oi.getName(),
     * ai.getName(), user.getUuid().toString()) + "?token=" + token;
     */
        sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                "Password Reset", appendEmailFooter( emailMsg( pageContext, PROPERTIES_EMAIL_USER_PASSWORD_RESET ) ) );
    }


    @Override
    public boolean newAppUsersNeedAdminApproval( UUID applicationId ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        Boolean registration_requires_admin_approval = ( Boolean ) em
                .getProperty( new SimpleEntityRef( Application.ENTITY_TYPE, applicationId ),
                        REGISTRATION_REQUIRES_ADMIN_APPROVAL );
        return registration_requires_admin_approval != null && registration_requires_admin_approval.booleanValue();
    }


    @Override
    public boolean newAppUsersRequireConfirmation( UUID applicationId ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        Boolean registration_requires_email_confirmation = ( Boolean ) em
                .getProperty( new SimpleEntityRef( Application.ENTITY_TYPE, applicationId ),
                        REGISTRATION_REQUIRES_EMAIL_CONFIRMATION );
        return registration_requires_email_confirmation != null && registration_requires_email_confirmation.booleanValue();
    }


    public boolean notifyAdminOfNewAppUsers( UUID applicationId ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        Boolean notify_admin_of_new_users = ( Boolean ) em
                .getProperty( new SimpleEntityRef( Application.ENTITY_TYPE, applicationId ),
                        NOTIFY_ADMIN_OF_NEW_USERS );
        return notify_admin_of_new_users != null && notify_admin_of_new_users.booleanValue();
    }


    @Override
    public void startAppUserActivationFlow( UUID applicationId, User user ) throws Exception {
        if ( newAppUsersRequireConfirmation( applicationId ) ) {
            sendAppUserConfirmationEmail( applicationId, user );
        }
        else if ( newAppUsersNeedAdminApproval( applicationId ) ) {
            sendAdminRequestAppUserActivationEmail( applicationId, user );
        }
        else {
            sendAppUserActivatedEmail( applicationId, user );
            sendAdminNewAppUserActivatedNotificationEmail( applicationId, user );
        }
    }


    @Override
    public ActivationState handleConfirmationTokenForAppUser( UUID applicationId, UUID userId, String token )
            throws Exception {
        AuthPrincipalInfo principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_CONFIRM, APPLICATION_USER );

        if ( ( principal != null ) && userId.equals( principal.getUuid() ) ) {
            EntityManager em = emf.getEntityManager( applicationId );
            User user = em.get( userId, User.class );
            confirmAppUser( applicationId, user.getUuid() );

            if ( newAppUsersNeedAdminApproval( applicationId ) ) {
                sendAppUserConfirmedAwaitingActivationEmail( applicationId, user );
                sendAdminRequestAppUserActivationEmail( applicationId, user );
                return ActivationState.CONFIRMED_AWAITING_ACTIVATION;
            }
            else {
                activateAppUser( applicationId, principal.getUuid() );
                sendAppUserActivatedEmail( applicationId, user );
                sendAdminNewAppUserActivatedNotificationEmail( applicationId, user );
                return ActivationState.ACTIVATED;
            }
        }

        return ActivationState.UNKNOWN;
    }


    @Override
    public ActivationState handleActivationTokenForAppUser( UUID applicationId, UUID userId, String token )
            throws Exception {
        AuthPrincipalInfo principal = getPrincipalFromAccessToken( token, TOKEN_TYPE_ACTIVATION, APPLICATION_USER );
        if ( ( principal != null ) && userId.equals( principal.getUuid() ) ) {
            activateAppUser( applicationId, principal.getUuid() );
            EntityManager em = emf.getEntityManager( applicationId );
            User user = em.get( userId, User.class );
            sendAppUserActivatedEmail( applicationId, user );
            sendAdminNewAppUserActivatedNotificationEmail( applicationId, user );
            return ActivationState.ACTIVATED;
        }
        return ActivationState.UNKNOWN;
    }


    public void sendAppUserConfirmationEmail( UUID applicationId, User user ) throws Exception {
        String token = getConfirmationTokenForAppUser( applicationId, user.getUuid() );
        String confirmation_url =
                buildUserAppUrl( applicationId, properties.getProperty( PROPERTIES_USER_CONFIRMATION_URL ), user,
                        token );

    /*
     * String confirmation_url = String.format(
     * properties.getProperty(PROPERTIES_USER_CONFIRMATION_URL),
     * applicationId.toString(), user.getUuid().toString()) + "?token=" + token;
     */
        sendAppUserEmail( user, "User Account Confirmation: " + user.getEmail(),
                emailMsg( hashMap( "confirmation_url", confirmation_url ), PROPERTIES_EMAIL_USER_CONFIRMATION ) );
    }


    protected String buildUserAppUrl(UUID applicationId, String url, User user, String token) throws Exception {
        ApplicationInfo ai = getApplicationInfo( applicationId );
        OrganizationInfo oi = getOrganizationForApplication( applicationId );
        return String.format( url, oi.getName(), StringUtils.stringOrSubstringAfterFirst( ai.getName(), '/' ),
                user.getUuid().toString() ) + "?token=" + token;
    }


    public void sendAdminRequestAppUserActivationEmail( UUID applicationId, User user ) throws Exception {
        String token = getActivationTokenForAppUser( applicationId, user.getUuid() );
        String activation_url =
                buildUserAppUrl( applicationId, properties.getProperty( PROPERTIES_USER_ACTIVATION_URL ), user, token );
    /*
     * String activation_url = String.format(
     * properties.getProperty(PROPERTIES_USER_ACTIVATION_URL),
     * applicationId.toString(), user.getUuid().toString()) + "?token=" + token;
     */
        OrganizationInfo organization = this.getOrganizationForApplication( applicationId );
        this.sendOrganizationEmail( organization, "Request For User Account Activation " + user.getEmail(), emailMsg(
                hashMap( "organization_name", organization.getName() ).map( "activation_url", activation_url ),
                PROPERTIES_EMAIL_ADMIN_USER_ACTIVATION ) );
    }


    public void sendAdminNewAppUserActivatedNotificationEmail( UUID applicationId, User user ) throws Exception {
        if ( notifyAdminOfNewAppUsers( applicationId ) ) {
            OrganizationInfo organization = this.getOrganizationForApplication( applicationId );
            this.sendOrganizationEmail( organization, "New User Account Activated " + user.getEmail(),
                    emailMsg( hashMap( "organization_name", organization.getName() ),
                            PROPERTIES_EMAIL_ADMIN_USER_ACTIVATION ) );
        }
    }


    public void sendAppUserConfirmedAwaitingActivationEmail( UUID applicationId, User user ) throws Exception {
        sendAppUserEmail( user, "User Account Confirmed",
                properties.getProperty( PROPERTIES_EMAIL_USER_CONFIRMED_AWAITING_ACTIVATION ) );
    }


    public void sendAppUserActivatedEmail( UUID applicationId, User user ) throws Exception {
        sendAppUserEmail( user, "User Account Activated", properties.getProperty( PROPERTIES_EMAIL_USER_ACTIVATED ) );
    }


    @Override
    public void activateAppUser( UUID applicationId, UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        em.setProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "activated", true );
    }


    public void confirmAppUser( UUID applicationId, UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        em.setProperty( new SimpleEntityRef( User.ENTITY_TYPE, userId ), "confirmed", true );
    }


    @Override
    public void setAppUserPassword( UUID applicationId, UUID userId, String newPassword ) throws Exception {
        if ( ( userId == null ) || ( newPassword == null ) ) {
            return;
        }

        EntityManager em = emf.getEntityManager( applicationId );
        User user = em.get( userId, User.class );

        writeUserPassword( applicationId, user,
                encryptionService.defaultEncryptedCredentials( newPassword, user.getUuid(), applicationId ) );
    }


    @Override
    public void setAppUserPassword( UUID applicationId, UUID userId, String oldPassword, String newPassword )
            throws Exception {
        if ( ( userId == null ) ) {
            throw new IllegalArgumentException( "userId is required" );
        }
        if ( ( oldPassword == null ) || ( newPassword == null ) ) {
            throw new IllegalArgumentException( "oldpassword and newpassword are both required" );
        }
        // TODO load the user, send the hashType down to maybeSaltPassword
        User user = emf.getEntityManager( applicationId ).get( userId, User.class );
        if ( !verify( applicationId, user.getUuid(), oldPassword ) ) {
            throw new IncorrectPasswordException( "Old password does not match" );
        }

        setAppUserPassword( applicationId, userId, newPassword );
    }


    @Override
    public User verifyAppUserPasswordCredentials( UUID applicationId, String name, String password ) throws Exception {

        User user = findUserEntity( applicationId, name );
        if ( user == null ) {
            return null;
        }

        if ( verify( applicationId, user.getUuid(), password ) ) {
            if ( !user.activated() ) {
                throw new UnactivatedAppUserException();
            }
            if ( user.disabled() ) {
                throw new DisabledAppUserException();
            }
            return user;
        }

        return null;
    }


    public String getPasswordResetTokenForAppUser( UUID applicationId, UUID userId ) throws Exception {
        return getTokenForPrincipal( EMAIL, TOKEN_TYPE_PASSWORD_RESET, applicationId, APPLICATION_USER, userId, 0 );
    }


    public void sendAppUserEmail( User user, String subject, String html ) throws Exception {
        sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                subject, appendEmailFooter( html ) );
    }


    public String getActivationTokenForAppUser( UUID applicationId, UUID userId ) throws Exception {
        return getTokenForPrincipal( EMAIL, TOKEN_TYPE_ACTIVATION, applicationId, APPLICATION_USER, userId, 0 );
    }


    public String getConfirmationTokenForAppUser( UUID applicationId, UUID userId ) throws Exception {
        return getTokenForPrincipal( EMAIL, TOKEN_TYPE_CONFIRM, applicationId, APPLICATION_USER, userId, 0 );
    }


    @Override
    public void setAppUserPin( UUID applicationId, UUID userId, String newPin ) throws Exception {
        if ( ( userId == null ) || ( newPin == null ) ) {
            return;
        }

        writeUserPin( applicationId, new SimpleEntityRef( User.ENTITY_TYPE, userId ),
                encryptionService.plainTextCredentials( newPin, userId, applicationId ) );
    }


    @Override
    public void sendAppUserPin( UUID applicationId, UUID userId ) throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        User user = em.get( userId, User.class );
        if ( user == null ) {
            return;
        }
        if ( user.getEmail() == null ) {
            return;
        }
        String pin = getCredentialsSecret( readUserPin( applicationId, userId, user.getType() ) );

        sendHtmlMail( properties, user.getDisplayEmailAddress(), properties.getProperty( PROPERTIES_MAILER_EMAIL ),
                "Your app pin",
                appendEmailFooter( emailMsg( hashMap( USER_PIN, pin ), PROPERTIES_EMAIL_USER_PIN_REQUEST ) ) );
    }


    @Override
    public User verifyAppUserPinCredentials( UUID applicationId, String name, String pin ) throws Exception {

        User user = findUserEntity( applicationId, name );
        if ( user == null ) {
            return null;
        }
        if ( pin.equals( getCredentialsSecret( readUserPin( applicationId, user.getUuid(), user.getType() ) ) ) ) {
            return user;
        }
        return null;
    }


    @Override
    public void countAdminUserAction( UserInfo user, String action ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );
        em.incrementAggregateCounters( user.getUuid(), null, null, "admin_logins", 1 );
    }


    /*
   * (non-Javadoc)
   *
   * @see
   * org.apache.usergrid.management.ManagementService#setOrganizationProps(java.util
   * .UUID, java.util.Map)
   */
    @Override
    public void setOrganizationProps( UUID orgId, Map<String, Object> props ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        Group org = em.get( orgId, Group.class );

        if ( org == null ) {
            throw new EntityNotFoundException( String.format( "Could not find organization with id {}", orgId ) );
        }

        org.setProperties( props );

        em.update( org );
    }


    /*
   * (non-Javadoc)
   *
   * @see
   * org.apache.usergrid.management.ManagementService#getOrganizationProps(java.util
   * .UUID)
   */
    @Override
    public Group getOrganizationProps( UUID orgId ) throws Exception {
        EntityManager em = emf.getEntityManager( smf.getManagementAppId() );

        return em.get( orgId, Group.class );
    }


    /** Persist the user's password credentials info */
    protected void writeUserPassword( UUID appId, EntityRef owner, CredentialsInfo creds ) throws Exception {
        writeCreds( appId, owner, creds, USER_PASSWORD );
    }


    /** read the user password credential's info */
    protected CredentialsInfo readUserPasswordCredentials( UUID appId, UUID ownerId, String ownerType ) throws Exception {
        return readCreds( appId, ownerId, ownerType, USER_PASSWORD );
    }


    /** Write the user's token */
    protected void writeUserToken( UUID appId, EntityRef owner, CredentialsInfo token ) throws Exception {
        writeCreds( appId, owner, token, USER_TOKEN );
    }


    /** Read the credentials info for the user's token */
    protected CredentialsInfo readUserToken( UUID appId, UUID ownerId, String ownerType ) throws Exception {
        return readCreds( appId, ownerId, ownerType, USER_TOKEN );
    }


    /** Write the mongo password */
    protected void writeUserMongoPassword( UUID appId, EntityRef owner, CredentialsInfo password ) throws Exception {
        writeCreds( appId, owner, password, USER_MONGO_PASSWORD );
    }


    /** Read the mongo password */
    protected CredentialsInfo readUserMongoPassword( UUID appId, UUID ownerId, String ownerType ) throws Exception {
        return readCreds( appId, ownerId, ownerType, USER_MONGO_PASSWORD );
    }


    /** Write the user's pin */
    protected void writeUserPin( UUID appId, EntityRef owner, CredentialsInfo pin ) throws Exception {
        writeCreds( appId, owner, pin, USER_PIN );
    }


    /** Read the user's pin */
    protected CredentialsInfo readUserPin( UUID appId, UUID ownerId, String ownerType ) throws Exception {
        return readCreds( appId, ownerId, ownerType, USER_PIN );
    }


    private void writeCreds( UUID appId, EntityRef owner, CredentialsInfo creds, String key ) throws Exception {
        EntityManager em = emf.getEntityManager( appId );
        em.addToDictionary( owner, DICTIONARY_CREDENTIALS, key, creds );
    }


    private CredentialsInfo readCreds( UUID appId, UUID ownerId, String ownerType, String key ) throws Exception {
        EntityManager em = emf.getEntityManager( appId );
        Entity owner = em.get( ownerId );
        return ( CredentialsInfo ) em.getDictionaryElementValue( owner, DICTIONARY_CREDENTIALS, key );
    }


    private Set<CredentialsInfo> readUserPasswordHistory( UUID appId, UUID ownerId ) throws Exception {
        EntityManager em = emf.getEntityManager( appId );
        Entity owner = em.get( new SimpleEntityRef("user", ownerId ));
        return ( Set<CredentialsInfo> ) em
                .getDictionaryElementValue( owner, DICTIONARY_CREDENTIALS, USER_PASSWORD_HISTORY );
    }


    @Override
    public boolean newAdminUsersNeedSysAdminApproval() {
        return properties.newAdminUsersNeedSysAdminApproval();
    }


    @Override
    public boolean newAdminUsersRequireConfirmation() {
        return properties.newAdminUsersRequireConfirmation();
    }


    @Override
    public boolean newOrganizationsNeedSysAdminApproval() {
        return properties.newOrganizationsNeedSysAdminApproval();
    }


    private boolean areActivationChecksDisabled() {
        return !( newOrganizationsNeedSysAdminApproval() || properties.newOrganizationsRequireConfirmation()
                || newAdminUsersNeedSysAdminApproval() || newAdminUsersRequireConfirmation() );
    }


    private void sendHtmlMail( AccountCreationProps props, String to, String from, String subject, String html ) {
        mailUtils.sendHtmlMail( props.getMailProperties(), to, from, subject, html );
    }


    public AccountCreationProps getAccountCreationProps() {
        return properties;
    }


    private boolean verify( UUID applicationId, UUID userId, String password ) throws Exception {
        CredentialsInfo ci = readUserPasswordCredentials( applicationId, userId, User.ENTITY_TYPE );

        if ( ci == null ) {
            return false;
        }

        return encryptionService.verify( password, ci, userId, applicationId );
    }


    /** @return the saltProvider */
    public SaltProvider getSaltProvider() {
        return saltProvider;
    }


    /** @param saltProvider the saltProvider to set */
    public void setSaltProvider( SaltProvider saltProvider ) {
        this.saltProvider = saltProvider;
    }


    @Override
    public Object registerAppWithAPM( OrganizationInfo orgInfo, ApplicationInfo appInfo ) throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    private String getProperty(String key) {
        String obj = properties.getProperty(key);
        if(StringUtils.isEmpty(obj))
            return null;
        else
            return obj;
    }

    private boolean getBooleanProperty(String key) {
        String obj = getProperty(key);
        if(StringUtils.isEmpty(obj))
            return false;
        else
            return Boolean.parseBoolean(obj);
    }

}
