/**
   * Determine the type of a field access (implicit or explicit) based on the receiver type and the
   * declared annotations for the field.
   *
   * @param type Type of the field access expression
   * @param declaredFieldAnnotations Annotations on the element.
   * @param receiverType Inferred annotations of the receiver
   */
  private void computeFieldAccessType(
      AnnotatedTypeMirror type,
      Collection<? extends AnnotationMirror> declaredFieldAnnotations,
      AnnotatedTypeMirror receiverType,
      AnnotatedTypeMirror fieldAnnotations,
      Element element) {
    // not necessary for primitive fields
    if (TypesUtils.isPrimitive(type.getUnderlyingType())) {
      return;
    }
    // not necessary if there is an explicit UnknownInitialization
    // annotation on the field
    if (AnnotationUtils.containsSameIgnoringValues(
        fieldAnnotations.getAnnotations(), UNCLASSIFIED)) {
      return;
    }
    if (isUnclassified(receiverType) || isFree(receiverType)) {

      TypeMirror fieldDeclarationType = element.getEnclosingElement().asType();
      boolean isInitializedForFrame = isInitializedForFrame(receiverType, fieldDeclarationType);
      if (isInitializedForFrame) {
        // The receiver is initialized for this frame.
        // Change the type of the field to @UnknownInitialization or @Raw so that
        // anything can be assigned to this field.
        type.replaceAnnotation(UNCLASSIFIED);
      } else if (computingAnnotatedTypeMirrorOfLHS) {
        // The receiver is not initialized for this frame, but the type of a lhs is being computed.
        // Change the type of the field to @UnknownInitialization or @Raw so that
        // anything can be assigned to this field.
        type.replaceAnnotation(UNCLASSIFIED);
      } else {
        // The receiver is not initialized for this frame and the type being computed is not a LHS.
        // Replace all annotations with the top annotation for that hierarchy.
        type.clearAnnotations();
        type.addAnnotations(qualHierarchy.getTopAnnotations());
      }

      if (!AnnotationUtils.containsSame(declaredFieldAnnotations, NOT_ONLY_COMMITTED) || !useFbc) {
        // add root annotation for all other hierarchies, and
        // Committed for the commitment hierarchy
        type.replaceAnnotation(COMMITTED);
      }
    }
  }