/** {@inheritDoc} */
  @Override
  protected void writeTo0(DexFile file, AnnotatedOutput out) {
    boolean annotates = out.annotates();
    int classOff = OffsettedItem.getAbsoluteOffsetOr0(classAnnotations);
    int fieldsSize = listSize(fieldAnnotations);
    int methodsSize = listSize(methodAnnotations);
    int parametersSize = listSize(parameterAnnotations);

    if (annotates) {
      out.annotate(0, offsetString() + " annotations directory");
      out.annotate(4, "  class_annotations_off: " + Hex.u4(classOff));
      out.annotate(4, "  fields_size:           " + Hex.u4(fieldsSize));
      out.annotate(4, "  methods_size:          " + Hex.u4(methodsSize));
      out.annotate(4, "  parameters_size:       " + Hex.u4(parametersSize));
    }

    out.writeInt(classOff);
    out.writeInt(fieldsSize);
    out.writeInt(methodsSize);
    out.writeInt(parametersSize);

    if (fieldsSize != 0) {
      Collections.sort(fieldAnnotations);
      if (annotates) {
        out.annotate(0, "  fields:");
      }
      for (FieldAnnotationStruct item : fieldAnnotations) {
        item.writeTo(file, out);
      }
    }

    if (methodsSize != 0) {
      Collections.sort(methodAnnotations);
      if (annotates) {
        out.annotate(0, "  methods:");
      }
      for (MethodAnnotationStruct item : methodAnnotations) {
        item.writeTo(file, out);
      }
    }

    if (parametersSize != 0) {
      Collections.sort(parameterAnnotations);
      if (annotates) {
        out.annotate(0, "  parameters:");
      }
      for (ParameterAnnotationStruct item : parameterAnnotations) {
        item.writeTo(file, out);
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  protected void writeTo0(DexFile file, AnnotatedOutput out) {
    if (out.annotates()) {
      /*
       * Re-run the encoder to generate the annotations,
       * but write the bits from the original encode
       */

      out.annotate(offsetString() + " debug info");
      encode(file, null, null, out, true);
    }

    out.write(encoded);
  }
  /**
   * Writes this instance to the given raw data object.
   *
   * @param out {@code non-null;} where to write to
   */
  public final void writeTo(AnnotatedOutput out) {
    throwIfNotPrepared();
    align(out);

    int cursor = out.getCursor();

    if (fileOffset < 0) {
      fileOffset = cursor;
    } else if (fileOffset != cursor) {
      throw new RuntimeException(
          "alignment mismatch: for " + this + ", at " + cursor + ", but expected " + fileOffset);
    }

    if (out.annotates()) {
      if (name != null) {
        out.annotate(0, "\n" + name + ":");
      } else if (cursor != 0) {
        out.annotate(0, "\n");
      }
    }

    writeTo0(out);
  }