static BigInteger toUnsignedBigInteger(long input) {
    // if the value is less than the max unsigned, avoid doing conversion to avoid performance impact
    if (input >= 0L) {
      return BigInteger.valueOf(input);
    } else {
      int upper = (int) (input >>> 32);
      int lower = (int) input;
      return BigInteger.valueOf(Integer.toUnsignedLong(upper)).shiftLeft(32).add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
    }
  }
@Test
  public void longToUnsignedBigIntegerConversion() {
    Assertions.assertEquals("0", toUnsignedBigInteger(0).toString());
    Assertions.assertEquals(MAX_UNSIGNED_LONG, toUnsignedBigInteger(-1).toString());
    Assertions.assertEquals(String.valueOf(Long.MAX_VALUE), toUnsignedBigInteger(Long.MAX_VALUE).toString());
    Assertions.assertEquals("10", toUnsignedBigInteger(10L).toString());
    // equivalent of lower 32 bits all set to 0 and upper 32 bits alternating 10
    Assertions.assertEquals("12297829379609722880", toUnsignedBigInteger(-6148914694099828736L).toString());
  }