def search(value, criteria_pattern, criteria_condition, check_function):
    """
    Search a list of values that match all child criteria. If condition is 'any', return a
    successful match if any items match all child criteria. If condition is 'all', return a
    successful match if ALL items match all child criteria.

    value: the payload list to search
    condition: one of:
      * any - return true if any payload items of the list match all criteria items
      * all - return true if all payload items of the list match all criteria items
      * all2any - return true if all payload items of the list match any criteria items
      * any2any - return true if any payload items match any criteria items
    pattern: a dictionary of criteria to apply to each item of the list

    This operator has O(n) algorithmic complexity in terms of number of child patterns.
    This operator has O(n) algorithmic complexity in terms of number of payload fields.

    However, it has O(n_patterns * n_payloads) algorithmic complexity, where:
      n_patterns = number of child patterns
      n_payloads = number of fields in payload
    It is therefore very easy to write a slow rule when using this operator.

    This operator should ONLY be used when trying to match a small number of child patterns and/or
    a small number of payload list elements.

    Other conditions (such as 'count', 'count_gt', 'count_gte', etc.) can be added as needed.

    Data from the trigger:

    {
        "fields": [
            {
                "field_name": "Status",
                "to_value": "Approved"
            }
        ]
    }

    Example #1

    ---
    criteria:
      trigger.fields:
        type: search
        # Controls whether this criteria has to match any or all items of the list
        condition: any  # or all or all2any or any2any
        pattern:
          # Here our context is each item of the list
          # All of these patterns have to match the item for the item to match
          # These are simply other operators applied to each item in the list
          # "#" and text after are ignored.
          # This allows dictionary keys to be unique but refer to the same field
          item.field_name:
            type: "equals"
            pattern: "Status"

          item.to_value:
            type: "equals"
            pattern: "Approved"

          item.field_name#1:
            type: "greaterthan"
            pattern: 40

          item.field_name#2:
            type: "lessthan"
            pattern: 50
    """
    if isinstance(value, dict):
        value = [value]
    payloadItemMatch = all
    patternMatch = all
    if criteria_condition == "any":
        payloadItemMatch = any
    elif criteria_condition == "all2any":
        patternMatch = any
    elif criteria_condition == "any2any":
        payloadItemMatch = any
        patternMatch = any
    elif criteria_condition != "all":
        raise UnrecognizedConditionError(
            "The '%s' condition is not recognized for type search, 'any', 'all', 'any2any'"
            " and 'all2any' are allowed" % criteria_condition
        )

    rtn = payloadItemMatch(
        [
            # any/all payload item can match
            patternMatch(
                [
                    # Match any/all patterns
                    check_function(
                        child_criterion_k,
                        child_criterion_v,
                        PayloadLookup(
                            child_payload, prefix=TRIGGER_ITEM_PAYLOAD_PREFIX
                        ),
                    )
                    for child_criterion_k, child_criterion_v in six.iteritems(
                        criteria_pattern
                    )
                ]
            )
            for child_payload in value
        ]
    )
    return rtn

    Search a list of values that match all child criteria. If condition is 'any', return a
    successful match if any items match all child criteria. If condition is 'all', return a
    successful match if ALL items match all child criteria.

    value: the payload list to search
    condition: one of:
      * any - return true if any payload items of the list match all criteria items
      * all - return true if all payload items of the list match all criteria items
      * all2any - return true if all payload items of the list match any criteria items
      * any2any - return true if any payload items match any criteria items
    pattern: a dictionary of criteria to apply to each item of the list

    This operator has O(n) algorithmic complexity in terms of number of child patterns.
    This operator has O(n) algorithmic complexity in terms of number of payload fields.

    However, it has O(n_patterns * n_payloads) algorithmic complexity, where:
      n_patterns = number of child patterns
      n_payloads = number of fields in payload
    It is therefore very easy to write a slow rule when using this operator.

    This operator should ONLY be used when trying to match a small number of child patterns and/or
    a small number of payload list elements.

    Other conditions (such as 'count', 'count_gt', 'count_gte', etc.) can be added as needed.

    Data from the trigger:

    {
        "fields": [
            {
                "field_name": "Status",
                "to_value": "Approved"
            }
        ]
    }

    Example #1

    ---
    criteria:
      trigger.fields:
        type: search
        # Controls whether this criteria has to match any or all items of the list
        condition: any  # or all or all2any or any2any
        pattern:
          # Here our context is each item of the list
          # All of these patterns have to match the item for the item to match
          # These are simply other operators applied to each item in the list
          # "#" and text after are ignored.
          # This allows dictionary keys to be unique but refer to the same field
          item.field_name:
            type: "equals"
            pattern: "Status"

          item.to_value:
            type: "equals"
            pattern: "Approved"

          item.field_name#1:
            type: "greaterthan"
            pattern: 40

          item.field_name#2:
            type: "lessthan"
            pattern: 50
    
st2common/st2common/operators.py