protected function scriptDataState() {
		if ( $this->appropriateEndTag === null ) {
			$this->pos = $this->length;
			return self::STATE_EOF;
		}

		$re = <<<REGEX
~
			(?: # Outer loop start
				# Script data state
				# Stop iteration if we previously matched an appropriate end tag.
				# This is a conditional subpattern: if capture 1 previously
				# matched, then run the pattern /$./ which always fails.
				(?(1) $. )
				.*?
				(?:
					$ |
					(
						</ {$this->appropriateEndTag}
						# If we hit the "anything else" case in the script data
						# end tag name state, don't exit
						(?= [\t\n\f />] )
					) | # 1. Appropriate end tag
					<!--
					# Script data escaped dash dash state
					# Hyphens at this point are consumed without a state transition
					# and so are not part of a comment-end.
					-*+

					(?: # Inner loop start
						# Script data escaped state
						.*?
						(?:
							$ |
							# Stop at, but do not consume, comment-close or end tag.
							# This causes the inner loop to exit, since restarting the
							# inner loop at this input position will cause the loop
							# body to match zero characters. Repeating a zero-character
							# match causes the repeat to terminate.
							(?= --> ) |
							(?= </ {$this->appropriateEndTag} [\t\n\f />] ) |
							<script [\t\n\f />]
							# Script data double escaped state
							.*?
							(?:
								$ |
								# Stop at, but do not consume, comment-close
								(?= --> ) |
								</script [\t\n\f />]
							)
						)
					)*


					# Consume the comment close which exited the inner loop, if any
					(?: --> )?
				)
			)*+
			~xsiA
REGEX;

		do {
			$count = preg_match( $re, $this->text, $m, 0, $this->pos );
			if ( $count === false ) {
				$this->throwPregError();
			} elseif ( !$count ) {
				$this->fatal( 'unexpected regex failure: this pattern can match zero characters' );
			}

			$startPos = $this->pos;
			$matchLength = strlen( $m[0] );
			$endTagLength = isset( $m[1] ) ? strlen( $m[1] ) : 0;
			$textLength = $matchLength - $endTagLength;
			$this->emitRawTextRange( true, $startPos, $textLength );
			$this->pos = $startPos + $matchLength;
			$tagStartPos = $startPos + $textLength;

			if ( $endTagLength ) {
				$nextState = $this->handleAttribsAndClose( self::STATE_SCRIPT_DATA,
					$this->appropriateEndTag, true, $tagStartPos );
			} else {
				$nextState = self::STATE_EOF;
			}
		} while ( $nextState === self::STATE_SCRIPT_DATA );
		return $nextState;
	}