/**
  * @return array of match
  *                  every match is an array with the following entries:
  *                          0: int startIndex
  *                                      the index at which the pattern starts
  *                          1: int endIndex
  *                                      the index at which the pattern ends
  *
  */
 public function find(array $tokens)
 {
     $ret = [];
     $tai = new TokenArrayIterator($tokens);
     $start = null;
     while ($tai->valid()) {
         $cur = $tai->current();
         if (null === $start) {
             if (TokenTool::match(T_VARIABLE, $cur)) {
                 $start = $tai->key();
                 $isDynamic = false;
                 if (true === $this->allowDynamic) {
                     $tai->prev();
                     while (TokenTool::match('$', $tai->current())) {
                         $isDynamic = true;
                         $tai->prev();
                     }
                     if (true === $isDynamic) {
                         $tai->next();
                         // re-balancing the last prev move from the while loop
                         $parseStart = $start;
                         $start = $tai->key();
                         $tai->seek($parseStart);
                     } else {
                         $tai->next();
                     }
                 }
                 /**
                  * By default in this implementation, we have chosen to parse
                  * array affectation ONLY IF the variable is not dynamic,
                  * because this (array affectation on a dynamic var) is not valid php:
                  *
                  *          $$x["pou"] = 6;
                  *
                  */
                 if (true === $this->allowArrayAffectation && false === $isDynamic) {
                     $tai->next();
                     if (false === TokenArrayIteratorTool::skipSquareBracketsChain($tai)) {
                         $tai->prev();
                     }
                 }
             } else {
                 if (true === $this->skipControlStructure) {
                     if (true === TokenTool::match('{', $tai->current())) {
                         TokenArrayIteratorTool::moveToCorrespondingEnd($tai);
                     }
                 }
                 if (true === $this->skipClass) {
                     TokenArrayIteratorTool::skipClassLike($tai);
                 }
                 if (true === $this->skipFunction) {
                     TokenArrayIteratorTool::skipFunction($tai);
                 }
                 if (true === $this->skipForLoopCondition) {
                     if (true === TokenTool::match(T_FOR, $tai->current())) {
                         $tai->next();
                         TokenArrayIteratorTool::skipWhiteSpaces($tai);
                         if (true === TokenTool::match('(', $tai->current())) {
                             TokenArrayIteratorTool::moveToCorrespondingEnd($tai);
                         }
                     }
                 }
             }
         } else {
             $found = false;
             TokenArrayIteratorTool::skipWhiteSpaces($tai);
             if (TokenTool::match("=", $tai->current())) {
                 while ($tai->valid()) {
                     if (false === TokenTool::match(';', $tai->current())) {
                         TokenArrayIteratorTool::skipWhiteSpaces($tai);
                         if (TokenTool::match(['(', '[', '{'], $tai->current())) {
                             TokenArrayIteratorTool::moveToCorrespondingEnd($tai);
                         } elseif (true === TokenTool::match([')', ']', '}'], $tai->current())) {
                             break;
                         }
                     } else {
                         break;
                     }
                     $tai->next();
                 }
                 if (true === TokenTool::match(';', $tai->current())) {
                     $found = true;
                     $ret[] = [$start, $tai->key()];
                     $this->onMatchFound($start, $tai);
                     $start = null;
                 }
             }
             if (false === $found) {
                 $start = null;
             }
         }
         $tai->next();
     }
     return $ret;
 }