private AbstractJClass narrowed(AbstractJClass usedDataType, AbstractJClass resultType, AbstractJClass exceptionType, AbstractJClass selfType) {
Iterator<? extends AbstractJClass> dataTypeArgumentIterator = usedDataType.getTypeParameters().iterator();
AbstractJClass result = visitorInterfaceModel;
for (JTypeVar typeVariable: visitorInterfaceModel.typeParams()) {
if (typeParameters.isSpecial(typeVariable))
result = result.narrow(typeParameters.substituteSpecialType(typeVariable, usedDataType, resultType, exceptionType));
else
result = result.narrow(dataTypeArgumentIterator.next());
}
return result;
}