/**
  * Writes all annotations of the supplied type to this instance's annotation appender.
  *
  * @param typeDescription The type of what all annotations should be written of.
  * @param typePath The type path to use.
  * @return The resulting annotation appender.
  */
 private AnnotationAppender apply(TypeDescription.Generic typeDescription, String typePath) {
   AnnotationAppender annotationAppender = this.annotationAppender;
   for (AnnotationDescription annotationDescription : typeDescription.getDeclaredAnnotations()) {
     annotationAppender =
         annotationAppender.append(
             annotationDescription, annotationValueFilter, typeReference, typePath);
   }
   return annotationAppender;
 }
 @Override
 public int hashCode() {
   int result = annotationAppender.hashCode();
   result = 31 * result + annotationValueFilter.hashCode();
   result = 31 * result + typeReference;
   result = 31 * result + typePath.hashCode();
   return result;
 }
 @Override
 public boolean equals(Object other) {
   if (this == other) return true;
   if (other == null || getClass() != other.getClass()) return false;
   ForTypeAnnotations that = (ForTypeAnnotations) other;
   return typeReference == that.typeReference
       && annotationAppender.equals(that.annotationAppender)
       && annotationValueFilter.equals(that.annotationValueFilter)
       && typePath.equals(that.typePath);
 }
 /**
  * Appends all supplied type variables to the supplied method appender.
  *
  * @param annotationAppender The annotation appender to write any type annotation to.
  * @param annotationValueFilter The annotation value filter to apply.
  * @param variableOnType {@code true} if the type variables are declared by a type, {@code
  *     false} if they are declared by a method.
  * @param subListIndex The index of the first type variable to append. All previous type
  *     variables are ignored.
  * @param typeVariables The type variables to append.
  * @return The resulting annotation appender.
  */
 public static AnnotationAppender ofTypeVariable(
     AnnotationAppender annotationAppender,
     AnnotationValueFilter annotationValueFilter,
     boolean variableOnType,
     int subListIndex,
     List<? extends TypeDescription.Generic> typeVariables) {
   int typeVariableIndex = subListIndex, variableBaseReference, variableBoundBaseBase;
   if (variableOnType) {
     variableBaseReference = TypeReference.CLASS_TYPE_PARAMETER;
     variableBoundBaseBase = TypeReference.CLASS_TYPE_PARAMETER_BOUND;
   } else {
     variableBaseReference = TypeReference.METHOD_TYPE_PARAMETER;
     variableBoundBaseBase = TypeReference.METHOD_TYPE_PARAMETER_BOUND;
   }
   for (TypeDescription.Generic typeVariable :
       typeVariables.subList(subListIndex, typeVariables.size())) {
     int typeReference =
         TypeReference.newTypeParameterReference(variableBaseReference, typeVariableIndex)
             .getValue();
     for (AnnotationDescription annotationDescription : typeVariable.getDeclaredAnnotations()) {
       annotationAppender =
           annotationAppender.append(
               annotationDescription, annotationValueFilter, typeReference, EMPTY_TYPE_PATH);
     }
     int boundIndex =
         !typeVariable.getUpperBounds().get(0).getSort().isTypeVariable()
                 && typeVariable.getUpperBounds().get(0).asErasure().isInterface()
             ? 1
             : 0;
     for (TypeDescription.Generic typeBound : typeVariable.getUpperBounds()) {
       annotationAppender =
           typeBound.accept(
               new ForTypeAnnotations(
                   annotationAppender,
                   annotationValueFilter,
                   TypeReference.newTypeParameterBoundReference(
                       variableBoundBaseBase, typeVariableIndex, boundIndex++)));
     }
     typeVariableIndex++;
   }
   return annotationAppender;
 }