class FactorServiceImpl implements FactorService {

    @Override
    public List<Factor> listAvailableFactors(OktaUser user) throws OktaException
    {
        if (user != null)
        {
            String apiPath = String.format(OktaAPIConstants.LIST_AVAILABLE_ENROLLED_FACTORS, user.getId());
            ResponseEntity<Factor[]> exchange = oktaRestService.doRestCall(apiPath, HttpMethod.GET, Factor[].class, "parameters");
            if (!exchange.getStatusCode().is2xxSuccessful())
            {
                throw new OktaException(exchange.toString());
            }

            if (exchange.getBody().length > 0)
            {
                List<Factor> factorCatalog = Arrays.asList(exchange.getBody());

                List<Factor> factorsAlreadyEnrolled = listEnrolledFactors(user);
                if (factorsAlreadyEnrolled != null)
                {
                    if (!factorsAlreadyEnrolled.isEmpty())
                    {
                        List<FactorType> factorTypes = factorsAlreadyEnrolled.stream()
                                .filter(factor -> FactorStatus.ACTIVE.equals(factor.getStatus())
                                        || FactorStatus.ENROLLED.equals(factor.getStatus()))
                                .map(Factor::getFactorType)
                                .collect(Collectors.toList());
                        return factorCatalog.stream().filter(factor -> !factorTypes.contains(factor.getFactorType()))
                                .collect(Collectors.toList());
                    }
                    else
                    {
                        return factorCatalog;
                    }
                }
            }
        }

        return Collections.emptyList();
    }

}