protected void configureSubProtocol(
      final ServiceLocator habitat,
      final NetworkListener networkListener,
      final Protocol protocol,
      final FilterChainBuilder filterChainBuilder) {

    if (protocol.getHttp() != null) {
      final Http http = protocol.getHttp();
      configureHttpProtocol(
          habitat,
          networkListener,
          http,
          filterChainBuilder,
          Boolean.valueOf(protocol.getSecurityEnabled()));

    } else if (protocol.getPortUnification() != null) {
      // Port unification
      final PortUnification pu = protocol.getPortUnification();
      final String puFilterClassname = pu.getClassname();
      PUFilter puFilter = null;
      if (puFilterClassname != null) {
        try {
          puFilter =
              Utils.newInstance(habitat, PUFilter.class, puFilterClassname, puFilterClassname);
          configureElement(habitat, networkListener, pu, puFilter);
        } catch (Exception e) {
          LOGGER.log(
              Level.WARNING,
              "Can not initialize port unification filter: "
                  + puFilterClassname
                  + " default filter will be used instead",
              e);
        }
      }
      if (puFilter == null) {
        puFilter = new PUFilter();
      }
      List<org.glassfish.grizzly.config.dom.ProtocolFinder> findersConfig = pu.getProtocolFinder();
      for (org.glassfish.grizzly.config.dom.ProtocolFinder finderConfig : findersConfig) {
        final String finderClassname = finderConfig.getClassname();
        try {
          final ProtocolFinder protocolFinder =
              Utils.newInstance(habitat, ProtocolFinder.class, finderClassname, finderClassname);
          configureElement(habitat, networkListener, finderConfig, protocolFinder);
          final Protocol subProtocol = finderConfig.findProtocol();
          final FilterChainBuilder subProtocolFilterChainBuilder =
              puFilter.getPUFilterChainBuilder();
          // If subprotocol is secured - we need to wrap it under SSLProtocolFinder
          if (Boolean.valueOf(subProtocol.getSecurityEnabled())) {
            final PUFilter extraSslPUFilter = new PUFilter();

            final Filter addedSSLFilter =
                configureSsl(habitat, getSsl(subProtocol), subProtocolFilterChainBuilder);

            subProtocolFilterChainBuilder.add(extraSslPUFilter);
            final FilterChainBuilder extraSslPUFilterChainBuilder =
                extraSslPUFilter.getPUFilterChainBuilder();

            try {
              // temporary add SSL Filter, so subprotocol
              // will see it
              extraSslPUFilterChainBuilder.add(addedSSLFilter);
              configureSubProtocol(
                  habitat, networkListener, subProtocol, extraSslPUFilterChainBuilder);
            } finally {
              // remove SSL Filter
              extraSslPUFilterChainBuilder.remove(addedSSLFilter);
            }

            extraSslPUFilter.register(protocolFinder, extraSslPUFilterChainBuilder.build());

            puFilter.register(
                new SSLProtocolFinder(new SSLConfigurator(habitat, subProtocol.getSsl())),
                subProtocolFilterChainBuilder.build());
          } else {
            configureSubProtocol(
                habitat, networkListener, subProtocol, subProtocolFilterChainBuilder);
            puFilter.register(protocolFinder, subProtocolFilterChainBuilder.build());
          }
        } catch (Exception e) {
          LOGGER.log(
              Level.WARNING, "Can not initialize sub protocol. Finder: " + finderClassname, e);
        }
      }
      filterChainBuilder.add(puFilter);
    } else if (protocol.getHttpRedirect() != null) {
      filterChainBuilder.add(createHttpServerCodecFilter());
      final HttpRedirectFilter filter = new HttpRedirectFilter();
      filter.configure(habitat, networkListener, protocol.getHttpRedirect());
      filterChainBuilder.add(filter);
    } else {
      ProtocolChainInstanceHandler pcihConfig = protocol.getProtocolChainInstanceHandler();
      if (pcihConfig == null) {
        LOGGER.log(Level.WARNING, "Empty protocol declaration");
        return;
      }
      ProtocolChain filterChainConfig = pcihConfig.getProtocolChain();
      for (ProtocolFilter filterConfig : filterChainConfig.getProtocolFilter()) {
        final String filterClassname = filterConfig.getClassname();
        try {
          final Filter filter = loadFilter(habitat, filterConfig.getName(), filterClassname);
          configureElement(habitat, networkListener, filterConfig, filter);
          filterChainBuilder.add(filter);
        } catch (Exception e) {
          LOGGER.log(Level.WARNING, "Can not initialize protocol filter: " + filterClassname, e);
          throw new IllegalStateException("Can not initialize protocol filter: " + filterClassname);
        }
      }
    }
  }