/** This initalizes the map based on mime type and suffix. */
  private void initializeSuffixAndMimeBasedMaps() {
    for (MetaMetadata metaMetadata : repositoryByTagName) {
      metaMetadata.inheritMetaMetadata(this);
      Class<? extends Metadata> metadataClass = metaMetadata.getMetadataClass(metadataTScope);
      if (metadataClass == null) {
        error(metaMetadata + "\tCan't resolve in TranslationScope " + metadataTScope);
        continue;
      }

      ArrayList<String> suffixes = metaMetadata.getSuffixes();
      if (suffixes != null) {
        for (String suffix : suffixes) {
          // FIXME-- Ask whether the suffix and mime should be inherited or not
          if (!repositoryBySuffix.containsKey(suffix)) repositoryBySuffix.put(suffix, metaMetadata);
        }
      }

      ArrayList<String> mimeTypes = metaMetadata.getMimeTypes();
      if (mimeTypes != null) {
        for (String mimeType : mimeTypes) {
          // FIXME -- Ask whether the suffix and mime should be inherited or not
          if (!repositoryByMime.containsKey(mimeType)) repositoryByMime.put(mimeType, metaMetadata);
        }
      }
    }
  }
 /**
  * Look-up MetaMetadata for this purl. If there is no special MetaMetadata, use Image. Construct
  * Metadata of the correct subtype, base on the MetaMetadata.
  *
  * @param purl
  * @return A Metadata object, either of type Image, or a subclass. Never null!
  */
 public Media constructImage(ParsedURL purl) {
   MetaMetadata metaMetadata = getImageMM(purl);
   Media result = null;
   if (metaMetadata != null) {
     result = (Media) metaMetadata.constructMetadata(metadataTScope);
   }
   return result;
 }
  /**
   * Combines the HashMaps and HashMapStates of the parameter repository to this repository.
   *
   * @param repository
   * @return
   */
  public void joinRepository(MetaMetadataRepository repository) {
    // combine userAgents
    if (!combineMapStates(repository.userAgents, this.userAgents))
      this.userAgents = repository.userAgents;

    // combine searchEngines
    if (!combineMapStates(repository.searchEngines, this.searchEngines))
      this.searchEngines = repository.searchEngines;

    // combine namedStyles
    if (!combineMapStates(repository.namedStyles, this.namedStyles))
      this.namedStyles = repository.namedStyles;

    // set metaMetadata to have the correct parent repository
    for (MetaMetadata metametadata : repository.repositoryByTagName) metametadata.setParent(this);

    // combine metaMetadata
    if (!combineMaps(repository.repositoryByTagName, this.repositoryByTagName))
      this.repositoryByTagName = repository.repositoryByTagName;
  }
  /**
   * Initializes HashMaps for MetaMetadata selectors by URL or pattern. Uses the Media and Document
   * base classes to ensure that maps are only filled with appropriate matching MetaMetadata.
   */
  private void initializeLocationBasedMaps() {
    // 1st pass -- resolve nested and collection types as needed -- fill in all child metadata
    // fields
    /*
     * for (MetaMetadata metaMetadata : repositoryByTagName) { metaMetadata.bindNonScalarChildren();
     * }
     */

    for (MetaMetadata metaMetadata : repositoryByTagName) {
      metaMetadata.inheritMetaMetadata(this);
      Class<? extends Metadata> metadataClass = metaMetadata.getMetadataClass(metadataTScope);
      if (metadataClass == null) {
        error(metaMetadata + "\tCan't resolve in TranslationScope " + metadataTScope);
        continue;
      }

      HashMap<String, MetaMetadata> repositoryByPURL;
      HashMap<String, ArrayList<RepositoryPatternEntry>> repositoryByPattern;

      if (Media.class.isAssignableFrom(metadataClass)) {
        repositoryByPURL = mediaRepositoryByURL;
        repositoryByPattern = mediaRepositoryByPattern;
      } else if (Document.class.isAssignableFrom(metadataClass)) {
        repositoryByPURL = documentRepositoryByURL;
        repositoryByPattern = documentRepositoryByPattern;
      } else continue;

      ParsedURL purl = metaMetadata.getUrlBase();
      if (purl != null) repositoryByPURL.put(purl.noAnchorNoQueryPageString(), metaMetadata);
      else {
        ParsedURL urlPrefix = metaMetadata.getUrlPrefix();
        if (urlPrefix != null) {
          urlprefixCollection.add(urlPrefix);
          repositoryByPURL.put(urlPrefix.toString(), metaMetadata);
        } else {
          String domain = metaMetadata.getDomain();
          Pattern urlPattern = metaMetadata.getUrlRegex();
          if (domain != null && urlPattern != null) {
            ArrayList<RepositoryPatternEntry> bucket = repositoryByPattern.get(domain);
            if (bucket == null) {
              bucket = new ArrayList<RepositoryPatternEntry>(2);
              repositoryByPattern.put(domain, bucket);
            }
            bucket.add(new RepositoryPatternEntry(urlPattern, metaMetadata));
          }
        }
      }
    }
  }
 /**
  * Look-up MetaMetadata for this purl. If there is no special MetaMetadata, use Document.
  * Construct Metadata of the correct subtype, base on the MetaMetadata. Set its location field to
  * purl.
  *
  * @param purl
  * @return
  */
 public Document constructDocument(ParsedURL purl) {
   MetaMetadata metaMetadata = getDocumentMM(purl);
   Document result = (Document) metaMetadata.constructMetadata(metadataTScope);
   result.setLocation(purl);
   return result;
 }