@Override
  public Map<String, Object> postProcessModels(Map<String, Object> objs) {
    List<Object> models = (List<Object>) objs.get("models");
    for (Object _mo : models) {
      Map<String, Object> mo = (Map<String, Object>) _mo;
      CodegenModel cm = (CodegenModel) mo.get("model");
      for (CodegenProperty var : cm.vars) {
        Map<String, Object> allowableValues = var.allowableValues;

        // handle ArrayProperty
        if (var.items != null) {
          allowableValues = var.items.allowableValues;
        }

        if (allowableValues == null) {
          continue;
        }
        List<String> values = (List<String>) allowableValues.get("values");
        if (values == null) {
          continue;
        }

        // put "enumVars" map into `allowableValues", including `name` and `value`
        List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
        String commonPrefix = findCommonPrefixOfVars(values);
        int truncateIdx = commonPrefix.length();
        for (String value : values) {
          Map<String, String> enumVar = new HashMap<String, String>();
          String enumName;
          if (truncateIdx == 0) {
            enumName = value;
          } else {
            enumName = value.substring(truncateIdx);
            if ("".equals(enumName)) {
              enumName = value;
            }
          }
          enumVar.put("name", toEnumVarName(enumName));
          enumVar.put("value", value);
          enumVars.add(enumVar);
        }
        allowableValues.put("enumVars", enumVars);
        // handle default value for enum, e.g. available => StatusEnum.AVAILABLE
        if (var.defaultValue != null) {
          String enumName = null;
          for (Map<String, String> enumVar : enumVars) {
            if (var.defaultValue.equals(enumVar.get("value"))) {
              enumName = enumVar.get("name");
              break;
            }
          }
          if (enumName != null) {
            var.defaultValue = var.datatypeWithEnum + "." + enumName;
          }
        }
      }
    }
    return objs;
  }
  private static CodegenModel reconcileInlineEnums(
      CodegenModel codegenModel, CodegenModel parentCodegenModel) {
    // This generator uses inline classes to define enums, which breaks when
    // dealing with models that have subTypes. To clean this up, we will analyze
    // the parent and child models, look for enums that match, and remove
    // them from the child models and leave them in the parent.
    // Because the child models extend the parents, the enums will be available via the parent.

    // Only bother with reconciliation if the parent model has enums.
    if (parentCodegenModel.hasEnums) {

      // Get the properties for the parent and child models
      final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
      List<CodegenProperty> codegenProperties = codegenModel.vars;

      // Iterate over all of the parent model properties
      boolean removedChildEnum = false;
      for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
        // Look for enums
        if (parentModelCodegenPropery.isEnum) {
          // Now that we have found an enum in the parent class,
          // and search the child class for the same enum.
          Iterator<CodegenProperty> iterator = codegenProperties.iterator();
          while (iterator.hasNext()) {
            CodegenProperty codegenProperty = iterator.next();
            if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
              // We found an enum in the child class that is
              // a duplicate of the one in the parent, so remove it.
              iterator.remove();
              removedChildEnum = true;
            }
          }
        }
      }

      if (removedChildEnum) {
        // If we removed an entry from this model's vars, we need to ensure hasMore is updated
        int count = 0, numVars = codegenProperties.size();
        for (CodegenProperty codegenProperty : codegenProperties) {
          count += 1;
          codegenProperty.hasMore = (count < numVars) ? true : null;
        }
        codegenModel.vars = codegenProperties;
      }
    }

    return codegenModel;
  }