// Path: src/main/java/sockslib/common/KeyStoreInfo.java
// public class KeyStoreInfo {
// 
//   private String keyStorePath;
//   private String password;
//   private String type = "JKS";
// 
//   public KeyStoreInfo() {
//   }
// 
//   public KeyStoreInfo(String keyStorePath, String password, String type) {
//     this.keyStorePath = checkNotNull(keyStorePath, "Argument [keyStorePath] may not be null");
//     this.password = checkNotNull(password, "Argument [password] may not be null");
//     this.type = checkNotNull(type, "Argument [type] may not be null");
//   }
// 
//   public KeyStoreInfo(String keyStorePath, String password) {
//     this(keyStorePath, password, "JKS");
//   }
// 
//   public String getKeyStorePath() {
//     return keyStorePath;
//   }
// 
//   public KeyStoreInfo setKeyStorePath(String keyStorePath) {
//     this.keyStorePath = checkNotNull(keyStorePath);
//     return this;
//   }
// 
//   public String getPassword() {
//     return password;
//   }
// 
//   public KeyStoreInfo setPassword(String password) {
//     this.password = password;
//     return this;
//   }
// 
//   public String getType() {
//     return type;
//   }
// 
//   public void setType(String type) {
//     this.type = checkNotNull(type);
//   }
// 
//   @Override
//   public String toString() {
//     return "[KEY STORE] PATH:" + keyStorePath + " PASSWORD:" + password + " TYPE:" + type;
//   }
// 
// }


import com.google.common.base.Strings;
import sockslib.common.Credentials;
import sockslib.common.KeyStoreInfo;
import sockslib.common.SSLConfiguration;
import sockslib.common.UsernamePasswordCredentials;
import sockslib.utils.PathUtil;
import java.io.FileNotFoundException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

        case 4:
          host = values[0];
          port = Integer.parseInt(values[1]);
          username = values[2];
          password = values[3];
          if (Strings.isNullOrEmpty(username)) {
            return new Socks5(host, port);
          } else {
            return new Socks5(host, port, new UsernamePasswordCredentials(username, password));
          }

        case 6:
          host = values[0];
          port = Integer.parseInt(values[1]);
          username = values[2];
          password = values[3];
          trustKeyStoreInfo = new KeyStoreInfo(PathUtil.getAbstractPath(values[4]), values[5]);
          configuration = new SSLConfiguration(null, trustKeyStoreInfo);
          socks = new SSLSocks5(new InetSocketAddress(host, port), configuration);
          if (!Strings.isNullOrEmpty(username)) {
            socks.setCredentials(new UsernamePasswordCredentials(username, password));
          }
          return socks;

        case 8:
          host = values[0];
          port = Integer.parseInt(values[1]);
          username = values[2];
          password = values[3];
// Path: src/main/java/sockslib/common/KeyStoreInfo.java
// public class KeyStoreInfo {
// 
//   private String keyStorePath;
//   private String password;
//   private String type = "JKS";
// 
//   public KeyStoreInfo() {
//   }
// 
//   public KeyStoreInfo(String keyStorePath, String password, String type) {
//     this.keyStorePath = checkNotNull(keyStorePath, "Argument [keyStorePath] may not be null");
//     this.password = checkNotNull(password, "Argument [password] may not be null");
//     this.type = checkNotNull(type, "Argument [type] may not be null");
//   }
// 
//   public KeyStoreInfo(String keyStorePath, String password) {
//     this(keyStorePath, password, "JKS");
//   }
// 
//   public String getKeyStorePath() {
//     return keyStorePath;
//   }
// 
//   public KeyStoreInfo setKeyStorePath(String keyStorePath) {
//     this.keyStorePath = checkNotNull(keyStorePath);
//     return this;
//   }
// 
//   public String getPassword() {
//     return password;
//   }
// 
//   public KeyStoreInfo setPassword(String password) {
//     this.password = password;
//     return this;
//   }
// 
//   public String getType() {
//     return type;
//   }
// 
//   public void setType(String type) {
//     this.type = checkNotNull(type);
//   }
// 
//   @Override
//   public String toString() {
//     return "[KEY STORE] PATH:" + keyStorePath + " PASSWORD:" + password + " TYPE:" + type;
//   }
// 
// }


// Path: src/main/java/sockslib/client/SocksProxyFactory.java
import com.google.common.base.Strings;
import sockslib.common.Credentials;
import sockslib.common.KeyStoreInfo;
import sockslib.common.SSLConfiguration;
import sockslib.common.UsernamePasswordCredentials;
import sockslib.utils.PathUtil;
import java.io.FileNotFoundException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;


        case 4:
          host = values[0];
          port = Integer.parseInt(values[1]);
          username = values[2];
          password = values[3];
          if (Strings.isNullOrEmpty(username)) {
            return new Socks5(host, port);
          } else {
            return new Socks5(host, port, new UsernamePasswordCredentials(username, password));
          }

        case 6:
          host = values[0];
          port = Integer.parseInt(values[1]);
          username = values[2];
          password = values[3];
          trustKeyStoreInfo = new KeyStoreInfo(PathUtil.getAbstractPath(values[4]), values[5]);
          configuration = new SSLConfiguration(null, trustKeyStoreInfo);
          socks = new SSLSocks5(new InetSocketAddress(host, port), configuration);
          if (!Strings.isNullOrEmpty(username)) {
            socks.setCredentials(new UsernamePasswordCredentials(username, password));
          }
          return socks;

        case 8:
          host = values[0];
          port = Integer.parseInt(values[1]);
          username = values[2];
          password = values[3];
          trustKeyStoreInfo = new KeyStoreInfo(PathUtil.getAbstractPath(values[4]), values[5]);