Converts the current expression into a single matcher, applying
            coordination operators to operands according to their binding rules

def evaluate(self):
        """ Converts the current expression into a single matcher, applying
            coordination operators to operands according to their binding rules
        """

        # Apply Shunting Yard algorithm to convert the infix expression
        # into Reverse Polish Notation. Since we have a very limited
        # set of operators and binding rules, the implementation becomes
        # really simple. The expression is formed of hamcrest matcher instances
        # and operators identifiers (ints).
        ops = []
        rpn = []
        for token in self.expr:
            if isinstance(token, int):
                while len(ops) and token <= ops[-1]:
                    rpn.append(ops.pop())
                ops.append(token)
            else:
                rpn.append(token)

        # Append the remaining operators
        while len(ops):
            rpn.append(ops.pop())

        # Walk the RPN expression to create AllOf/AnyOf matchers
        stack = []
        for token in rpn:
            if isinstance(token, int):
                # Handle the NOT case in a special way since it's unary
                if token == OPERATOR.NOT:
                    stack[-1] = IsNot(stack[-1])
                    continue

                # Our operators always need two operands
                if len(stack) < 2:
                    raise RuntimeError('Unable to build a valid expression. Not enough operands available.')

                # Check what kind of matcher we need to create
                if token == OPERATOR.OR:
                    matcher = hc.any_of(*stack[-2:])
                else:  # AND, BUT
                    matcher = hc.all_of(*stack[-2:])

                stack[-2:] = [matcher]
            else:
                stack.append(token)

        if len(stack) != 1:
            raise RuntimeError('Unable to build a valid expression. The RPN stack should have just one item.')

        matcher = stack.pop()

        # If a description has been given include it in the matcher
        if self.description:
            matcher = hc.described_as(self.description, matcher)

        return matcher