class AccessRequestService {

    public AccessRequestCreationResponse storeAccessRequest(AccessRequestWrapper request) throws GatekeeperException{
        GatekeeperUserEntry requestor = gatekeeperRoleService.getUserProfile();

        Integer maxDays = gatekeeperRoleService.isApprover() ? overridePolicy.getMaxDays() : overridePolicy.getMaxDaysForRequest(gatekeeperRoleService.getRoleMemberships(), request.getRoles(), request.getAccountSdlc());
        logger.info("Maximum days allowed for user " + requestor.getUserId() + ": " + maxDays);

        if(request.getDays() > maxDays){
            throw new GatekeeperException("Days requested (" + request.getDays() + ") exceeded the maximum of " + maxDays + " for roles " + request.getRoles() + " on account with SDLC " + request.getAccountSdlc());
        }


        //throw gk in front of all the user id's
        request.getUsers().forEach(u -> u.setUserId("gk_" + u.getUserId()));

        AccessRequest accessRequest = new AccessRequest()
                .setAccount(request.getAccount().toUpperCase())
                .setAccountSdlc(request.getAccountSdlc())
                .setRegion(request.getRegion())
                .setDays(request.getDays())
                .setRequestorId(requestor.getUserId())
                .setRequestorName(requestor.getName())
                .setRequestorEmail(requestor.getEmail())
                .setUsers(request.getUsers())
                .setAwsRdsInstances(request.getInstances())
                .setTicketId(request.getTicketId())
                .setRequestReason(request.getRequestReason())
                .setRoles(request.getRoles());

        logger.info("Checking Users associated with this access request");

        List<String> checkResult;
        AWSRdsDatabase database = accessRequest.getAwsRdsInstances().get(0);
        try {
            checkResult = databaseConnectionService.checkUsersAndDbs(request.getRoles(), request.getUsers(), request.getInstances().get(0),
                    new AWSEnvironment(accessRequest.getAccount(), accessRequest.getRegion(), accessRequest.getAccountSdlc()));
        }catch(Exception e){
            throw new GatekeeperException("Unable to verify the Users for the provided databases", e);
        }

        if(!checkResult.isEmpty()){
            return new AccessRequestCreationResponse(AccessRequestCreationOutcome.NOT_CREATED_USER_ISSUE,checkResult);
        }

        logger.info("Storing Access Request");
        accessRequestRepository.save(accessRequest);
        logger.info("Access Request stored with ID: " + accessRequest.getId());

        //Kick off the activiti workflow

        Map<String, Object> variables = new HashMap<>();
        variables.put("accessRequest", accessRequest);
        runtimeService.startProcessInstanceByKey("gatekeeperAccessRequest", variables);

        // Verify that we started a new process instance
        logger.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());
        return new AccessRequestCreationResponse(AccessRequestCreationOutcome.CREATED, accessRequest);
    }

    @Autowired public  AccessRequestService(TaskService taskService,
                                AccessRequestRepository accessRequestRepository,
                                GatekeeperRoleService gatekeeperRoleService,
                                RuntimeService runtimeService,
                                HistoryService historyService,
                                GatekeeperApprovalProperties gatekeeperApprovalProperties,
                                AccountInformationService accountInformationService,
                                GatekeeperOverrideProperties overridePolicy,
                                DatabaseConnectionService databaseConnectionService,
                                EntityManager entityManager);

}