docs: def parse(self, conditions):
          """ Parse filter conditions.
  
              @param conditions: multiple conditions.
              @type conditions: list or str
          """
          conditions_text = conditions
          try:
              conditions = shlex.split(fmt.to_utf8(conditions))
          except AttributeError:
              # Not a string, assume parsed tree
              conditions_text = self._tree2str(conditions)
  
          # Empty list?
          if not conditions:
              raise FilterError("No conditions given at all!")
  
          # NOT *must* appear at the start of a group
          negate = conditions[:1] == ["NOT"]
          if negate:
              conditions = conditions[1:]
              if not conditions:
                  raise FilterError("NOT must be followed by some conditions!")
  
          # Handle grouping
          if '[' in conditions:
              tree = [[]]
              for term in conditions:
                  if term == '[':
                      tree.append([]) # new grouping
                  elif term == ']':
                      subtree = tree.pop()
                      if not tree:
                          raise FilterError("Unbalanced brackets, too many closing ']' in condition %r" % (conditions_text,))
                      tree[-1].append(subtree) # append finished group to containing level
                  else:
                      tree[-1].append(term) # append to current level
  
              if len(tree) > 1:
                  raise FilterError("Unbalanced brackets, too many open '[' in condition %r" % (conditions_text,))
              conditions = tree[0]
  
          # Prepare root matcher
          conditions = list(conditions)
          matcher = CompoundFilterAll()
          if "OR" in conditions:
              root = CompoundFilterAny()
              root.append(matcher)
          else:
              root = matcher
  
          # Go through conditions and parse them
          for condition in conditions:
              if condition == "OR":
                  # Leading OR, or OR OR in sequence?
                  if not matcher:
                      raise FilterError("Left-hand side of OR missing in %r!" % (conditions_text,))
  
                  # Start next run of AND conditions
                  matcher = CompoundFilterAll()
                  root.append(matcher)
              elif isinstance(condition, list):
                  matcher.append(self.parse(condition))
              else:
                  matcher.append(self._create_filter(condition))
  
          # Trailing OR?
          if not matcher:
              raise FilterError("Right-hand side of OR missing in %r!" % (conditions_text,))
  
          return NegateFilter(root) if negate else root