docs: @FFDCIgnore(value = {InvocationTargetException.class, PrivilegedActionException.class })
      public Object createResource(String databaseName, boolean createDatabase, int resAuth, List<? extends ResourceInfo.Property> loginPropertyList) throws Exception {
          final boolean trace = TraceComponent.isAnyTracingEnabled();
          try {
              ComponentMetaData cData = ComponentMetaDataAccessorImpl.getComponentMetaDataAccessor().getComponentMetaData();
              if (cData != null)
                  applications.add(cData.getJ2EEName().getApplication());
              if (trace && tc.isDebugEnabled())
                  Tr.debug(this, tc, cloudantConfigIdentifier + " accessed by " + cData);
  
              AuthData containerAuthData = null;
              if (resAuth == ResourceInfo.AUTH_CONTAINER) {
                  containerAuthData = getContainerAuthData(loginPropertyList);
              }
  
              String userName = containerAuthData == null ? (String) props.get(USERNAME) : containerAuthData.getUserName();
              String password = null;
              if (containerAuthData == null) {
                  SerializableProtectedString protectedPwd = (SerializableProtectedString) props.get(PASSWORD);
                  if (protectedPwd != null) {
                      password = String.valueOf(protectedPwd.getChars());
                      password = PasswordUtil.getCryptoAlgorithm(password) == null ? password : PasswordUtil.decode(password);
                  }
              } else
                  password = String.valueOf(containerAuthData.getPassword());
  
              ClassLoader appClassLoader;
              String appClassLoaderId;
              if (loadFromApp) {
                  if (System.getSecurityManager() == null) {
                      appClassLoader = Thread.currentThread().getContextClassLoader();
                  } else {
                      appClassLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
                          @Override
                          public ClassLoader run() {
                              return Thread.currentThread().getContextClassLoader();
                          }
                      });
                  }
                  if (appClassLoader == null)
                      throw new ClassNotFoundException(Tr.formatMessage(tc, "class.not.found.CWWKD0302E", CLOUDANT_CLIENT_OPTIONS_BUILDER_CLS_STR, cloudantConfigIdentifier));
                  else {
                      appClassLoaderId = classLoaderIdSvc.getClassLoaderIdentifier(appClassLoader);
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                          Tr.debug(this, tc, "classloader identifier", appClassLoaderId, appClassLoader);
                      if (appClassLoaderId == null)
                          throw new ClassNotFoundException(Tr.formatMessage(tc, "class.not.found.CWWKD0302E", CLOUDANT_CLIENT_OPTIONS_BUILDER_CLS_STR, cloudantConfigIdentifier));
                  }
              } else {
                  appClassLoader = null;
                  appClassLoaderId = null;
              }
  
              if (databaseName == null)
                  return createClientBuilder(appClassLoader, userName, password);
  
              final ClientKey key = new ClientKey(appClassLoaderId, userName, password);
              Object client = clients.get(key);
              if (client == null) {
                  final Object builder = createClientBuilder(appClassLoader, userName, password);
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                      Tr.debug(this, tc, "creating Cloudant client with " + builder);
  
                  // Invoke the build method of the builder class to create a CloudantClient.
                  // which is then used to create the cloudant db
                  client = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                      @Override
                      @Trivial
                      public Object run() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
                          Object newClient = builder.getClass().getMethod("build").invoke(builder);
                          Object existingClient = clients.putIfAbsent(key, newClient);
                          if (existingClient == null) {
                              // Not found in map, which means the new instance was added
                              if (key.getApplicationClassLoaderIdentifier() != null)
                                  appListener.register(CloudantService.this, clients); // to avoid leaking the classloader when app stops
                              return newClient;
                          } else {
                              // Found existing instance, so discard and shut down the instance we optimistically created
                              newClient.getClass().getMethod("shutdown").invoke(newClient);
                              return existingClient;
                          }
                      }
                  });
              }
  
              return client.getClass()
                      .getMethod("database", String.class, boolean.class)
                      .invoke(client, databaseName, createDatabase);
          } catch (InvocationTargetException x) {
              Throwable cause = x.getCause();
              FFDCFilter.processException(cause, getClass().getName(), "224", this, new Object[] { createDatabase, databaseName, resAuth, loginPropertyList });
              if (cause instanceof Exception)
                  throw (Exception) cause;
              else if (cause instanceof Error)
                  throw (Error) cause;
              else
                  throw x;
          } catch (PrivilegedActionException x) {
              Throwable cause = x.getCause();
              if (cause instanceof InvocationTargetException)
                  cause = cause.getCause();
              FFDCFilter.processException(cause, getClass().getName(), "228", this, new Object[] { createDatabase, databaseName, resAuth, loginPropertyList });
              if (cause instanceof Exception)
                  throw (Exception) cause;
              else if (cause instanceof Error)
                  throw (Error) cause;
              else
                  throw x;
          } catch (Exception x) {
              // rethrowing the exception allows it to be captured in FFDC
              throw x;
          } catch (Error x) {
              // rethrowing the exception allows it to be captured in FFDC
              throw x;
          }
      }