@VisibleForTesting
  public static boolean updateMapInternal(BiMap<Integer, String> map,
      String mapName, String command, String regex,
      Map<Integer, Integer> staticMapping) throws IOException  {
    boolean updated = false;
    BufferedReader br = null;
    try {
      Process process = Runtime.getRuntime().exec(
          new String[] { "bash", "-c", command });
      br = new BufferedReader(
          new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
      String line = null;
      while ((line = br.readLine()) != null) {
        String[] nameId = line.split(regex);
        if ((nameId == null) || (nameId.length != 2)) {
          throw new IOException("Can't parse " + mapName + " list entry:" + line);
        }
        LOG.debug("add to " + mapName + "map:" + nameId[0] + " id:" + nameId[1]);
        // HDFS can't differentiate duplicate names with simple authentication
        final Integer key = staticMapping.get(parseId(nameId[1]));
        final String value = nameId[0];
        if (map.containsKey(key)) {
          final String prevValue = map.get(key);
          if (value.equals(prevValue)) {
            // silently ignore equivalent entries
            continue;
          }
          reportDuplicateEntry(
              "Got multiple names associated with the same id: ",
              key, value, key, prevValue);           
          continue;
        }
        if (map.containsValue(value)) {
          final Integer prevKey = map.inverse().get(value);
          reportDuplicateEntry(
              "Got multiple ids associated with the same name: ",
              key, value, prevKey, value);
          continue;
        }
        map.put(key, value);
        updated = true;
      }
      LOG.debug("Updated " + mapName + " map size: " + map.size());
      
    } catch (IOException e) {
      LOG.error("Can't update " + mapName + " map");
      throw e;
    } finally {
      if (br != null) {
        try {
          br.close();
        } catch (IOException e1) {
          LOG.error("Can't close BufferedReader of command result", e1);
        }
      }
    }
    return updated;
  }
@Test
  public void testIdOutOfIntegerRange() throws IOException {
    assumeNotWindows();
    String GET_ALL_USERS_CMD = "echo \""
        + "nfsnobody:x:4294967294:4294967294:Anonymous NFS User:/var/lib/nfs:/sbin/nologin\n"
        + "nfsnobody1:x:4294967295:4294967295:Anonymous NFS User:/var/lib/nfs1:/sbin/nologin\n"
        + "maxint:x:2147483647:2147483647:Grid Distributed File System:/home/maxint:/bin/bash\n"
        + "minint:x:2147483648:2147483648:Grid Distributed File System:/home/minint:/bin/bash\n"
        + "archivebackup:*:1031:4294967294:Archive Backup:/home/users/archivebackup:/bin/sh\n"
        + "hdfs:x:11501:10787:Grid Distributed File System:/home/hdfs:/bin/bash\n"
        + "daemon:x:2:2:daemon:/sbin:/sbin/nologin\""
        + " | cut -d: -f1,3";
    String GET_ALL_GROUPS_CMD = "echo \""
        + "hdfs:*:11501:hrt_hdfs\n"
        + "rpcuser:*:29:\n"
        + "nfsnobody:*:4294967294:\n"
        + "nfsnobody1:*:4294967295:\n"
        + "maxint:*:2147483647:\n"
        + "minint:*:2147483648:\n"
        + "mapred3:x:498\"" 
        + " | cut -d: -f1,3";
    // Maps for id to name map
    BiMap<Integer, String> uMap = HashBiMap.create();
    BiMap<Integer, String> gMap = HashBiMap.create();

    ShellBasedIdMapping.updateMapInternal(uMap, "user", GET_ALL_USERS_CMD, ":",
        EMPTY_PASS_THROUGH_MAP);
    assertTrue(uMap.size() == 7);
    assertEquals("nfsnobody", uMap.get(-2));
    assertEquals("nfsnobody1", uMap.get(-1));
    assertEquals("maxint", uMap.get(2147483647));
    assertEquals("minint", uMap.get(-2147483648));
    assertEquals("archivebackup", uMap.get(1031));
    assertEquals("hdfs",uMap.get(11501));
    assertEquals("daemon", uMap.get(2));

    ShellBasedIdMapping.updateMapInternal(gMap, "group", GET_ALL_GROUPS_CMD, ":",
        EMPTY_PASS_THROUGH_MAP);
    assertTrue(gMap.size() == 7);
    assertEquals("hdfs",gMap.get(11501));
    assertEquals("rpcuser", gMap.get(29));
    assertEquals("nfsnobody", gMap.get(-2));
    assertEquals("nfsnobody1", gMap.get(-1));
    assertEquals("maxint", gMap.get(2147483647));
    assertEquals("minint", gMap.get(-2147483648));
    assertEquals("mapred3", gMap.get(498));
  }