protected final void hardcodeValidCopyMethod(Class<?> fieldType, String fullyQualifiedMethodName, Class<?> argType) {
        if (argType==null || fieldType==null || fullyQualifiedMethodName==null) {
            throw new IllegalArgumentException("All parameters must be supplied - no nulls");
        }
        String className = fullyQualifiedMethodName.substring(0, fullyQualifiedMethodName.lastIndexOf("."));
        String methodName = fullyQualifiedMethodName.substring(fullyQualifiedMethodName.lastIndexOf(".")+1);

        
        String desc = null;
        try {
            if (MethodIs.aConstructor(methodName)) {
                Constructor<?> ctor = Class.forName(className).getDeclaredConstructor(argType);
                desc = Type.getConstructorDescriptor(ctor);
            } else {
                Method method = Class.forName(className).getMethod(methodName, argType);
                desc = Type.getMethodDescriptor(method);
            }
        } catch (NoSuchMethodException e) {
            rethrow("No such method", e);
        } catch (SecurityException e) {
            rethrow("Security error", e);
        } catch (ClassNotFoundException e) {
            rethrow("Class not  found", e);
        }
        CopyMethod copyMethod = new CopyMethod(dotted(className), methodName, desc);
        hardcodeValidCopyMethod(fieldType, copyMethod);
    }
protected final void hardcodeValidCopyMethod ( Class < ? > fieldType , String fullyQualifiedMethodName , Class < ? > argType ) { if ( argType == null || fieldType == null || fullyQualifiedMethodName == null ) { throw new IllegalArgumentException ( "All parameters must be supplied - no nulls" ) ; } String className = fullyQualifiedMethodName . substring ( 0 , fullyQualifiedMethodName . lastIndexOf ( "." ) ) ; String methodName = fullyQualifiedMethodName . substring ( fullyQualifiedMethodName . lastIndexOf ( "." ) + 1 ) ; String desc = null ; try { if ( MethodIs . aConstructor ( methodName ) ) { Constructor < ? > ctor = Class . forName ( className ) . getDeclaredConstructor ( argType ) ; desc = Type . getConstructorDescriptor ( ctor ) ; } else { Method method = Class . forName ( className ) . getMethod ( methodName , argType ) ; desc = Type . getMethodDescriptor ( method ) ; } } catch ( NoSuchMethodException e ) { rethrow ( "No such method" , e ) ; } catch ( SecurityException e ) { rethrow ( "Security error" , e ) ; } catch ( ClassNotFoundException e ) { rethrow ( "Class not  found" , e ) ; } CopyMethod copyMethod = new CopyMethod ( dotted ( className ) , methodName , desc ) ; hardcodeValidCopyMethod ( fieldType , copyMethod ) ; }
Hardcode a copy method as being valid. This should be used to tell Mutability Detector about
a method which copies a collection, and when the copy can be wrapped in an immutable wrapper
we can consider the assignment immutable. Useful for allowing Mutability Detector to correctly
work with other collections frameworks such as Google Guava. Reflection is used to obtain the
method's descriptor and to verify the method's existence.

@param fieldType - the type of the field to which the result of the copy is assigned
@param fullyQualifiedMethodName - the fully qualified method name
@param argType - the type of the argument passed to the copy method

@throws MutabilityAnalysisException - if the specified class or method does not exist
@throws IllegalArgumentException - if any of the arguments are null