/**
   * Sets the indexed type of IdxPropertyPattern
   *
   * @param type New indexed type of the indexed property
   * @throws SourceException If the modification of source code is impossible
   */
  public void setIndexedType(Type type) throws SourceException {

    if (this.indexedType.compareTo(type, true)) return;

    // Remember the old type & old indexed type
    Type oldIndexedType = this.indexedType;
    Type oldType = this.type;

    // Change the indexed type
    if (indexedGetterMethod != null) {
      indexedGetterMethod.setReturn(type);
    }
    if (indexedSetterMethod != null) {
      MethodParameter[] params = indexedSetterMethod.getParameters();
      if (params.length > 1) {
        params[1].setType(type);
        indexedSetterMethod.setParameters(params);
      }
    }

    // Test if the old type of getter and seter was an array of indexedType
    // if so change the type of that array.
    if (oldType != null
        && oldType.isArray()
        && oldType.getElementType().compareTo(oldIndexedType, false)) {
      Type newArrayType = Type.createArray(type);
      super.setType(newArrayType);
    }

    indexedType = type;
  }
  /**
   * Generates indexed getter method with body and optionaly with Javadoc comment.
   *
   * @param body Body of the method
   * @param javadoc Generate Javadoc comment?
   * @throws SourceException If modification of source code is impossible.
   */
  void generateIndexedGetterMethod(String body, boolean javadoc) throws SourceException {

    ClassElement declaringClass = getDeclaringClass();
    MethodElement newGetter = new MethodElement();
    MethodParameter[] newParameters = {new MethodParameter("index", Type.INT, false)}; // NOI18N

    newGetter.setName(Identifier.create("get" + capitalizeFirstLetter(getName()))); // NOI18N
    newGetter.setReturn(indexedType);
    newGetter.setModifiers(Modifier.PUBLIC);
    newGetter.setParameters(newParameters);
    if (declaringClass.isInterface()) {
      newGetter.setBody(null);
    } else if (body != null) newGetter.setBody(body);

    if (javadoc) {
      String comment =
          MessageFormat.format(
              bundle.getString("COMMENT_IdxPropertyGetter"), new Object[] {getName()});
      newGetter.getJavaDoc().setRawText(comment);
    }

    // System.out.println ("Generating getter" ); // NOI18N

    if (declaringClass == null) throw new SourceException();
    else {
      // System.out.println ( "Adding getter method" ); // NOI18N
      declaringClass.addMethod(newGetter);
      indexedGetterMethod =
          declaringClass.getMethod(newGetter.getName(), getParameterTypes(newGetter));
    }
  }
  /**
   * Sets the non-indexed type of IdxPropertyPattern
   *
   * @param type New non-indexed type of the indexed property
   * @throws SourceException If the modification of source code is impossible
   */
  public void setType(Type type) throws SourceException {

    if (this.type != null && this.type.compareTo(type, true)) return;

    // Remember the old type & old indexed type
    Type oldIndexedType = this.indexedType;
    Type oldType = this.type;

    if (oldType == null) {
      this.type = type;
      oldType = type;
      int mode = getMode();
      if (mode == READ_WRITE || mode == READ_ONLY) generateGetterMethod();
      if (mode == READ_WRITE || mode == WRITE_ONLY) generateSetterMethod();
    } else
      // Change the type
      super.setType(type);

    // Test if the idexedType is the type of array and change it if so
    if (type.isArray()
        && oldType.isArray()
        && oldType.getElementType().compareTo(oldIndexedType, false)) {
      Type newType = type.getElementType();

      if (indexedGetterMethod != null) {
        indexedGetterMethod.setReturn(newType);
      }
      if (indexedSetterMethod != null) {
        MethodParameter[] params = indexedSetterMethod.getParameters();
        if (params.length > 1) {
          params[1].setType(newType);
          indexedSetterMethod.setParameters(params);
        }
      }

      // Set the type  to new type
      setIndexedType(newType);
    }
  }
  /**
   * Generates indexed setter method with body and optionaly with Javadoc comment.
   *
   * @param body Body of the method
   * @param javadoc Generate Javadoc comment?
   * @param constrained Is the property constrained?
   * @throws SourceException If modification of source code is impossible.
   */
  void generateIndexedSetterMethod(String body, boolean constrained, boolean javadoc)
      throws SourceException {

    ClassElement declaringClass = getDeclaringClass();
    MethodElement newSetter = new MethodElement();
    MethodParameter[] newParameters = {
      new MethodParameter("index", Type.INT, false), // NOI18N
      new MethodParameter(name, indexedType, false)
    };

    newSetter.setName(Identifier.create("set" + capitalizeFirstLetter(getName()))); // NOI18N
    newSetter.setReturn(Type.VOID);
    newSetter.setModifiers(Modifier.PUBLIC);
    newSetter.setParameters(newParameters);
    if (constrained)
      newSetter.setExceptions(
          (new Identifier[] {Identifier.create("java.beans.PropertyVetoException")})); // NOI18N
    if (declaringClass.isInterface()) {
      newSetter.setBody(null);
    } else if (body != null) {
      newSetter.setBody(body);
    }

    if (javadoc) {
      String comment =
          MessageFormat.format(
              bundle.getString("COMMENT_IdxPropertySetter"), new Object[] {getName(), name});
      if (constrained) comment = comment + bundle.getString("COMMENT_Tag_ThrowsPropertyVeto");
      newSetter.getJavaDoc().setRawText(comment);
    }

    if (declaringClass == null) throw new SourceException();
    else {
      declaringClass.addMethod(newSetter);
      indexedSetterMethod =
          declaringClass.getMethod(newSetter.getName(), getParameterTypes(newSetter));
    }
  }