'Combine this tree and the data represented by data using the
connector conn_type. The combine is done by squashing the node other
away if possible.
This tree (self) will never be pushed to a child node of the
combined tree, nor will the connector or negated properties change.
Return a node which can be used in place of data regardless if the
node other got squashed or not.
If `squash` is False the data is prepared and added as a child to
this tree without further logic.'

def add(self, data, conn_type, squash=True):

    if (data in self.children):
        return data
    if (not squash):
        self.children.append(data)
        return data
    if (self.connector == conn_type):
        if (isinstance(data, Node) and (not data.negated) and ((data.connector == conn_type) or (len(data) == 1))):
            self.children.extend(data.children)
            return self
        else:
            self.children.append(data)
            return data
    else:
        obj = self._new_instance(self.children, self.connector, self.negated)
        self.connector = conn_type
        self.children = [obj, data]
        return data
