/**
   * Creates an array of types of each parameter by looking at the method's <code>Signature</code>
   * attribute, and querying the parent <code>ClassFile</code> instance for any type argument
   * values. This attribute was introduced in Java 5, and is the only way to detect generic
   * parameters.
   *
   * @return The parameter types.
   * @see #createParamTypesFromDescriptor()
   */
  private String[] createParamTypesFromTypeSignature() {

    String[] params = null;

    if (signatureAttr != null) {
      List paramTypes = signatureAttr.getMethodParamTypes(this, cf);
      if (paramTypes != null) {
        params = new String[paramTypes.size()];
        params = (String[]) paramTypes.toArray(params);
      }
    }

    return params;
  }
  /**
   * Returns the signature of this method, as determined from its method descriptor.
   *
   * @return The signature of this method.
   */
  public String getSignature() {

    StringBuffer sb = new StringBuffer();

    // Return type.
    if (!isConstructor()) { // Don't print "void" return type.
      sb.append(getReturnTypeString(false));
      sb.append(' ');
    }

    // Method name and param list.
    sb.append(getName());
    sb.append('(');
    appendParamDescriptors(sb);
    sb.append(')');

    // "throws" clause.
    for (int i = 0; i < getAttributeCount(); i++) {
      AttributeInfo ai = (AttributeInfo) attributes.get(i);
      if (ai instanceof Exceptions) { // At most 1 Exceptions attribute
        sb.append(" throws ");
        Exceptions ex = (Exceptions) ai;
        for (int j = 0; j < ex.getExceptionCount(); j++) {
          sb.append(ex.getException(j));
          if (j < ex.getExceptionCount() - 1) {
            sb.append(", ");
          }
        }
      }
    }

    return sb.toString();
  }
 /**
  * Adds the specified attribute to this field.
  *
  * @param info Information about the attribute.
  */
 private void addAttribute(AttributeInfo info) {
   attributes.add(info);
 }
 /**
  * Returns the number of attributes of this field.
  *
  * @return The number of attributes.
  */
 public int getAttributeCount() {
   return attributes.size();
 }
 /**
  * Returns the specified attribute.
  *
  * @param index The index of the attribute.
  * @return The attribute.
  */
 public AttributeInfo getAttribute(int index) {
   return (AttributeInfo) attributes.get(index);
 }
  /**
   * Creates an array of types of each parameter by looking at the method's descriptor field. This
   * technique should work with Java 1.0+, but won't pick up on generic types added in Java 5.
   *
   * @return The parameter types.
   * @see #createParamTypesFromTypeSignature()
   */
  private String[] createParamTypesFromDescriptor(boolean qualified) {

    String descriptor = getDescriptor();
    int rparen = descriptor.indexOf(')');
    String paramDescriptors = descriptor.substring(1, rparen);
    // String returnDescriptor = descriptor.substring(rparen+1);

    List paramTypeList = new ArrayList();
    String type = null;

    while (paramDescriptors.length() > 0) {

      // Can't do lastIndexOf() as there may be > 1 array parameter
      // in the descriptors.
      // int braceCount = paramDescriptors.lastIndexOf('[') + 1;
      int braceCount = -1;
      while (paramDescriptors.charAt(++braceCount) == '[') ;
      int pos = braceCount;

      switch (paramDescriptors.charAt(pos)) {

          // BaseType
        case 'B':
          type = "byte";
          pos++;
          break;
        case 'C':
          type = "char";
          pos++;
          break;
        case 'D':
          type = "double";
          pos++;
          break;
        case 'F':
          type = "float";
          pos++;
          break;
        case 'I':
          type = "int";
          pos++;
          break;
        case 'J':
          type = "long";
          pos++;
          break;
        case 'S':
          type = "short";
          pos++;
          break;
        case 'Z':
          type = "boolean";
          pos++;
          break;

          // ObjectType
        case 'L':
          String clazz = paramDescriptors.substring(pos + 1, paramDescriptors.indexOf(';'));
          type =
              qualified
                  ? org.fife.rsta.ac.java.Util.replaceChar(clazz, '/', '.')
                  : clazz.substring(clazz.lastIndexOf('/') + 1);
          // clazz = org.fife.rsta.ac.java.Util.replaceChar(clazz, '/', '.');
          // type = clazz;
          pos += clazz.length() + 2; // "+2" for the 'L' & semicolon
          break;

          // Invalid method descriptor
        default:
          String temp = "INVALID_TYPE_" + paramDescriptors;
          type = temp;
          pos += paramDescriptors.length();
          break;
      }

      for (int i = 0; i < braceCount; i++) {
        type += "[]";
      }
      paramTypeList.add(type);

      paramDescriptors = paramDescriptors.substring(pos);
    }

    String[] types = new String[paramTypeList.size()];
    types = (String[]) paramTypeList.toArray(types);
    return types;
  }