/**
  * Check for the existence of a docblock for the current token
  * o go back and find the previous token that is not a whitespace
  * o if it is a access specifier (private, public etc), then
  * see if private members are excluded from comment check
  * (input argument specified this). if we find an access
  * specifier move on to find the next best token
  * o if it is ABSTRACT or STATIC specifier move on to find the next best token
  * o if the found token is a T_DOC_COMMENT, then we have a docblock
  *
  * This, of course, assumes that the function/class/interface has to be
  * immediately preceded by docblock. Even regular comments are not
  * allowed, which I think is okay.
  *
  * Launched when a CLASS / FUNCTION or INTERFACE statement is found.
  *
  * @param Integer $token
  *        	T_CLASS, T_FUNCTION or T_INTERFACE
  * @return true is docblock is found
  */
 private function _checkDocExists($token)
 {
     // current token = the token after T_CLASS, T_FUNCTION or T_INTERFACE
     //
     // token positions:
     // . curToken - 1 = T_CLASS/T_FUNCTION/T_INTERFACE
     // . curToken - 2 = whitespace before T_CLASS/T_FUNCTION/T_INTERFACE
     // . curToken - 3 = T_ABSTRACT/T_PUBLIC/T_PROTECTED/T_PRIVATE/T_STATIC
     // or T_DOC_COMMENT, if it is present
     //
     $isPrivateExcluded = $this->_config->getTestProperty('docBlocks', 'excludePrivateMembers');
     // Locate the function, class or interface token
     $functionTokenPosition = $this->tokenizer->getCurrentPosition();
     while (true) {
         // the type - function, class or interface. (Horribly named).
         $functionToken = $this->tokenizer->peekTokenAt($functionTokenPosition);
         $isFunction = $this->tokenizer->checkToken($functionToken, T_FUNCTION);
         $isClass = $this->tokenizer->checkToken($functionToken, T_CLASS);
         $isInterface = $this->tokenizer->checkToken($functionToken, T_INTERFACE);
         if ($isFunction || $isClass || $isInterface) {
             break;
         }
         $functionTokenPosition--;
     }
     // Records the type, as well as the type name for more precise error reporting.
     // Two positions forward from declaration of type.
     $typeToken = $this->tokenizer->peekTokenAt($functionTokenPosition);
     $type = $typeToken->text;
     $nameToken = $this->tokenizer->peekTokenAt($functionTokenPosition + 2);
     $name = $nameToken->text;
     $isOldStyleConstructor = strtolower($name) == strtolower($this->_currentClassname);
     $isNewStyleConstructor = strtolower($name) == '__construct';
     if ($isOldStyleConstructor || $isNewStyleConstructor) {
         $type = "constructor";
     }
     $found = false;
     $isPrivate = false;
     $docTokenPosition = $functionTokenPosition - 1;
     // List of tokens to ignore when looking for the docblock
     $tokenToIgnoreList = array(T_STATIC, T_FINAL, T_ABSTRACT, T_PROTECTED, T_PUBLIC, T_WHITESPACE, T_TAB, T_COMMENT, T_ML_COMMENT, T_NEW_LINE);
     // Go backward and look for a T_DOC_COMMENT
     while (true) {
         $docToken = $this->tokenizer->peekTokenAt($docTokenPosition);
         // if the token is in the list above.
         if ($this->tokenizer->isTokenInList($docToken, $tokenToIgnoreList)) {
             // All these tokens are ignored
         } else {
             if ($this->tokenizer->checkToken($docToken, T_PRIVATE)) {
                 $isPrivate = true;
                 // we are in a private function
             } else {
                 if ($this->tokenizer->checkToken($docToken, T_DOC_COMMENT)) {
                     // We have found a doc comment
                     $found = true;
                     break;
                 } else {
                     // Any other token found, we stop
                     $found = false;
                     break;
                 }
             }
         }
         $docTokenPosition--;
         if ($docTokenPosition == 0) {
             break;
             // special case for beginning of the file
         }
     }
     if ($found) {
         // Doc found, look for annotations
         $this->_processAnnotation($token, $docToken->text);
     } else {
         // No documentation found
         if ($this->_isActive('docBlocks') && !($isPrivateExcluded && $isPrivate)) {
             $msg = $this->_getMessage('MISSING_DOCBLOCK', $type, $name);
             $this->_writeError('docBlocks', $msg);
         }
     }
 }