/** {@inheritDoc} */
 public String getConciseIdentity() {
   TypeIdItem parentType = getParentType();
   if (parentType == null) {
     return "annotation_directory_item @0x" + Integer.toHexString(getOffset());
   }
   return "annotation_directory_item @0x"
       + Integer.toHexString(getOffset())
       + " ("
       + parentType.getTypeDescriptor()
       + ")";
 }
 @Override
 public int hashCode() {
   // If the item has a single parent, we can use the re-use the identity (hash) of that parent
   TypeIdItem parentType = getParentType();
   if (parentType != null) {
     return parentType.hashCode();
   }
   if (classAnnotations != null) {
     return classAnnotations.hashCode();
   }
   return 0;
 }
  /** {@inheritDoc} */
  public int compareTo(AnnotationDirectoryItem o) {
    Preconditions.checkNotNull(o);

    TypeIdItem parentType = getParentType();
    TypeIdItem otherParentType = o.getParentType();
    if (parentType != null) {
      if (otherParentType != null) {
        return parentType.compareTo(otherParentType);
      }
      return 1;
    }
    if (otherParentType != null) {
      return -1;
    }

    if (classAnnotations != null) {
      if (o.classAnnotations != null) {
        return classAnnotations.compareTo(o.classAnnotations);
      }
      return 1;
    }
    return -1;
  }
  /** {@inheritDoc} */
  protected void writeItem(AnnotatedOutput out) {
    if (out.annotates()) {
      TypeIdItem parentType = getParentType();
      if (parentType != null) {
        out.annotate(0, parentType.getTypeDescriptor());
      }
      if (classAnnotations != null) {
        out.annotate(
            4, "class_annotations_off: 0x" + Integer.toHexString(classAnnotations.getOffset()));
      } else {
        out.annotate(4, "class_annotations_off:");
      }

      int length = fieldAnnotations == null ? 0 : fieldAnnotations.length;
      out.annotate(
          4, "annotated_fields_size: 0x" + Integer.toHexString(length) + " (" + length + ")");
      length = methodAnnotations == null ? 0 : methodAnnotations.length;
      out.annotate(
          4, "annotated_methods_size: 0x" + Integer.toHexString(length) + " (" + length + ")");
      length = parameterAnnotations == null ? 0 : parameterAnnotations.length;
      out.annotate(
          4, "annotated_parameters_size: 0x" + Integer.toHexString(length) + " (" + length + ")");

      int index;
      if (fieldAnnotations != null) {
        index = 0;
        for (FieldAnnotation fieldAnnotation : fieldAnnotations) {
          out.annotate(0, "[" + index++ + "] field_annotation");

          out.indent();
          out.annotate(
              4,
              "field: "
                  + fieldAnnotation.field.getFieldName().getStringValue()
                  + ":"
                  + fieldAnnotation.field.getFieldType().getTypeDescriptor());
          out.annotate(
              4,
              "annotations_off: 0x"
                  + Integer.toHexString(fieldAnnotation.annotationSet.getOffset()));
          out.deindent();
        }
      }

      if (methodAnnotations != null) {
        index = 0;
        for (MethodAnnotation methodAnnotation : methodAnnotations) {
          out.annotate(0, "[" + index++ + "] method_annotation");
          out.indent();
          out.annotate(4, "method: " + methodAnnotation.method.getMethodString());
          out.annotate(
              4,
              "annotations_off: 0x"
                  + Integer.toHexString(methodAnnotation.annotationSet.getOffset()));
          out.deindent();
        }
      }

      if (parameterAnnotations != null) {
        index = 0;
        for (ParameterAnnotation parameterAnnotation : parameterAnnotations) {
          out.annotate(0, "[" + index++ + "] parameter_annotation");
          out.indent();
          out.annotate(4, "method: " + parameterAnnotation.method.getMethodString());
          out.annotate(
              4,
              "annotations_off: 0x"
                  + Integer.toHexString(parameterAnnotation.annotationSet.getOffset()));
        }
      }
    }

    out.writeInt(classAnnotations == null ? 0 : classAnnotations.getOffset());
    out.writeInt(fieldAnnotations == null ? 0 : fieldAnnotations.length);
    out.writeInt(methodAnnotations == null ? 0 : methodAnnotations.length);
    out.writeInt(parameterAnnotations == null ? 0 : parameterAnnotations.length);

    if (fieldAnnotations != null) {
      for (FieldAnnotation fieldAnnotation : fieldAnnotations) {
        out.writeInt(fieldAnnotation.field.getIndex());
        out.writeInt(fieldAnnotation.annotationSet.getOffset());
      }
    }

    if (methodAnnotations != null) {
      for (MethodAnnotation methodAnnotation : methodAnnotations) {
        out.writeInt(methodAnnotation.method.getIndex());
        out.writeInt(methodAnnotation.annotationSet.getOffset());
      }
    }

    if (parameterAnnotations != null) {
      for (ParameterAnnotation parameterAnnotation : parameterAnnotations) {
        out.writeInt(parameterAnnotation.method.getIndex());
        out.writeInt(parameterAnnotation.annotationSet.getOffset());
      }
    }
  }