/**
   * Locates the entity manager field that should be used.
   *
   * <p>If a parent is defined, it must provide the field.
   *
   * <p>We generally expect the field to be named "entityManager" and be of type
   * javax.persistence.EntityManager. We also require it to be public or protected, and annotated
   * with @PersistenceContext. If there is an existing field which doesn't meet these latter
   * requirements, we add an underscore prefix to the "entityManager" name and try again, until such
   * time as we come up with a unique name that either meets the requirements or the name is not
   * used and we will create it.
   *
   * @return the entity manager field (never returns null)
   */
  public FieldMetadata getEntityManagerField() {
    if (parent != null) {
      // The parent is required to guarantee this is available
      return parent.getEntityManagerField();
    }

    // Need to locate it ourself
    int index = -1;
    while (true) {
      // Compute the required field name
      index++;
      final JavaSymbolName fieldSymbolName =
          new JavaSymbolName(StringUtils.repeat("_", index) + "entityManager");
      final FieldMetadata candidate = governorTypeDetails.getField(fieldSymbolName);
      if (candidate != null) {
        // Verify if candidate is suitable

        if (!Modifier.isPublic(candidate.getModifier())
            && !Modifier.isProtected(candidate.getModifier())
            && (Modifier.TRANSIENT != candidate.getModifier())) {
          // Candidate is not public and not protected and not simply a transient field (in which
          // case subclasses
          // will see the inherited field), so any subsequent subclasses won't be able to see it.
          // Give up!
          continue;
        }

        if (!candidate.getFieldType().equals(ENTITY_MANAGER)) {
          // Candidate isn't an EntityManager, so give up
          continue;
        }

        if (MemberFindingUtils.getAnnotationOfType(candidate.getAnnotations(), PERSISTENCE_CONTEXT)
            == null) {
          // Candidate doesn't have a PersistenceContext annotation, so give up
          continue;
        }

        // If we got this far, we found a valid candidate
        return candidate;
      }

      // Candidate not found, so let's create one
      final List<AnnotationMetadataBuilder> annotations =
          new ArrayList<AnnotationMetadataBuilder>();
      final AnnotationMetadataBuilder annotationBuilder =
          new AnnotationMetadataBuilder(PERSISTENCE_CONTEXT);
      if (StringUtils.hasText(crudAnnotationValues.getPersistenceUnit())) {
        annotationBuilder.addStringAttribute("unitName", crudAnnotationValues.getPersistenceUnit());
      }
      annotations.add(annotationBuilder);

      final FieldMetadataBuilder fieldBuilder =
          new FieldMetadataBuilder(
              getId(), Modifier.TRANSIENT, annotations, fieldSymbolName, ENTITY_MANAGER);
      return fieldBuilder.build();
    }
  }