docs: boolean haveAppropriateParams(Pointcut thePointcut, HookParams theParams) {
  		Validate.isTrue(theParams.getParamsForType().values().size() == thePointcut.getParameterTypes().size(), "Wrong number of params for pointcut %s - Wanted %s but found %s", thePointcut.name(), toErrorString(thePointcut.getParameterTypes()), theParams.getParamsForType().values().stream().map(t -> t != null ? t.getClass().getSimpleName() : "null").sorted().collect(Collectors.toList()));
  
  		List<String> wantedTypes = new ArrayList<>(thePointcut.getParameterTypes());
  
  		ListMultimap<Class<?>, Object> givenTypes = theParams.getParamsForType();
  		for (Class<?> nextTypeClass : givenTypes.keySet()) {
  			String nextTypeName = nextTypeClass.getName();
  			for (Object nextParamValue : givenTypes.get(nextTypeClass)) {
  				Validate.isTrue(nextParamValue == null || nextTypeClass.isAssignableFrom(nextParamValue.getClass()), "Invalid params for pointcut %s - %s is not of type %s", thePointcut.name(), nextParamValue != null ? nextParamValue.getClass() : "null", nextTypeClass);
  				Validate.isTrue(wantedTypes.remove(nextTypeName), "Invalid params for pointcut %s - Wanted %s but found %s", thePointcut.name(), toErrorString(thePointcut.getParameterTypes()), nextTypeName);
  			}
  		}
  
  		return true;
  	}