@Override
  protected ItdTypeDetailsProvidingMetadataItem getMetadata(
      final String metadataIdentificationString,
      final JavaType aspectName,
      final PhysicalTypeMetadata governorPhysicalTypeMetadata,
      final String itdFilename) {
    // Acquire bean info (we need getters details, specifically)
    final JavaType javaType = JsonMetadata.getJavaType(metadataIdentificationString);
    final LogicalPath path = JsonMetadata.getPath(metadataIdentificationString);

    // We need to parse the annotation, if it is not present we will simply
    // get the default annotation values
    final JsonAnnotationValues annotationValues =
        new JsonAnnotationValues(governorPhysicalTypeMetadata);

    String plural = javaType.getSimpleTypeName() + "s";
    final PluralMetadata pluralMetadata =
        (PluralMetadata) getMetadataService().get(PluralMetadata.createIdentifier(javaType, path));
    if (pluralMetadata != null) {
      plural = pluralMetadata.getPlural();
    }

    return new JsonMetadata(
        metadataIdentificationString,
        aspectName,
        governorPhysicalTypeMetadata,
        plural,
        annotationValues);
  }
 @Override
 protected String getGovernorPhysicalTypeIdentifier(final String metadataIdentificationString) {
   final JavaType javaType = JsonMetadata.getJavaType(metadataIdentificationString);
   final LogicalPath path = JsonMetadata.getPath(metadataIdentificationString);
   final String physicalTypeIdentifier = PhysicalTypeIdentifier.createIdentifier(javaType, path);
   return physicalTypeIdentifier;
 }
 public String getProvidesType() {
   return JsonMetadata.getMetadataIdentiferType();
 }
 @Override
 protected String createLocalIdentifier(final JavaType javaType, final LogicalPath path) {
   return JsonMetadata.createIdentifier(javaType, path);
 }
  @Override
  protected ItdTypeDetailsProvidingMetadataItem getMetadata(
      final String metadataIdentificationString,
      final JavaType aspectName,
      final PhysicalTypeMetadata governorPhysicalTypeMetadata,
      final String itdFilename) {
    // We need to parse the annotation, which we expect to be present
    final WebJsonAnnotationValues annotationValues =
        new WebJsonAnnotationValues(governorPhysicalTypeMetadata);
    if (!annotationValues.isAnnotationFound()
        || annotationValues.getJsonObject() == null
        || governorPhysicalTypeMetadata.getMemberHoldingTypeDetails() == null) {
      return null;
    }

    // Lookup the form backing object's metadata
    final JavaType jsonObject = annotationValues.getJsonObject();
    final ClassOrInterfaceTypeDetails jsonTypeDetails =
        typeLocationService.getTypeDetails(jsonObject);
    if (jsonTypeDetails == null) {
      return null;
    }
    final LogicalPath jsonObjectPath =
        PhysicalTypeIdentifier.getPath(jsonTypeDetails.getDeclaredByMetadataId());
    final JsonMetadata jsonMetadata =
        (JsonMetadata)
            metadataService.get(JsonMetadata.createIdentifier(jsonObject, jsonObjectPath));
    if (jsonMetadata == null) {
      return null;
    }

    final PhysicalTypeMetadata backingObjectPhysicalTypeMetadata =
        (PhysicalTypeMetadata)
            metadataService.get(
                PhysicalTypeIdentifier.createIdentifier(
                    jsonObject, typeLocationService.getTypePath(jsonObject)));
    Validate.notNull(
        backingObjectPhysicalTypeMetadata,
        "Unable to obtain physical type metadata for type %s",
        jsonObject.getFullyQualifiedTypeName());
    final MemberDetails formBackingObjectMemberDetails =
        getMemberDetails(backingObjectPhysicalTypeMetadata);
    final MemberHoldingTypeDetails backingMemberHoldingTypeDetails =
        MemberFindingUtils.getMostConcreteMemberHoldingTypeDetailsWithTag(
            formBackingObjectMemberDetails, CustomDataKeys.PERSISTENT_TYPE);
    if (backingMemberHoldingTypeDetails == null) {
      return null;
    }

    // We need to be informed if our dependent metadata changes
    metadataDependencyRegistry.registerDependency(
        backingMemberHoldingTypeDetails.getDeclaredByMetadataId(), metadataIdentificationString);

    final Set<FinderMetadataDetails> finderDetails =
        webMetadataService.getDynamicFinderMethodsAndFields(
            jsonObject, formBackingObjectMemberDetails, metadataIdentificationString);
    if (finderDetails == null) {
      return null;
    }
    final Map<MethodMetadataCustomDataKey, MemberTypeAdditions> persistenceAdditions =
        webMetadataService.getCrudAdditions(jsonObject, metadataIdentificationString);
    final JavaTypePersistenceMetadataDetails javaTypePersistenceMetadataDetails =
        webMetadataService.getJavaTypePersistenceMetadataDetails(
            jsonObject, getMemberDetails(jsonObject), metadataIdentificationString);
    final PluralMetadata pluralMetadata =
        (PluralMetadata)
            metadataService.get(
                PluralMetadata.createIdentifier(
                    jsonObject, typeLocationService.getTypePath(jsonObject)));
    if (persistenceAdditions.isEmpty()
        || javaTypePersistenceMetadataDetails == null
        || pluralMetadata == null) {
      return null;
    }

    // Maintain a list of entities that are being tested
    managedEntityTypes.put(jsonObject, metadataIdentificationString);

    return new WebJsonMetadata(
        metadataIdentificationString,
        aspectName,
        governorPhysicalTypeMetadata,
        annotationValues,
        persistenceAdditions,
        javaTypePersistenceMetadataDetails.getIdentifierField(),
        pluralMetadata.getPlural(),
        finderDetails,
        jsonMetadata,
        introduceLayerComponents(governorPhysicalTypeMetadata));
  }