private void init(
      AuthenticationService authenticationService,
      WebDavResponseHandler webdavResponseHandler,
      ResourceTypeHelper resourceTypeHelper) {
    initDone = true;
    if (handlerHelper == null) {
      handlerHelper = new HandlerHelper(authenticationService);
      showLog("handlerHelper", handlerHelper);
    }
    if (resourceHandlerHelper == null) {
      resourceHandlerHelper =
          new ResourceHandlerHelper(handlerHelper, urlAdapter, webdavResponseHandler);
      showLog("resourceHandlerHelper", resourceHandlerHelper);
    }

    if (protocols == null) {
      protocols = new ArrayList<HttpExtension>();

      if (matchHelper == null) {
        matchHelper = new MatchHelper(eTagGenerator);
      }
      if (partialGetHelper == null) {
        partialGetHelper = new PartialGetHelper(webdavResponseHandler);
      }

      Http11Protocol http11Protocol =
          new Http11Protocol(
              webdavResponseHandler,
              handlerHelper,
              resourceHandlerHelper,
              enableOptionsAuth,
              matchHelper,
              partialGetHelper);
      protocols.add(http11Protocol);
      if (propertySources == null) {
        propertySources = initDefaultPropertySources(resourceTypeHelper);
        showLog("propertySources", propertySources);
      }
      if (extraPropertySources != null) {
        for (PropertySource ps : extraPropertySources) {
          log.info("Add extra property source: " + ps.getClass());
          propertySources.add(ps);
        }
      }
      if (propPatchSetter == null) {
        propPatchSetter = new PropertySourcePatchSetter(propertySources);
      }
      if (userAgentHelper == null) {
        userAgentHelper = new DefaultUserAgentHelper();
      }

      if (webDavProtocol == null && webdavEnabled) {
        webDavProtocol =
            new WebDavProtocol(
                handlerHelper,
                resourceTypeHelper,
                webdavResponseHandler,
                propertySources,
                quotaDataAccessor,
                propPatchSetter,
                initPropertyAuthoriser(),
                eTagGenerator,
                urlAdapter,
                resourceHandlerHelper,
                userAgentHelper);
      }
      if (webDavProtocol != null) {
        protocols.add(webDavProtocol);
      }

      if (calDavProtocol == null && caldavEnabled) {
        calDavProtocol =
            new CalDavProtocol(
                mainResourceFactory, webdavResponseHandler, handlerHelper, webDavProtocol);
      }
      if (calDavProtocol != null) {
        protocols.add(calDavProtocol);
      }

      if (aclProtocol == null && aclEnabled) {
        aclProtocol = new ACLProtocol(webDavProtocol);
      }
      if (aclProtocol != null) {
        protocols.add(aclProtocol);
      }

      if (cardDavProtocol == null && carddavEnabled) {
        cardDavProtocol =
            new CardDavProtocol(
                mainResourceFactory, webdavResponseHandler, handlerHelper, webDavProtocol);
      }
      if (calDavProtocol != null) {
        protocols.add(cardDavProtocol);
      }
    }

    if (protocolHandlers == null) {
      protocolHandlers = new ProtocolHandlers(protocols);
    }

    if (wellKnownHandlers == null) {
      wellKnownHandlers = new ArrayList<WellKnownResourceFactory.WellKnownHandler>();
      for (HttpExtension p : protocols) {
        if (p instanceof WellKnownResourceFactory.WellKnownHandler) {
          WellKnownResourceFactory.WellKnownHandler wellKnownHandler =
              (WellKnownResourceFactory.WellKnownHandler) p;
          wellKnownHandlers.add(wellKnownHandler);
        }
      }
    }

    // wrap the real (ie main) resource factory to provide well-known support and ajax gateway
    if (outerResourceFactory == null) {
      outerResourceFactory = mainResourceFactory; // in case nothing else enabled
      if (enabledJson) {
        outerResourceFactory =
            new JsonResourceFactory(
                outerResourceFactory,
                eventManager,
                propertySources,
                propPatchSetter,
                initPropertyAuthoriser());
        log.info("Enabled json/ajax gatewayw with: " + outerResourceFactory.getClass());
      }
      if (enableWellKnown) {
        outerResourceFactory =
            new WellKnownResourceFactory(outerResourceFactory, wellKnownHandlers);
        log.info("Enabled well-known protocol support with: " + outerResourceFactory.getClass());
      }
      if (enabledCkBrowser) {
        outerResourceFactory = new FckResourceFactory(outerResourceFactory);
        log.info("Enabled CK Editor support with: " + outerResourceFactory.getClass());
      }
    }
    if (filters != null) {
      filters = new ArrayList<Filter>(filters);
    } else {
      filters = new ArrayList<Filter>();
    }
    filters.add(defaultStandardFilter);
  }
  /**
   * This method creates instances of required objects which have not been set on the builder.
   *
   * <p>These are subsequently wired together immutably in HttpManager when buildHttpManager is
   * called.
   *
   * <p>You can call this before calling buildHttpManager if you would like to modify property
   * values on the created objects before HttpManager is instantiated. Otherwise, you can call
   * buildHttpManager directly and it will call init if it has not been called
   */
  public final void init() {
    if (mainResourceFactory == null) {
      rootDir = new File(System.getProperty("user.home"));
      if (!rootDir.exists() || !rootDir.isDirectory()) {
        throw new RuntimeException("Root directory is not valie: " + rootDir.getAbsolutePath());
      }
      if (securityManager == null) {
        if (mapOfNameAndPasswords == null) {
          mapOfNameAndPasswords = new HashMap<String, String>();
          mapOfNameAndPasswords.put(defaultUser, defaultPassword);
        }
        securityManager = new SimpleSecurityManager(fsRealm, mapOfNameAndPasswords);
      }
      log.info("Using securityManager: " + securityManager.getClass());
      mainResourceFactory = new FileSystemResourceFactory(rootDir, securityManager, fsContextPath);
      log.info("Using file system with root directory: " + rootDir.getAbsolutePath());
    }
    log.info("Using mainResourceFactory: " + mainResourceFactory.getClass());
    if (authenticationService == null) {
      if (authenticationHandlers == null) {
        authenticationHandlers = new ArrayList<AuthenticationHandler>();
        if (basicHandler == null) {
          if (enableBasicAuth) {
            basicHandler = new BasicAuthHandler();
          }
        }
        if (basicHandler != null) {
          authenticationHandlers.add(basicHandler);
        }
        if (digestHandler == null) {
          if (enableDigestAuth) {
            if (nonceProvider == null) {
              if (expiredNonceRemover == null) {
                expiredNonceRemover = new ExpiredNonceRemover(nonces, nonceValiditySeconds);
                showLog("expiredNonceRemover", expiredNonceRemover);
              }
              nonceProvider =
                  new SimpleMemoryNonceProvider(nonceValiditySeconds, expiredNonceRemover, nonces);
              showLog("nonceProvider", nonceProvider);
            }
            digestHandler = new DigestAuthenticationHandler(nonceProvider);
          }
        }
        if (digestHandler != null) {
          authenticationHandlers.add(digestHandler);
        }
        if (formAuthenticationHandler == null) {
          if (enableFormAuth) {
            formAuthenticationHandler = new FormAuthenticationHandler();
          }
        }
        if (formAuthenticationHandler != null) {
          authenticationHandlers.add(formAuthenticationHandler);
        }
        if (cookieAuthenticationHandler == null) {
          if (enableCookieAuth) {
            if (cookieDelegateHandlers == null) {
              // Don't add digest!
              cookieDelegateHandlers = new ArrayList<AuthenticationHandler>();
              if (basicHandler != null) {
                cookieDelegateHandlers.add(basicHandler);
                authenticationHandlers.remove(basicHandler);
              }
              if (formAuthenticationHandler != null) {
                cookieDelegateHandlers.add(formAuthenticationHandler);
                authenticationHandlers.remove(formAuthenticationHandler);
              }
            }
            cookieAuthenticationHandler =
                new CookieAuthenticationHandler(cookieDelegateHandlers, mainResourceFactory);
            authenticationHandlers.add(cookieAuthenticationHandler);
          }
        }
      }
      authenticationService = new AuthenticationService(authenticationHandlers);
      showLog("authenticationService", authenticationService);
    }

    init(authenticationService);
    shutdownHandlers.add(expiredNonceRemover);
    expiredNonceRemover.start();
  }