package com.fluentinterface.utils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class GenericsUtils {

    private GenericsUtils() {}

    /**
     * Finds the generic type declared on a single interface implemented by the provided class.
     * @param clazz the class on which we want to find the generic type.
     * @return the actual type declared on the provided generic interface.
     */
    public static Class<?> getDeclaredGenericType(Class<?> clazz, Class<?> genericInterface) {
        Type[] genericInterfaces = clazz.getGenericInterfaces();
        for (Type genericType : genericInterfaces) {
            if (genericType instanceof ParameterizedType) {
                ParameterizedType paramType = (ParameterizedType) genericType;
                if (paramType.getRawType().equals(genericInterface)) {
                    Type type = paramType.getActualTypeArguments()[0];

                    /**
                     * Test if the declared generic type is also generic,
                     * and if so return the raw type class
                     */
                    Class<?> rawType;
                    if (type instanceof ParameterizedType) {
                        rawType = (Class<?>) ((ParameterizedType) type).getRawType();
                    } else {
                        rawType = (Class<?>) type;
                    }

                    return rawType;
                }
            }
        }
        return null;
    }
}

@@ -271,16 +271,213 @@
  class.%0A
+     * If the generic type is itself a generic type (ex: %3Cpre%3ESomeType%3CSomeOtherType%3CT%3E%3E%3C/pre%3E,%0A     * the actal raw type will be returned (in the example, SomeOtherType would be returned).%0A     *%0A
      * @
@@ -1118,17 +1118,16 @@
 s()%5B0%5D;%0A
-%0A
         
@@ -1134,27 +1134,54 @@
             
-/**
+return getActualRawType(type);
 %0A           
@@ -1188,168 +1188,345 @@
     
+ %7D%0A
       
-* Test if the declared generic type is also generic,%0A                     * and if so return the raw type class%0A                     */%0A         
+      %7D%0A        %7D%0A        return null;%0A    %7D%0A%0A    /**%0A     * Java's introspection API differentiates between a raw type and a generic (parameterized) type.%0A     * To determine the actual raw type from a type, we need to take both cases into consideration.%0A
      
+*/%0A
     
+private static Class%3C?%3E getActualRawType(Type type) %7B%0A      
   Cl
@@ -1537,36 +1537,24 @@
 ?%3E rawType;%0A
-            
         if (
@@ -1598,36 +1598,24 @@
             
-          
-  
 rawType = (C
@@ -1664,28 +1664,16 @@
 Type();%0A
-            
         
@@ -1693,28 +1693,16 @@
         
- 
-           
 rawType 
@@ -1732,120 +1732,32 @@
     
-            %7D%0A%0A                    return rawType;%0A                %7D%0A            %7D%0A        %7D%0A        return null
+%7D%0A        return rawType
 ;%0A  

Refactor for more clarity