public static boolean isLoopInvariant(PsiExpression expression, @SuppressWarnings("unused") PsiLoopStatement loopStatement) {
    if (PsiUtil.isConstantExpression(expression)) return true;
    if (SideEffectChecker.mayHaveSideEffects(expression)) return false;
    Collection<PsiReferenceExpression> refs = PsiTreeUtil.collectElementsOfType(expression, PsiReferenceExpression.class);
    for (PsiReferenceExpression ref : refs) {
      PsiElement target = ref.resolve();
      // TODO: more sophisticated analysis
      if (target instanceof PsiField && ((PsiField)target).hasModifierProperty(PsiModifier.FINAL)) continue;
      if (target instanceof PsiLocalVariable || target instanceof PsiParameter) {
        PsiVariable var = (PsiVariable)target;
        if (var.hasModifierProperty(PsiModifier.FINAL) ||
            HighlightControlFlowUtil.isEffectivelyFinal(var, PsiUtil.getVariableCodeBlock(var, null), null)) {
          continue;
        }
      }
      return false;
    }
    return true;
  }
public static boolean isLoopInvariant(PsiExpression expression, @SuppressWarnings("unused") PsiLoopStatement loopStatement)