private boolean isAllowedViolation(@Nullable Component c, StackTraceElement[] stackTrace) {
    boolean repaint = false;
    boolean fromSwing = false;
    boolean swingKnownNonAwtOperations = false;
    for (StackTraceElement st : stackTrace) {
      String className = st.getClassName();
      String methodName = st.getMethodName();

      if (repaint && className.startsWith("javax.swing.")) {
        fromSwing = true;
      }
      if (repaint && "imageUpdate".equals(methodName)) {
        swingKnownNonAwtOperations = true;
      }

      if ("read".equals(methodName) && className.startsWith("javax.swing.JEditorPane") ||
          "setCharacterAttributes".equals(methodName) && className.startsWith("javax.swing.text.DefaultStyledDocument")) {
        swingKnownNonAwtOperations = true;
        break;
      }

      if ("repaint".equals(methodName)) {
        repaint = true;
        fromSwing = false;
      }
    }
    if (swingKnownNonAwtOperations) {
      return true;
    }
    if (repaint && !fromSwing) {
      //no problems here, since repaint() is thread safe
      return true;
    }
    //ignore the last processed component
    if (SoftReference.dereference(myLastComponent) == c) {
      return true;
    }
    myLastComponent = new WeakReference<>(c);
    return false;
  }
private boolean isAllowedViolation(@Nullable Component c, StackTraceElement[] stackTrace)