import re


def parse_branch_names(expression, tree, expandAliases=True):
    """
    Parses an *expression* string and returns the contained branch names in a list. The *tree*
    is required to validate the found branch names. When multiple
    expressions are passed, a joined list with unique branch names is returned. When
    *expandAliases* is *True*, all expressions are tested for aliases which get expanded.
    """
    expressions = list(expression) if isinstance(expression, (list, tuple, set)) \
        else [expression]

    allBranches = [b.GetName() for b in tree.GetListOfBranches()]
    branches = []

    while expressions:
        expression = expressions.pop(0)
        spaced = re.sub("(\+|\-|\*|\/|\(|\)|\:|\,)", " ", expression)
        parts = [s.strip() for s in spaced.split(" ") if s.strip()]
        for b in parts:
            if expandAliases and tree.GetAlias(b):
                expressions.insert(0, tree.GetAlias(b))
                continue
            if b in allBranches and b not in branches:
                branches.append(b)

    return branches