/**
	 * Parses the tokens generated by executeScanner() and generates a tree
	 *
	 * @param array $tokens
	 * @param BBCodeToken $currentToken
	 * @return BBCodeToken Root node containing all nodes of the tree
	 */
	private function executeParser(array &$tokens, BBCodeToken $currentToken) {
		if ($currentToken->getTagName() === 'viscacha_root_node') {
			// This is the root node, reset the array pointer for $tokens
			reset($tokens);
		}

		// Use while as foreach will reset the array pointer on each call
		while (list(, $token) = each($tokens)) {
			if (is_string($token) == true) {
				// It' a string, add it to the current token as child
				$currentToken->addChild($token);
			}
			elseif ($token instanceof BBCodeToken) {
				// Get the tag object for this Token
				if ($token->getDisplayType() == BBCodeTag::DT_BLOCK) {
					if ($token->isStandalone() == true) {
						// Add standalone tags to the current token (can't have childs => no recursion)
						$currentToken->addChild($token);
					}
					elseif ($token->isOpeningTag() == true) {
						$currentToken->addChild($this->executeParser($tokens, $token));
					}
					else {
						$currentToken->setClosingToken($token);
						break;
					}
				}
				else { // Inline Tag
					if ($token->isStandalone() == true) {
						// Add standalone tags to the current token (can't have childs => no recursion)
						$currentToken->addChild($token);
					}
					elseif ($token->isOpeningTag() == true) {
						$currentToken->addChild($this->executeParser($tokens, $token));
					}
					else {
						$currentToken->setClosingToken($token);
						break;
					}
				}
			}
		}

		return $currentToken;
	}