public static InetAddress getAddressFromLong(Long addr) {
    if (addr == null) {
      return null;
    }

    AuAssert.check(addr >= 0 && addr < (1L << 32));

    byte[] bytes =
        new byte[] {
          (byte) ((addr >> 24) & 0xff),
          (byte) ((addr >> 16) & 0xff),
          (byte) ((addr >> 8) & 0xff),
          (byte) (addr & 0xff)
        };

    try {
      return InetAddress.getByAddress(bytes);
    } catch (UnknownHostException e) {
      AuAssert.unreachable();
      return null;
    }
  }
  public static Long getAddressAsLong(InetAddress addr) {
    if (addr == null) {
      return null;
    }

    byte[] bytes = addr.getAddress();
    AuAssert.check(bytes.length == 4); // ipv4 only

    // byte & 0xff is a hack to use java unsigned byte
    return ((bytes[0] & 0xffL) << 24)
        + ((bytes[1] & 0xffL) << 16)
        + ((bytes[2] & 0xffL) << 8)
        + (bytes[3] & 0xffL);
  }
  /**
   * Get the number of network prefix bits from a netmask. This function does not validate whether
   * the netmask is really usufull or not, for example, it will treat "255.255.255.255",
   * "255.255.255.254", "255.255.255.252" as valid netmasks though they can not be used practically.
   *
   * @param netmask netmask
   * @return a 1 - 32 integer indicates the network part length, -1 when the input is not a valid
   *     netmask.
   */
  public static int getNetworkPrefixBits(long netmask) {
    AuAssert.check(netmask >= 0 && netmask < (1L << 32));

    int i = 0;
    long tmp = netmask;
    while (i <= 32) {
      if ((tmp & 1L) == 1L) {
        long expected = ((1L << 32) - 1L) >> i;
        if ((expected & tmp) == expected) {
          return 32 - i;
        } else {
          return -1;
        }
      }
      ++i;
      tmp = tmp >> 1;
    }

    return -1;
  }