private void manageIdentifier(
      final JavaType javaType,
      final AnnotationMetadataBuilder jpaAnnotationBuilder,
      final Set<JavaSymbolName> attributesToDeleteIfPresent,
      final Table table) {
    final JavaType identifierType = getIdentifierType(javaType);
    final PhysicalTypeMetadata identifierPhysicalTypeMetadata =
        getPhysicalTypeMetadata(identifierType);

    // Process primary keys and add 'identifierType' attribute
    final int pkCount = table.getPrimaryKeyCount();
    if (pkCount == 1) {
      // Table has one primary key
      // Check for redundant, managed identifier class and delete if found
      if (isIdentifierDeletable(identifierType)) {
        deleteJavaType(
            identifierType, "the " + table.getName() + " table has only one primary key");
      }

      attributesToDeleteIfPresent.add(new JavaSymbolName(IDENTIFIER_TYPE));

      // We don't need a PK class, so we just tell the
      // JpaActiveRecordProvider via IdentifierService the column name,
      // field type and field name to use
      final List<Identifier> identifiers = getIdentifiersFromPrimaryKeys(table);
      identifierResults.put(javaType, identifiers);
    } else if (pkCount == 0 || pkCount > 1) {
      // Table has either no primary keys or more than one primary key so
      // create a composite key

      // Check if identifier class already exists and if not, create it
      if (identifierPhysicalTypeMetadata == null
          || !identifierPhysicalTypeMetadata.isValid()
          || identifierPhysicalTypeMetadata.getMemberHoldingTypeDetails() == null) {
        createIdentifierClass(identifierType);
      }

      jpaAnnotationBuilder.addClassAttribute(IDENTIFIER_TYPE, identifierType);

      // We need a PK class, so we tell the IdentifierMetadataProvider via
      // IdentifierService the various column names, field types and field
      // names to use
      // For tables with no primary keys, create a composite key using all
      // the table's columns
      final List<Identifier> identifiers =
          pkCount == 0 ? getIdentifiersFromColumns(table) : getIdentifiersFromPrimaryKeys(table);
      identifierResults.put(identifierType, identifiers);
    }
  }
  /** Adds the JUnit and Spring type level annotations if needed */
  private void addRequiredIntegrationTestClassIntroductions(final JavaType dodGovernor) {
    // Add an @RunWith(SpringJunit4ClassRunner) annotation to the type, if
    // the user did not define it on the governor directly
    if (MemberFindingUtils.getAnnotationOfType(governorTypeDetails.getAnnotations(), RUN_WITH)
        == null) {
      AnnotationMetadataBuilder runWithBuilder = new AnnotationMetadataBuilder(RUN_WITH);
      runWithBuilder.addClassAttribute(
          "value", "org.springframework.test.context.junit4.SpringJUnit4ClassRunner");
      builder.addAnnotation(runWithBuilder);
    }

    // Add an @ContextConfiguration("classpath:/applicationContext.xml")
    // annotation to the type, if the user did not define it on the governor
    // directly
    if (MemberFindingUtils.getAnnotationOfType(
            governorTypeDetails.getAnnotations(), CONTEXT_CONFIGURATION)
        == null) {
      AnnotationMetadataBuilder contextConfigurationBuilder =
          new AnnotationMetadataBuilder(CONTEXT_CONFIGURATION);
      contextConfigurationBuilder.addStringAttribute(
          "locations", "classpath:/META-INF/spring/applicationContext*.xml");
      builder.addAnnotation(contextConfigurationBuilder);
    }

    // Add an @Transactional, if the user did not define it on the governor
    // directly
    if (annotationValues.isTransactional()
        && MemberFindingUtils.getAnnotationOfType(
                governorTypeDetails.getAnnotations(), TRANSACTIONAL)
            == null) {
      AnnotationMetadataBuilder transactionalBuilder = new AnnotationMetadataBuilder(TRANSACTIONAL);
      if (StringUtils.hasText(transactionManager)
          && !"transactionManager".equals(transactionManager)) {
        transactionalBuilder.addStringAttribute("value", transactionManager);
      }
      builder.addAnnotation(transactionalBuilder);
    }

    // Add the data on demand field if the user did not define it on the
    // governor directly
    FieldMetadata field = governorTypeDetails.getField(new JavaSymbolName("dod"));
    if (field != null) {
      Assert.isTrue(
          field.getFieldType().equals(dodGovernor),
          "Field 'dod' on '"
              + destination.getFullyQualifiedTypeName()
              + "' must be of type '"
              + dodGovernor.getFullyQualifiedTypeName()
              + "'");
      Assert.notNull(
          MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), AUTOWIRED),
          "Field 'dod' on '"
              + destination.getFullyQualifiedTypeName()
              + "' must be annotated with @Autowired");
    } else {
      // Add the field via the ITD
      List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
      annotations.add(new AnnotationMetadataBuilder(AUTOWIRED));
      FieldMetadataBuilder fieldBuilder =
          new FieldMetadataBuilder(
              getId(), Modifier.PRIVATE, annotations, new JavaSymbolName("dod"), dodGovernor);
      builder.addField(fieldBuilder);
    }

    builder.getImportRegistrationResolver().addImport(ASSERT);
  }