public function addChild(self $node)
    {
        $cardinalityMap = $this->getCardinalityMap();
        $nodeType = $node->getNodeType();

        // if proposed child node is of an invalid type
        if (!isset($cardinalityMap[$nodeType])) {
            throw new OutOfBoundsException(sprintf(
                'QueryBuilder node "%s" of type "%s" cannot be appended to "%s". '.
                'Must be one type of "%s"',
                $node->getName(),
                $nodeType,
                $this->getName(),
                implode(', ', array_keys($cardinalityMap))
            ));
        }

        $currentCardinality = isset($this->children[$node->getName()]) ?
            count($this->children[$node->getName()]) : 0;

        list($min, $max) = $cardinalityMap[$nodeType];

        // if bounded and cardinality will exceed max
        if (null !== $max && $currentCardinality + 1 > $max) {
            throw new OutOfBoundsException(sprintf(
                'QueryBuilder node "%s" cannot be appended to "%s". '.
                'Number of "%s" nodes cannot exceed "%s"',
                $node->getName(),
                $this->getName(),
                $nodeType,
                $max
            ));
        }

        $this->children[$nodeType][] = $node;

        return $node->getNext();
    }