docs: @SuppressWarnings("unchecked")
      public static <T> T buildApplicationObject(Class<T> interfaceClass, Class<? extends T> extendedInterfaceClass,
              Class<? extends T> extendedInterfaceWrapperClass,
              Collection<String> classNamesIterator, T defaultObject,FacesConfigurator config)
      {
          T current = defaultObject;
          
  
          for (String implClassName : classNamesIterator)
          {
              Class<? extends T> implClass = ClassUtils.simpleClassForName(implClassName);
  
              // check, if class is of expected interface type
              if (!interfaceClass.isAssignableFrom(implClass))
              {
                  throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName());
              }
  
              if (current == null)
              {
                  // nothing to decorate
                  if (config != null) {
                      // We have a config object so use it to create the objects for CDI 1.2 support
                      try {
                          current = (T) config.injectAndPostConstruct(implClass);
                      } catch (InjectionProviderException ipe) {
                          log.log(Level.SEVERE, ipe.getMessage(), ipe);
                          throw new FacesException(ipe);
                      }
                  } else {
                      current = ClassUtils.newInstance(implClass);
                  }
               }
              else
              {
                  // let's check if class supports the decorator pattern
                  T newCurrent = null;
                  try
                  {
                      Constructor<? extends T> delegationConstructor = null;
                      
                      // first, if there is a extendedInterfaceClass,
                      // try to find a constructor that uses that
                      if (extendedInterfaceClass != null 
                              && extendedInterfaceClass.isAssignableFrom(current.getClass()))
                      {
                          try
                          {
                              delegationConstructor = 
                                      implClass.getConstructor(new Class[] {extendedInterfaceClass});
                          }
                          catch (NoSuchMethodException mnfe)
                          {
                              // just eat it
                          }
                      }
                      if (delegationConstructor == null)
                      {
                          // try to find the constructor with the "normal" interfaceClass
                          delegationConstructor = 
                                  implClass.getConstructor(new Class[] {interfaceClass});
                      }
                      // impl class supports decorator pattern at this point
                      try
                      {
                          // create new decorator wrapping current
                          newCurrent = delegationConstructor.newInstance(new Object[] { current });
                          
                          // Because a specific constructor is being used we do not need to
                          // use CDI to create the object. So add CDI after the instance is created.
                          if (config != null) {
                              config.injectAndPostConstruct(newCurrent);
                          }
                          
                      }
                      catch (InjectionProviderException ipe) 
                      {
                          log.log(Level.SEVERE, ipe.getMessage(), ipe);
                          throw new FacesException(ipe);
                      }    
                      catch (InstantiationException e)
                      {
                          log.log(Level.SEVERE, e.getMessage(), e);
                          throw new FacesException(e);
                      }
                      catch (IllegalAccessException e)
                      {
                          log.log(Level.SEVERE, e.getMessage(), e);
                          throw new FacesException(e);
                      }
                      catch (InvocationTargetException e)
                      {
                          log.log(Level.SEVERE, e.getMessage(), e);
                          throw new FacesException(e);
                      }
                  }
                  catch (NoSuchMethodException e)
                  {
                      // no decorator pattern support
                      if (config != null) {
                          // We have a config object so use it to create the objects for CDI 1.2 support
                          try {
                              newCurrent = (T) config.injectAndPostConstruct(implClass);
                          } catch (InjectionProviderException ipe) {
                              log.log(Level.SEVERE, ipe.getMessage(), ipe);
                              throw new FacesException(ipe);
                          }
                      } else {
                          newCurrent = ClassUtils.newInstance(implClass);
                      }
                  }
                  
                  // now we have a new current object (newCurrent)
                  // --> find out if it is assignable from extendedInterfaceClass
                  // and if not, wrap it in a backwards compatible wrapper (if available)
                  if (extendedInterfaceWrapperClass != null
                          && !extendedInterfaceClass.isAssignableFrom(newCurrent.getClass()))
                  {
                      try
                      {
                          Constructor<? extends T> wrapperConstructor
                                  = extendedInterfaceWrapperClass.getConstructor(
                                          new Class[] {interfaceClass, extendedInterfaceClass});
                          newCurrent = wrapperConstructor.newInstance(new Object[] {newCurrent, current});
                          // Because a specific constructor is being used we do not need to
                          // use CDI to create the object and constructor injection would cause issues.
                          // So add CDI after the instance is created.
                          if (config != null) {
                              config.injectAndPostConstruct(newCurrent);
                          }
                      }
                      catch (InjectionProviderException ipe) 
                      {
                          log.log(Level.SEVERE, ipe.getMessage(), ipe);
                          throw new FacesException(ipe);
                      }    
                      catch (NoSuchMethodException e)
                      {
                          log.log(Level.SEVERE, e.getMessage(), e);
                          throw new FacesException(e);
                      }
                      catch (InstantiationException e)
                      {
                          log.log(Level.SEVERE, e.getMessage(), e);
                          throw new FacesException(e);
                      }
                      catch (IllegalAccessException e)
                      {
                          log.log(Level.SEVERE, e.getMessage(), e);
                          throw new FacesException(e);
                      }
                      catch (InvocationTargetException e)
                      {
                          log.log(Level.SEVERE, e.getMessage(), e);
                          throw new FacesException(e);
                      }
                  }
                  
                  current = newCurrent;
              }
          }
  
          return current;
      }