@Override
    public void init(String keyspace) {
      Iterator<InetAddress> hostiter = hosts.iterator();
      while (hostiter.hasNext()) {
        try {
          // Query endpoint to ranges map and schemas from thrift
          InetAddress host = hostiter.next();
          Cassandra.Client client =
              createThriftClient(
                  host.getHostAddress(), rpcPort, this.user, this.passwd, this.transportFactory);

          setPartitioner(client.describe_partitioner());
          Token.TokenFactory tkFactory = getPartitioner().getTokenFactory();

          for (TokenRange tr : client.describe_ring(keyspace)) {
            Range<Token> range =
                new Range<>(
                    tkFactory.fromString(tr.start_token),
                    tkFactory.fromString(tr.end_token),
                    getPartitioner());
            for (String ep : tr.endpoints) {
              addRangeForEndpoint(range, InetAddress.getByName(ep));
            }
          }

          String query =
              String.format(
                  "SELECT * FROM %s.%s WHERE keyspace_name = '%s'",
                  Keyspace.SYSTEM_KS, SystemKeyspace.SCHEMA_COLUMNFAMILIES_CF, keyspace);
          CqlResult result =
              client.execute_cql3_query(
                  ByteBufferUtil.bytes(query), Compression.NONE, ConsistencyLevel.ONE);
          for (CqlRow row : result.rows) {
            CFMetaData metadata = CFMetaData.fromThriftCqlRow(row);
            knownCfs.put(metadata.cfName, metadata);
          }
          break;
        } catch (Exception e) {
          if (!hostiter.hasNext())
            throw new RuntimeException("Could not retrieve endpoint ranges: ", e);
        }
      }
    }
    public static LoaderOptions parseArgs(String cmdArgs[]) {
      CommandLineParser parser = new GnuParser();
      CmdLineOptions options = getCmdLineOptions();
      try {
        CommandLine cmd = parser.parse(options, cmdArgs, false);

        if (cmd.hasOption(HELP_OPTION)) {
          printUsage(options);
          System.exit(0);
        }

        String[] args = cmd.getArgs();
        if (args.length == 0) {
          System.err.println("Missing sstable directory argument");
          printUsage(options);
          System.exit(1);
        }

        if (args.length > 1) {
          System.err.println("Too many arguments");
          printUsage(options);
          System.exit(1);
        }

        String dirname = args[0];
        File dir = new File(dirname);

        if (!dir.exists()) errorMsg("Unknown directory: " + dirname, options);

        if (!dir.isDirectory()) errorMsg(dirname + " is not a directory", options);

        LoaderOptions opts = new LoaderOptions(dir);

        opts.debug = cmd.hasOption(DEBUG_OPTION);
        opts.verbose = cmd.hasOption(VERBOSE_OPTION);
        opts.noProgress = cmd.hasOption(NOPROGRESS_OPTION);

        if (cmd.hasOption(RPC_PORT_OPTION))
          opts.rpcPort = Integer.parseInt(cmd.getOptionValue(RPC_PORT_OPTION));

        if (cmd.hasOption(USER_OPTION)) opts.user = cmd.getOptionValue(USER_OPTION);

        if (cmd.hasOption(PASSWD_OPTION)) opts.passwd = cmd.getOptionValue(PASSWD_OPTION);

        if (cmd.hasOption(INITIAL_HOST_ADDRESS_OPTION)) {
          String[] nodes = cmd.getOptionValue(INITIAL_HOST_ADDRESS_OPTION).split(",");
          try {
            for (String node : nodes) {
              opts.hosts.add(InetAddress.getByName(node.trim()));
            }
          } catch (UnknownHostException e) {
            errorMsg("Unknown host: " + e.getMessage(), options);
          }

        } else {
          System.err.println("Initial hosts must be specified (-d)");
          printUsage(options);
          System.exit(1);
        }

        if (cmd.hasOption(IGNORE_NODES_OPTION)) {
          String[] nodes = cmd.getOptionValue(IGNORE_NODES_OPTION).split(",");
          try {
            for (String node : nodes) {
              opts.ignores.add(InetAddress.getByName(node.trim()));
            }
          } catch (UnknownHostException e) {
            errorMsg("Unknown host: " + e.getMessage(), options);
          }
        }

        // try to load config file first, so that values can be rewritten with other option values.
        // otherwise use default config.
        Config config;
        if (cmd.hasOption(CONFIG_PATH)) {
          File configFile = new File(cmd.getOptionValue(CONFIG_PATH));
          if (!configFile.exists()) {
            errorMsg("Config file not found", options);
          }
          config = new YamlConfigurationLoader().loadConfig(configFile.toURI().toURL());
        } else {
          config = new Config();
        }
        opts.storagePort = config.storage_port;
        opts.sslStoragePort = config.ssl_storage_port;
        opts.throttle = config.stream_throughput_outbound_megabits_per_sec;
        opts.encOptions = config.client_encryption_options;
        opts.serverEncOptions = config.server_encryption_options;

        if (cmd.hasOption(THROTTLE_MBITS)) {
          opts.throttle = Integer.parseInt(cmd.getOptionValue(THROTTLE_MBITS));
        }

        if (cmd.hasOption(SSL_TRUSTSTORE)) {
          opts.encOptions.truststore = cmd.getOptionValue(SSL_TRUSTSTORE);
        }

        if (cmd.hasOption(SSL_TRUSTSTORE_PW)) {
          opts.encOptions.truststore_password = cmd.getOptionValue(SSL_TRUSTSTORE_PW);
        }

        if (cmd.hasOption(SSL_KEYSTORE)) {
          opts.encOptions.keystore = cmd.getOptionValue(SSL_KEYSTORE);
          // if a keystore was provided, lets assume we'll need to use it
          opts.encOptions.require_client_auth = true;
        }

        if (cmd.hasOption(SSL_KEYSTORE_PW)) {
          opts.encOptions.keystore_password = cmd.getOptionValue(SSL_KEYSTORE_PW);
        }

        if (cmd.hasOption(SSL_PROTOCOL)) {
          opts.encOptions.protocol = cmd.getOptionValue(SSL_PROTOCOL);
        }

        if (cmd.hasOption(SSL_ALGORITHM)) {
          opts.encOptions.algorithm = cmd.getOptionValue(SSL_ALGORITHM);
        }

        if (cmd.hasOption(SSL_STORE_TYPE)) {
          opts.encOptions.store_type = cmd.getOptionValue(SSL_STORE_TYPE);
        }

        if (cmd.hasOption(SSL_CIPHER_SUITES)) {
          opts.encOptions.cipher_suites = cmd.getOptionValue(SSL_CIPHER_SUITES).split(",");
        }

        if (cmd.hasOption(TRANSPORT_FACTORY)) {
          ITransportFactory transportFactory =
              getTransportFactory(cmd.getOptionValue(TRANSPORT_FACTORY));
          configureTransportFactory(transportFactory, opts);
          opts.transportFactory = transportFactory;
        }

        return opts;
      } catch (ParseException | ConfigurationException | MalformedURLException e) {
        errorMsg(e.getMessage(), options);
        return null;
      }
    }