class SwaggerEnvironment {

  public SwaggerConsumer createConsumer(Class<?> consumerIntf, Swagger swagger) {
    Map<Class<?>, ContextArgumentMapperFactory> contextFactorys = SPIServiceUtils
        .getOrLoadSortedService(ConsumerContextArgumentMapperFactory.class)
        .stream()
        .collect(Collectors.toMap(ConsumerContextArgumentMapperFactory::getContextClass, Function.identity()));
    ResponseMapperFactorys<ConsumerResponseMapper> consumerResponseMapperFactorys =
        new ResponseMapperFactorys<>(ConsumerResponseMapperFactory.class);

    SwaggerOperations swaggerOperations = new SwaggerOperations(swagger);

    SwaggerConsumer consumer = new SwaggerConsumer();
    consumer.setConsumerIntf(consumerIntf);
    for (Method consumerMethod : MethodUtils.findSwaggerMethods(consumerIntf)) {
      String operationId = findOperationId(consumerMethod);
      SwaggerOperation swaggerOperation = swaggerOperations.findOperation(operationId);
      if (swaggerOperation == null) {
        // consumer method set is bigger than contract, it's invalid
        // but we need to support consumer upgrade before producer, so only log and ignore it.
        LOGGER.warn("consumer method {}:{} not exist in contract.",
            consumerIntf.getName(),
            consumerMethod.getName());
        continue;
      }

      ConsumerArgumentsMapperCreator creator = new ConsumerArgumentsMapperCreator(
          Json.mapper().getSerializationConfig(),
          contextFactorys,
          consumerIntf,
          consumerMethod,
          swaggerOperation);
      ArgumentsMapper argsMapper = creator.createArgumentsMapper();
      ConsumerResponseMapper responseMapper = consumerResponseMapperFactorys
          .createResponseMapper(consumerMethod.getGenericReturnType());

      SwaggerConsumerOperation op = new SwaggerConsumerOperation();
      op.setConsumerClass(consumerIntf);
      op.setConsumerMethod(consumerMethod);
      op.setSwaggerOperation(swaggerOperation);
      op.setArgumentsMapper(argsMapper);
      op.setResponseMapper(responseMapper);

      consumer.addOperation(op);
    }

    return consumer;
  }

}