/**
   * Constructs a new MultiElementQuery instance. MultiElementQuery requires the target, the result
   * and the element class being provided. It will use them for creating the result object.
   *
   * <p>The execution of an empty query will result in the same object being returned. No operation
   * will be performed.
   *
   * @param elementClass A class of the components in the queried composition.
   * @param targetClass A class of the queried object.
   * @param resultClass A class of the result, it must be a class that can be instantiated. If it is
   *     not, a {@link QueryException} will be thrown during query execution.
   */
  public MultiElementQuery(Class<?> elementClass, Class<?> targetClass, Class<?> resultClass) {
    initialSelectors.add(InitialSelectors.all());
    valueFilter = ValueFilters.any();
    functions.add(QueryFunctions.<R>noOperation());

    this.targetClass = targetClass;
    this.elementClass = elementClass;
    this.resultClass = resultClass;
  }
 @SuppressWarnings("unchecked")
 protected void addValueFilter(IValueFilter<? super E> filter) {
   valueFilter = ValueFilters.<Object>allOf(valueFilter, filter);
 }
 /**
  * Adds a value filter that operates on a specific field of the target class to the query.
  *
  * @param fieldName A field name that will be used in matching.
  * @param filter A value filter to add.
  * @param <S> A type of the field.
  * @return This query.
  */
 public <S> MultiElementQuery<E, Q, R> matching(String fieldName, IValueFilter<S> filter) {
   addValueFilter(ValueFilters.<E, S>fieldValue(fieldName, filter));
   return this;
 }