/**
   * Returns the signature for the binding. Returns an empty string if a signature is not required
   * for the binding.
   *
   * @param binding
   * @return the signature or an empty string
   * @throws CoreException
   * @throws DOMException
   */
  public static String getSignature(IBinding binding) throws CoreException, DOMException {
    StringBuilder buffer = new StringBuilder();
    if (binding instanceof ICPPDeferredClassInstance) {
      buffer.append(getSignature(((ICPPDeferredClassInstance) binding).getTemplateDefinition()));
    }
    if (binding instanceof ICPPTemplateInstance) {
      ICPPTemplateInstance inst = (ICPPTemplateInstance) binding;
      buffer.append(getTemplateArgString(inst.getTemplateArguments(), true));
    } else if (binding instanceof ICPPUnknownMemberClassInstance) {
      ICPPUnknownMemberClassInstance inst = (ICPPUnknownMemberClassInstance) binding;
      buffer.append(getTemplateArgString(inst.getArguments(), true));
    } else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
      ICPPClassTemplatePartialSpecialization partial =
          (ICPPClassTemplatePartialSpecialization) binding;
      buffer.append(getTemplateArgString(partial.getTemplateArguments(), false));
    }

    if (binding instanceof ICPPFunction) {
      IFunction function = (ICPPFunction) binding;
      final IFunctionType ftype = function.getType();
      buffer.append(getFunctionParameterString(ftype));
      if (binding instanceof ICPPTemplateDefinition) {
        ICPPTemplateDefinition tdef = (ICPPTemplateDefinition) binding;
        appendTemplateParameters(tdef.getTemplateParameters(), buffer);
        ASTTypeUtil.appendType(ftype.getReturnType(), true, buffer);
      }
    }
    if (binding instanceof ICPPMethod && !(binding instanceof ICPPConstructor)) {
      ICPPFunctionType ft = ((ICPPMethod) binding).getType();
      if (ft.isConst()) buffer.append('c');
      if (ft.isVolatile()) buffer.append('v');
    }

    return buffer.toString();
  }