@param \PHP_CodeSniffer\Files\File $phpCsFile
@param int $stackPointer

@return int|null Stackpointer value of docblock end tag, or null if cannot be found
779838
protected function findDocBlock(File $phpCsFile, int $stackPointer): ?int
    {
        $tokens = $phpCsFile->getTokens();

        $index = $phpCsFile->findPrevious(T_WHITESPACE, $stackPointer - 1, null, true);

        if ($tokens[$index]['type'] === 'T_DOC_COMMENT_CLOSE_TAG') {
            return $index;
        }

        return null;
    }
215430
protected function getStackPointerOfClassBegin(File $phpCsFile, int $stackPointer): int
    {
        $abstractPosition = (int)$phpCsFile->findPrevious(T_ABSTRACT, $stackPointer);
        if ($abstractPosition) {
            return $abstractPosition;
        }

        return $stackPointer;
    }
698099
protected function checkUseToken(File $phpcsFile, $stackPtr) {
		// If the use token is for a closure we want to ignore it.
		$isClosure = $this->isClosure($phpcsFile, $stackPtr);
		if ($isClosure) {
			return;
		}

		$tokens = $phpcsFile->getTokens();

		$content = '';
		$startIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true);
		$endIndex = $phpcsFile->findNext([T_SEMICOLON, T_OPEN_CURLY_BRACKET], $startIndex + 1);

		for ($i = $startIndex; $i < $endIndex; $i++) {
			$content .= $tokens[$i]['content'];
		}

		// Check for class scoping on use. Traits should be
		// ordered independently.
		$scope = 0;
		if (!empty($tokens[$i]['conditions'])) {
			$scope = key($tokens[$i]['conditions']);
		}
		$this->_uses[$scope][$content] = $stackPtr;
	}
1005914
protected function isInheritDoc(File $phpcsFile, $stackPtr)
    {
        $start = $phpcsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $stackPtr - 1);
        $end = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $start);

        $content = $phpcsFile->getTokensAsString($start, ($end - $start));

        return
            preg_match('#({@inheritdoc}|(?<!{)@inheritdoc(?!}))#i', $content) === 1;
    }
987020
protected function existsFileDocBlock(File $phpCsFile, int $stackPointer): bool
    {
        $fileDocBlockStartPosition = $phpCsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $stackPointer);

        return ($fileDocBlockStartPosition !== false);
    }
684335
protected function checkCustomFileDocBlock(File $phpCsFile, int $stackPointer): void
    {
        $path = str_replace(getcwd(), '', $phpCsFile->getFilename());
        if (strpos($path, DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR) === 0) {
            $pathArray = explode(DIRECTORY_SEPARATOR, substr($path, 8));

            $path = getcwd() . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR
                . array_shift($pathArray) . DIRECTORY_SEPARATOR . array_shift($pathArray) . DIRECTORY_SEPARATOR;
        } else {
            $path = getcwd() . DIRECTORY_SEPARATOR;
        }

        $license = $this->getLicense($path);
        if (!$license) {
            return;
        }

        if (!$this->existsFileDocBlock($phpCsFile, $stackPointer)) {
            $fix = $phpCsFile->addFixableError('No file doc block', $stackPointer, 'CustomFileDocBlockMissing');
            if ($fix) {
                $this->addFileDocBlock($phpCsFile, 0);
            }
            return;
        }

        $this->assertNewlineBefore($phpCsFile, $stackPointer);

        if ($this->isCustomFileDocBlock($phpCsFile, $stackPointer, $license)) {
            return;
        }

        $fix = $phpCsFile->addFixableError('Wrong file doc block', $stackPointer, 'CustomFileDocBlockWrong');
        if ($fix) {
            $this->addCustomFileDocBlock($phpCsFile, 0, $license);
        }
    }
1312372
protected function assertNoApiTag(File $phpCsFile, int $stackPointer): void
    {
        $apiIndex = $this->findApiAnnotationIndex($phpCsFile, $stackPointer);
        if (!$apiIndex) {
            return;
        }

        $fix = $phpCsFile->addFixableError('@api annotation is invalid.', $stackPointer, 'ApiAnnotationInvalid');

        if (!$fix) {
            return;
        }

        $tokens = $phpCsFile->getTokens();
        $line = $tokens[$apiIndex]['line'];

        $phpCsFile->fixer->beginChangeset();
        $phpCsFile->fixer->replaceToken($apiIndex, '');

        $index = $apiIndex;
        while ($tokens[$index - 1]['line'] === $line) {
            $index--;
            $phpCsFile->fixer->replaceToken($index, '');
        }
        $index = $apiIndex;
        while ($tokens[$index + 1]['line'] === $line) {
            $index++;
            $phpCsFile->fixer->replaceToken($index, '');
        }

        $phpCsFile->fixer->endChangeset();
    }
1281858
protected function checkTag(File $phpcsFile, int $stackPtr): void
    {
        $tokens = $phpcsFile->getTokens();

        $followingWhitespace = (int)$phpcsFile->findNext(T_DOC_COMMENT_WHITESPACE, $stackPtr + 1, $stackPtr + 2);
        if (!$followingWhitespace || $tokens[$followingWhitespace]['line'] !== $tokens[$stackPtr]['line']) {
            return;
        }

        // Skip for file doc blocks
        $namespaceStatement = $this->getNamespaceStatement($phpcsFile);
        if (!$namespaceStatement || $stackPtr < $namespaceStatement['start']) {
            return;
        }

        $content = $tokens[$followingWhitespace]['content'];
        if (strpos($content, ' ') === false || $content === ' ') {
            return;
        }

        $fix = $phpcsFile->addFixableError('There should be no additional whitespace around doc block tag types.', $stackPtr, 'WhitespaceAroundTypes');
        if ($fix) {
            $phpcsFile->fixer->replaceToken($followingWhitespace, ' ');
        }
    }
613991
protected function assertNewLineAtTheBeginning(File $phpCsFile, int $stackPointer): void
    {
        $tokens = $phpCsFile->getTokens();

        $line = $tokens[$stackPointer]['line'];
        $firstTokenInLineIndex = $stackPointer;
        while ($tokens[$firstTokenInLineIndex - 1]['line'] === $line) {
            $firstTokenInLineIndex--;
        }

        $prevContentIndex = $phpCsFile->findPrevious(T_WHITESPACE, $firstTokenInLineIndex - 1, null, true);
        if ($tokens[$prevContentIndex]['type'] === 'T_DOC_COMMENT_CLOSE_TAG') {
            $firstTokenInLineIndex = $tokens[$prevContentIndex]['comment_opener'];
            while ($tokens[$firstTokenInLineIndex - 1]['line'] === $line) {
                $firstTokenInLineIndex--;
            }
        }

        $prevContentIndex = $phpCsFile->findPrevious(T_WHITESPACE, $firstTokenInLineIndex - 1, null, true);

        // Do not mess with the start of the class
        if ($tokens[$prevContentIndex]['type'] === 'T_OPEN_CURLY_BRACKET') {
            return;
        }

        if ($tokens[$prevContentIndex]['line'] < $tokens[$firstTokenInLineIndex]['line'] - 1) {
            return;
        }

        $fix = $phpCsFile->addFixableError('Every function/method needs a newline before', $firstTokenInLineIndex, 'Concrete');
        if ($fix) {
            $phpCsFile->fixer->addNewline($prevContentIndex);
        }
    }
412945
public function process(File $phpcsFile, $stackPointer)
    {
        $tokens  = $phpcsFile->getTokens();
        $content = $tokens[$stackPointer]['content'];
        if (preg_match('/@ *inject/i', $content) !== 0)
        {
            $injectContent     = $tokens[$stackPointer]['content']
                . $tokens[$stackPointer + 1]['content']
                . $tokens[$stackPointer + 2]['content'];
            $injectMatches     = [];
            $injectPattern     = '@Inject(\(\{"[a-zA-Z]+((\.|\\\\|_)[a-zA-Z]+)*"(, "[a-zA-Z]+((\.|\\\\|_)[a-zA-Z]+)*")*\}\))?';
            $injectablePattern = '@Injectable\([a-zA-Z]+="[a-zA-Z]+"(, ([a-zA-Z]+="[a-zA-Z]+"|[a-zA-Z]+=(true|false)))*\)';
            $completePattern   = '/(' . $injectPattern . ')|(' . $injectablePattern . ')/';
            preg_match($completePattern, $injectContent, $injectMatches);
            if (empty($injectMatches))
            {
                $type  = 'Production.Inject.InjectionFound';
                $data  = [$injectContent];
                $error = 'Inject[able] annotation has wrong format.';
                $phpcsFile->addWarning($error, $stackPointer, $type, $data);
            }
        }
    }
1041172
protected function isSprykerFacadeApiClass(File $phpCsFile, int $stackPointer): bool
    {
        if (!$this->hasNamespace($phpCsFile, $stackPointer)) {
            return false;
        }

        $namespace = $this->getNamespace($phpCsFile, $stackPointer);
        $name = $this->findClassOrInterfaceName($phpCsFile, $stackPointer);
        if (!$name || $name === 'AbstractFacade') {
            return false;
        }

        if (preg_match('/^Spryker\\\\Zed\\\\(.*?)\\\\Business$/', $namespace) && preg_match('/^(.+?)(Facade|FacadeInterface)$/', $name)) {
            return true;
        }

        return false;
    }
747535
protected function processTokenWithinScope(File $phpcsFile, $stackPointer, $currScope)
    {
        $methodName = $phpcsFile->getDeclarationName($stackPointer);
        if ($methodName === null)
        {
            // Ignore closures.
            return;
        }

        // Ignore magic methods.
        $magicPart = strtolower(substr($methodName, 2));
        if (isset($this->magicMethods[$magicPart]) === true
            || isset($this->methodsDoubleUnderscore[$magicPart]) === true
        )
        {
            return;
        }

        $testName = ltrim($methodName, '_');

        if (Common::isCamelCaps($testName, false, true, false) === false)
        {
            $className = $phpcsFile->getDeclarationName($currScope);
            if ($this->isUnitTest($phpcsFile, $stackPointer) === false)
            {
                $error     = 'Method name "%s" is not in camel caps format';
                $errorData = [$className . '::' . $methodName];
                $phpcsFile->addError($error, $stackPointer, 'Production.CamelCapsMethodName.NotCamelCaps', $errorData);
                $phpcsFile->recordMetric($stackPointer, 'CamelCase method name', 'no');
            }
        }
        else
        {
            $phpcsFile->recordMetric($stackPointer, 'CamelCase method name', 'yes');
        }
    }
345037
protected function checkBracketSpacing(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        if (isset($tokens[$stackPtr]['parenthesis_opener']) === false) {
            return;
        }

        $parenOpener    = $tokens[$stackPtr]['parenthesis_opener'];
        $parenCloser    = $tokens[$stackPtr]['parenthesis_closer'];
        $spaceAfterOpen = 0;
        if ($tokens[($parenOpener + 1)]['code'] === T_WHITESPACE) {
            $spaceAfterOpen = $tokens[($parenOpener + 1)]['length'];
        }

        if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) {
            $error = 'Expected %s spaces after "%s" opening bracket; %s found';
            $data  = array(
                      $this->requiredSpacesAfterOpen,
                      $tokens[$stackPtr]['content'],
                      $spaceAfterOpen,
                     );
            $fix   = $phpcsFile->addFixableError($error, ($parenOpener + 1), 'SpacingAfterOpenBrace', $data);

            if ($fix === true) {
                $phpcsFile->fixer->beginChangeset();

                for ($i = $spaceAfterOpen; $i < $this->requiredSpacesAfterOpen; $i++) {
                    $phpcsFile->fixer->addContent($parenOpener, ' ');
                }

                $phpcsFile->fixer->endChangeset();
            }
        }

        if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']) {
            $spaceBeforeClose = 0;
            if ($tokens[($parenCloser - 1)]['code'] === T_WHITESPACE) {
                $spaceBeforeClose = $tokens[($parenCloser - 1)]['length'];
            }

            if ($spaceBeforeClose !== $this->requiredSpacesBeforeClose) {
                $error = 'Expected %s spaces before "%s" closing bracket; %s found';
                $data  = array(
                          $this->requiredSpacesBeforeClose,
                          $tokens[$stackPtr]['content'],
                          $spaceBeforeClose,
                         );
                $fix   = $phpcsFile->addFixableError($error, ($parenCloser - 1), 'SpaceBeforeCloseBrace', $data);

                if ($fix === true) {
                    $phpcsFile->fixer->beginChangeset();

                    for ($i = $spaceBeforeClose; $i < $this->requiredSpacesBeforeClose; $i++) {
                        $phpcsFile->fixer->addContentBefore($parenCloser, ' ');
                    }

                    $phpcsFile->fixer->endChangeset();
                }
            }
        }//end if
    }
249742
public function process(File $phpcsFile, $stackPointer)
    {
        $tokens       = $phpcsFile->getTokens();
        $currentToken = $tokens[$stackPointer];
        $prevToken    = $tokens[($stackPointer - 1)];
        $nextToken    = $tokens[($stackPointer + 1)];

        if ($prevToken['code'] !== T_WHITESPACE || $nextToken['code'] !== T_WHITESPACE)
        {
            $error = 'Concat operator must be surrounded by spaces. ';
            $phpcsFile->addError($error, $stackPointer, 'Production.ConcatenationSpacing.NoSpaceAroundConcat');
        }

        if (($prevToken['code'] === T_WHITESPACE && false !== strpos($prevToken['content'], '  '))
            || ($nextToken['code'] === T_WHITESPACE && false !== strpos($nextToken['content'], '  '))
        )
        {
            // Indents in multi-line concatenations must not throw warnings.
            if ($currentToken['code'] === T_STRING_CONCAT && $prevToken['code'] === T_WHITESPACE)
            {
                return;
            }

            $error = 'Concat operator should be surrounded by just one space';
            $phpcsFile->addWarning($error, $stackPointer, 'Production.ConcatenationSpacing.OnlyOneSpaceAroundConcat');
        }
    }
694410
protected function assertNewlineBefore(File $phpCsFile, int $stackPointer): void
    {
        $fileDocBlockStartPosition = $phpCsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $stackPointer);

        $tokens = $phpCsFile->getTokens();

        $prevIndex = $phpCsFile->findPrevious(T_WHITESPACE, $fileDocBlockStartPosition - 1, 0, true);

        if ($tokens[$prevIndex]['line'] === $tokens[$fileDocBlockStartPosition]['line'] - 2) {
            return;
        }

        $fix = $phpCsFile->addFixableError('Whitespace issue around file doc block', $stackPointer, 'FileDocBlockSpacing');
        if (!$fix) {
            return;
        }

        $phpCsFile->fixer->beginChangeset();

        if ($tokens[$prevIndex]['line'] > $tokens[$fileDocBlockStartPosition]['line'] - 2) {
            $phpCsFile->fixer->addNewline($prevIndex);
        } else {
            $index = $prevIndex;
            while ($index < $fileDocBlockStartPosition - 1) {
                $index++;
                $phpCsFile->fixer->replaceToken($index, '');
            }
        }

        $phpCsFile->fixer->endChangeset();
    }
1202978
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
            // Probably an interface method.
            return;
        }

        $closeBrace  = $tokens[$stackPtr]['scope_closer'];
        $prevContent = $phpcsFile->findPrevious(T_WHITESPACE, ($closeBrace - 1), null, true);

        // Special case for empty JS functions.
        if ($phpcsFile->tokenizerType === 'JS' && $prevContent === $tokens[$stackPtr]['scope_opener']) {
            // In this case, the opening and closing brace must be
            // right next to each other.
            if ($tokens[$stackPtr]['scope_closer'] !== ($tokens[$stackPtr]['scope_opener'] + 1)) {
                $error = 'The opening and closing braces of empty functions must be directly next to each other; e.g., function () {}';
                $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'SpacingBetween');
                if ($fix === true) {
                    $phpcsFile->fixer->beginChangeset();
                    for ($i = ($tokens[$stackPtr]['scope_opener'] + 1); $i < $closeBrace; $i++) {
                        $phpcsFile->fixer->replaceToken($i, '');
                    }

                    $phpcsFile->fixer->endChangeset();
                }
            }

            return;
        }

        $nestedFunction = false;
        if ($phpcsFile->hasCondition($stackPtr, T_FUNCTION) === true
            || $phpcsFile->hasCondition($stackPtr, T_CLOSURE) === true
            || isset($tokens[$stackPtr]['nested_parenthesis']) === true
        ) {
            $nestedFunction = true;
        }

        $braceLine = $tokens[$closeBrace]['line'];
        $prevLine  = $tokens[$prevContent]['line'];
        $found     = ($braceLine - $prevLine - 1);

        $afterKeyword  = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
        $beforeKeyword = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
        if ($nestedFunction === true) {
            if ($found < 0) {
                $error = 'Closing brace of nested function must be on a new line';
                $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'ContentBeforeClose');
                if ($fix === true) {
                    $phpcsFile->fixer->addNewlineBefore($closeBrace);
                }
            } else if ($found > $this->allowedNestedLines) {
                $error = 'Expected %s blank lines before closing brace of nested function; %s found';
                $data  = array(
                          $this->allowedNestedLines,
                          $found,
                         );
                $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'SpacingBeforeNestedClose', $data);

                if ($fix === true) {
                    $phpcsFile->fixer->beginChangeset();
                    $changeMade = false;
                    for ($i = ($prevContent + 1); $i < $closeBrace; $i++) {
                        // Try to maintain indentation.
                        if ($tokens[$i]['line'] === ($braceLine - 1)) {
                            break;
                        }

                        $phpcsFile->fixer->replaceToken($i, '');
                        $changeMade = true;
                    }

                    // Special case for when the last content contains the newline
                    // token as well, like with a comment.
                    if ($changeMade === false) {
                        $phpcsFile->fixer->replaceToken(($prevContent + 1), '');
                    }

                    $phpcsFile->fixer->endChangeset();
                }//end if
            }//end if
        } else {
            if ($found !== (int) $this->allowedLines) {
                if ($this->allowedLines === 1) {
                    $plural = '';
                } else {
                    $plural = 's';
                }

                $error = 'Expected %s blank line%s before closing function brace; %s found';
                $data  = array(
                          $this->allowedLines,
                          $plural,
                          $found,
                         );
                $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'SpacingBeforeClose', $data);

                if ($fix === true) {
                    if ($found > $this->allowedLines) {
                        $phpcsFile->fixer->beginChangeset();
                        for ($i = ($prevContent + 1); $i < ($closeBrace); $i++) {
                            $phpcsFile->fixer->replaceToken($i, '');
                        }

                        $phpcsFile->fixer->replaceToken(($closeBrace - 1), $phpcsFile->eolChar);
                        $phpcsFile->fixer->endChangeset();
                    } else {
                        $phpcsFile->fixer->addNewlineBefore($closeBrace);
                    }
                }
            }//end if
        }//end if

    }
1213881
public function process(File $phpcsFile, $stackPointer)
    {
        $this->file      = $phpcsFile;
        $tokens          = $phpcsFile->getTokens();
        $type            = $tokens[$stackPointer]['type'];
        $commentContext  = $tokens[$stackPointer]['content'];
        $isAtStartOfLine = $tokens[$stackPointer]['column'] === 1;

        if (($type === 'T_USE') && $isAtStartOfLine)
        {
            $this->collectUsedNamespace($tokens, $stackPointer);
        }
        elseif ($type === 'T_DOC_COMMENT_TAG' && in_array($commentContext, $this->wantedAnnotations, true))
        {
            $this->findFullyQualifiedNameSpaceInDocBlock($tokens, $stackPointer, $commentContext);
        }
    }