/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.internal;

import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
import static org.apache.geode.distributed.ConfigurationProperties.START_LOCATOR;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

import org.apache.commons.lang3.StringUtils;

import org.apache.geode.GemFireException;
import org.apache.geode.GemFireIOException;
import org.apache.geode.InternalGemFireException;
import org.apache.geode.NoSystemException;
import org.apache.geode.SystemFailure;
import org.apache.geode.UncreatedSystemException;
import org.apache.geode.UnstartedSystemException;
import org.apache.geode.admin.AdminException;
import org.apache.geode.admin.internal.AdminDistributedSystemImpl;
import org.apache.geode.annotations.Immutable;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.cache.persistence.PersistentID;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.distributed.internal.DistributionConfigImpl;
import org.apache.geode.distributed.internal.HighPriorityAckedMessage;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.distributed.internal.tcpserver.TcpClient;
import org.apache.geode.internal.admin.remote.TailLogResponse;
import org.apache.geode.internal.cache.DiskStoreImpl;
import org.apache.geode.internal.cache.backup.BackupOperation;
import org.apache.geode.internal.logging.DateFormatter;
import org.apache.geode.internal.logging.MergeLogFiles;
import org.apache.geode.internal.net.SocketCreator;
import org.apache.geode.internal.statistics.StatArchiveReader;
import org.apache.geode.internal.statistics.StatArchiveReader.ResourceInst;
import org.apache.geode.internal.statistics.StatArchiveReader.StatValue;
import org.apache.geode.internal.util.JavaCommandBuilder;
import org.apache.geode.internal.util.PluckStacks;
import org.apache.geode.internal.util.PluckStacks.ThreadStack;
import org.apache.geode.management.BackupStatus;

/**
 * Provides static methods for various system administation tasks.
 */
public class SystemAdmin {

  /**
   * Finds the gemfire jar path element in the given classpath and returns the directory that jar is
   * in.
   */
  public static File findGemFireLibDir() {
    URL jarURL = GemFireVersion.getJarURL();
    if (jarURL == null)
      return null;
    String path = jarURL.getPath();
    // Decode URL to get rid of escaped characters. See bug 32465.
    path = URLDecoder.decode(path);
    File f = new File(path);
    if (f.isDirectory()) {
      return f;
    }
    return f.getParentFile();
  }

  // ------------------- begin: Locator methods ------------------------------

  public void locatorStart(File directory, String portOption, String addressOption,
      String gemfirePropertiesFileOption, boolean peerOption, boolean serverOption,
      String hostnameForClientsOption) throws InterruptedException {
    // if (Thread.interrupted()) throw new InterruptedException(); not necessary checked in
    // locatorStart
    locatorStart(directory, portOption, addressOption, gemfirePropertiesFileOption, null, null,
        peerOption, serverOption, hostnameForClientsOption);
  }

  public void locatorStart(File directory, String portOption, String addressOption,
      String gemfirePropertiesFileOption, Properties propertyOptionArg, List xoptions,
      boolean peerOption, boolean serverOption, String hostnameForClientsOption)
      throws InterruptedException {
    if (Thread.interrupted())
      throw new InterruptedException();
    int port = DistributionLocator.parsePort(portOption);

    if (addressOption == null)
      addressOption = "";

    if (!addressOption.equals("")) {
      // make sure its a valid ip address
      if (!validLocalAddress(addressOption)) {
        throw new IllegalArgumentException(
            String.format("' %s ' is not a valid IP address for this machine",
                addressOption));
      }
    }
    // check to see if locator is already running
    File logFile = new File(directory, DistributionLocator.DEFAULT_STARTUP_LOG_FILE);
    try {
      // make sure file can be opened for writing
      (new FileOutputStream(logFile.getPath(), true)).close();
    } catch (IOException ex) {
      throw new GemFireIOException(
          String.format(
              "Logfile %s could not be opened for writing. Verify file permissions are correct and that another locator is not already running in the same directory.",
              logFile.getPath()),
          ex);
    }

    if (gemfirePropertiesFileOption != null) {
      Properties newPropOptions = new Properties();// see #43731
      newPropOptions.putAll(propertyOptionArg);
      newPropOptions.setProperty("gemfirePropertyFile", gemfirePropertiesFileOption);
      propertyOptionArg = newPropOptions;
    }

    // read ssl properties
    Map<String, String> env = new HashMap<String, String>();
    SocketCreator.readSSLProperties(env);

    List cmdVec = JavaCommandBuilder.buildCommand(getDistributionLocatorPath(), null,
        propertyOptionArg, xoptions);

    cmdVec.add(String.valueOf(port));
    cmdVec.add(addressOption);
    cmdVec.add(Boolean.toString(peerOption));
    cmdVec.add(Boolean.toString(serverOption));
    if (hostnameForClientsOption == null) {
      hostnameForClientsOption = "";
    }
    cmdVec.add(hostnameForClientsOption);

    String[] cmd = (String[]) cmdVec.toArray(new String[0]);

    // start with a fresh log each time
    if (!logFile.delete() && logFile.exists()) {
      throw new GemFireIOException("Unable to delete " + logFile.getAbsolutePath());
    }
    boolean treatAsPure = true;
    /**
     * A counter used by PureJava to determine when its waited too long to start the locator
     * process. countDown * 250 = how many seconds to wait before giving up.
     **/
    int countDown = 60;
    // NYI: wait around until we can attach
    while (!ManagerInfo.isLocatorStarted(directory)) {
      countDown--;
      Thread.sleep(250);
      if (countDown < 0) {
        try {
          String msg = tailFile(logFile, false);
          throw new GemFireIOException(
              String.format("Start of locator failed. The end of %s contained this message: %s.",
                  logFile, msg),
              null);
        } catch (IOException ignore) {
          throw new GemFireIOException(
              String.format("Start of locator failed. Check end of %s for reason.",
                  logFile),
              null);
        }
      }
      Thread.sleep(500);
    }
  }


  /** get the path to the distribution locator class */
  protected String getDistributionLocatorPath() {
    return "org.apache.geode.internal.DistributionLocator";
  }

  /**
   * enumerates all available local network addresses to find a match with the given address.
   * Returns false if the address is not usable on the current machine
   */
  public static boolean validLocalAddress(String bindAddress) {
    InetAddress addr = null;
    try {
      addr = InetAddress.getByName(bindAddress);
    } catch (UnknownHostException ex) {
      return false;
    }
    try {
      Enumeration en = NetworkInterface.getNetworkInterfaces();
      while (en.hasMoreElements()) {
        NetworkInterface ni = (NetworkInterface) en.nextElement();
        Enumeration en2 = ni.getInetAddresses();
        while (en2.hasMoreElements()) {
          InetAddress check = (InetAddress) en2.nextElement();
          if (check.equals(addr)) {
            return true;
          }
        }
      }
    } catch (SocketException sex) {
      return true; // can't query the interfaces - punt
    }
    return false;
  }

  @SuppressWarnings("hiding")
  public void locatorStop(File directory, String portOption, String addressOption,
      Properties propertyOption) throws InterruptedException {
    if (Thread.interrupted())
      throw new InterruptedException();
    InetAddress addr = null; // fix for bug 30810
    if (addressOption == null)
      addressOption = "";
    if (!addressOption.equals("")) {
      // make sure its a valid ip address
      try {
        addr = InetAddress.getByName(addressOption);
      } catch (UnknownHostException ex) {
        throw new IllegalArgumentException(
            String.format("-address value was not a known IP address: %s",
                ex));
      }
    }

    if (propertyOption != null) {
      Iterator iter = propertyOption.keySet().iterator();
      while (iter.hasNext()) {
        String key = (String) iter.next();
        System.setProperty(key, propertyOption.getProperty(key));
      }
    }
    int port = DistributionLocator.parsePort(portOption);
    int pid = 0;
    try {
      ManagerInfo info = ManagerInfo.loadLocatorInfo(directory);
      pid = info.getManagerProcessId();
      if (portOption == null || portOption.trim().length() == 0) {
        port = info.getManagerPort();
      }
      if (addressOption.trim().length() == 0) {
        addr = info.getManagerAddress();
      }

      try {
        new TcpClient().stop(addr, port);
      } catch (java.net.ConnectException ce) {
        System.out.println(
            "Unable to connect to Locator process. Possible causes are that an incorrect bind address/port combination was specified to the stop-locator command or the process is unresponsive.");
        return;
      }
      // wait for the locator process to go away
      // format and change message
      if (!quiet) {
        System.out.println(
            "Waiting 5 seconds for locator process to terminate...");
      }
      Thread.sleep(5000);
    } catch (UnstartedSystemException ex) {
      // fix for bug 28133
      throw new UnstartedSystemException(
          String.format("Locator in directory %s is not running.",
              directory));
    } catch (NoSystemException ex) {
      // before returning see if a stale lock file/shared memory can be cleaned up
      cleanupAfterKilledLocator(directory);
      throw ex;
    }
  }

  /**
   * Gets the status of a locator.
   *
   * @param directory the locator's directory
   * @return the status string. Will be one of the following: "running", "killed", "stopped",
   *         "stopping", or "starting".
   * @throws UncreatedSystemException if the locator <code>directory</code> does not exist or is not
   *         a directory.
   * @throws GemFireIOException if the manager info exists but could not be read. This probably
   *         means that the info file is corrupt.
   */
  public String locatorStatus(File directory) {
    return ManagerInfo.getLocatorStatusCodeString(directory);
  }

  /**
   * Gets information on the locator.
   *
   * @param directory the locator's directory
   * @return information string.
   * @throws UncreatedSystemException if the locator <code>directory</code> does not exist or is not
   *         a directory.
   * @throws GemFireIOException if the manager info exists but could not be read. This probably
   *         means that the info file is corrupt.
   */
  public String locatorInfo(File directory) {
    int statusCode = ManagerInfo.getLocatorStatusCode(directory);
    String statusString = ManagerInfo.statusToString(statusCode);
    try {
      ManagerInfo mi = ManagerInfo.loadLocatorInfo(directory);
      if (statusCode == ManagerInfo.KILLED_STATUS_CODE) {
        return String.format("Locator in %s was killed while it was %s. Locator process id was %s.",
            directory, ManagerInfo.statusToString(mi.getManagerStatus()),
            Integer.valueOf(mi.getManagerProcessId()));
      } else {
        return String.format("Locator in %s is %s. Locator process id is %s.",
            directory, statusString, Integer.valueOf(mi.getManagerProcessId()));
      }
    } catch (UnstartedSystemException ex) {
      return String.format("Locator in %s is stopped.", directory);
    } catch (GemFireIOException ex) {
      return String.format("Locator in %s is starting.", directory);
    }
  }

  /**
   * Cleans up any artifacts left by a killed locator. Namely the info file is deleted.
   */
  private static void cleanupAfterKilledLocator(File directory) {
    try {
      if (ManagerInfo.getLocatorStatusCode(directory) == ManagerInfo.KILLED_STATUS_CODE) {
        File infoFile = ManagerInfo.getLocatorInfoFile(directory);
        if (infoFile.exists()) {
          if (!infoFile.delete() && infoFile.exists()) {
            System.out.println("WARNING: unable to delete " + infoFile.getAbsolutePath());
          }
          if (!quiet) {
            System.out.println(
                "Cleaned up artifacts left by the previous killed locator.");
          }
        }
      }
    } catch (GemFireException ignore) {
    }
  }

  /**
   * Tails the end of the locator's log file
   *
   * @since GemFire 4.0
   */
  public String locatorTailLog(File directory) {
    File logFile = new File(directory, DistributionLocator.DEFAULT_LOG_FILE);
    if (!logFile.exists()) {
      return String.format("Log file %s does not exist.", logFile);
    }

    try {
      return TailLogResponse.tailSystemLog(logFile);
    } catch (IOException ex) {
      StringWriter sw = new StringWriter();
      PrintWriter pw = new PrintWriter(sw, true);
      sw.write(String.format("An IOException was thrown while tailing %s",
          logFile));
      ex.printStackTrace(pw);
      pw.flush();
      return sw.toString();
    }
  }

  // -------------------- end: Locator methods -------------------------------

  public static void compactDiskStore(String... args) {
    compactDiskStore(Arrays.asList(args));
  }

  public static void compactDiskStore(List args) {
    String diskStoreName = (String) args.get(0);
    List dirList = args.subList(1, args.size());
    File[] dirs = new File[dirList.size()];
    Iterator it = dirList.iterator();
    int idx = 0;
    while (it.hasNext()) {
      dirs[idx] = new File((String) it.next());
      idx++;
    }
    try {
      DiskStoreImpl.offlineCompact(diskStoreName, dirs, false, maxOplogSize);
    } catch (Exception ex) {
      throw new GemFireIOException(" disk-store=" + diskStoreName + ": " + ex, ex);
    }
  }

  public static void upgradeDiskStore(List args) {
    String diskStoreName = (String) args.get(0);
    List dirList = args.subList(1, args.size());
    File[] dirs = new File[dirList.size()];
    Iterator it = dirList.iterator();
    int idx = 0;
    while (it.hasNext()) {
      dirs[idx] = new File((String) it.next());
      idx++;
    }
    try {
      DiskStoreImpl.offlineCompact(diskStoreName, dirs, true, maxOplogSize);
    } catch (Exception ex) {
      throw new GemFireIOException(" disk-store=" + diskStoreName + ": " + ex, ex);
    }
  }

  public static void compactAllDiskStores(List args) throws AdminException {
    InternalDistributedSystem ads = getAdminCnx();
    Map<DistributedMember, Set<PersistentID>> status =
        AdminDistributedSystemImpl.compactAllDiskStores(ads.getDistributionManager());

    System.out.println("Compaction complete.");
    System.out.println("The following disk stores compacted some files:");
    for (Set<PersistentID> memberStores : status.values()) {
      for (PersistentID store : memberStores) {
        System.out.println("\t" + store);
      }
    }
  }

  public static void validateDiskStore(String... args) {
    validateDiskStore(Arrays.asList(args));
  }

  public static void validateDiskStore(List args) {
    String diskStoreName = (String) args.get(0);
    List dirList = args.subList(1, args.size());
    File[] dirs = new File[dirList.size()];
    Iterator it = dirList.iterator();
    int idx = 0;
    while (it.hasNext()) {
      dirs[idx] = new File((String) it.next());
      idx++;
    }
    try {
      DiskStoreImpl.validate(diskStoreName, dirs);
    } catch (Exception ex) {
      throw new GemFireIOException(" disk-store=" + diskStoreName + ": " + ex, ex);
    }
  }

  private static InternalDistributedSystem getAdminCnx() {
    InternalDistributedSystem.setCommandLineAdmin(true);
    Properties props = propertyOption;
    props.setProperty(LOG_LEVEL, "warning");
    DistributionConfigImpl dsc = new DistributionConfigImpl(props);
    System.out.print("Connecting to distributed system:");
    if (!"".equals(dsc.getLocators())) {
      System.out.println(" locators=" + dsc.getLocators());
    } else {
      System.out.println(" mcast=" + dsc.getMcastAddress() + ":" + dsc.getMcastPort());
    }
    InternalDistributedSystem ds =
        (InternalDistributedSystem) InternalDistributedSystem.connectForAdmin(props);
    Set existingMembers = ds.getDistributionManager().getDistributionManagerIds();
    if (existingMembers.isEmpty()) {
      throw new RuntimeException("There are no members in the distributed system");
    }
    return ds;
  }

  public static void shutDownAll(ArrayList<String> cmdLine) {
    try {
      long timeout = 0;
      if (cmdLine.size() > 0) {
        timeout = Long.parseLong(cmdLine.get(0));
      }
      InternalDistributedSystem ads = getAdminCnx();
      Set members =
          AdminDistributedSystemImpl.shutDownAllMembers(ads.getDistributionManager(), timeout);
      int count = members == null ? 0 : members.size();
      if (members == null) {
        System.err
            .println("Unable to shut down the distributed system in the specified amount of time.");
      } else if (count == 0) {
        System.err.println("The distributed system had no members to shut down.");
      } else if (count == 1) {
        System.out.println("Successfully shut down one member");
      } else {
        System.out.println("Successfully shut down " + count + " members");
      }
    } catch (Exception ex) {
      throw new GemFireIOException(ex.toString(), ex);
    }
  }

  /**
   * this is a test hook to allow us to drive SystemAdmin functions without invoking main(), which
   * can call System.exit().
   *
   */
  public static void setDistributedSystemProperties(Properties props) {
    propertyOption = props;
  }

  public static void printStacks(List<String> cmdLine, boolean allStacks) {
    try {
      InternalDistributedSystem ads = getAdminCnx();
      HighPriorityAckedMessage msg = new HighPriorityAckedMessage();
      OutputStream os;
      PrintWriter ps;
      File outputFile = null;

      if (cmdLine.size() > 0) {
        outputFile = new File(cmdLine.get(0));
        os = new FileOutputStream(outputFile);
        ps = new PrintWriter(os);
      } else {
        os = System.out;
        ps = new PrintWriter(System.out);
      }

      Map<InternalDistributedMember, byte[]> dumps =
          msg.dumpStacks(ads.getDistributionManager().getAllOtherMembers(), false, true);
      for (Map.Entry<InternalDistributedMember, byte[]> entry : dumps.entrySet()) {
        ps.append("--- dump of stack for member " + entry.getKey()
            + " ------------------------------------------------------------------------------\n");
        ps.flush();
        GZIPInputStream zipIn = new GZIPInputStream(new ByteArrayInputStream(entry.getValue()));
        if (allStacks) {
          BufferedInputStream bin = new BufferedInputStream(zipIn);
          byte[] buffer = new byte[10000];
          int count;
          while ((count = bin.read(buffer)) != -1) {
            os.write(buffer, 0, count);
          }
          ps.append('\n');
        } else {
          BufferedReader reader = new BufferedReader(new InputStreamReader(zipIn));
          List<ThreadStack> stacks = (new PluckStacks()).getStacks(reader);
          for (ThreadStack s : stacks) {
            s.writeTo(ps);
            ps.append('\n');
          }
          ps.append('\n');
        }
      }
      ps.flush();
      os.close();
      if (outputFile != null) {
        System.out.println(dumps.size() + " stack dumps written to " + outputFile.getName());
      }
    } catch (Exception ex) {
      throw new GemFireIOException(ex.toString(), ex);
    }
  }

  public static void backup(String targetDir) throws AdminException {
    InternalDistributedSystem ads = getAdminCnx();

    // Baseline directory should be null if it was not provided on the command line
    BackupStatus status =
        new BackupOperation(ads.getDistributionManager(), ads.getCache()).backupAllMembers(
            targetDir,
            SystemAdmin.baselineDir);

    boolean incomplete = !status.getOfflineDiskStores().isEmpty();

    System.out.println("The following disk stores were backed up:");
    for (Set<PersistentID> memberStores : status.getBackedUpDiskStores().values()) {
      for (PersistentID store : memberStores) {
        System.out.println("\t" + store);
      }
    }
    if (incomplete) {
      System.err.println("The backup may be incomplete. The following disk stores are not online:");
      for (PersistentID store : status.getOfflineDiskStores()) {
        System.err.println("\t" + store);
      }
    } else {
      System.out.println("Backup successful.");
    }
  }

  public static void listMissingDiskStores() throws AdminException {
    InternalDistributedSystem ads = getAdminCnx();
    Set s = AdminDistributedSystemImpl.getMissingPersistentMembers(ads.getDistributionManager());
    if (s.isEmpty()) {
      System.out.println("The distributed system did not have any missing disk stores");
    } else {
      for (Object o : s) {
        System.out.println(o);
      }
    }
  }

  private static File[] argsToFile(Collection<String> args) {
    File[] dirs = new File[args.size()];

    int i = 0;
    for (String dir : args) {
      dirs[i++] = new File(dir);
    }
    return dirs;
  }

  public static void showDiskStoreMetadata(ArrayList<String> args) {
    String dsName = args.get(0);
    File[] dirs = argsToFile(args.subList(1, args.size()));

    try {
      DiskStoreImpl.dumpMetadata(dsName, dirs, showBuckets);
    } catch (Exception ex) {
      throw new GemFireIOException(" disk-store=" + dsName + ": " + ex, ex);
    }
  }

  public static void exportDiskStore(ArrayList<String> args, String outputDir) {
    File out = outputDir == null ? new File(".") : new File(outputDir);
    if (!out.exists()) {
      out.mkdirs();
    }

    String dsName = args.get(0);
    File[] dirs = argsToFile(args.subList(1, args.size()));

    try {
      DiskStoreImpl.exportOfflineSnapshot(dsName, dirs, out);
    } catch (Exception ex) {
      throw new GemFireIOException(" disk-store=" + dsName + ": " + ex, ex);
    }
  }

  public static void revokeMissingDiskStores(ArrayList<String> cmdLine)
      throws UnknownHostException, AdminException {
    String uuidString = cmdLine.get(0);
    UUID uuid = UUID.fromString(uuidString);
    InternalDistributedSystem ads = getAdminCnx();
    AdminDistributedSystemImpl.revokePersistentMember(ads.getDistributionManager(), uuid);
    Set<PersistentID> s =
        AdminDistributedSystemImpl.getMissingPersistentMembers(ads.getDistributionManager());


    // Fix for 42607 - wait to see if the revoked member goes way if it is still in the set of
    // missing members. It may take a moment to clear the missing member set after the revoke.
    long start = System.currentTimeMillis();
    while (containsRevokedMember(s, uuid)) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException ignore) {
      }
      s = AdminDistributedSystemImpl.getMissingPersistentMembers(ads.getDistributionManager());
      if (start + 30000 < System.currentTimeMillis()) {
        break;
      }
    }
    if (s.isEmpty()) {
      System.out.println("revocation was successful and no disk stores are now missing");
    } else {
      System.out.println("The following disk stores are still missing:");
      for (Object o : s) {
        System.out.println(o);
      }
    }
  }

  private static boolean containsRevokedMember(Set<PersistentID> missing, UUID revokedUUID) {
    for (PersistentID id : missing) {
      if (id.getUUID().equals(revokedUUID)) {
        return true;
      }
    }
    return false;
  }

  public static void modifyDiskStore(String... args) {
    modifyDiskStore(Arrays.asList(args));
  }

  public static void modifyDiskStore(List args) {
    String diskStoreName = (String) args.get(0);
    List dirList = args.subList(1, args.size());
    File[] dirs = new File[dirList.size()];
    Iterator it = dirList.iterator();
    int idx = 0;
    while (it.hasNext()) {
      dirs[idx] = new File((String) it.next());
      idx++;
    }
    try {
      if (lruOption != null || lruActionOption != null || lruLimitOption != null
          || concurrencyLevelOption != null || initialCapacityOption != null
          || loadFactorOption != null || compressorClassNameOption != null
          || statisticsEnabledOption != null) {
        if (regionOption == null) {
          throw new IllegalArgumentException("modify-disk-store requires -region=<regionName>");
        }
        if (remove) {
          throw new IllegalArgumentException(
              "the -remove option can not be used with the other modify options.");
        }
        DiskStoreImpl.modifyRegion(diskStoreName, dirs, regionOption, lruOption, lruActionOption,
            lruLimitOption, concurrencyLevelOption, initialCapacityOption, loadFactorOption,
            compressorClassNameOption, statisticsEnabledOption, null/* offHeap */, true);
        System.out.println("The region " + regionOption
            + " was successfully modified in the disk store " + diskStoreName);
      } else if (remove) {
        if (regionOption == null) {
          throw new IllegalArgumentException("modify-disk-store requires -region=<regionName>");
        }
        DiskStoreImpl.destroyRegion(diskStoreName, dirs, regionOption);
        System.out.println("The region " + regionOption
            + " was successfully removed from the disk store " + diskStoreName);
      } else {
        DiskStoreImpl.dumpInfo(System.out, diskStoreName, dirs, regionOption, null);
        if (regionOption == null) {
          System.out.println("Please specify -region=<regionName> and a modify option.");
        } else {
          System.out.println("Please specify a modify option.");
        }
      }
    } catch (Exception ex) {
      throw new GemFireIOException(" disk-store=" + diskStoreName + ": " + ex, ex);
    }
  }

  public void mergeLogs(String outOption, List<String> args) {
    Map<String, InputStream> inputs = new HashMap<>();

    PrintStream ps;
    if (outOption != null) {
      try {
        ps = new PrintStream(new FileOutputStream(outOption));
      } catch (FileNotFoundException ex) {
        throw new GemFireIOException(
            String.format("Could not create file %s for output because %s",
                outOption, getExceptionMessage(ex)));
      }
    } else {
      ps = System.out;
    }
    PrintWriter mergedFile = new PrintWriter(ps, true);

    List<String> normalizedFiles =
        args.stream().map(f -> Paths.get(f).toAbsolutePath().toString()).collect(
            Collectors.toList());
    int prefixLength =
        StringUtils.getCommonPrefix(normalizedFiles.toArray(new String[] {})).length();

    if (!quiet) {
      ps.println("Merging the following log files:");
    }

    for (String fileName : normalizedFiles) {
      try {
        String shortName = fileName.substring(prefixLength);
        inputs.put(shortName, new FileInputStream(fileName));
      } catch (FileNotFoundException ex) {
        throw new GemFireIOException(
            String.format("Could not open to %s for reading because %s",
                fileName, getExceptionMessage(ex)));
      }
      if (!quiet) {
        ps.println("  " + fileName);
      }
    }

    if (MergeLogFiles.mergeLogFiles(inputs, mergedFile)) {
      throw new GemFireIOException(
          "trouble merging log files.");
    }
    mergedFile.flush();
    if (outOption != null) {
      mergedFile.close();
    }
    if (!quiet) {
      System.out
          .println(String.format("Completed merge of %s logs to %s.",
              args.size(),
              ((outOption != null) ? outOption : "stdout")));
    }
  }

  /**
   * Returns the contents located at the end of the file as a string.
   *
   * @throws IOException if the file can not be opened or read
   */
  public String tailFile(File file, boolean problemsOnly) throws IOException {
    byte buffer[] = new byte[128000];
    int readSize = buffer.length;
    RandomAccessFile f = new RandomAccessFile(file, "r");
    long length = f.length();
    if (length < readSize) {
      readSize = (int) length;
    }
    long seekOffset = length - readSize;
    f.seek(seekOffset);
    if (readSize != f.read(buffer, 0, readSize)) {
      throw new EOFException(
          "Failed to read " + readSize + " bytes from " + file.getAbsolutePath());
    }
    f.close();
    // Now look for the last message header
    int msgStart = -1;
    int msgEnd = readSize;
    for (int i = readSize - 1; i >= 0; i--) {
      if (buffer[i] == '[' && (buffer[i + 1] == 's' || buffer[i + 1] == 'e' || buffer[i
          + 1] == 'w' /* ignore all messages except severe, error, and warning to fix bug 28968 */)
          && i > 0 && (buffer[i - 1] == '\n' || buffer[i - 1] == '\r')) {
        msgStart = i;
        break;
      }
    }
    if (msgStart == -1) {
      if (problemsOnly) {
        return null;
      }
      // Could not find message start. Show last line instead.
      for (int i = readSize - 3; i >= 0; i--) {
        if (buffer[i] == '\n' || buffer[i] == '\r') {
          msgStart = (buffer[i] == '\n') ? (i + 1) : (i + 2);
          break;
        }
      }
      if (msgStart == -1) {
        // Could not find line so show entire buffer
        msgStart = 0;
      }
    } else {
      // try to find the start of the next message and get rid of it
      for (int i = msgStart + 1; i < readSize; i++) {
        if (buffer[i] == '[' && (buffer[i - 1] == '\n' || buffer[i - 1] == '\r')) {
          msgEnd = i;
          break;
        }
      }
    }
    for (int i = msgStart; i < msgEnd; i++) {
      if (buffer[i] == '\n' || buffer[i] == '\r') {
        buffer[i] = ' ';
      }
    }
    return new String(buffer, msgStart, msgEnd - msgStart);
  }

  protected void format(PrintWriter pw, String msg, String linePrefix, int initialLength) {
    final int maxWidth = 79;
    boolean firstLine = true;
    int lineLength = 0;
    final int prefixLength = linePrefix.length();
    int idx = 0;
    while (idx < msg.length()) {
      if (lineLength == 0) {
        if (isBreakChar(msg, idx)) {
          // skip over only lead break characters
          idx++;
          continue;
        }
        pw.print(linePrefix);
        lineLength += prefixLength;
        if (firstLine) {
          firstLine = false;
          lineLength += initialLength;
        }
      }
      if (msg.charAt(idx) == '\n' || msg.charAt(idx) == '\r') {
        pw.println();
        lineLength = 0;
        if (msg.charAt(idx) == '\r') {
          idx += 2;
        } else {
          idx++;
        }
      } else if (msg.charAt(idx) == ' ' && idx > 0 && msg.charAt(idx - 1) == '.'
          && idx < (msg.length() - 1) && msg.charAt(idx + 1) == ' ') {
        // treat ". " as a hardbreak
        pw.println();
        lineLength = 0;
        idx += 2;
      } else {
        String word = msg.substring(idx, findWordBreak(msg, idx));
        if (lineLength == prefixLength || (word.length() + lineLength) <= maxWidth) {
          pw.print(word);
          lineLength += word.length();
          idx += word.length();
        } else {
          // no room on current line. So start a new line.
          pw.println();
          lineLength = 0;
        }
      }
    }
    if (lineLength != 0) {
      pw.println();
    }
  }

  private static final char breakChars[] = new char[] {' ', '\t', '\n', '\r'};

  private static boolean isBreakChar(String str, int idx) {
    char c = str.charAt(idx);
    for (int i = 0; i < breakChars.length; i++) {
      if (c == breakChars[i]) {
        return true;
      }
    }
    return false;
  }

  private static int findWordBreak(String str, int fromIdx) {
    int result = str.length();
    for (int i = 0; i < breakChars.length; i++) {
      int tmp = str.indexOf(breakChars[i], fromIdx + 1);
      if (tmp > fromIdx && tmp < result) {
        result = tmp;
      }
    }
    return result;
  }

  public static class StatSpec implements StatArchiveReader.StatSpec {
    public final String cmdLineSpec;
    public final String typeId;
    public final String instanceId;
    public final String statId;
    private final Pattern tp;
    private final Pattern sp;
    private final Pattern ip;
    private final int combineType;

    public StatSpec(String cmdLineSpec) {
      this.cmdLineSpec = cmdLineSpec;
      if (cmdLineSpec.charAt(0) == '+') {
        cmdLineSpec = cmdLineSpec.substring(1);
        if (cmdLineSpec.charAt(0) == '+') {
          cmdLineSpec = cmdLineSpec.substring(1);
          this.combineType = GLOBAL;
        } else {
          this.combineType = FILE;
        }
      } else {
        this.combineType = NONE;
      }
      int dotIdx = cmdLineSpec.lastIndexOf('.');
      String typeId = null;
      String instanceId = null;
      String statId = null;
      if (dotIdx != -1) {
        statId = cmdLineSpec.substring(dotIdx + 1);
        cmdLineSpec = cmdLineSpec.substring(0, dotIdx);
      }
      int commaIdx = cmdLineSpec.indexOf(':');
      if (commaIdx != -1) {
        instanceId = cmdLineSpec.substring(0, commaIdx);
        typeId = cmdLineSpec.substring(commaIdx + 1);
      } else {
        instanceId = cmdLineSpec;
      }

      if (statId == null || statId.length() == 0) {
        this.statId = "";
        this.sp = null;
      } else {
        this.statId = statId;
        this.sp = Pattern.compile(statId, Pattern.CASE_INSENSITIVE);
      }
      if (typeId == null || typeId.length() == 0) {
        this.typeId = "";
        this.tp = null;
      } else {
        this.typeId = typeId;
        this.tp = Pattern.compile(".*" + typeId, Pattern.CASE_INSENSITIVE);
      }
      if (instanceId == null || instanceId.length() == 0) {
        this.instanceId = "";
        this.ip = null;
      } else {
        this.instanceId = instanceId;
        this.ip = Pattern.compile(instanceId, Pattern.CASE_INSENSITIVE);
      }
    }

    @Override
    public String toString() {
      return "StatSpec instanceId=" + this.instanceId + " typeId=" + this.typeId + " statId="
          + this.statId;
    }

    @Override
    public int getCombineType() {
      return this.combineType;
    }

    @Override
    public boolean archiveMatches(File archive) {
      return true;
    }

    @Override
    public boolean statMatches(String statName) {
      if (this.sp == null) {
        return true;
      } else {
        Matcher m = this.sp.matcher(statName);
        return m.matches();
      }
    }

    @Override
    public boolean typeMatches(String typeName) {
      if (this.tp == null) {
        return true;
      } else {
        Matcher m = this.tp.matcher(typeName);
        return m.matches();
      }
    }

    @Override
    public boolean instanceMatches(String textId, long numericId) {
      if (this.ip == null) {
        return true;
      } else {
        Matcher m = this.ip.matcher(textId);
        if (m.matches()) {
          return true;
        }
        m = this.ip.matcher(String.valueOf(numericId));
        return m.matches();
      }
    }
  }

  private static StatSpec[] createSpecs(List cmdLineSpecs) {
    StatSpec[] result = new StatSpec[cmdLineSpecs.size()];
    Iterator it = cmdLineSpecs.iterator();
    int idx = 0;
    while (it.hasNext()) {
      result[idx] = new StatSpec((String) it.next());
      idx++;
    }
    return result;
  }

  private static void printStatValue(StatArchiveReader.StatValue v, long startTime, long endTime,
      boolean nofilter, boolean persec, boolean persample, boolean prunezeros, boolean details) {
    v = v.createTrimmed(startTime, endTime);
    if (nofilter) {
      v.setFilter(StatArchiveReader.StatValue.FILTER_NONE);
    } else if (persec) {
      v.setFilter(StatArchiveReader.StatValue.FILTER_PERSEC);
    } else if (persample) {
      v.setFilter(StatArchiveReader.StatValue.FILTER_PERSAMPLE);
    }
    if (prunezeros) {
      if (v.getSnapshotsMinimum() == 0.0 && v.getSnapshotsMaximum() == 0.0) {
        return;
      }
    }
    System.out.println("  " + v.toString());
    if (details) {
      System.out.print("  values=");
      double[] snapshots = v.getSnapshots();
      for (int i = 0; i < snapshots.length; i++) {
        System.out.print(' ');
        System.out.print(snapshots[i]);
      }
      System.out.println();
      String desc = v.getDescriptor().getDescription();
      if (desc != null && desc.length() > 0) {
        System.out.println("    " + desc);
      }
    }
  }

  /**
   * List the statistics of a running system.
   *
   * @param directory the system directory of the system to list.
   * @param archiveNames the archive file(s) to read.
   * @param details if true the statistic descriptions will also be listed.
   * @param nofilter if true then printed stat values will all be raw unfiltered.
   * @param persec if true then printed stat values will all be the rate of change, per second, of
   *        the raw values.
   * @param persample if true then printed stat values will all be the rate of change, per sample,
   *        of the raw values.
   * @param prunezeros if true then stat values whose samples are all zero will not be printed.
   *
   * @throws UncreatedSystemException if the system <code>sysDir</code> does not exist, is not a
   *         directory, or does not contain a configuration file.
   * @throws NoSystemException if the system is not running or could not be connected to.
   * @throws IllegalArgumentException if a statSpec does not match a resource and/or statistic.
   * @throws GemFireIOException if the archive could not be read
   */
  public void statistics(File directory, List archiveNames, boolean details, boolean nofilter,
      boolean persec, boolean persample, boolean prunezeros, boolean monitor, long startTime,
      long endTime, List cmdLineSpecs) {
    if (persec && nofilter) {
      throw new IllegalArgumentException(
          "The -nofilter and -persec options are mutually exclusive.");
    }
    if (persec && persample) {
      throw new IllegalArgumentException(
          "The -persample and -persec options are mutually exclusive.");
    }
    if (nofilter && persample) {
      throw new IllegalArgumentException(
          "The -persample and -nofilter options are mutually exclusive.");
    }
    StatSpec[] specs = createSpecs(cmdLineSpecs);
    if (archiveOption != null) {
      if (directory != null) {
        throw new IllegalArgumentException(
            "The -archive= and -dir= options are mutually exclusive.");
      }
      StatArchiveReader reader = null;
      boolean interrupted = false;
      try {
        reader = new StatArchiveReader((File[]) archiveNames.toArray(new File[0]),
            specs, !monitor);
        // Runtime.getRuntime().gc(); System.out.println("DEBUG: heap size=" +
        // (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
        if (specs.length == 0) {
          if (details) {
            StatArchiveReader.StatArchiveFile[] archives = reader.getArchives();
            for (int i = 0; i < archives.length; i++) {
              System.out.println(archives[i].getArchiveInfo().toString());
            }
          }
        }
        do {
          if (specs.length == 0) {
            Iterator it = reader.getResourceInstList().iterator();
            while (it.hasNext()) {
              ResourceInst inst = (ResourceInst) it.next();
              StatValue values[] = inst.getStatValues();
              boolean firstTime = true;
              for (int i = 0; i < values.length; i++) {
                if (values[i] != null && values[i].hasValueChanged()) {
                  if (firstTime) {
                    firstTime = false;
                    System.out.println(inst.toString());
                  }
                  printStatValue(values[i], startTime, endTime, nofilter, persec, persample,
                      prunezeros, details);
                }
              }
            }
          } else {
            Map<CombinedResources, List<StatValue>> allSpecsMap =
                new HashMap<CombinedResources, List<StatValue>>();
            for (int i = 0; i < specs.length; i++) {
              StatValue[] values = reader.matchSpec(specs[i]);
              if (values.length == 0) {
                if (!quiet) {
                  System.err.println(String.format("[warning] No stats matched %s.",
                      specs[i].cmdLineSpec));
                }
              } else {
                Map<CombinedResources, List<StatValue>> specMap =
                    new HashMap<CombinedResources, List<StatValue>>();
                for (StatValue v : values) {
                  CombinedResources key = new CombinedResources(v);
                  List<StatArchiveReader.StatValue> list = specMap.get(key);
                  if (list != null) {
                    list.add(v);
                  } else {
                    specMap.put(key, new ArrayList<StatValue>(Collections.singletonList(v)));
                  }
                }
                if (!quiet) {
                  System.out.println(
                      String.format("[info] Found %s instances matching %s:",
                          new Object[] {Integer.valueOf(specMap.size()), specs[i].cmdLineSpec}));
                }
                for (Map.Entry<CombinedResources, List<StatValue>> me : specMap.entrySet()) {
                  List<StatArchiveReader.StatValue> list = allSpecsMap.get(me.getKey());
                  if (list != null) {
                    list.addAll(me.getValue());
                  } else {
                    allSpecsMap.put(me.getKey(), me.getValue());
                  }
                }
              }
            }
            for (Map.Entry<CombinedResources, List<StatValue>> me : allSpecsMap.entrySet()) {
              System.out.println(me.getKey());
              for (StatValue v : me.getValue()) {
                printStatValue(v, startTime, endTime, nofilter, persec, persample, prunezeros,
                    details);
              }
            }
          }
          if (monitor) {
            while (!reader.update()) {
              try {
                Thread.sleep(1000);
              } catch (InterruptedException ignore) {
                interrupted = true;
              }
            }
          }
        } while (monitor && !interrupted);
      } catch (IOException ex) {
        throw new GemFireIOException(
            String.format("Failed reading %s", archiveOption), ex);
      } finally {
        if (reader != null) {
          try {
            reader.close();
          } catch (IOException ignore) {
          }
        }
        if (interrupted) {
          Thread.currentThread().interrupt();
        }
      }
    }
  }

  /**
   * Represents a list of ResourceInst that have been combined together. Note the most common case
   * is for this class to only own a single ResourceInst.
   *
   */
  @SuppressWarnings("serial")
  private static class CombinedResources extends ArrayList<ResourceInst> {
    public CombinedResources(StatValue v) {
      super(Arrays.asList(v.getResources()));
    }

    @Override
    public String toString() {
      StringBuffer sb = new StringBuffer();
      boolean first = true;
      for (ResourceInst inst : this) {
        if (first) {
          first = false;
        } else {
          sb.append(" + ");
        }
        sb.append(inst);
      }
      return sb.toString();
    }
  }

  public SystemAdmin() {}

  private static final String[] helpTopics =
      new String[] {"all", "overview", "commands", "options", "usage", "configuration"};

  protected void printHelpTopic(String topic, PrintWriter pw) {
    if (topic.equalsIgnoreCase("all")) {
      for (int i = 0; i < helpTopics.length; i++) {
        if (!helpTopics[i].equals("all")) {
          pw.println("-------- " + helpTopics[i] + " --------");
          printHelpTopic(helpTopics[i], pw);
        }
      }
    } else if (topic.equalsIgnoreCase("overview")) {
      pw.println(
          String.format(
              "This program allows GemFire to be managed from the command line. It expects a command to execute.See the help topic %s. For a summary of supported options see the help topic %s.For a concise description of command line syntax see the help topic %s.For a description of system configuration see the help topic %s.For help on a specific command use the %s option with the command name.",

              new Object[] {"commands", "options", "usage", "configuration", "-h"}));
    } else if (topic.equalsIgnoreCase("commands")) {
      pw.println(usageMap.get("gemfire") + " <command> ...");
      format(pw, (String) helpMap.get("gemfire"), "  ", 0);
      for (int i = 0; i < validCommands.length; i++) {
        pw.println((String) usageMap.get(validCommands[i]));
        if (helpMap.get(validCommands[i]) == null) {
          pw.println("  (help message missing for " + validCommands[i] + ")");
        } else {
          format(pw, (String) helpMap.get(validCommands[i]), "  ", 0);
        }
      }
    } else if (topic.equalsIgnoreCase("options")) {
      pw.println(
          "All command line options start with a - and are not required.Each option has a default that will be used when its not specified.Options that take an argument always use a single = character, with no spaces, to delimit where the option name ends and the argument begins.Options that precede the command word can be used with any command and are also permitted to follow the command word.");
      for (int i = 0; i < validOptions.length; i++) {
        pw.print(validOptions[i] + ":");
        try {
          format(pw, (String) helpMap.get(validOptions[i]), "  ", validOptions[i].length() + 1);
        } catch (RuntimeException ex) {
          System.err.println(
              String.format("no help for option %s]", validOptions[i]));
          throw ex;
        }
      }
    } else if (topic.equalsIgnoreCase("usage")) {
      pw.println(
          "The following synax is used in the usage strings:[] designate an optional item() are used to group items<> designate non-literal text. Used to designate logical items* suffix means zero or more of the previous item| means the item to the left or right is required");
      for (int i = 0; i < validCommands.length; i++) {
        pw.println(getUsageString(validCommands[i]));
      }
    }
  }

  protected void help(List args) {
    String topic = "overview";
    if (args.size() > 0) {
      topic = (String) args.get(0);
      if (!Arrays.asList(helpTopics).contains(topic.toLowerCase())) {
        System.err.println(
            String.format("ERROR: Invalid help topic %s.", topic));
        usage();
      }
    }
    PrintWriter pw = new PrintWriter(System.out);
    printHelpTopic(topic, pw);
    pw.flush();
    if (args.size() == 0) {
      usage("help");
    }
  }

  protected void usage() {
    usage(null);
  }

  protected String getUsageString(String cmd) {
    StringBuffer result = new StringBuffer(80);
    result.append(usageMap.get("gemfire")).append(' ');
    if (cmd == null || cmd.equalsIgnoreCase("gemfire")) {
      result.append(join(Arrays.asList(validCommands), "|")).append(" ...");
    } else {
      result.append(usageMap.get(cmd.toLowerCase()));
    }
    return result.toString();
  }

  protected void usage(String cmd) {
    System.err.println(
        "Usage " + getUsageString(cmd));
    ExitCode.FATAL.doSystemExit();
  }

  private static final String[] validCommands = new String[] {"version", "stats", START_LOCATOR,
      "stop-locator", "status-locator", "info-locator", "tail-locator-log", "merge-logs",
      "revoke-missing-disk-store", "list-missing-disk-stores", "validate-disk-store",
      "upgrade-disk-store", "compact-disk-store", "compact-all-disk-stores", "modify-disk-store",
      "show-disk-store-metadata", "export-disk-store", "shut-down-all", "backup", "print-stacks",
      "help"};

  protected static String[] getValidCommands() {
    return validCommands.clone();
  }

  private static final String[] aliasCommands = new String[] {"locator-start", "locator-stop",
      "locator-status", "locator-info", "locator-tail-log", "logs-merge", "shutdown-all",
      "shutdownall", "compact", "modify", "validate"};
  private static final String[] validOptions =
      new String[] {"-address=", "-archive=", "-concurrencyLevel=", "-debug", "-remove", "-details",
          "-dir=", "-endtime=", "-h", "-help", "-initialCapacity=", "-loadFactor=", "-lru=",
          "-lruAction=", "-lruLimit=", "-maxOplogSize=", "-properties=", "-monitor", "-nofilter",
          "-persample", "-persec", "-out=", "-port=", "-prunezeros", "-region=", "-starttime=",
          "-statisticsEnabled=", "-peer=", "-server=", "-q", "-D", "-X", "-outputDir="};

  protected String checkCmd(String theCmd) {
    String cmd = theCmd;
    if (!Arrays.asList(validCommands).contains(cmd.toLowerCase())) {
      if (!Arrays.asList(aliasCommands).contains(cmd.toLowerCase())) {
        System.err
            .println(String.format("ERROR: Invalid command %s.", cmd));
        usage();
      } else {
        if (cmd.equalsIgnoreCase("locator-start")) {
          cmd = START_LOCATOR;
        } else if (cmd.equalsIgnoreCase("locator-stop")) {
          cmd = "stop-locator";
        } else if (cmd.equalsIgnoreCase("locator-info")) {
          cmd = "info-locator";
        } else if (cmd.equalsIgnoreCase("locator-status")) {
          cmd = "status-locator";
        } else if (cmd.equalsIgnoreCase("locator-tail-log")) {
          cmd = "tail-locator-log";
        } else if (cmd.equalsIgnoreCase("logs-merge")) {
          cmd = "merge-logs";
        } else if (cmd.equalsIgnoreCase("shutdownall")) {
          cmd = "shut-down-all";
        } else if (cmd.equalsIgnoreCase("shutdown-all")) {
          cmd = "shut-down-all";
        } else if (cmd.equalsIgnoreCase("upgrade")) {
          cmd = "upgrade-disk-store";
        } else if (cmd.equalsIgnoreCase("compact")) {
          cmd = "compact-disk-store";
        } else if (cmd.equalsIgnoreCase("modify")) {
          cmd = "modify-disk-store";
        } else if (cmd.equalsIgnoreCase("validate")) {
          cmd = "validate-disk-store";
        } else {
          throw new InternalGemFireException(
              String.format("Unhandled alias %s", cmd));
        }
      }
    }
    return cmd;
  }

  public static String join(Object[] a) {
    return join(a, " ");
  }

  public static String join(Object[] a, String joinString) {
    return join(Arrays.asList(a), joinString);
  }

  public static String join(List l) {
    return join(l, " ");
  }

  public static String join(List l, String joinString) {
    StringBuffer result = new StringBuffer(80);
    boolean firstTime = true;
    Iterator it = l.iterator();
    while (it.hasNext()) {
      if (firstTime) {
        firstTime = false;
      } else {
        result.append(joinString);
      }
      result.append(it.next());
    }
    return result.toString();
  }

  protected final Map helpMap = new HashMap();

  protected void initHelpMap() {
    helpMap.put("gemfire",
        "GemFire requires one of the following command strings: " + join(validCommands)
            + ". For additional help on a command specify it along with the '-h' option. "
            + "The '-debug' option causes gemfire to print out extra information when it fails.  "
            + "The '-h' and '-help' are synonyms that cause gemfire to print out help information instead of performing a task.  "
            + "The '-q' option quiets GemFire down by suppressing extra messages.  The '-J<vmOpt>' option passes <vmOpt> to the Java VM's command line.");
    helpMap.put("version", "Prints GemFire product version information.");
    helpMap.put("help",
        "Prints information on how to use this executable.  If an optional help topic is specified then more detailed help is printed.");
    helpMap.put("stats",
        "Prints statistic values from a statistic archive.  By default all statistics are printed.\n"
            + "The 'statSpec' arguments can be used to print individual resources or a specific statistic.\n"
            + "The format of a 'statSpec' is: an optional combine operator, followed by an optional instanceId, followed by an optional typeId, followed by an optional statId.\n"
            + "The '+' operator combines all matches in the same file.  The '++' operator combines all matches across all files.\n"
            + "An instanceId must be the name or id of a resource.  A typeId is a ':' followed by the name of a resource type.\n"
            + "A statId is a '.' followed by the name of a statistic.  A typeId or instanceId with no statId prints out all the matching resources and all their statistics.\n"
            + "A typeId or instanceId with a statId prints out just the named statistic on the matching resources.  A statId with no typeId or instanceId matches all statistics with that name.\n"
            + "The '-details' option causes statistic descriptions to also be printed.\n"
            + "The '-nofilter' option, in conjunction with '-archive=', causes the printed statistics to all be raw, unfiltered, values.\n"
            + "The '-persec' option, in conjunction with '-archive=', causes the printed statistics to be the rate of change, per second, of the raw values.\n"
            + "The '-persample' option, in conjunction with '-archive=', causes the printed statistics to be the rate of change, per sample, of the raw values.\n"
            + "The '-prunezeros' option', in conjunction with '-archive=', causes statistics whose values are all zero to not be printed.\n"
            + "The '-starttime=' option, in conjunction with '-archive=', causes statistics samples taken before this time to be ignored. The argument format must match "
            + DateFormatter.FORMAT_STRING + ".\n"
            + "The '-endtime' option, in conjunction with '-archive=', causes statistics samples taken after this time to be ignored. The argument format must match "
            + DateFormatter.FORMAT_STRING + ".\n"
            + "The '-archive=' option causes the data to come from an archive file.");
    helpMap.put(START_LOCATOR,
        "Starts a locator.\n"
            + "The 'port=' option specifies the port the locator will listen on.  It defaults to "
            + DistributionLocator.DEFAULT_LOCATOR_PORT + "\n."
            + "The '-address=' option specifies the address the locator will listen on.  It defaults to listening on all local addresses.\n"
            + "The '-dir=' option can be used to specify the directory the locator will run in.\n"
            + "The '-properties=' option can be used to specify the gemfire.properties file for configuring the locator's distributed system.  The file's path should be absolute, or relative to the locator's directory ('-dir=').\n"
            + "The '-peer=' option can be used to specify whether peer locator service should be enabled.  True (the default) will enable the service.\n"
            + "The '-server=' option can be used to specify whether server locator service should be enabled. True (the default) will enable the service.\n"
            + "The '-hostname-for-clients=' option can be used to specify a host name or ip address that will be sent to clients so they can connect to this locator. The default is to use the address the locator is listening on.\n"
            + "The '-D' option can be used to set system properties for the locator VM.  "
            + "The '-X' option can be used to set vendor-specific VM options and is usually used to increase the size of the locator VM when using multicast.");
    helpMap.put("stop-locator",
        "Stops a locator.\n"
            + "The '-port=' option specifies the port the locator is listening on. It defaults to "
            + DistributionLocator.DEFAULT_LOCATOR_PORT + ".\n"
            + "The '-address=' option specifies the address the locator is listening on. It defaults to the local host's address.\n"
            + "The '-dir=' option can be used to specify the directory the locator is running in.");
    helpMap.put("status-locator",
        "Prints the status of a locator. The status string will one of the following: "
            + join(ManagerInfo.statusNames) + ".\n"
            + "The '-dir=' option can be used to specify the directory of the locator whose status is desired.");
    helpMap.put("info-locator",
        "Prints information on a locator.  The information includes the process id of the locator, if the product is not running in PureJava mode.  "
            + "The '-dir=' option can be used to specify the directory of the locator whose information is desired.");
    helpMap.put("tail-locator-log",
        "Prints the last 64K bytes of the locator's log file.  The '-dir=' option can be used to specify the directory of the locator whose information is desired.");
    helpMap.put("merge-logs",
        "Merges multiple logs files into a single log.The -out option can be used to specify the file to write the merged log to. The default is stdout.");
    helpMap.put("validate-disk-store",
        "Checks to make sure files of a disk store are valid. The name of the disk store and the directories its files are stored in are required arguments.");
    helpMap.put("upgrade-disk-store", "Upgrade an offline disk store with new version format.\n"
        + "'-maxOplogSize=<long> causes the oplogs created by compaction to be no larger than the specified size in megabytes.");
    helpMap.put("compact-disk-store",
        "Compacts an offline disk store. Compaction removes all unneeded records from the persistent files.\n"
            + "-maxOplogSize=<long> causes the oplogs created by compaction to be no larger than the specified size in megabytes.");
    helpMap.put("compact-all-disk-stores",
        "Connects to a running system and tells its members to compact their disk stores. "
            + "This command uses the compaction threshold that each member has "
            + "configured for its disk stores. The disk store must have allow-force-compaction "
            + "set to true in order for this command to work.\n"
            + "This command will use the gemfire.properties file to determine what distributed system to connect to.");
    helpMap.put("modify-disk-store",
        "Modifies the contents stored in a disk store. Note that this operation writes to the disk store files so use it with care. Requires that a region name by specified using -region=<regionName> Options:   -remove will remove the region from the disk store causing any data stored in the disk store for this region to no longer exist. Subregions of the removed region will not be removed.   -lru=<type> Sets region's lru algorithm. Valid types are: none, lru-entry-count, lru-heap-percentage, or lru-memory-size   -lruAction=<action> Sets the region's lru action. Valid actions are: none, overflow-to-disk, local-destroy   -lruLimit=<int> Sets the region's lru limit. Valid values are >= 0   -concurrencyLevel=<int> Sets the region's concurrency level. Valid values are >= 0   -initialCapacity=<int> Sets the region's initial capacity. Valid values are >= 0.   -loadFactor=<float> Sets the region's load factory. Valid values are >= 0.0   -statisticsEnabled=<boolean> Sets the region's statistics enabled. Value values are true or false. The name of the disk store and the directories its files are stored in and the region to target are all required arguments.");
    helpMap.put("revoke-missing-disk-store",
        "Connects to a running system and tells its members to stop waiting for the "
            + "specified disk store to be available. Only revoke a disk store if its files "
            + "are lost. Once a disk store is revoked its files can no longer be loaded so be "
            + "careful. Use the list-missing-disk-stores command to get descriptions of the"
            + "missing disk stores.\n"
            + "You must pass the in the unique id for the disk store to revoke. The unique id is listed in the output "
            + "of the list-missing-disk-stores command, for example a63d7d99-f8f8-4907-9eb7-cca965083dbb.\n"
            + "This command will use the gemfire.properties file to determine what distributed system to connect to.");
    helpMap.put("list-missing-disk-stores",
        "Prints out a description of the disk stores that are currently missing from a distributed system\n\\n."
            + "This command will use the gemfire.properties file to determine what distributed system to connect to.");
    helpMap.put("export-disk-store",
        "Exports an offline disk store.  The persistent data is written to a binary format.\n"
            + "  -outputDir=<directory> specifies the location of the exported snapshot files.");
    helpMap.put("shut-down-all",
        "Connects to a running system and asks all its members that have a cache to close the cache and disconnect from system."
            + "The timeout parameter allows you to specify that the system should be shutdown forcibly after the time has exceeded.\n"
            + "This command will use the gemfire.properties file to determine what distributed system to connect to.");
    helpMap.put("backup",
        "Connects to a running system and asks all its members that have persistent data "
            + "to backup their data to the specified directory. The directory specified must exist "
            + "on all members, but it can be a local directory on each machine. This command "
            + "takes care to ensure that the backup files will not be corrupted by concurrent "
            + "operations. Backing up a running system with filesystem copy is not recommended.\n"
            + "This command will use the gemfire.properties file to determine what distributed system to connect to.");
    helpMap.put("print-stacks",
        "fetches stack dumps of all processes.  By default an attempt"
            + " is made to remove idle GemFire threads from the dump.  "
            + "Use -all-threads to include these threads in the dump.  "
            + "An optional filename may be given for storing the dumps.");
    helpMap.put("-out=",
        "Causes gemfire to write output to the specified file. The file is overwritten if it already exists.");
    helpMap.put("-debug",
        "Causes gemfire to print out extra information when it fails. This option is supported by all commands.");
    helpMap.put("-details",
        "Causes gemfire to print detailed information.  With the 'stats' command it means statistic descriptions.");
    helpMap.put("-nofilter",
        "Causes gemfire 'stats' command to print unfiltered, raw, statistic values. This is the default for non-counter statistics.");
    helpMap.put("-persec",
        "Causes gemfire 'stats' command to print the rate of change, per second, for statistic values. This is the default for counter statistics.");
    helpMap.put("-persample",
        "Causes gemfire 'stats' command to print the rate of change, per sample, for statistic values.");
    helpMap.put("-prunezeros",
        "Causes gemfire 'stats' command to not print statistics whose values are all zero.");
    helpMap.put("-port=",
        "Used to specify a non-default port when starting or stopping a locator.");
    helpMap.put("-address=",
        "Used to specify a specific IP address to listen on when starting or stopping a locator.");
    helpMap.put("-hostname-for-clients=",
        "Used to specify a host name or IP address to give to clients so they can connect to a locator.");
    helpMap.put("-properties=",
        "Used to specify the " + DistributionConfig.GEMFIRE_PREFIX
            + "properties file to be used in configuring the locator's DistributedSystem.");
    helpMap.put("-archive=",
        "The argument is the statistic archive file the 'stats' command should read.");
    helpMap.put("-h",
        "Causes GemFire to print out information instead of performing the command. This option is supported by all commands.");
    helpMap.put("-help", helpMap.get("-h"));
    helpMap.put("-q",
        "Turns on quiet mode. This option is supported by all commands.");
    helpMap.put("-starttime=",
        "Causes the 'stats' command to ignore statistics samples taken before this time. The argument format must match "
            + DateFormatter.FORMAT_STRING + ".");
    helpMap.put("-endtime=",
        "Causes the 'stats' command to ignore statistics samples taken after this time. The argument format must match "
            + DateFormatter.FORMAT_STRING + ".");
    helpMap.put("-dir=",
        "The argument is the system directory the command should operate on.  If the argument is empty then a default system directory will be search for.\n"
            + "However the search will not include the " + DistributionConfig.GEMFIRE_PREFIX
            + "properties file.  By default if a command needs a system directory, and one is not specified, then a search is done.\n"
            + "If a " + DistributionConfig.GEMFIRE_PREFIX + "properties file can be located then "
            + DistributionConfig.GEMFIRE_PREFIX
            + "systemDirectory property from that file is used.\n"
            + "Otherwise if the GEMFIRE environment variable is set to a directory that contains a subdirectory named defaultSystem then that directory is used.\n"
            + "The property file is searched for in the following locations:\n"
            + "1. The current working directory.\n"
            + "2. The user's home directory.\n"
            + "3. The class path.  All commands except 'version' use the system directory.");
    helpMap.put("-D",
        "Sets a Java system property in the locator VM.  Used most often for configuring SSL communication.");
    helpMap.put("-X",
        "Sets a Java VM X setting in the locator VM.  Used most often for increasing the size of the virtual machine.");
    helpMap.put("-remove",
        "Causes the region specified by the -region=<regionName> to be removed from a disk store. Any records in the disk store for this region become garbage and will be deleted from the disk store files if compact-disk-store is called. Note that this option writes to the disk store files so use it with care.");
    helpMap.put("-maxOplogSize=",
        "Limits the size of any oplogs that are created to the specified size in megabytes.");
    helpMap.put("-lru=",
        "-lru=<type> Sets region's lru algorithm. Valid types are: none, lru-entry-count, lru-heap-percentage, or lru-memory-size");
    helpMap.put("-lruAction=",
        "-lruAction=<action> Sets the region's lru action. Valid actions are: none, overflow-to-disk, local-destroy");
    helpMap.put("-lruLimit=",
        "-lruLimit=<int> Sets the region's lru limit. Valid values are >= 0");
    helpMap.put("-concurrencyLevel=",
        "-concurrencyLevel=<int> Sets the region's concurrency level. Valid values are >= 0");
    helpMap.put("-initialCapacity=",
        "-initialCapacity=<int> Sets the region's initial capacity. Valid values are >= 0");
    helpMap.put("-loadFactor=",
        "-loadFactor=<float> Sets the region's load factory. Valid values are >= 0.0");
    helpMap.put("-statisticsEnabled=",
        "-statisticsEnabled=<boolean> Sets the region's statistics enabled. Value values are true or false");
    helpMap.put("-region=", "Used to specify what region an operation is to be done on.");
    helpMap.put("-monitor",
        "-monitor Causes the stats command to keep periodically checking its statistic archives for updates.");
    helpMap.put("-peer=",
        "-peer=<true|false> True, the default, causes the locator to find peers for other peers. False will cause the locator to not locate peers.");
    helpMap.put("-server=",
        "-server=<true|false> True, the default, causes the locator to find servers for clients. False will cause the locator to not locate servers for clients.");
    helpMap.put("-outputDir=", "The directory where the disk store should be exported.");
  }

  protected final Map usageMap = new HashMap();

  protected void initUsageMap() {
    usageMap.put("gemfire", "gemfire [-debug] [-h[elp]] [-q] [-J<vmOpt>]*");
    usageMap.put("version", "version");
    usageMap.put("help", "help [" + join(helpTopics, "|") + "]");
    usageMap.put("stats",
        "stats ([<instanceId>][:<typeId>][.<statId>])* [-details] [-nofilter|-persec|-persample] [-prunezeros] [-starttime=<time>] [-endtime=<time>] -archive=<statFile>");
    usageMap.put(START_LOCATOR,
        "start-locator [-port=<port>] [-address=<ipAddr>] [-dir=<locatorDir>] [-properties=<gemfire.properties>] [-peer=<true|false>] [-server=<true|false>] [-hostname-for-clients=<ipAddr>] [-D<system.property>=<value>] [-X<vm-setting>]");
    usageMap.put("stop-locator",
        "stop-locator [-port=<port>] [-address=<ipAddr>] [-dir=<locatorDir>]");
    usageMap.put("status-locator", "status-locator [-dir=<locatorDir>]");
    usageMap.put("info-locator", "info-locator [-dir=<locatorDir>]");
    usageMap.put("tail-locator-log", "tail-locator-log [-dir=<locatorDir>]");
    usageMap.put("merge-logs", "merge-logs <logFile>+ [-out=<outFile>]");
    usageMap.put("validate-disk-store", "validate-disk-store <diskStoreName> <directory>+");
    usageMap.put("upgrade-disk-store",
        "upgrade-disk-store <diskStoreName> <directory>+ [-maxOplogSize=<int>]");
    usageMap.put("compact-disk-store",
        "compact-disk-store <diskStoreName> <directory>+ [-maxOplogSize=<int>]");
    usageMap.put("compact-all-disk-stores", "compact-all-disk-stores");
    usageMap.put("modify-disk-store",
        "modify-disk-store <diskStoreName> <directory>+ [-region=<regionName> [-remove|(-lru=<none|lru-entry-count|lru-heap-percentage|lru-memory-size>|-lruAction=<none|overflow-to-disk|local-destroy>|-lruLimit=<int>|-concurrencyLevel=<int>|-initialCapacity=<int>|-loadFactor=<float>|-statisticsEnabled=<boolean>)*]]");
    usageMap.put("list-missing-disk-stores", "list-missing-disk-stores");
    usageMap.put("export-disk-store",
        "export-disk-store <diskStoreName> <directory>+ [-outputDir=<directory>]");
    usageMap.put("shut-down-all", "shut-down-all [timeout_in_ms]");
    usageMap.put("backup", "backup [-baseline=<baseline directory>] <target directory>");
    usageMap.put("revoke-missing-disk-store", "revoke-missing-disk-store <disk-store-id>");
    usageMap.put("print-stacks", "print-stacks [-all-threads] [<filename>]");
  }

  // option statics
  @MakeNotStatic
  private static boolean debug = false;
  @MakeNotStatic
  private static boolean details = false;
  @MakeNotStatic
  private static boolean nofilter = false;
  @MakeNotStatic
  private static boolean persec = false;
  @MakeNotStatic
  private static boolean persample = false;
  @MakeNotStatic
  private static boolean prunezeros = false;
  @MakeNotStatic
  private static boolean quiet = false;
  @MakeNotStatic
  private static boolean help = false;
  @MakeNotStatic
  private static boolean monitor = false;
  @MakeNotStatic
  private static boolean showBuckets = false;
  @MakeNotStatic
  private static long startTime = -1;
  @MakeNotStatic
  private static long endTime = -1;
  @MakeNotStatic
  private static String portOption = null;
  @MakeNotStatic
  private static String addressOption = "";
  @MakeNotStatic
  private static String regionOption = null;
  @MakeNotStatic
  private static long maxOplogSize = -1L;
  @MakeNotStatic
  private static String lruOption = null;
  @MakeNotStatic
  private static String lruActionOption = null;
  @MakeNotStatic
  private static String lruLimitOption = null;
  @MakeNotStatic
  private static String concurrencyLevelOption = null;
  @MakeNotStatic
  private static String initialCapacityOption = null;
  @MakeNotStatic
  private static String loadFactorOption = null;
  @MakeNotStatic
  private static String compressorClassNameOption = null;
  @MakeNotStatic
  private static String statisticsEnabledOption = null;
  @MakeNotStatic
  private static boolean remove = false;
  @MakeNotStatic
  private static String sysDirName = null;
  @MakeNotStatic
  private static final ArrayList archiveOption = new ArrayList();
  @MakeNotStatic
  private static String printStacksOption = null;
  @MakeNotStatic
  private static String outOption = null;
  @MakeNotStatic
  private static Properties propertyOption = new Properties();
  @MakeNotStatic
  private static boolean serverOption = true;
  @MakeNotStatic
  private static boolean peerOption = true;
  @MakeNotStatic
  private static String gemfirePropertiesFileOption = null;
  @MakeNotStatic
  private static final ArrayList xoptions = new ArrayList();
  @MakeNotStatic
  private static String hostnameForClientsOption = null;
  @MakeNotStatic
  private static String baselineDir = null; // Baseline directory option value for backup command
  @MakeNotStatic
  private static String outputDir = null;

  @Immutable
  private static final Map<String, String[]> cmdOptionsMap;
  static {
    Map<String, String[]> optionsMap = new HashMap<>();
    optionsMap.put("gemfire", new String[] {"--help", "-h", "-help", "-debug", "-q"});
    optionsMap.put("version", new String[] {});
    optionsMap.put("help", new String[] {});
    optionsMap.put("merge-logs", new String[] {"-out="});
    optionsMap.put("stats", new String[] {"-details", "-monitor", "-nofilter", "-persec",
        "-persample", "-prunezeros", "-archive=", "-starttime=", "-endtime="});
    optionsMap.put(START_LOCATOR, new String[] {"-port=", "-dir=", "-address=", "-properties=",
        "-D", "-X", "-peer=", "-server=", "-hostname-for-clients="});
    optionsMap.put("stop-locator", new String[] {"-port=", "-dir=", "-address=", "-D"});
    optionsMap.put("status-locator", new String[] {"-dir=", "-D"});
    optionsMap.put("info-locator", new String[] {"-dir=", "-D"});
    optionsMap.put("tail-locator-log", new String[] {"-dir=", "-D"});
    optionsMap.put("validate-disk-store", new String[] {});
    optionsMap.put("upgrade-disk-store", new String[] {"-maxOplogSize="});
    optionsMap.put("compact-disk-store", new String[] {"-maxOplogSize="});
    optionsMap.put("modify-disk-store",
        new String[] {"-region=", "-remove", "-lru=", "-lruAction=", "-lruLimit=",
            "-concurrencyLevel=", "-initialCapacity=", "-loadFactor=", "-statisticsEnabled="});
    optionsMap.put("list-missing-disk-stores", new String[] {});
    optionsMap.put("compact-all-disk-stores", new String[] {});
    optionsMap.put("revoke-missing-disk-store", new String[] {});
    optionsMap.put("show-disk-store-metadata", new String[] {"-buckets"});
    optionsMap.put("export-disk-store", new String[] {"-outputDir="});
    optionsMap.put("shut-down-all", new String[] {});
    optionsMap.put("backup", new String[] {"-baseline="});
    optionsMap.put("print-stacks", new String[] {"-all-threads"});

    cmdOptionsMap = Collections.unmodifiableMap(optionsMap);
  }

  private static long parseLong(String arg) {
    try {
      return Long.parseLong(arg);
    } catch (NumberFormatException ex) {
      throw new IllegalArgumentException(
          "Could not parse -maxOplogSize=" + arg + " because: " + ex.getMessage());
    }
  }

  private static long parseTime(String arg) {
    DateFormat fmt = DateFormatter.createDateFormat();
    try {
      Date d = fmt.parse(arg);
      return d.getTime();
    } catch (ParseException ex) {
      throw new IllegalArgumentException(
          String.format("Time was not in this format %s. %s",
              new Object[] {DateFormatter.FORMAT_STRING, ex}));
    }
  }

  protected boolean matchCmdArg(String cmd, String arg) {
    String[] validArgs = (String[]) cmdOptionsMap.get(cmd.toLowerCase());
    for (int i = 0; i < validArgs.length; i++) {
      if (validArgs[i].endsWith("=") || validArgs[i].equals("-D") || validArgs[i].equals("-X")) {
        if (arg.toLowerCase().startsWith(validArgs[i]) || arg.startsWith(validArgs[i])) {
          String argValue = arg.substring(validArgs[i].length());
          if (validArgs[i].equals("-dir=")) {
            sysDirName = argValue;
          } else if (validArgs[i].equals("-archive=")) {
            archiveOption.add(new File(argValue));
          } else if (validArgs[i].equals("-port=")) {
            portOption = argValue;
          } else if (validArgs[i].equals("-address=")) {
            addressOption = argValue;
          } else if (validArgs[i].equals("-region=")) {
            regionOption = argValue;
          } else if (validArgs[i].equals("-maxOplogSize=")) {
            maxOplogSize = parseLong(argValue);
          } else if (validArgs[i].equals("-lru=")) {
            lruOption = argValue;
          } else if (validArgs[i].equals("-lruAction=")) {
            lruActionOption = argValue;
          } else if (validArgs[i].equals("-lruLimit=")) {
            lruLimitOption = argValue;
          } else if (validArgs[i].equals("-concurrencyLevel=")) {
            concurrencyLevelOption = argValue;
          } else if (validArgs[i].equals("-initialCapacity=")) {
            initialCapacityOption = argValue;
          } else if (validArgs[i].equals("-loadFactor=")) {
            loadFactorOption = argValue;
          } else if (validArgs[i].equals("-compressor=")) {
            compressorClassNameOption = argValue;
          } else if (validArgs[i].equals("-statisticsEnabled=")) {
            statisticsEnabledOption = argValue;
          } else if (validArgs[i].equals("-properties=")) {
            gemfirePropertiesFileOption = argValue;
          } else if (validArgs[i].equals("-out=")) {
            outOption = argValue;
          } else if (validArgs[i].equals("-starttime=")) {
            startTime = parseTime(argValue);
          } else if (validArgs[i].equals("-endtime=")) {
            endTime = parseTime(argValue);
          } else if (validArgs[i].equals("-peer=")) {
            peerOption = "true".equalsIgnoreCase(argValue);
          } else if (validArgs[i].equals("-server=")) {
            serverOption = "true".equalsIgnoreCase(argValue);
          } else if (validArgs[i].equals("-hostname-for-clients=")) {
            hostnameForClientsOption = argValue;
          } else if (validArgs[i].equals("-D")) {
            int idx = argValue.indexOf('=');
            String key = argValue.substring(0, idx);
            String value = argValue.substring(idx + 1);
            propertyOption.setProperty(key, value);
          } else if (validArgs[i].equals("-X")) {
            xoptions.add(arg);
          } else if (validArgs[i].equals("-baseline=")) {
            baselineDir = argValue;
          } else if (validArgs[i].equals("-outputDir=")) {
            outputDir = argValue;
          } else {
            throw new InternalGemFireException(
                String.format("unexpected valid option %s",
                    validArgs[i]));
          }
          return true;
        }
      } else if (validArgs[i].equalsIgnoreCase(arg)) {
        if (validArgs[i].equals("-h") || validArgs[i].toLowerCase().matches("-{0,2}help")) {
          help = true;
        } else if (validArgs[i].equals("-debug")) {
          debug = true;
        } else if (validArgs[i].equals("-remove")) {
          remove = true;
        } else if (validArgs[i].equals("-q")) {
          quiet = true;
        } else if (validArgs[i].equals("-details")) {
          details = true;
        } else if (validArgs[i].equals("-nofilter")) {
          nofilter = true;
        } else if (validArgs[i].equals("-persec")) {
          persec = true;
        } else if (validArgs[i].equals("-persample")) {
          persample = true;
        } else if (validArgs[i].equals("-prunezeros")) {
          prunezeros = true;
        } else if (validArgs[i].equals("-monitor")) {
          monitor = true;
        } else if (validArgs[i].equalsIgnoreCase("-buckets")) {
          showBuckets = true;
        } else if (validArgs[i].equals("-all-threads")) {
          printStacksOption = arg;
        } else {
          throw new InternalGemFireException(String.format("unexpected valid option %s",
              validArgs[i]));
        }
        return true;
      }
    }
    return false;
  }

  protected void printHelp(String cmd) {
    List<String> lines = format((String) helpMap.get(cmd.toLowerCase()), 80);
    for (String line : lines) {
      System.err.println(line);
    }
    usage(cmd);
  }

  public static List<String> format(String string, int width) {
    List<String> results = new ArrayList<String>();
    String[] realLines = string.split("\n");
    for (String line : realLines) {
      results.addAll(lineWrapOut(line, width));
      results.add("");
    }

    return results;
  }

  public static List<String> lineWrapOut(String string, int width) {
    Pattern pattern =
        Pattern.compile("(.{0," + (width - 1) + "}\\S|\\S{" + (width) + ",})(\n|\\s+|$)");

    Matcher matcher = pattern.matcher(string);
    List<String> lines = new ArrayList<String>();
    while (matcher.find()) {
      lines.add(matcher.group(1));
    }

    return lines;
  }

  private static String getExceptionMessage(Throwable ex) {
    String result = ex.getMessage();
    if (result == null || result.length() == 0) {
      result = ex.toString();
    }
    return result;
  }

  private static boolean needsSysDir(String cmd) {
    return !(cmd.equalsIgnoreCase("stats") || cmd.equalsIgnoreCase("merge-logs")
        || cmd.equalsIgnoreCase("version") || cmd.equalsIgnoreCase("help"));
  }

  public static File getProductDir() {
    File libdir = findGemFireLibDir();
    if (libdir == null) {
      return new File("").getAbsoluteFile(); // default to current directory
    } else {
      return libdir.getParentFile();
    }
  }

  public static File getHiddenDir() throws IOException {
    File prodDir = getProductDir();
    if (prodDir == null) {
      return null;
    }
    File hiddenDir = new File(prodDir.getParentFile(), "hidden");
    if (!hiddenDir.exists()) {
      hiddenDir = new File(prodDir.getCanonicalFile().getParentFile(), "hidden");
    }
    if (!hiddenDir.exists()) {
      // If we don't have a jar file (eg, when running in eclipse), look for a hidden
      // directory in same same directory as our classes.
      File libDir = findGemFireLibDir();
      File oldHiddenDir = hiddenDir;
      if (libDir != null && libDir.exists()) {
        hiddenDir = new File(libDir, "hidden");
      }
      if (!hiddenDir.exists()) {
        hiddenDir = oldHiddenDir;
      }
    }

    return hiddenDir;
  }

  public static void main(String[] args) {
    try {
      final SystemAdmin admin = new SystemAdmin();
      admin.initHelpMap();
      admin.initUsageMap();
      admin.invoke(args);
    } finally {
      InternalDistributedSystem sys = InternalDistributedSystem.getConnectedInstance();
      if (sys != null) {
        sys.disconnect();
      }
    }
  }

  public void invoke(String[] args) {
    String cmd = null;
    ArrayList cmdLine = new ArrayList(Arrays.asList(args));
    try {
      Iterator it = cmdLine.iterator();
      while (it.hasNext()) {
        String arg = (String) it.next();
        if (arg.startsWith("-")) {
          if (matchCmdArg("gemfire", arg)) {
            it.remove();
          } else {
            System.err.println(
                String.format("ERROR: Unknown option %s.", arg));
            usage();
          }
        } else {
          break;
        }
      }
    } catch (IllegalArgumentException ex) {
      System.err.println(
          "ERROR: " + getExceptionMessage(ex));
      if (debug) {
        ex.printStackTrace(System.err);
      }
      ExitCode.FATAL.doSystemExit(); // fix for bug 28351
    }
    if (cmdLine.size() == 0) {
      if (help) {
        printHelp("gemfire");
      } else {
        System.err.println("ERROR: Wrong number of command line args.");
        usage();
      }
    }
    cmd = (String) cmdLine.remove(0);
    cmd = checkCmd(cmd);
    File sysDir = null;
    // File configFile = null;
    try {
      Iterator it = cmdLine.iterator();
      while (it.hasNext()) {
        String arg = (String) it.next();
        if (arg.startsWith("-")) {
          if (matchCmdArg(cmd, arg) || matchCmdArg("gemfire", arg)) {
            it.remove();
          } else {
            System.err.println(
                String.format("ERROR: Unknown option %s.", arg));
            usage(cmd);
          }
        }
      }
    } catch (IllegalArgumentException ex) {
      System.err.println(
          "ERROR: " + getExceptionMessage(ex));
      if (debug) {
        ex.printStackTrace(System.err);
      }
      ExitCode.FATAL.doSystemExit(); // fix for bug 28351
    }
    if (needsSysDir(cmd) && !help) {
      if (sysDirName != null && sysDirName.length() > 0) {
        sysDir = new File(sysDirName).getAbsoluteFile();
      } else {
        sysDir = new File(System.getProperty("user.dir")).getAbsoluteFile();
      }
    }
    SystemFailure.loadEmergencyClasses();
    if (help) {
      printHelp(cmd);
    }
    try {
      if (cmd.equalsIgnoreCase("stats")) {
        statistics(sysDir, archiveOption, details, nofilter, persec, persample, prunezeros, monitor,
            startTime, endTime, cmdLine);
      } else if (cmd.equalsIgnoreCase("version")) {
        boolean optionOK = (cmdLine.size() == 0);
        if (cmdLine.size() == 1) {
          optionOK = false;

          String option = (String) cmdLine.get(0);
          if ("CREATE".equals(option) || "FULL".equalsIgnoreCase(option)) {
            // CREATE and FULL are secret for internal use only
            optionOK = true;
          }
        }

        if (!optionOK) {
          System.err.println(String.format("ERROR: unexpected command line arguments: %s.",
              join(cmdLine)));
          usage(cmd);
        }
        System.out.println(String.format("GemFire product directory: %s",
            getProductDir()));

        GemFireVersion.print(System.out);

      } else if (cmd.equalsIgnoreCase("help")) {
        if (cmdLine.size() > 1) {
          System.err.println(String.format("ERROR: unexpected command line arguments: %s.",
              join(cmdLine)));
          usage(cmd);
        }
        help(cmdLine);
      } else if (cmd.equalsIgnoreCase(START_LOCATOR)) {
        if (cmdLine.size() != 0) {
          System.err.println(String.format("ERROR: unexpected command line arguments: %s.",
              join(cmdLine)));
          usage(cmd);
        }
        locatorStart(sysDir, portOption, addressOption, gemfirePropertiesFileOption, propertyOption,
            xoptions, peerOption, serverOption, hostnameForClientsOption);
        if (!quiet) {
          System.out
              .println("Locator start complete.");
        }
      } else if (cmd.equalsIgnoreCase("stop-locator")) {
        if (cmdLine.size() != 0) {
          System.err.println(String.format("ERROR: unexpected command line arguments: %s.",
              join(cmdLine)));
          usage(cmd);
        }
        locatorStop(sysDir, portOption, addressOption, propertyOption);
        if (!quiet) {
          System.out
              .println("Locator stop complete.");
        }
      } else if (cmd.equalsIgnoreCase("status-locator")) {
        if (cmdLine.size() != 0) {
          System.err.println(String.format("ERROR: unexpected command line arguments: %s.",
              join(cmdLine)));
          usage(cmd);
        }
        if (!quiet) {
          System.out.println(locatorStatus(sysDir));
        }
      } else if (cmd.equalsIgnoreCase("info-locator")) {
        if (cmdLine.size() != 0) {
          System.err.println(String.format("ERROR: unexpected command line arguments: %s.",
              join(cmdLine)));
          usage(cmd);
        }
        System.out.println(locatorInfo(sysDir));
      } else if (cmd.equalsIgnoreCase("tail-locator-log")) {
        if (cmdLine.size() != 0) {
          System.err.println(String.format("ERROR: unexpected command line arguments: %s.",
              join(cmdLine)));
          usage(cmd);
        }
        System.out.println(locatorTailLog(sysDir));
      } else if (cmd.equalsIgnoreCase("merge-logs")) {
        if (cmdLine.size() == 0) {
          System.err
              .println("ERROR: expected at least one log file to merge.");
          usage(cmd);
        }
        mergeLogs(outOption, cmdLine);
      } else if (cmd.equalsIgnoreCase("validate-disk-store")) {
        if (cmdLine.size() == 0) {
          System.err.println("Expected disk store name and at least one directory");
          usage(cmd);
        } else if (cmdLine.size() == 1) {
          System.err.println("Expected at least one directory");
          usage(cmd);
        }
        validateDiskStore(cmdLine);
      } else if (cmd.equalsIgnoreCase("upgrade-disk-store")) {
        if (cmdLine.size() == 0) {
          System.err.println("Expected disk store name and at least one directory");
          usage(cmd);
        } else if (cmdLine.size() == 1) {
          System.err.println("Expected at least one directory");
          usage(cmd);
        }
        upgradeDiskStore(cmdLine);
      } else if (cmd.equalsIgnoreCase("compact-disk-store")) {
        if (cmdLine.size() == 0) {
          System.err.println("Expected disk store name and at least one directory");
          usage(cmd);
        } else if (cmdLine.size() == 1) {
          System.err.println("Expected at least one directory");
          usage(cmd);
        }
        compactDiskStore(cmdLine);
      } else if (cmd.equalsIgnoreCase("compact-all-disk-stores")) {
        if (cmdLine.size() != 0) {
          System.err.println("Did not expect any command line arguments");
          usage(cmd);
        }
        compactAllDiskStores(cmdLine);
      } else if (cmd.equalsIgnoreCase("modify-disk-store")) {
        if (cmdLine.size() == 0) {
          System.err.println("Expected disk store name and at least one directory");
          usage(cmd);
        } else if (cmdLine.size() == 1) {
          System.err.println("Expected at least one directory");
          usage(cmd);
        }
        modifyDiskStore(cmdLine);
      } else if (cmd.equalsIgnoreCase("list-missing-disk-stores")) {
        if (cmdLine.size() != 0) {
          System.err.println("Did not expect any command line arguments");
          usage(cmd);
        }
        listMissingDiskStores();
      } else if (cmd.equalsIgnoreCase("revoke-missing-disk-store")) {
        if (cmdLine.size() != 1) {
          System.err.println("Expected a disk store id");
          usage(cmd);
        }
        revokeMissingDiskStores(cmdLine);
      } else if (cmd.equalsIgnoreCase("show-disk-store-metadata")) {
        if (cmdLine.size() == 0) {
          System.err.println("Expected disk store name and at least one directory");
          usage(cmd);
        } else if (cmdLine.size() == 1) {
          System.err.println("Expected at least one directory");
          usage(cmd);
        }
        showDiskStoreMetadata(cmdLine);
      } else if (cmd.equalsIgnoreCase("export-disk-store")) {
        if (cmdLine.size() == 0) {
          System.err.println("Expected disk store name and at least one directory");
          usage(cmd);
        } else if (cmdLine.size() == 1) {
          System.err.println("Expected at least one directory");
          usage(cmd);
        }
        exportDiskStore(cmdLine, outputDir);
      } else if (cmd.equalsIgnoreCase("shut-down-all")) {
        if (cmdLine.size() > 1) {
          System.err.println("Expected an optional timeout (ms)");
          usage(cmd);
        }
        shutDownAll(cmdLine);
      } else if (cmd.equalsIgnoreCase("backup")) {
        if (cmdLine.size() != 1) {
          usage(cmd);
        }
        backup((String) cmdLine.get(0));
      } else if (cmd.equalsIgnoreCase("print-stacks")) {
        printStacks(cmdLine, printStacksOption != null);
      } else {
        System.err
            .println(String.format("ERROR: Unknown command %s.", cmd));
        usage();
      }
    } catch (InterruptedException ex) {
      System.err.println(String.format("ERROR: Operation %s failed because: %s.",
          new Object[] {cmd, getExceptionMessage(ex)}));
      if (debug) {
        ex.printStackTrace(System.err);
      }
      ExitCode.FATAL.doSystemExit(); // fix for bug 28351
    } catch (IllegalArgumentException ex) {
      System.err.println(String.format("ERROR: Operation %s failed because: %s.",
          new Object[] {cmd, getExceptionMessage(ex)}));

      if (debug) {
        ex.printStackTrace(System.err);
      }
      ExitCode.FATAL.doSystemExit(); // fix for bug 28351
    } catch (Exception ex) {
      System.err.println(String.format("ERROR: Operation %s failed because: %s.",
          new Object[] {cmd, getExceptionMessage(ex)}));
      if (debug) {
        ex.printStackTrace(System.err);
      }
      ExitCode.FATAL.doSystemExit(); // fix for bug 28351
    }
  }
}
