public OverloadedFunction(AbstractFunction function) {
    super(function.getType(), null, function.getEval());

    this.name = function.getName();

    this.primaryCandidates = new ArrayList<AbstractFunction>(1);
    this.defaultCandidates = new ArrayList<AbstractFunction>(1);

    if (function.isDefault()) {
      defaultCandidates.add(function);
    } else {
      primaryCandidates.add(function);
    }

    this.isStatic = function.isStatic();
  }
  public OverloadedFunction add(AbstractFunction candidate) {
    List<AbstractFunction> joined = new ArrayList<AbstractFunction>(primaryCandidates.size() + 1);
    joined.addAll(primaryCandidates);
    List<AbstractFunction> defJoined =
        new ArrayList<AbstractFunction>(defaultCandidates.size() + 1);
    defJoined.addAll(defaultCandidates);

    if (candidate.isDefault() && !defJoined.contains(candidate)) {
      defJoined.add(candidate);
    } else if (!candidate.isDefault() && !joined.contains(candidate)) {
      joined.add(candidate);
    }

    return new OverloadedFunction(
        "(" + name + "+" + candidate.getName() + ")",
        lub(joined).lub(lub(defJoined)),
        joined,
        defJoined,
        ctx);
  }