public static Map<String, Object> describe(IMethodDescription desc) {
    Map<String, Object> result = Maps.newHashMap();
    result.put(DESCRIPTION, desc.description());
    result.put(SOURCE, desc.source());

    result.put(RETURN_TYPES, desc.returnTypes().describe());

    {
      List<Map<String, Object>> args = Lists.newArrayList();
      for (IArgumentDescription arg : desc.arguments()) args.add(describeArgument(arg));

      result.put(ARGS, args);
    }
    return result;
  }
  private static String createDocString(IMethodDescription desc) {
    // (arg:type[, optionArg:type]):resultType -- Description

    List<String> args = Lists.newArrayList();

    for (IArgumentDescription arg : desc.arguments())
      args.add(arg.name() + ":" + decorate(arg.type().describe(), arg));

    final IScriptType returnTypes = desc.returnTypes();

    String argsJoined = Joiner.on(',').join(args);
    String argsAndResult;
    if (TypeHelper.isVoid(returnTypes)) {
      argsAndResult = String.format("(%s)", argsJoined);
    } else {
      final String ret = returnTypes.describe();
      argsAndResult = String.format("(%s):%s", argsJoined, ret);
    }

    return !Strings.isNullOrEmpty(desc.description())
        ? argsAndResult + " -- " + desc.description()
        : argsAndResult;
  }
  public static String signature(IMethodDescription desc) {
    List<String> tmp = Lists.newArrayList();
    for (IArgumentDescription arg : desc.arguments()) tmp.add(decorate(arg.name(), arg));

    return "(" + Joiner.on(",").join(tmp) + ")";
  }