diff --git a/java/java-tests/testData/inspection/redundantCast/generics/BoxingInConditional.java b/java/java-tests/testData/inspection/redundantCast/generics/BoxingInConditional.java
new file mode 100644
index 000000000000..8a61e21a4291
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/BoxingInConditional.java
@@ -0,0 +1,22 @@
+//This is a test for JDK_15 LanguageLevel
+class Test {
+ private Integer foo(String s, Integer i) {
+ return s == null ? i : (Integer)2;
+ }
+
+ private int foo1(String s, Integer i) {
+ return s == null ? i : (Integer)2;
+ }
+}
+
+class RedundantCastTest {
+
+ public static void main(String[] args) {
+ Integer foo = 5;
+ Integer bar = null;
+ print(args == null || args.length == 0 ? bar : (Integer) 1);
+ int i = args == null || args.length == 0 ? bar : (Integer) 1;
+ }
+
+ private static void print(Integer i) {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/BoxingInRef.java b/java/java-tests/testData/inspection/redundantCast/generics/BoxingInRef.java
new file mode 100644
index 000000000000..ec45da64d7ba
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/BoxingInRef.java
@@ -0,0 +1,7 @@
+//This is a test for JDK_15 LanguageLevel
+class Test {
+ void foo () {
+ int x = 4;
+ ((Integer) x).toString();
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/BoxingTopCast.java b/java/java-tests/testData/inspection/redundantCast/generics/BoxingTopCast.java
new file mode 100644
index 000000000000..148422b00588
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/BoxingTopCast.java
@@ -0,0 +1,20 @@
+class TestCasting
+{
+ public void testRedundantCast() throws Exception
+ {
+ Object o = getObject();
+ double d = 0.0;
+
+ if( o instanceof Integer )
+ {
+ d = (double) (Integer)o;
+ }
+
+ System.out.println( "d = " + d );
+ }
+
+ private Object getObject()
+ {
+ return new Integer(42);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/CaseThrowable.java b/java/java-tests/testData/inspection/redundantCast/generics/CaseThrowable.java
new file mode 100644
index 000000000000..a12ae74ece2d
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/CaseThrowable.java
@@ -0,0 +1,13 @@
+public class RedundantCast{
+ void m(IOEx e) throws IOEx {
+ throw (FileNotFoundEx)e;
+ }
+
+ void foo(RuntimeException e) {
+ throw (Ex)e;
+ }
+
+ static class Ex extends RuntimeException {}
+ static class IOEx extends Exception {}
+ static class FileNotFoundEx extends Exception {}
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/CastToUnboundWildcard.java b/java/java-tests/testData/inspection/redundantCast/generics/CastToUnboundWildcard.java
new file mode 100644
index 000000000000..bf7e46e214d4
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/CastToUnboundWildcard.java
@@ -0,0 +1,9 @@
+import java.util.*;
+import java.util.Map;
+
+class Test {
+ {
+ Map map1 = null;
+ Map map2 = (Map) (Map, ?>) map1;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/DifferentNullness.java b/java/java-tests/testData/inspection/redundantCast/generics/DifferentNullness.java
new file mode 100644
index 000000000000..278716e42be8
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/DifferentNullness.java
@@ -0,0 +1,32 @@
+import org.jetbrains.annotations.*;
+
+class A {
+ static String doit(A a) {
+ String d = ((AA)a).danuna();
+ String notNull = ((AA)a).doadd();
+ return notNull + d;
+ }
+
+ @Nullable
+ String doadd() {
+ return null;
+ }
+
+ @NotNull
+ String danuna() {
+ return "";
+ }
+}
+
+class AA extends A {
+ @NotNull
+ String doadd() {
+ return "";
+ }
+
+ @Override
+ @NotNull
+ String danuna() {
+ return "";
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/EnumConstant.java b/java/java-tests/testData/inspection/redundantCast/generics/EnumConstant.java
new file mode 100644
index 000000000000..cf7383350783
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/EnumConstant.java
@@ -0,0 +1,7 @@
+
+enum Test {
+ A((String) "");
+
+ Test(String s) {
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/ForEachValue.java b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValue.java
new file mode 100644
index 000000000000..857f498820fc
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValue.java
@@ -0,0 +1,12 @@
+import java.util.ArrayList;
+import java.util.List;
+
+class RedundantCast {
+ void redundantCasts() {
+ List list = new ArrayList<>();
+ for (String s : (ArrayList) list) {}
+
+ Object o = new ArrayList<>();
+ for (String s : (ArrayList) o) {}
+ }
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166.java b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166.java
new file mode 100644
index 000000000000..18bf47f111b5
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166.java
@@ -0,0 +1,11 @@
+import java.util.ArrayList;
+import java.util.List;
+
+class SomeClass {
+ public void test() {
+ List> objects = new ArrayList<>();
+ for (String value : (Iterable extends String>) objects) {
+ System.out.println(value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/GetClassProcessing.java b/java/java-tests/testData/inspection/redundantCast/generics/GetClassProcessing.java
new file mode 100644
index 000000000000..0fa9d056bae9
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/GetClassProcessing.java
@@ -0,0 +1,10 @@
+class B { }
+class A extends B { }
+
+class C {
+ void m(Class extends A> c) {}
+
+ void x(B b) {
+ m(((A)b).getClass());
+ }
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/IDEA22899.java b/java/java-tests/testData/inspection/redundantCast/generics/IDEA22899.java
new file mode 100644
index 000000000000..2cf47217bf9a
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/IDEA22899.java
@@ -0,0 +1,15 @@
+class RedundantIntCast
+{
+ public static void main(String[] args) {
+ Integer i = 8;
+ method((int)i, 1); // int cast is marked as redundant
+ }
+
+ static void method(Object o, Object o1) {
+ System.out.println("this method works on objects");
+ }
+
+ static void method(int i, int i1) {
+ System.out.println("this method works on ints");
+ }
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/Inference1.java b/java/java-tests/testData/inspection/redundantCast/generics/Inference1.java
new file mode 100644
index 000000000000..40313a46e366
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/Inference1.java
@@ -0,0 +1,20 @@
+import java.util.Map;
+class Test2 {
+ public String s;
+ public void maina(Object key, Map parameters) {
+ s = ((String[]) parameters.get(key))[0];
+ }
+}
+
+class Test {
+ static class SomeClass {
+ public T getX() {
+ return null;
+ }
+ }
+
+ public static void main(String[] args) {
+ //cast is needed for 'String' to be infered!
+ System.getProperty((String)new SomeClass().getX());
+ }
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/Inference2.java b/java/java-tests/testData/inspection/redundantCast/generics/Inference2.java
new file mode 100644
index 000000000000..5950a93e1746
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/Inference2.java
@@ -0,0 +1,31 @@
+import java.util.Set;
+
+final class Pair {
+ public final A first;
+ public final B second;
+
+ public Pair(A first, B second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public final A getFirst() {
+ return first;
+ }
+
+ public final B getSecond() {
+ return second;
+ }
+
+ public static Pair create(A first, B second) {
+ return new Pair(first, second);
+ }
+
+}
+
+class Test {
+ final Set strings = null;
+ final Pair, Set> x = Boolean.TRUE.booleanValue()
+ ? Pair.create(strings, strings)
+ : Pair.create(((Set) null), (Set) null); //these casts are not redundant
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/Inference3.java b/java/java-tests/testData/inspection/redundantCast/generics/Inference3.java
new file mode 100644
index 000000000000..76a1a74593e5
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/Inference3.java
@@ -0,0 +1,31 @@
+import java.util.Set;
+
+final class Pair {
+ public final A first;
+ public final B second;
+
+ public Pair(A first, B second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public final A getFirst() {
+ return first;
+ }
+
+ public final B getSecond() {
+ return second;
+ }
+
+ public static Pair create(A first, A second) {
+ return new Pair(first, second);
+ }
+
+}
+
+class Test {
+ final Set strings = null;
+ final Pair, Set> x = Boolean.TRUE.booleanValue()
+ ? Pair.create(strings, strings)
+ : Pair.create(((Set) null), (Set) null); //both casts are marked, but one is required for correct inference
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/InferenceFromCast.java b/java/java-tests/testData/inspection/redundantCast/generics/InferenceFromCast.java
new file mode 100644
index 000000000000..c1172a17142d
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/InferenceFromCast.java
@@ -0,0 +1,18 @@
+class Test {
+
+ {
+ f((Bar) getComponent());
+ f1((Bar) getComponent());
+ Bar b = (Bar) getComponent();
+ }
+
+ private void f(J j) {}
+
+ private void f1(J j) {}
+
+ private T getComponent() {
+ return null;
+ }
+
+ static class Bar {}
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/InstanceOfChecks.java b/java/java-tests/testData/inspection/redundantCast/generics/InstanceOfChecks.java
new file mode 100644
index 000000000000..8e867d693b8a
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/InstanceOfChecks.java
@@ -0,0 +1,10 @@
+import java.util.ArrayList;
+import java.util.List;
+
+class RedundantCast {
+ boolean redundantCasts(Object o) {
+ int p = 0;
+ if ((Number)p instanceof Integer) {}
+ return (List)o instanceof ArrayList;
+ }
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/NullInVarargsParameter.java b/java/java-tests/testData/inspection/redundantCast/generics/NullInVarargsParameter.java
new file mode 100644
index 000000000000..caca9e3dea1d
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/NullInVarargsParameter.java
@@ -0,0 +1,11 @@
+class Test {
+ void f(Class... classes) {
+ }
+
+ void g() {
+ f(((Class[])null));
+ f(((Class)null));
+ f(((Class)null),
+ ((Class)null));
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/RawCast.java b/java/java-tests/testData/inspection/redundantCast/generics/RawCast.java
new file mode 100644
index 000000000000..77d769643a66
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/RawCast.java
@@ -0,0 +1,21 @@
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+class Main {
+ public static void main(String[] args) throws Exception {
+ Properties properties = new Properties();
+
+ Map map = (Map) properties;
+ System.out.println(map);
+ }
+}
+
+interface I {}
+class C implements I {}
+class U {
+ void foo() {
+ List listOfC = null;
+ List listOfI = (List) listOfC;
+ }
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/RawCast1.java b/java/java-tests/testData/inspection/redundantCast/generics/RawCast1.java
new file mode 100644
index 000000000000..6f302ded2732
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/RawCast1.java
@@ -0,0 +1,10 @@
+class Test {
+ {
+ class TypedQuery {}
+ class TemporalDataDTO {}
+ class FOLDER_ID {}
+
+ TypedQuery h = null;
+ TypedQuery> typedQuery = (TypedQuery>) (TypedQuery>)h;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName.java b/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName.java
new file mode 100644
index 000000000000..215f623b6e09
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/SafeTempVarName.java
@@ -0,0 +1,9 @@
+import java.util.*;
+
+class RedundantCast{
+ void foo2(List