public function parse(Array $tokens)
	{	
		// if groups are mis-matched, short-circuit
		if ($this->countGroupOpen($tokens) !== $this->countGroupClose($tokens)) {
			throw new \InvalidArgumentException(
				__METHOD__."() expects parameter one, tokens, to be valid RTF "
				 . "string; however, the number of groups opened does not equal "
				 . "the number of groups closed"
			);
		}
		
		$root  = null;
		
		// loop through the tokens
		$stack = new \SplStack();
		foreach ($tokens as $token) {
			// if the token is a group-open token
			if ($token instanceof Token\Group\Open) {
				$this->parseGroupOpen($token, $stack, $root);
				if ($root === null) {
					$root = $stack->bottom();
				}
			} else {
				// if at least a root group exists
				if ($stack->count()) {
					if ($token instanceof Token\Group\Close) {
						$this->parseGroupClose($token, $stack);
					} elseif ($token instanceof Token\Control\Word) {
						$this->parseControlWord($token, $stack->top());
					} elseif ($token instanceof Token\Control\Symbol) {
						$this->parseControlSymbol($token, $stack->top());
					} elseif ($token instanceof Token\Text) {
						$this->parseText($token, $stack->top());
					}
				} else {
					// otherwise, ignore the tokens
					// hmmm, this is good because if text preceeds the root group 
					//     (observed in wild) it's ignored as it should be; however, 
					//     it's also bad, because if an extra bracket closes the 
					//     root-group early (also observed in the wild), it's not an 
					//     error
					//
				}
			}
		}
		
		return $root;
	}