gt:                 props = getGlobalLoginFormProps();
context: /*******************************************************************************
   * Copyright (c) 2017, 2018 IBM Corporation and others.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *     IBM Corporation - initial API and implementation
   *******************************************************************************/
  package com.ibm.ws.security.javaeesec.cdi.extensions;
  
  import java.lang.annotation.Annotation;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.lang.reflect.Type;
  import java.net.URL;
  import java.security.AccessController;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Properties;
  import java.util.Set;
  
  import javax.enterprise.event.Observes;
  import javax.enterprise.inject.spi.AfterBeanDiscovery;
  import javax.enterprise.inject.spi.AnnotatedType;
  import javax.enterprise.inject.spi.Bean;
  import javax.enterprise.inject.spi.BeanManager;
  import javax.enterprise.inject.spi.BeforeBeanDiscovery;
  import javax.enterprise.inject.spi.DeploymentException;
  import javax.enterprise.inject.spi.Extension;
  import javax.enterprise.inject.spi.ProcessAnnotatedType;
  import javax.enterprise.inject.spi.ProcessBean;
  import javax.enterprise.inject.spi.ProcessBeanAttributes;
  import javax.enterprise.inject.spi.WithAnnotations;
  import javax.security.enterprise.authentication.mechanism.http.AutoApplySession;
  import javax.security.enterprise.authentication.mechanism.http.BasicAuthenticationMechanismDefinition;
  import javax.security.enterprise.authentication.mechanism.http.CustomFormAuthenticationMechanismDefinition;
  import javax.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition;
  import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
  import javax.security.enterprise.authentication.mechanism.http.LoginToContinue;
  import javax.security.enterprise.authentication.mechanism.http.RememberMe;
  import javax.security.enterprise.identitystore.DatabaseIdentityStoreDefinition;
  import javax.security.enterprise.identitystore.IdentityStore;
  import javax.security.enterprise.identitystore.IdentityStore.ValidationType;
  import javax.security.enterprise.identitystore.IdentityStoreHandler;
  import javax.security.enterprise.identitystore.LdapIdentityStoreDefinition;
  import javax.security.enterprise.identitystore.PasswordHash;
  import javax.security.enterprise.identitystore.Pbkdf2PasswordHash;
  
  import org.osgi.service.component.annotations.Component;
  
  import com.ibm.websphere.csi.J2EEName;
  import com.ibm.websphere.ras.Tr;
  import com.ibm.websphere.ras.TraceComponent;
  import com.ibm.websphere.ras.annotation.Sensitive;
  import com.ibm.ws.cdi.extension.WebSphereCDIExtension;
  import com.ibm.ws.runtime.metadata.ModuleMetaData;
  import com.ibm.ws.security.javaeesec.JavaEESecConstants;
  import com.ibm.ws.security.javaeesec.cdi.beans.BasicHttpAuthenticationMechanism;
  import com.ibm.ws.security.javaeesec.cdi.beans.CustomFormAuthenticationMechanism;
  import com.ibm.ws.security.javaeesec.cdi.beans.FormAuthenticationMechanism;
  import com.ibm.ws.security.javaeesec.properties.ModuleProperties;
  import com.ibm.ws.security.javaeesec.ApplicationUtils;
  import com.ibm.ws.threadContext.ModuleMetaDataAccessorImpl;
  import com.ibm.ws.webcontainer.security.WebAppSecurityConfig;
  import com.ibm.ws.webcontainer.security.metadata.LoginConfiguration;
  import com.ibm.ws.webcontainer.security.metadata.SecurityMetadata;
  import com.ibm.ws.webcontainer.security.util.WebConfigUtils;
  import com.ibm.wsspi.webcontainer.metadata.WebModuleMetaData;
  
  /**
   * TODO: Add all JSR-375 API classes that can be bean types to api.classes.
   *
   * @param <T>
   */
  @Component(service = { WebSphereCDIExtension.class },
             property = { "api.classes=javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;javax.security.enterprise.identitystore.IdentityStore;javax.security.enterprise.identitystore.IdentityStoreHandler;javax.security.enterprise.identitystore.RememberMeIdentityStore;javax.security.enterprise.SecurityContext;com.ibm.ws.security.javaeesec.properties.ModulePropertiesProvider",
                          "bean.defining.annotations=javax.security.enterprise.authentication.mechanism.http.BasicAuthenticationMechanismDefinition;javax.security.enterprise.authentication.mechanism.http.CustomFormAuthenticationMechanismDefinition;javax.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition;javax.security.enterprise.authentication.mechanism.http.LoginToContinue;javax.security.enterprise.identitystore.DatabaseIdentityStoreDefinition;javax.security.enterprise.identitystore.LdapIdentityStoreDefinition" },
             immediate = true)
  public class JavaEESecCDIExtension<T> implements Extension, WebSphereCDIExtension {
  
      private static final TraceComponent tc = Tr.register(JavaEESecCDIExtension.class);
  
      // TODO: Track beans by annotated type
      private final Set<Bean> beansToAdd = new HashSet<Bean>();
      private boolean identityStoreHandlerRegistered = false;
      private boolean identityStoreRegistered = false;
      private final Map<String, ModuleProperties> moduleMap = new HashMap<String, ModuleProperties>(); // map of module name and list of authmechs.
      private final List<LdapIdentityStoreDefinition> ldapDefinitionList = new ArrayList<LdapIdentityStoreDefinition>();
      private final List<DatabaseIdentityStoreDefinition> databaseDefinitionList = new ArrayList<DatabaseIdentityStoreDefinition>();
  
      public void processApplicationHAMClass(@Observes ProcessAnnotatedType<? extends HttpAuthenticationMechanism> processAnnotatedType, BeanManager beanManager) {
          processAnnotatedType(processAnnotatedType, beanManager);
      }
  
      public <T> void processAnnotatedHAMandIS(@Observes @WithAnnotations({BasicAuthenticationMechanismDefinition.class, FormAuthenticationMechanismDefinition.class, CustomFormAuthenticationMechanismDefinition.class, LdapIdentityStoreDefinition.class, DatabaseIdentityStoreDefinition.class, LoginToContinue.class}) ProcessAnnotatedType<T> processAnnotatedType, BeanManager beanManager) {
          processAnnotatedType(processAnnotatedType, beanManager);
      }
  
      public <T> void processAnnotatedType(ProcessAnnotatedType<T> processAnnotatedType, BeanManager beanManager) {
          if (tc.isDebugEnabled())
              Tr.debug(tc, "processAnnotatedType : instance : " + Integer.toHexString(this.hashCode()) + " BeanManager : " + Integer.toHexString(beanManager.hashCode()));
          AnnotatedType<T> annotatedType = processAnnotatedType.getAnnotatedType();
  
          if (tc.isDebugEnabled())
              Tr.debug(tc, "processAnnotatedType : annotation : " + annotatedType);
  
          Class<?> javaClass = annotatedType.getJavaClass();
          boolean isAuthMechOverridden = isAuthMechOverridden();
          if (isApplicationAuthMech(javaClass)) {
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "Found an application specific HttpAuthenticationMechanism : " + javaClass);
              }
              if (isAuthMechOverridden) {
                  createModulePropertiesProviderBeanForGlobalLogin(beanManager, javaClass);
              } else {
                  Annotation ltc = annotatedType.getAnnotation(LoginToContinue.class);
                  createModulePropertiesProviderBeanForApplicationAuthMechToAdd(beanManager, ltc, javaClass);
              }
          }
          //look at the class level annotations
          Set<Annotation> annotations = annotatedType.getAnnotations();
          for (Annotation annotation : annotations) {
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "Annotations found: " + annotation);
                  Tr.debug(tc, "Annotation class: ", annotation.getClass());
              }
  
              // TODO: If I see my annotations, create beans by type. Add more bean types.
              Class<? extends Annotation> annotationType = annotation.annotationType();
              if (BasicAuthenticationMechanismDefinition.class.equals(annotationType)) {
                  if (isAuthMechOverridden) {
                      createModulePropertiesProviderBeanForGlobalLogin(beanManager, javaClass);
                  } else {
                      createModulePropertiesProviderBeanForBasicToAdd(beanManager, annotation, annotationType, javaClass);
                  }
              } else if (FormAuthenticationMechanismDefinition.class.equals(annotationType) || CustomFormAuthenticationMechanismDefinition.class.equals(annotationType)) {
                  if (isAuthMechOverridden) {
                      createModulePropertiesProviderBeanForGlobalLogin(beanManager, javaClass);
                  } else {
                      createModulePropertiesProviderBeanForFormToAdd(beanManager, annotation, annotationType, javaClass);
                  }
              } else if (LdapIdentityStoreDefinition.class.equals(annotationType)) {
                  createLdapIdentityStoreBeanToAdd(beanManager, annotation, annotationType);
                  identityStoreRegistered = true;
              } else if (DatabaseIdentityStoreDefinition.class.equals(annotationType)) {
                  createDatabaseIdentityStoreBeanToAdd(beanManager, annotation, annotationType);
                  identityStoreRegistered = true;
              }
          }
      }
  
      public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) {
          AnnotatedType<SecurityContextProducer> securityContextProducerType = beanManager.createAnnotatedType(SecurityContextProducer.class);
          beforeBeanDiscovery.addAnnotatedType(securityContextProducerType, SecurityContextProducer.class.getName() + ":" + getClass().getClassLoader().hashCode());
          AnnotatedType<AutoApplySessionInterceptor> autoApplySessionInterceptorType = beanManager.createAnnotatedType(AutoApplySessionInterceptor.class);
          beforeBeanDiscovery.addAnnotatedType(autoApplySessionInterceptorType, AutoApplySessionInterceptor.class.getName() + ":" + getClass().getClassLoader().hashCode());
          AnnotatedType<RememberMeInterceptor> rememberMeInterceptorInterceptorType = beanManager.createAnnotatedType(RememberMeInterceptor.class);
          beforeBeanDiscovery.addAnnotatedType(rememberMeInterceptorInterceptorType, RememberMeInterceptor.class.getName() + ":" + getClass().getClassLoader().hashCode());
      }
  
      public <T> void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {
          if (tc.isDebugEnabled())
              Tr.debug(tc, "afterBeanDiscovery : instance : " + Integer.toHexString(this.hashCode()) + " BeanManager : " + Integer.toHexString(beanManager.hashCode()));
          try {
              verifyConfiguration();
              if (!identityStoreHandlerRegistered) {
                  beansToAdd.add(new IdentityStoreHandlerBean(beanManager));
                  if (tc.isDebugEnabled())
                      Tr.debug(tc, "registering the default IdentityStoreHandler.");
              } else {
                  if (tc.isDebugEnabled())
                      Tr.debug(tc, "IdentityStoreHandler is not registered because a custom IdentityStoreHandler has been registered,");
              }
          } catch (DeploymentException de) {
              afterBeanDiscovery.addDefinitionError(de);
          }
          if (!isEmptyModuleMap()) {
              // this is a JSR375 app.
              ModulePropertiesProviderBean bean = new ModulePropertiesProviderBean(beanManager, moduleMap);
              beansToAdd.add(bean);
              // register the application name for recycle the apps.
              ApplicationUtils.registerApplication(getApplicationName());
          }
  
          // TODO: Validate beans to add.
          for (Bean bean : beansToAdd) {
              afterBeanDiscovery.addBean(bean);
          }
      }
  
      public void processBean(@Observes ProcessBean<?> processBean, BeanManager beanManager) {
          if (tc.isDebugEnabled())
              Tr.debug(tc, "processBean : instance : " + Integer.toHexString(this.hashCode()) + " BeanManager : " + Integer.toHexString(beanManager.hashCode()));
          if (!identityStoreHandlerRegistered) {
              if (isIdentityStoreHandler(processBean)) {
                  identityStoreHandlerRegistered = true;
              }
          }
          if (!identityStoreRegistered) {
              if (isIdentityStore(processBean)) {
                  identityStoreRegistered = true;
              }
          }
      }
  
      public void processBasicHttpAuthMechNeeded(@Observes ProcessBeanAttributes<BasicHttpAuthenticationMechanism> processBeanAttributes, BeanManager beanManager) {
          if (!existAuthMech(BasicHttpAuthenticationMechanism.class)) {
              processBeanAttributes.veto();
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "BasicHttpAuthenticationMechanism is disabled since another HttpAuthorizationMechanism is registered.");
              }
          }
      }
  
      public void processFormAuthMechNeeded(@Observes ProcessBeanAttributes<FormAuthenticationMechanism> processBeanAttributes, BeanManager beanManager) {
          if (!existAuthMech(FormAuthenticationMechanism.class)) {
              processBeanAttributes.veto();
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "FormAuthenticationMechanism is disabled since another HttpAuthorizationMechanism is registered.");
              }
          }
      }
  
      public void processCustomFormAuthMechNeeded(@Observes ProcessBeanAttributes<CustomFormAuthenticationMechanism>  processBeanAttributes, BeanManager beanManager) {
          if (!existAuthMech(CustomFormAuthenticationMechanism.class)) {
              processBeanAttributes.veto();
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "CustomFormAuthenticationMechanism is disabled since another HttpAuthorizationMechanism is registered.");
              }
          }
      }
  
      /**
       * @param <T>
       * @param beanManager
       * @param annotation
       * @param annotationType
       */
      private <T> void createModulePropertiesProviderBeanForFormToAdd(BeanManager beanManager, Annotation annotation, Class<? extends Annotation> annotationType,
                                                                      Class<?> annotatedClass) {
          try {
              Method loginToContinueMethod = annotationType.getMethod("loginToContinue");
              Annotation ltcAnnotation = (Annotation) loginToContinueMethod.invoke(annotation);
              Properties props = parseLoginToContinue(ltcAnnotation);
              Class<?> implClass;
              if (FormAuthenticationMechanismDefinition.class.equals(annotationType)) {
                  implClass = FormAuthenticationMechanism.class;
              } else {
                  implClass = CustomFormAuthenticationMechanism.class;
              }
              addAuthMech(annotatedClass, implClass, props);
          } catch (Exception e) {
              // TODO Auto-generated catch block
              // Do you need FFDC here? Remember FFDC instrumentation and @FFDCIgnore
              e.printStackTrace();
          }
      }
  
      /**
       * @param beanManager
       * @param annotation
       * @param annotationType
       */
      private void createModulePropertiesProviderBeanForBasicToAdd(BeanManager beanManager, Annotation annotation, Class<? extends Annotation> annotationType, Class annotatedClass) {
          try {
              Method realmNameMethod = annotationType.getMethod("realmName");
              String realmName = (String) realmNameMethod.invoke(annotation);
              Properties props = new Properties();
              props.put(JavaEESecConstants.REALM_NAME, realmName);
              addAuthMech(annotatedClass, BasicHttpAuthenticationMechanism.class, props);
          } catch (Exception e) {
              // TODO Auto-generated catch block
              // Do you need FFDC here? Remember FFDC instrumentation and @FFDCIgnore
              e.printStackTrace();
          }
      }
  
      /**
       * @param beanManager
       * @param ltc LoginToContinue annotation if it exists.
       * @param implClass the implementation class
       */
      @SuppressWarnings("rawtypes")
      private void createModulePropertiesProviderBeanForApplicationAuthMechToAdd(BeanManager beanManager, Annotation ltc, Class implClass) {
          Properties props = null;
          if (ltc != null) {
              try {
                  props = parseLoginToContinue(ltc);
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  // Do you need FFDC here? Remember FFDC instrumentation and @FFDCIgnore
                  e.printStackTrace();
              }
          }
          addAuthMech(implClass, implClass, props);
      }
  
      /**
       * @param beanManager
       */
      private void createModulePropertiesProviderBeanForGlobalLogin(BeanManager beanManager, Class annotatedClass) {
          try {
              Properties props;
              Class implClass;
  
              if (isAuthMechOverriddenByForm()) {
  