docs: @Override
      public ServerSocket createServerSocket(int port, int backlog, InetAddress address, String[] params) throws IOException {
          try {
              ServerSocket socket;
              String sslConfigName = null;
              boolean soReuseAddr = true;
              for (int i = 0; i < params.length - 1; i++) {
                  String param = params[i];
                  if ("--sslConfigName".equals(param)) {
                      sslConfigName = params[++i];
                  }
                  if ("--soReuseAddr".equals(param)) {
                      soReuseAddr = Boolean.parseBoolean(params[++i]);
                  }
              }
              OptionsKey options = sslConfig.getAssociationOptions(sslConfigName);
              // if no protection is required, just create a plain socket.
              if ((NoProtection.value & options.requires) == NoProtection.value) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                      Tr.debug(tc, "Created plain server socket for port " + port);
                  socket = new ServerSocket();
              } else {
                  // SSL is required.  Create one from the SSLServerFactory retrieved from the config.  This will
                  // require additional QOS configuration after creation.
                  SSLServerSocketFactory serverSocketFactory = getServerSocketFactory(sslConfigName);
                  SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory.createServerSocket();
                  configureServerSocket(serverSocket, serverSocketFactory, sslConfigName, options);
                  socket = serverSocket;
              }
              // there is a situation that yoko closes and opens a server socket quickly upon updating
              // the configuration, and occasionally, the openSocket is invoked while closeSocket is processing.
              // To avoid the issue, try binding the socket a few times. Since this is the error scenario, 
              // it is less impact for the performance.
              IOException bindError = null;
              for (int i=0; i < 3; i++) {
                  bindError = openSocket(port, backlog, address, socket, soReuseAddr);
                  if (bindError == null) {
                      break;
                  }
                  try {
                      if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                          Tr.debug(tc, "bind error, retry binding... count : " + i);
                      Thread.sleep(500L);
                  } catch (Exception e) {
                      Tr.debug(tc, "An exception is caught while retrying binding. the error message is  " + e.getMessage());
                  }
              }
              if (bindError == null) {
                  // listen port can be different than config port if configed port is '0'
                  int listenPort = socket.getLocalPort();
                  SocketInfo info = new SocketInfo(address, listenPort, options, sslConfigName);
                  socketInfos.add(info);
              } else {
                  Tr.error(tc, "SOCKET_BIND_ERROR", address.getHostName(), port, bindError.getLocalizedMessage());
                  throw bindError;
              }
  
              return socket;
          } catch (SSLException e) {
              throw new IOException("Could not retrieve association options from ssl configuration", e);
          }
      }