protected function parseBranch()
	{
		// Record the control structure
		$structure = $this->captureStructure();

		// Record the output expressions at the start of this branch
		$head = $this->captureOutput();
		$body = '';
		$tail = [];

		$braces = 0;
		do
		{
			$tail = $this->mergeOutput($tail, array_reverse($this->captureOutput()));
			if ($this->tokens[$this->i] === '}' && !$braces)
			{
				break;
			}

			$body .= $this->serializeOutput(array_reverse($tail));
			$tail  = [];

			if ($this->tokens[$this->i][0] === T_IF)
			{
				$child = $this->parseIfBlock();

				// If this is the start of current branch, what's been optimized away and moved
				// outside, before the child branch is the head of this one. Otherwise it's just
				// part of its body
				if ($body === '')
				{
					$head = $this->mergeOutput($head, $child['before']);
				}
				else
				{
					$body .= $this->serializeOutput($child['before']);
				}

				$body .= $child['source'];
				$tail  = $child['after'];
			}
			else
			{
				$body .= $this->serializeToken($this->tokens[$this->i]);

				if ($this->tokens[$this->i] === '{')
				{
					++$braces;
				}
				elseif ($this->tokens[$this->i] === '}')
				{
					--$braces;
				}
			}
		}
		while (++$this->i < $this->cnt);

		return [
			'structure' => $structure,
			'head'      => $head,
			'body'      => $body,
			'tail'      => $tail
		];
	}