@Override
 public void visitClass(@NotNull PsiClass aClass) {
   // no call to super, so it doesn't drill down
   if (aClass.isInterface() || aClass.isAnnotationType()) {
     return;
   }
   if (!SerializationUtils.isSerializable(aClass)) {
     return;
   }
   PsiClass ancestor = aClass.getSuperClass();
   final Set<PsiClass> visitedClasses = new HashSet<PsiClass>(16);
   while (ancestor != null && SerializationUtils.isSerializable(ancestor)) {
     ancestor = ancestor.getSuperClass();
     if (!visitedClasses.add(ancestor)) {
       return;
     }
   }
   if (ancestor == null) {
     return; // can't happen, since Object isn't serializable,
     //// but I don't trust the PSI as far as I can throw it
   }
   if (classHasNoArgConstructor(ancestor)) {
     return;
   }
   registerClassError(aClass, ancestor);
 }
 @Override
 public void visitMethodCallExpression(PsiMethodCallExpression methodCallExpression) {
   super.visitMethodCallExpression(methodCallExpression);
   if (!MethodCallUtils.isSimpleCallToMethod(
           methodCallExpression,
           "javax.servlet.http.HttpSession",
           PsiType.VOID,
           "putValue",
           "java.lang.String",
           "java.lang.Object")
       && !MethodCallUtils.isSimpleCallToMethod(
           methodCallExpression,
           "javax.servlet.http.HttpSession",
           PsiType.VOID,
           "setAttribute",
           "java.lang.String",
           "java.lang.Object")) {
     return;
   }
   final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
   final PsiExpression[] arguments = argumentList.getExpressions();
   if (arguments.length != 2) {
     return;
   }
   final PsiExpression argument = arguments[1];
   final PsiType argumentType = argument.getType();
   if (argumentType == null) {
     return;
   }
   if (SerializationUtils.isProbablySerializable(argumentType)) {
     return;
   }
   registerError(argument);
 }