@SuppressWarnings({ "unchecked", "rawtypes" })
  protected Object convertRecursive(Object value, Object valueSource, GenericType<?> targetType, Class<?> currentTargetClass, ValueConverter previousConverter,
      TargetClass2ConverterMap converterMap) {

    boolean traceEnabled = LOG.isTraceEnabled();
    ValueConverter lastConverter = previousConverter;
    Class<?> currentClass = currentTargetClass;
    Object result = null;
    try {
      while (currentClass != null) {
        if (isAccepted(currentClass)) {
          if (traceEnabled) {
            LOG.trace("searching converter for target-type '" + currentClass + "'");
          }
          ValueConverter converter = converterMap.get(currentClass);
          if ((converter != null) && (converter != lastConverter) && (isApplicable(converter, targetType))) {
            if (traceEnabled) {
              StringWriter sw = new StringWriter(50);
              sw.append("trying converter for target-type '");
              sw.append(converter.getTargetType().toString());
              sw.append("'");
              if (!converter.getTargetType().equals(currentClass)) {
                sw.append(" for current-type '");
                sw.append(currentClass.toString());
                sw.append("'");
              }
              LOG.trace(sw.toString());
            }
            result = converter.convert(value, valueSource, targetType);
            if (result != null) {
              return result;
            }
            lastConverter = converter;
          }
        }
        for (Class<?> superInterface : currentClass.getInterfaces()) {
          if (isAccepted(superInterface)) {
            result = convertRecursive(value, valueSource, targetType, superInterface, lastConverter, converterMap);
            if (result != null) {
              return result;
            }
          }
        }
        if ((currentClass.isInterface()) && (targetType.getRetrievalClass() == currentClass)) {
          currentClass = Object.class;
        } else {
          currentClass = currentClass.getSuperclass();
        }
      }
    } catch (ValueException e) {
      throw e;
    } catch (RuntimeException e) {
      throw new NlsParseException(e, value, targetType, valueSource);
    }
    return null;
  }
@ SuppressWarnings ( { "unchecked" , "rawtypes" } ) protected Object convertRecursive ( Object value , Object valueSource , GenericType < ? > targetType , Class < ? > currentTargetClass , ValueConverter previousConverter , TargetClass2ConverterMap converterMap ) { boolean traceEnabled = LOG . isTraceEnabled ( ) ; ValueConverter lastConverter = previousConverter ; Class < ? > currentClass = currentTargetClass ; Object result = null ; try { while ( currentClass != null ) { if ( isAccepted ( currentClass ) ) { if ( traceEnabled ) { LOG . trace ( "searching converter for target-type '" + currentClass + "'" ) ; } ValueConverter converter = converterMap . get ( currentClass ) ; if ( ( converter != null ) && ( converter != lastConverter ) && ( isApplicable ( converter , targetType ) ) ) { if ( traceEnabled ) { StringWriter sw = new StringWriter ( 50 ) ; sw . append ( "trying converter for target-type '" ) ; sw . append ( converter . getTargetType ( ) . toString ( ) ) ; sw . append ( "'" ) ; if ( ! converter . getTargetType ( ) . equals ( currentClass ) ) { sw . append ( " for current-type '" ) ; sw . append ( currentClass . toString ( ) ) ; sw . append ( "'" ) ; } LOG . trace ( sw . toString ( ) ) ; } result = converter . convert ( value , valueSource , targetType ) ; if ( result != null ) { return result ; } lastConverter = converter ; } } for ( Class < ? > superInterface : currentClass . getInterfaces ( ) ) { if ( isAccepted ( superInterface ) ) { result = convertRecursive ( value , valueSource , targetType , superInterface , lastConverter , converterMap ) ; if ( result != null ) { return result ; } } } if ( ( currentClass . isInterface ( ) ) && ( targetType . getRetrievalClass ( ) == currentClass ) ) { currentClass = Object . class ; } else { currentClass = currentClass . getSuperclass ( ) ; } } } catch ( ValueException e ) { throw e ; } catch ( RuntimeException e ) { throw new NlsParseException ( e , value , targetType , valueSource ) ; } return null ; }
This method performs the {@link #convert(Object, Object, GenericType) conversion} recursive.

@param value is the value to convert.
@param valueSource describes the source of the value. This may be the filename where the value was read from, an
XPath where the value was located in an XML document, etc. It is used in exceptions thrown if something goes
wrong. This will help to find the problem easier.
@param targetType is the {@link GenericType} to convert the {@code value} to.
@param currentTargetClass is the current {@link ValueConverter#getTargetType() target-type} to try.
@param previousConverter is the converter that has been tried last time without success. It is used to avoid trying
the same converter again. Will initially be {@code null}.
@param converterMap is the {@link TargetClass2ConverterMap}.
@return the converted {@code value} or {@code null} if the conversion is NOT possible. The returned value has to be
an {@link Class#isInstance(Object) instance} of the given {@code targetType}.