@SuppressWarnings("static-method")
  public Map<String, Object> processOperations(
      CodegenConfig config, String tag, List<CodegenOperation> ops) {
    Map<String, Object> operations = new HashMap<String, Object>();
    Map<String, Object> objs = new HashMap<String, Object>();
    objs.put("classname", config.toApiName(tag));
    objs.put("pathPrefix", config.toApiVarName(tag));

    // check for operationId uniqueness
    Set<String> opIds = new HashSet<String>();
    int counter = 0;
    for (CodegenOperation op : ops) {
      String opId = op.nickname;
      if (opIds.contains(opId)) {
        counter++;
        op.nickname += "_" + counter;
      }
      opIds.add(opId);
    }
    objs.put("operation", ops);

    operations.put("operations", objs);
    operations.put("package", config.apiPackage());

    Set<String> allImports = new LinkedHashSet<String>();
    for (CodegenOperation op : ops) {
      allImports.addAll(op.imports);
    }

    List<Map<String, String>> imports = new ArrayList<Map<String, String>>();
    for (String nextImport : allImports) {
      Map<String, String> im = new LinkedHashMap<String, String>();
      String mapping = config.importMapping().get(nextImport);
      if (mapping == null) {
        mapping = config.toModelImport(nextImport);
      }
      if (mapping != null) {
        im.put("import", mapping);
        imports.add(im);
      }
    }

    operations.put("imports", imports);

    // add a flag to indicate whether there's any {{import}}
    if (imports.size() > 0) {
      operations.put("hasImport", true);
    }

    config.postProcessOperations(operations);
    if (objs.size() > 0) {
      List<CodegenOperation> os = (List<CodegenOperation>) objs.get("operation");

      if (os != null && os.size() > 0) {
        CodegenOperation op = os.get(os.size() - 1);
        op.hasMore = null;
      }
    }
    return operations;
  }
 @Override
 public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
   if ("retrofit".equals(getLibrary()) || "retrofit2".equals(getLibrary())) {
     Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
     if (operations != null) {
       List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
       for (CodegenOperation operation : ops) {
         if (operation.hasConsumes == Boolean.TRUE) {
           Map<String, String> firstType = operation.consumes.get(0);
           if (firstType != null) {
             if ("multipart/form-data".equals(firstType.get("mediaType"))) {
               operation.isMultipart = Boolean.TRUE;
             }
           }
         }
         if (operation.returnType == null) {
           operation.returnType = "Void";
         }
         if ("retrofit2".equals(getLibrary())
             && StringUtils.isNotEmpty(operation.path)
             && operation.path.startsWith("/")) operation.path = operation.path.substring(1);
       }
     }
   }
   return objs;
 }
  @Override
  public CodegenOperation fromOperation(
      String path,
      String httpMethod,
      Operation operation,
      Map<String, Model> definitions,
      Swagger swagger) {
    CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger);

    op.path = sanitizePath(op.path);

    return op;
  }
  @Override
  public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
    // Remove imports of List, ArrayList, Map and HashMap as they are
    // imported in the template already.
    List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
    Pattern pattern = Pattern.compile("java\\.util\\.(List|ArrayList|Map|HashMap)");
    for (Iterator<Map<String, String>> itr = imports.iterator(); itr.hasNext(); ) {
      String _import = itr.next().get("import");
      if (pattern.matcher(_import).matches()) {
        itr.remove();
      }
    }

    if (usesAnyRetrofitLibrary()) {
      Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
      if (operations != null) {
        List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
        for (CodegenOperation operation : ops) {
          if (operation.hasConsumes == Boolean.TRUE) {
            Map<String, String> firstType = operation.consumes.get(0);
            if (firstType != null) {
              if ("multipart/form-data".equals(firstType.get("mediaType"))) {
                operation.isMultipart = Boolean.TRUE;
              }
            }
          }
          if (operation.returnType == null) {
            operation.returnType = "Void";
          }
          if (usesRetrofit2Library()
              && StringUtils.isNotEmpty(operation.path)
              && operation.path.startsWith("/")) operation.path = operation.path.substring(1);
        }
      }
    }
    return objs;
  }
 @Override
 public CodegenOperation fromOperation(
     String resourcePath,
     String httpMethod,
     Operation operation,
     Map<String, Model> definitions,
     Swagger swagger) {
   CodegenOperation op =
       super.fromOperation(resourcePath, httpMethod, operation, definitions, swagger);
   String path = op.path;
   op.nickname =
       addReturnPath(
           headerPath(
               formPath(
                   bodyPath(
                       queryPath(
                           capturePath(replacePathSplitter(path), op.pathParams), op.queryParams),
                       op.bodyParams),
                   op.formParams),
               op.headerParams),
           op.httpMethod,
           op.returnType);
   return op;
 }
  public void processOperation(
      String resourcePath,
      String httpMethod,
      Operation operation,
      Map<String, List<CodegenOperation>> operations,
      Path path) {
    if (operation != null) {
      if (System.getProperty("debugOperations") != null) {
        LOGGER.debug(
            "processOperation: resourcePath= "
                + resourcePath
                + "\t;"
                + httpMethod
                + " "
                + operation
                + "\n");
      }
      List<String> tags = operation.getTags();
      if (tags == null) {
        tags = new ArrayList<String>();
        tags.add("default");
      }

      /*
       build up a set of parameter "ids" defined at the operation level
       per the swagger 2.0 spec "A unique parameter is defined by a combination of a name and location"
        i'm assuming "location" == "in"
      */
      Set<String> operationParameters = new HashSet<String>();
      if (operation.getParameters() != null) {
        for (Parameter parameter : operation.getParameters()) {
          operationParameters.add(generateParameterId(parameter));
        }
      }

      // need to propagate path level down to the operation
      if (path.getParameters() != null) {
        for (Parameter parameter : path.getParameters()) {
          // skip propagation if a parameter with the same name is already defined at the operation
          // level
          if (!operationParameters.contains(generateParameterId(parameter))) {
            operation.addParameter(parameter);
          }
        }
      }

      for (String tag : tags) {
        CodegenOperation co = null;
        try {
          co =
              config.fromOperation(
                  resourcePath, httpMethod, operation, swagger.getDefinitions(), swagger);
          co.tags = new ArrayList<String>();
          co.tags.add(sanitizeTag(tag));
          config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations);

          List<Map<String, List<String>>> securities = operation.getSecurity();
          if (securities == null && swagger.getSecurity() != null) {
            securities = new ArrayList<Map<String, List<String>>>();
            for (SecurityRequirement sr : swagger.getSecurity()) {
              securities.add(sr.getRequirements());
            }
          }
          if (securities == null || securities.isEmpty()) {
            continue;
          }
          Map<String, SecuritySchemeDefinition> authMethods =
              new HashMap<String, SecuritySchemeDefinition>();
          // NOTE: Use only the first security requirement for now.
          // See the "security" field of "Swagger Object":
          //  https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#swagger-object
          //  "there is a logical OR between the security requirements"
          if (securities.size() > 1) {
            LOGGER.warn("More than 1 security requirements are found, using only the first one");
          }
          Map<String, List<String>> security = securities.get(0);
          for (String securityName : security.keySet()) {
            SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
            if (securityDefinition != null) {
              if (securityDefinition instanceof OAuth2Definition) {
                OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition;
                OAuth2Definition oauth2Operation = new OAuth2Definition();
                oauth2Operation.setType(oauth2Definition.getType());
                oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl());
                oauth2Operation.setFlow(oauth2Definition.getFlow());
                oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
                oauth2Operation.setScopes(new HashMap<String, String>());
                for (String scope : security.get(securityName)) {
                  if (oauth2Definition.getScopes().containsKey(scope)) {
                    oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
                  }
                }
                authMethods.put(securityName, oauth2Operation);
              } else {
                authMethods.put(securityName, securityDefinition);
              }
            }
          }
          if (!authMethods.isEmpty()) {
            co.authMethods = config.fromSecurity(authMethods);
            co.hasAuthMethods = true;
          }
        } catch (Exception ex) {
          String msg =
              "Could not process operation:\n" //
                  + "  Tag: "
                  + tag
                  + "\n" //
                  + "  Operation: "
                  + operation.getOperationId()
                  + "\n" //
                  + "  Resource: "
                  + httpMethod
                  + " "
                  + resourcePath
                  + "\n" //
                  + "  Definitions: "
                  + swagger.getDefinitions()
                  + "\n" //
                  + "  Exception: "
                  + ex.getMessage();
          throw new RuntimeException(msg, ex);
        }
      }
    }
  }