package com.intellij.structuralsearch.impl.matcher.compiler;

import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.psi.impl.source.tree.ElementType;
import gnu.trove.THashSet;

/**
 * @author Maxim.Mossienko
*/
abstract class OptimizingSearchHelperBase implements OptimizingSearchHelper {
  private final THashSet<String> scanned;
  private final THashSet<String> scannedText;
  private final THashSet<String> scannedComments;
  private final THashSet<String> scannedLiterals;
  protected int scanRequest;
  private Lexer javaLexer;

  protected final CompileContext context;

  OptimizingSearchHelperBase(CompileContext _context) {
    context = _context;

    scanRequest = 0;
    scanned = new THashSet<String>();
    scannedText = new THashSet<String>();
    scannedComments = new THashSet<String>();
    scannedLiterals = new THashSet<String>();
  }

  public void clear() {
    scanned.clear();
    scannedComments.clear();
    scannedLiterals.clear();
  }

  public boolean addWordToSearchInCode(final String refname) {
    if (!scanned.contains(refname)) {
      boolean isJavaReservedWord = false;

      if (context.getOptions().getFileType() == StdFileTypes.JAVA) {
        if (javaLexer == null) {
          javaLexer = LanguageParserDefinitions.INSTANCE.forLanguage(JavaLanguage.INSTANCE).createLexer(context.getProject());
        }
        javaLexer.start(refname);
        isJavaReservedWord = ElementType.KEYWORD_BIT_SET.contains(javaLexer.getTokenType());
      }

      if (isJavaReservedWord) {
        doAddSearchJavaReservedWordInCode(refname);
      } else {
        doAddSearchWordInCode(refname);
      }

      scanned.add( refname );
      return true;
    }

    return false;
  }

  public boolean addWordToSearchInText(final String refname) {
    if (!scannedText.contains(refname)) {
      doAddSearchWordInText(refname);
      scannedText.add(refname);
      return true;
    }
    return false;
  }

  protected abstract void doAddSearchJavaReservedWordInCode(final String refname);
  protected abstract void doAddSearchWordInText(final String refname);
  protected abstract void doAddSearchWordInCode(final String refname);
  protected abstract void doAddSearchWordInComments(final String refname);
  protected abstract void doAddSearchWordInLiterals(final String refname);

  public void endTransaction() {
    scanRequest++;
  }

  public boolean addWordToSearchInComments(final String refname) {
    if (!scannedComments.contains(refname)) {
      doAddSearchWordInComments(refname);

      scannedComments.add( refname );
      return true;
    }
    return false;
  }

  public boolean addWordToSearchInLiterals(final String refname) {
    if (!scannedLiterals.contains(refname)) {
      doAddSearchWordInLiterals(refname);
      scannedLiterals.add( refname );
      return true;
    }
    return false;
  }

  public boolean isScannedSomething() {
    return scanned.size() > 0 || scannedComments.size() > 0 || scannedLiterals.size() > 0;
  }

}

@@ -1613,16 +1613,111 @@
 nType())
+ %7C%7C%0A                             ElementType.LITERAL_BIT_SET.contains(javaLexer.getTokenType())
 ;%0A      
@@ -3220,11 +3220,10 @@
  0;%0A  %7D%0A
-%0A
 %7D%0A

Fix literal keywords highlighting; cleanup