@Override
  protected OpenFuture doInit(Buffer buffer) {
    OpenFuture f = new DefaultOpenFuture(this);
    try {
      out =
          new ChannelOutputStream(
              this, getRemoteWindow(), log, SshConstants.SSH_MSG_CHANNEL_DATA, true);
      authSocket = PropertyResolverUtils.getString(this, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
      pool = Pool.create(AprLibrary.getInstance().getRootPool());
      handle = Local.create(authSocket, pool);
      int result = Local.connect(handle, 0);
      if (result != Status.APR_SUCCESS) {
        throwException(result);
      }

      ExecutorService service = getExecutorService();
      forwardService =
          (service == null)
              ? ThreadUtils.newSingleThreadExecutor("ChannelAgentForwarding[" + authSocket + "]")
              : service;
      shutdownForwarder = service != forwardService || isShutdownOnExit();

      final int copyBufSize =
          PropertyResolverUtils.getIntProperty(
              this, FORWARDER_BUFFER_SIZE, DEFAULT_FORWARDER_BUF_SIZE);
      ValidateUtils.checkTrue(
          copyBufSize >= MIN_FORWARDER_BUF_SIZE, "Copy buf size below min.: %d", copyBufSize);
      ValidateUtils.checkTrue(
          copyBufSize <= MAX_FORWARDER_BUF_SIZE, "Copy buf size above max.: %d", copyBufSize);

      forwarder =
          forwardService.submit(
              () -> {
                try {
                  byte[] buf = new byte[copyBufSize];
                  while (true) {
                    int len = Socket.recv(handle, buf, 0, buf.length);
                    if (len > 0) {
                      out.write(buf, 0, len);
                      out.flush();
                    }
                  }
                } catch (IOException e) {
                  close(true);
                }
              });

      signalChannelOpenSuccess();
      f.setOpened();
    } catch (Throwable t) {
      Throwable e = GenericUtils.peelException(t);
      signalChannelOpenFailure(e);
      f.setException(e);
    }

    return f;
  }
  protected void checkConfig() {
    ValidateUtils.checkNotNullAndNotEmpty(
        getKeyExchangeFactories(), "KeyExchangeFactories not set");

    if (getScheduledExecutorService() == null) {
      setScheduledExecutorService(
          ThreadUtils.newSingleThreadScheduledExecutor(this.toString() + "-timer"), true);
    }

    ValidateUtils.checkNotNullAndNotEmpty(getCipherFactories(), "CipherFactories not set");
    ValidateUtils.checkNotNullAndNotEmpty(
        getCompressionFactories(), "CompressionFactories not set");
    ValidateUtils.checkNotNullAndNotEmpty(getMacFactories(), "MacFactories not set");

    ValidateUtils.checkNotNull(getRandomFactory(), "RandomFactory not set");

    if (getIoServiceFactoryFactory() == null) {
      setIoServiceFactoryFactory(new DefaultIoServiceFactoryFactory());
    }
  }
 static Provider createProviderInstance(Class<?> anchor, String providerClassName)
     throws ReflectiveOperationException {
   return ThreadUtils.createDefaultInstance(anchor, Provider.class, providerClassName);
 }