/** Merges the two provided arguments into one OR filter in the most efficient way. */
 public static ObjectFilter filterOr(ObjectFilter origFilter, ObjectFilter additionalFilter) {
   if (origFilter == additionalFilter) {
     // OR with itself
     return origFilter;
   }
   if (origFilter == null) {
     return additionalFilter;
   }
   if (additionalFilter == null) {
     return origFilter;
   }
   if (origFilter instanceof AllFilter) {
     return origFilter;
   }
   if (additionalFilter instanceof AllFilter) {
     return additionalFilter;
   }
   if (origFilter instanceof NoneFilter) {
     return additionalFilter;
   }
   if (additionalFilter instanceof NoneFilter) {
     return origFilter;
   }
   if (origFilter instanceof OrFilter) {
     if (!((OrFilter) origFilter).contains(additionalFilter)) {
       ((OrFilter) origFilter).addCondition(additionalFilter);
     }
     return origFilter;
   }
   return OrFilter.createOr(origFilter, additionalFilter);
 }
  public static ObjectFilter simplify(ObjectFilter filter) {
    if (filter == null) {
      return null;
    }
    if (filter instanceof AndFilter) {
      List<ObjectFilter> conditions = ((AndFilter) filter).getConditions();
      AndFilter simplifiedFilter = ((AndFilter) filter).cloneEmpty();
      for (ObjectFilter subfilter : conditions) {
        if (subfilter instanceof NoneFilter) {
          // AND with "false"
          return NoneFilter.createNone();
        } else if (subfilter instanceof AllFilter) {
          // AND with "true", just skip it
        } else {
          ObjectFilter simplifiedSubfilter = simplify(subfilter);
          simplifiedFilter.addCondition(simplifiedSubfilter);
        }
      }
      if (simplifiedFilter.isEmpty()) {
        return AllFilter.createAll();
      }
      return simplifiedFilter;

    } else if (filter instanceof OrFilter) {
      List<ObjectFilter> conditions = ((OrFilter) filter).getConditions();
      OrFilter simplifiedFilter = ((OrFilter) filter).cloneEmpty();
      for (ObjectFilter subfilter : conditions) {
        if (subfilter instanceof NoneFilter) {
          // OR with "false", just skip it
        } else if (subfilter instanceof AllFilter) {
          // OR with "true"
          return AllFilter.createAll();
        } else {
          ObjectFilter simplifiedSubfilter = simplify(subfilter);
          simplifiedFilter.addCondition(simplifiedSubfilter);
        }
      }
      if (simplifiedFilter.isEmpty()) {
        return AllFilter.createAll();
      }
      return simplifiedFilter;

    } else if (filter instanceof NotFilter) {
      ObjectFilter subfilter = ((NotFilter) filter).getFilter();
      ObjectFilter simplifiedSubfilter = simplify(subfilter);
      if (subfilter instanceof NoneFilter) {
        return AllFilter.createAll();
      } else if (subfilter instanceof AllFilter) {
        return NoneFilter.createNone();
      } else {
        NotFilter simplifiedFilter = ((NotFilter) filter).cloneEmpty();
        simplifiedFilter.setFilter(simplifiedSubfilter);
        return simplifiedFilter;
      }
    } else {
      // Cannot simplify
      return filter.clone();
    }
  }
  private ObjectQuery createQuery() {
    AccountContentSearchDto dto = searchModel.getObject();
    if (StringUtils.isEmpty(dto.getSearchText())) {
      return null;
    }

    try {
      ObjectQuery query = null;

      List<ObjectFilter> conditions = new ArrayList<>();
      ObjectClassComplexTypeDefinition def = getAccountDefinition();
      if (dto.isIdentifiers()) {

        List<ResourceAttributeDefinition> identifiers = new ArrayList<>();
        if (def.getIdentifiers() != null) {
          identifiers.addAll(def.getIdentifiers());
        }

        // TODO set matching rule instead fo null
        for (ResourceAttributeDefinition attrDef : identifiers) {
          conditions.add(
              EqualFilter.createEqual(
                  new ItemPath(ShadowType.F_ATTRIBUTES, attrDef.getName()),
                  attrDef,
                  dto.getSearchText()));
        }
      }

      if (dto.isName()) {
        List<ResourceAttributeDefinition> secondaryIdentifiers = new ArrayList<>();
        if (def.getNamingAttribute() != null) {
          secondaryIdentifiers.add(def.getNamingAttribute());
        } else if (def.getSecondaryIdentifiers() != null) {
          secondaryIdentifiers.addAll(def.getSecondaryIdentifiers());
        }
        for (ResourceAttributeDefinition attrDef : secondaryIdentifiers) {
          conditions.add(
              SubstringFilter.createSubstring(
                  new ItemPath(ShadowType.F_ATTRIBUTES, attrDef.getName()),
                  attrDef,
                  dto.getSearchText()));
        }
      }

      if (!conditions.isEmpty()) {
        if (conditions.size() > 1) {
          query = ObjectQuery.createObjectQuery(OrFilter.createOr(conditions));
        } else {
          query = ObjectQuery.createObjectQuery(conditions.get(0));
        }
      }

      return query;
    } catch (Exception ex) {
      error(getString("pageUsers.message.queryError") + " " + ex.getMessage());
      LoggingUtils.logException(LOGGER, "Couldn't create query filter.", ex);
    }

    return null;
  }