/**
   * Initialize all persistence units found on initializationClassLoader. Initialization is a two
   * phase process. First the predeploy process builds the metadata and creates any required
   * transformers. Second the deploy process creates an EclipseLink session based on that metadata.
   */
  protected void initPersistenceUnits(Archive archive, Map m) {
    Iterator<SEPersistenceUnitInfo> persistenceUnits =
        PersistenceUnitProcessor.getPersistenceUnits(archive, initializationClassloader).iterator();
    while (persistenceUnits.hasNext()) {
      SEPersistenceUnitInfo persistenceUnitInfo = persistenceUnits.next();
      if (isPersistenceProviderSupported(persistenceUnitInfo.getPersistenceProviderClassName())) {
        // puName uniquely defines the pu on a class loader
        String puName = persistenceUnitInfo.getPersistenceUnitName();

        // don't add puInfo that could not be used standalone (only as composite member).
        if (EntityManagerSetupImpl.mustBeCompositeMember(persistenceUnitInfo)) {
          continue;
        }

        // If puName is already in the map then there are two jars containing persistence units with
        // the same name.
        // Because both are loaded from the same classloader there is no way to distinguish between
        // them - throw exception.
        EntityManagerSetupImpl anotherEmSetupImpl = null;
        if (initialEmSetupImpls != null) {
          anotherEmSetupImpl = this.initialEmSetupImpls.get(puName);
        }
        if (anotherEmSetupImpl != null) {
          EntityManagerSetupImpl.throwPersistenceUnitNameAlreadyInUseException(
              puName, persistenceUnitInfo, anotherEmSetupImpl.getPersistenceUnitInfo());
        }

        // Note that session name is extracted only from puInfo, the passed properties ignored.
        String sessionName =
            EntityManagerSetupImpl.getOrBuildSessionName(
                Collections.emptyMap(), persistenceUnitInfo, puName);
        EntityManagerSetupImpl emSetupImpl =
            callPredeploy(persistenceUnitInfo, m, puName, sessionName);
        if (initialEmSetupImpls != null) {
          this.initialEmSetupImpls.put(puName, emSetupImpl);
        }
        if (initialPuInfos != null) {
          this.initialPuInfos.put(puName, persistenceUnitInfo);
        }
      }
    }
  }
  /**
   * predeploy (with deploy) is one of the two steps required in deployment of entities This method
   * will prepare to call predeploy, call it and finally register the transformer returned to be
   * used for weaving.
   */
  public EntityManagerSetupImpl callPredeploy(
      SEPersistenceUnitInfo persistenceUnitInfo,
      Map m,
      String persistenceUnitUniqueName,
      String sessionName) {
    AbstractSessionLog.getLog()
        .log(
            SessionLog.FINER,
            "cmp_init_invoke_predeploy",
            persistenceUnitInfo.getPersistenceUnitName());
    Map mergedProperties =
        EntityManagerFactoryProvider.mergeMaps(m, persistenceUnitInfo.getProperties());
    // Bug#4452468  When globalInstrumentation is null, there is no weaving
    checkWeaving(mergedProperties);

    Set tempLoaderSet = PersistenceUnitProcessor.buildClassSet(persistenceUnitInfo, m);
    // Create the temp loader that will not cache classes for entities in our persistence unit
    ClassLoader tempLoader = createTempLoader(tempLoaderSet);
    persistenceUnitInfo.setNewTempClassLoader(tempLoader);

    EntityManagerSetupImpl emSetupImpl =
        new EntityManagerSetupImpl(persistenceUnitUniqueName, sessionName);

    // A call to predeploy will partially build the session we will use
    final ClassTransformer transformer =
        emSetupImpl.predeploy(persistenceUnitInfo, mergedProperties);

    // After preDeploy it's impossible to weave again - so may substitute the temporary classloader
    // with the real one.
    // The temporary classloader could be garbage collected even if the puInfo is cached for the
    // future use by other emSetupImpls.
    persistenceUnitInfo.setNewTempClassLoader(persistenceUnitInfo.getClassLoader());

    registerTransformer(transformer, persistenceUnitInfo, m);
    return emSetupImpl;
  }