private boolean isIteratorNext(
   PsiElement element, String iteratorName, PsiType contentType) {
   if (element == null) {
     return false;
   }
   if (element instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression castExpression =
       (PsiTypeCastExpression)element;
     final PsiType type = castExpression.getType();
     if (type == null) {
       return false;
     }
     if (!type.equals(contentType)) {
       return false;
     }
     final PsiExpression operand =
       castExpression.getOperand();
     return isIteratorNext(operand, iteratorName, contentType);
   }
   if (!(element instanceof PsiMethodCallExpression)) {
     return false;
   }
   final PsiMethodCallExpression callExpression =
     (PsiMethodCallExpression)element;
   final PsiExpressionList argumentList =
     callExpression.getArgumentList();
   final PsiExpression[] args = argumentList.getExpressions();
   if (args.length != 0) {
     return false;
   }
   final PsiReferenceExpression reference =
     callExpression.getMethodExpression();
   final PsiExpression qualifier = reference.getQualifierExpression();
   if (qualifier == null) {
     return false;
   }
   if (!iteratorName.equals(qualifier.getText())) {
     return false;
   }
   final String referenceName = reference.getReferenceName();
   return HardcodedMethodConstants.NEXT.equals(referenceName);
 }
 @Override
 public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
   super.visitTypeCastExpression(expression);
   final PsiExpression operand = expression.getOperand();
   if (operand == null) {
     return;
   }
   final PsiType operandType = operand.getType();
   if (operandType == null) {
     return;
   }
   final PsiType type = expression.getType();
   if (type == null) {
     return;
   }
   final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true);
   if (expectedType == null) {
     return;
   }
   if (expectedType.equals(type)) {
     return;
   }
   final PsiClass resolved = PsiUtil.resolveClassInType(expectedType);
   if (resolved != null && !resolved.isPhysical()) {
     return;
   }
   if (expectedType.isAssignableFrom(operandType)) {
     // then it's redundant, and caught by the built-in exception
     return;
   }
   if (isTypeParameter(expectedType)) {
     return;
   }
   if (expectedType instanceof PsiArrayType) {
     final PsiArrayType arrayType = (PsiArrayType) expectedType;
     final PsiType componentType = arrayType.getDeepComponentType();
     if (isTypeParameter(componentType)) {
       return;
     }
   }
   if (type instanceof PsiPrimitiveType || expectedType instanceof PsiPrimitiveType) {
     return;
   }
   if (PsiPrimitiveType.getUnboxedType(type) != null
       || PsiPrimitiveType.getUnboxedType(expectedType) != null) {
     return;
   }
   if (expectedType instanceof PsiClassType) {
     final PsiClassType expectedClassType = (PsiClassType) expectedType;
     final PsiClassType expectedRawType = expectedClassType.rawType();
     if (type.equals(expectedRawType)) {
       return;
     }
     if (type instanceof PsiClassType) {
       final PsiClassType classType = (PsiClassType) type;
       final PsiClassType rawType = classType.rawType();
       if (rawType.equals(expectedRawType)) {
         return;
       }
     }
     if (type instanceof PsiArrayType) {
       return;
     }
   }
   if (ignoreInMatchingInstanceof && InstanceOfUtils.hasAgreeingInstanceof(expression)) {
     return;
   }
   final PsiTypeElement castTypeElement = expression.getCastType();
   if (castTypeElement == null) {
     return;
   }
   registerError(castTypeElement, expectedType);
 }