protected function parseBBCode()
	{
		$this->parseBBCodeSuffix();

		// Test whether this is an end tag
		if ($this->text[$this->startPos + 1] === '/')
		{
			// Test whether the tag is properly closed and whether this tag has an identifier.
			// We skip end tags that carry an identifier because they're automatically added
			// when their start tag is processed
			if (substr($this->text, $this->pos, 1) === ']' && $this->bbcodeSuffix === '')
			{
				++$this->pos;
				$this->addBBCodeEndTag();
			}

			return;
		}

		// Parse attributes
		$this->parseAttributes();

		// Test whether the tag is properly closed
		if (substr($this->text, $this->pos, 1) === ']')
		{
			++$this->pos;
		}
		else
		{
			// Test whether this is a self-closing tag
			if (substr($this->text, $this->pos, 2) === '/]')
			{
				$this->pos += 2;
				$this->addBBCodeSelfClosingTag();
			}

			return;
		}

		// Record the names of attributes that need the content of this tag
		$contentAttributes = [];
		if (isset($this->bbcodeConfig['contentAttributes']))
		{
			foreach ($this->bbcodeConfig['contentAttributes'] as $attrName)
			{
				if (!isset($this->attributes[$attrName]))
				{
					$contentAttributes[] = $attrName;
				}
			}
		}

		// Look ahead and parse the end tag that matches this tag, if applicable
		$requireEndTag = ($this->bbcodeSuffix || !empty($this->bbcodeConfig['forceLookahead']));
		$endTag = ($requireEndTag || !empty($contentAttributes)) ? $this->captureEndTag() : null;
		if (isset($endTag))
		{
			foreach ($contentAttributes as $attrName)
			{
				$this->attributes[$attrName] = substr($this->text, $this->pos, $endTag->getPos() - $this->pos);
			}
		}
		elseif ($requireEndTag)
		{
			return;
		}

		// Create this start tag
		$tag = $this->addBBCodeStartTag();

		// If an end tag was created, pair it with this start tag
		if (isset($endTag))
		{
			$tag->pairWith($endTag);
		}
	}