protected String chooseJavaArgName(String name, int iArg, Set<String> names) {
    Identifier jan = result.typeConverter.getValidJavaArgumentName(ident(name));
    String baseArgName = jan == null ? null : jan.toString();
    int i = 1;
    if (baseArgName == null) baseArgName = "arg";

    String argName;
    do {
      argName = baseArgName + (i == 1 ? "" : i + "");
      i++;
    } while (names.contains(argName) || result.typeConverter.isJavaKeyword(argName));
    names.add(argName);
    return argName;
  }
  public List<Define> reorderDefines(Collection<Define> defines) {
    List<Define> reordered = new ArrayList<Define>(defines.size());
    HashSet<Identifier> added = new HashSet<Identifier>(), all = new HashSet<Identifier>();

    Map<String, Pair<Define, Set<Identifier>>> pending =
        new HashMap<String, Pair<Define, Set<Identifier>>>();
    for (Define define : defines) {
      Set<Identifier> dependencies = new TreeSet<Identifier>();
      computeVariablesDependencies(define.getValue(), dependencies);
      all.add(ident(define.getName()));
      if (dependencies.isEmpty()) {
        reordered.add(define);
        added.add(ident(define.getName()));
      } else {
        pending.put(define.getName(), new Pair<Define, Set<Identifier>>(define, dependencies));
      }
    }

    boolean progressed;
    do {
      progressed = false;
      for (Iterator<Map.Entry<String, Pair<Define, Set<Identifier>>>> it =
              pending.entrySet().iterator();
          it.hasNext(); ) {
        Map.Entry<String, Pair<Define, Set<Identifier>>> e = it.next();
        Set<Identifier> dependencies = e.getValue().getSecond();
        String name = e.getKey();
        boolean missesDep = false;
        for (Identifier dependency : dependencies) {
          if (!added.contains(dependency)) {
            missesDep = true;
            if (!all.contains(dependency)) {
              it.remove();
              all.remove(name);
            }

            break;
          }
        }
        if (missesDep) continue;

        it.remove();
        reordered.add(e.getValue().getFirst());
        added.add(ident(name));
        progressed = true;
      }
    } while (!pending.isEmpty() && progressed);

    return reordered;
  }