docs: static final void internalHll4Update(final AbstractHllArray host, final int slotNo, final int newValue) {
      assert ((0 <= slotNo) && (slotNo < (1 << host.getLgConfigK())));
      assert (newValue > 0);
      final int curMin = host.getCurMin();
  
      AuxHashMap auxHashMap = host.getAuxHashMap(); //may be null
      final int rawStoredOldValue = host.getSlot(slotNo);  //could be 0
      //This is provably a LB:
      final int lbOnOldValue =  rawStoredOldValue + curMin; //lower bound, could be 0
  
      if (newValue > lbOnOldValue) { //842:
        //Note: if an AUX_TOKEN exists, then auxHashMap must already exist
        final int actualOldValue = (rawStoredOldValue < AUX_TOKEN)
            ? lbOnOldValue
            //846 rawStoredOldValue == AUX_TOKEN
            : auxHashMap.mustFindValueFor(slotNo); //lgtm [java/dereferenced-value-may-be-null]
  
        if (newValue > actualOldValue) { //848: actualOldValue could still be 0; newValue > 0
  
          //We know that the array will be changed, but we haven't actually updated yet.
          AbstractHllArray.hipAndKxQIncrementalUpdate(host, actualOldValue, newValue);
  
          assert (newValue >= curMin)
            : "New value " + newValue + " is less than current minimum " + curMin;
  
          //newValue >= curMin
  
          final int shiftedNewValue = newValue - curMin; //874
          assert (shiftedNewValue >= 0);
  
          if (rawStoredOldValue == AUX_TOKEN) { //879
  
            //Given that we have an AUX_TOKEN, there are four cases for how to
            //  actually modify the data structure
  
            if (shiftedNewValue >= AUX_TOKEN) { //CASE 1: //881
              //the byte array already contains aux token
              //This is the case where old and new values are both exceptions.
              //Therefore, the 4-bit array already is AUX_TOKEN. Only need to update auxMap
              auxHashMap.mustReplace(slotNo, newValue); //lgtm [java/dereferenced-value-may-be-null]
            }
            else {                              //CASE 2: //885
              //This is the (hypothetical) case where old value is an exception and the new one is not.
              // which is impossible given that curMin has not changed here and the newValue > oldValue.
              throw new SketchesStateException("Impossible case");
            }
          }
  
          else { //rawStoredOldValue != AUX_TOKEN
  
            if (shiftedNewValue >= AUX_TOKEN) { //CASE 3: //892
              //This is the case where the old value is not an exception and the new value is.
              //Therefore the AUX_TOKEN must be stored in the 4-bit array and the new value
              // added to the exception table.
              host.putSlot(slotNo, AUX_TOKEN);
              if (auxHashMap == null) {
                auxHashMap = host.getNewAuxHashMap();
                host.putAuxHashMap(auxHashMap, false);
              }
              auxHashMap.mustAdd(slotNo, newValue);
            }
            else {                             // CASE 4: //897
              //This is the case where neither the old value nor the new value is an exception.
              //Therefore we just overwrite the 4-bit array with the shifted new value.
              host.putSlot(slotNo, shiftedNewValue);
            }
          }
  
          // we just increased a pair value, so it might be time to change curMin
          if (actualOldValue == curMin) { //908
            assert (host.getNumAtCurMin() >= 1);
            host.decNumAtCurMin();
            while (host.getNumAtCurMin() == 0) {
              shiftToBiggerCurMin(host); //increases curMin by 1, and builds a new aux table,
              //shifts values in 4-bit table, and recounts curMin
            }
          }
        } //end newValue <= actualOldValue
      } //end newValue <= lbOnOldValue -> return, no need to update array
    }