code: private String generateSubstitutionTokenString(String baseToken,
                                                     Long suffixCounter,
                                                     Set<String> expressionAttributeNamesKeys,
                                                     Set<String> expressionAttributeValuesKeys) {
          String hexSuffix = Long.toHexString(suffixCounter);
          String tokenBase = baseToken.substring(0, Math.min(baseToken.length(), 4)) + hexSuffix;
          if (!expressionAttributeNamesKeys.contains(getExpressionAttributeNameSubstitutionToken(tokenBase)) &&
                      !expressionAttributeValuesKeys.contains(getExpressionAttributeValueSubstitutionToken(tokenBase))) {
              return tokenBase;
          }
          // Fallback to fullToken in case of conflict
          String fullToken = baseToken + hexSuffix;
          if (!expressionAttributeNamesKeys.contains(getExpressionAttributeNameSubstitutionToken(fullToken)) &&
                      !expressionAttributeValuesKeys.contains(getExpressionAttributeValueSubstitutionToken(fullToken))) {
              return fullToken;
          } else {
              throw new DynamoDBMappingException("Failed to process update operation inside transactionWrite request due to conflict with expressionAttributeName or expressionAttributeValue token name: "
                                                         + fullToken + ". Please replace this token name with a different token name.");
          }
      }
docs: Generate a string that can be used as a substitution token for attributeNames and attributeValues in
  update expression. De-dupes generated string on existingAttributesKeyList.
  The string starts with a baseToken's substring that is passed in from the caller and then appended with a hex string
  the hex string represents the locally incremented counter across attributes.
  In case there is a conflict with above generated string, we'll instead substitute with the full baseToken
  instead of the baseToken substring
  
  For ex:
  For a baseToken: 5d81, suffixCounter: 9
  the *next* generated string will be 5d81a, 5d81 from baseToken and `a` from the incremented hex counter 9 -> a