docs: private static <T> void processKeyConditions(
          final QueryRequest queryRequest,
          final DynamoDBQueryExpression<T> expression,
          final DynamoDBMapperTableModel<T> model
      ) {
          // Hash key (primary or index) condition
          final Map<String,Condition> hashKeyConditions = new LinkedHashMap<String,Condition>();
          if (expression.getHashKeyValues() != null) {
              for (final DynamoDBMapperFieldModel<T,Object> field : model.fields()) {
                  if (field.keyType() == HASH || !field.globalSecondaryIndexNames(HASH).isEmpty()) {
                      final Object value = field.get(expression.getHashKeyValues());
                      if (value != null) {
                          hashKeyConditions.put(field.name(), field.eq(value));
                      }
                  }
              }
          }
  
          // Range key (primary or index) conditions
          final Map<String, Condition> rangeKeyConditions = expression.getRangeKeyConditions();
  
          // There should be least one hash key condition.
          final String keyCondExpression = queryRequest.getKeyConditionExpression();
          if (keyCondExpression == null) {
              if (isNullOrEmpty(hashKeyConditions)) {
                  throw new IllegalArgumentException(
                      "Illegal query expression: No hash key condition is found in the query");
              }
          } else {
              if (!isNullOrEmpty(hashKeyConditions)) {
                  throw new IllegalArgumentException(
                      "Illegal query expression: Either the hash key conditions or the key condition expression must be specified but not both.");
              }
              if (!isNullOrEmpty(rangeKeyConditions)) {
                  throw new IllegalArgumentException(
                      "Illegal query expression: The range key conditions can only be specified when the key condition expression is not specified.");
              }
              // key condition expression is in use
              return;
          }
          // We don't allow multiple range key conditions.
          if (rangeKeyConditions != null && rangeKeyConditions.size() > 1) {
              throw new IllegalArgumentException(
                      "Illegal query expression: Conditions on multiple range keys ("
                      + rangeKeyConditions.keySet().toString()
                      + ") are found in the query. DynamoDB service only accepts up to ONE range key condition.");
          }
          final boolean hasRangeKeyCondition = (rangeKeyConditions != null)
                                              && (!rangeKeyConditions.isEmpty());
          final String userProvidedIndexName = queryRequest.getIndexName();
          final String primaryHashKeyName = model.hashKey().name();
  
          // First collect the names of all the global/local secondary indexes that could be applied to this query.
          // If the user explicitly specified an index name, we also need to
          //   1) check the index is applicable for both hash and range key conditions
          //   2) choose one hash key condition if there are more than one of them
          boolean hasPrimaryHashKeyCondition = false;
          final Map<String, Set<String>> annotatedGSIsOnHashKeys = new HashMap<String, Set<String>>();
          String hashKeyNameForThisQuery = null;
  
          boolean hasPrimaryRangeKeyCondition = false;
          final Set<String> annotatedLSIsOnRangeKey = new HashSet<String>();
          final Set<String> annotatedGSIsOnRangeKey = new HashSet<String>();
  
          // Range key condition
          String rangeKeyNameForThisQuery = null;
          if (hasRangeKeyCondition) {
              for (String rangeKeyName : rangeKeyConditions.keySet()) {
                  rangeKeyNameForThisQuery = rangeKeyName;
  
                  final DynamoDBMapperFieldModel<T,Object> rk = model.field(rangeKeyName);
  
                  if (rk.keyType() == RANGE) {
                      hasPrimaryRangeKeyCondition = true;
                  }
  
                  annotatedLSIsOnRangeKey.addAll(rk.localSecondaryIndexNames());
                  annotatedGSIsOnRangeKey.addAll(rk.globalSecondaryIndexNames(RANGE));
              }
  
              if ( !hasPrimaryRangeKeyCondition
                   && annotatedLSIsOnRangeKey.isEmpty()
                   && annotatedGSIsOnRangeKey.isEmpty()) {
                  throw new DynamoDBMappingException(
                          "The query contains a condition on a range key (" +
                          rangeKeyNameForThisQuery + ") " +
                          "that is not annotated with either @DynamoDBRangeKey or @DynamoDBIndexRangeKey.");
              }
          }
  
          final boolean userProvidedLSIWithRangeKeyCondition = (userProvidedIndexName != null)
                                          && (annotatedLSIsOnRangeKey.contains(userProvidedIndexName));
          final boolean hashOnlyLSIQuery = (userProvidedIndexName != null)
                                          && ( !hasRangeKeyCondition )
                                          && model.localSecondaryIndex(userProvidedIndexName) != null;
          final boolean userProvidedLSI = userProvidedLSIWithRangeKeyCondition || hashOnlyLSIQuery;
  
          final boolean userProvidedGSIWithRangeKeyCondition = (userProvidedIndexName != null)
                                          && (annotatedGSIsOnRangeKey.contains(userProvidedIndexName));
          final boolean hashOnlyGSIQuery = (userProvidedIndexName != null)
                                          && ( !hasRangeKeyCondition )
                                          && model.globalSecondaryIndex(userProvidedIndexName) != null;
          final boolean userProvidedGSI = userProvidedGSIWithRangeKeyCondition || hashOnlyGSIQuery;
  
          if (userProvidedLSI && userProvidedGSI ) {
              throw new DynamoDBMappingException(
                      "Invalid query: " +
                      "Index \"" + userProvidedIndexName + "\" " +
                      "is annotateded as both a LSI and a GSI for attribute.");
          }
  
          // Hash key conditions
          for (String hashKeyName : hashKeyConditions.keySet()) {
              if (hashKeyName.equals(primaryHashKeyName)) {
                  hasPrimaryHashKeyCondition = true;
              }
  
              final DynamoDBMapperFieldModel<T,Object> hk = model.field(hashKeyName);
  
              Collection<String> annotatedGSINames = hk.globalSecondaryIndexNames(HASH);
              annotatedGSIsOnHashKeys.put(hashKeyName,
                      annotatedGSINames == null ? new HashSet<String>() : new HashSet<String>(annotatedGSINames));
  
              // Additional validation if the user provided an index name.
              if (userProvidedIndexName != null) {
                  boolean foundHashKeyConditionValidWithUserProvidedIndex = false;
                  if (userProvidedLSI && hashKeyName.equals(primaryHashKeyName)) {
                      // found an applicable hash key condition (primary hash + LSI range)
                      foundHashKeyConditionValidWithUserProvidedIndex = true;
                  } else if (userProvidedGSI &&
                          annotatedGSINames != null && annotatedGSINames.contains(userProvidedIndexName)) {
                      // found an applicable hash key condition (GSI hash + range)
                      foundHashKeyConditionValidWithUserProvidedIndex = true;
                  }
                  if (foundHashKeyConditionValidWithUserProvidedIndex) {
                      if ( hashKeyNameForThisQuery != null ) {
                          throw new IllegalArgumentException(
                                  "Ambiguous query expression: More than one hash key EQ conditions (" +
                                  hashKeyNameForThisQuery + ", " + hashKeyName +
                                  ") are applicable to the specified index ("
                                  + userProvidedIndexName + "). " +
                                  "Please provide only one of them in the query expression.");
                      } else {
                          // found an applicable hash key condition
                          hashKeyNameForThisQuery = hashKeyName;
                      }
                  }
              }
          }
  
          // Collate all the key conditions
          Map<String, Condition> keyConditions = new HashMap<String, Condition>();
  
          // With user-provided index name
          if (userProvidedIndexName != null) {
              if (hasRangeKeyCondition
                      && ( !userProvidedLSI )
                      && ( !userProvidedGSI )) {
                  throw new IllegalArgumentException(
                          "Illegal query expression: No range key condition is applicable to the specified index ("
                          + userProvidedIndexName + "). ");
              }
              if (hashKeyNameForThisQuery == null) {
                  throw new IllegalArgumentException(
                          "Illegal query expression: No hash key condition is applicable to the specified index ("
                          + userProvidedIndexName + "). ");
              }
  
              keyConditions.put(hashKeyNameForThisQuery, hashKeyConditions.get(hashKeyNameForThisQuery));
              if (hasRangeKeyCondition) {
                  keyConditions.putAll(rangeKeyConditions);
              }
          }
          // Infer the index name by finding the index shared by both hash and range key annotations.
          else {
              if (hasRangeKeyCondition) {
                  String inferredIndexName = null;
                  hashKeyNameForThisQuery = null;
                  if (hasPrimaryHashKeyCondition && hasPrimaryRangeKeyCondition) {
                      // Found valid query: primary hash + range key conditions
                      hashKeyNameForThisQuery = primaryHashKeyName;
                  } else {
                      // Intersect the set of all the indexes applicable to the range key
                      // with the set of indexes applicable to each hash key condition.
                      for (String hashKeyName : annotatedGSIsOnHashKeys.keySet()) {
                          boolean foundValidQueryExpressionWithInferredIndex = false;
                          String indexNameInferredByThisHashKey = null;
                          if (hashKeyName.equals(primaryHashKeyName)) {
                              if (annotatedLSIsOnRangeKey.size() == 1) {
                                  // Found valid query (Primary hash + LSI range conditions)
                                  foundValidQueryExpressionWithInferredIndex = true;
                                  indexNameInferredByThisHashKey = annotatedLSIsOnRangeKey.iterator().next();
                              }
                          }
  
                          Set<String> annotatedGSIsOnHashKey = annotatedGSIsOnHashKeys.get(hashKeyName);
                          // We don't need the data in annotatedGSIsOnHashKeys afterwards,
                          // so it's safe to do the intersection in-place.
                          annotatedGSIsOnHashKey.retainAll(annotatedGSIsOnRangeKey);
                          if (annotatedGSIsOnHashKey.size() == 1) {
                              // Found valid query (Hash + range conditions on a GSI)
                              if (foundValidQueryExpressionWithInferredIndex) {
                                  hashKeyNameForThisQuery = hashKeyName;
                                  inferredIndexName = indexNameInferredByThisHashKey;
                              }
  
                              foundValidQueryExpressionWithInferredIndex = true;
                              indexNameInferredByThisHashKey = annotatedGSIsOnHashKey.iterator().next();
                          }
  
                          if (foundValidQueryExpressionWithInferredIndex) {
                              if (hashKeyNameForThisQuery != null) {
                                  throw new IllegalArgumentException(
                                          "Ambiguous query expression: Found multiple valid queries: " +
                                          "(Hash: \"" + hashKeyNameForThisQuery + "\", Range: \"" + rangeKeyNameForThisQuery + "\", Index: \"" + inferredIndexName + "\") and " +
                                          "(Hash: \"" + hashKeyName + "\", Range: \"" + rangeKeyNameForThisQuery + "\", Index: \"" + indexNameInferredByThisHashKey + "\").");
                              } else {
                                  hashKeyNameForThisQuery = hashKeyName;
                                  inferredIndexName = indexNameInferredByThisHashKey;
                              }
                          }
                      }
                  }
  
                  if (hashKeyNameForThisQuery != null) {
                      keyConditions.put(hashKeyNameForThisQuery, hashKeyConditions.get(hashKeyNameForThisQuery));
                      keyConditions.putAll(rangeKeyConditions);
                      queryRequest.setIndexName(inferredIndexName);
                  } else {
                      throw new IllegalArgumentException(
                              "Illegal query expression: Cannot infer the index name from the query expression.");
                  }
  
              } else {
                  // No range key condition is specified.
                  if (hashKeyConditions.size() > 1) {
                      if ( hasPrimaryHashKeyCondition ) {
                          keyConditions.put(primaryHashKeyName, hashKeyConditions.get(primaryHashKeyName));
                      } else {
                          throw new IllegalArgumentException(
                                  "Ambiguous query expression: More than one index hash key EQ conditions (" +
                                  hashKeyConditions.keySet() +
                                  ") are applicable to the query. " +
                                  "Please provide only one of them in the query expression, or specify the appropriate index name.");
                      }
  
                  } else {
                      // Only one hash key condition
                      String hashKeyName = annotatedGSIsOnHashKeys.keySet().iterator().next();
                      if ( !hasPrimaryHashKeyCondition ) {
                          if (annotatedGSIsOnHashKeys.get(hashKeyName).size() == 1) {
                              // Set the index if the index hash key is only annotated with one GSI.
                              queryRequest.setIndexName(annotatedGSIsOnHashKeys.get(hashKeyName).iterator().next());
                          } else if (annotatedGSIsOnHashKeys.get(hashKeyName).size() > 1) {
                              throw new IllegalArgumentException(
                                      "Ambiguous query expression: More than one GSIs (" +
                                      annotatedGSIsOnHashKeys.get(hashKeyName) +
                                      ") are applicable to the query. " +
                                      "Please specify one of them in your query expression.");
                          } else {
                              throw new IllegalArgumentException(
                                      "Illegal query expression: No GSI is found in the @DynamoDBIndexHashKey annotation for attribute " +
                                      "\"" + hashKeyName + "\".");
                          }
                      }
                      keyConditions.putAll(hashKeyConditions);
                  }
  
              }
          }
  
          queryRequest.setKeyConditions(keyConditions);
      }