Returns the closest matching converter for the given type, or null if
none found.

@param type type to select, which may be null
@throws IllegalStateException if multiple converters match the type
equally well
493278
Converter select(Class<?> type) throws IllegalStateException {
        // Check the hashtable first.
        Entry[] entries = iSelectEntries;
        int length = entries.length;
        int index = type == null ? 0 : type.hashCode() & (length - 1);

        Entry e;
        // This loop depends on there being at least one null slot.
        while ((e = entries[index]) != null) {
            if (e.iType == type) {
                return e.iConverter;
            }
            if (++index >= length) {
                index = 0;
            }
        }

        // Not found in the hashtable, so do actual work.

        Converter converter = selectSlow(this, type);
        e = new Entry(type, converter);

        // Save the entry for future selects. This class must be threadsafe,
        // but there is no synchronization. Since the hashtable is being used
        // as a cache, it is okay to destroy existing entries. This isn't
        // likely to occur unless there is a high amount of concurrency. As
        // time goes on, cache updates will occur less often, and the cache
        // will fill with all the necessary entries.

        // Do all updates on a copy: slots in iSelectEntries must not be
        // updated by multiple threads as this can allow all null slots to be
        // consumed.
        entries = (Entry[])entries.clone();

        // Add new entry.
        entries[index] = e;

        // Verify that at least one null slot exists!
        for (int i=0; i<length; i++) {
            if (entries[i] == null) {
                // Found a null slot, swap in new hashtable.
                iSelectEntries = entries;
                return converter;
            }
        }

        // Double capacity and re-hash.

        int newLength = length << 1;
        Entry[] newEntries = new Entry[newLength];
        for (int i=0; i<length; i++) {
            e = entries[i];
            type = e.iType;
            index = type == null ? 0 : type.hashCode() & (newLength - 1);
            while (newEntries[index] != null) {
                if (++index >= newLength) {
                    index = 0;
                }
            }
            newEntries[index] = e;
        }

        // Swap in new hashtable.
        iSelectEntries = newEntries;
        return converter;
    }
634125
@SuppressWarnings("unchecked")
  public <T extends R> Converter<S, T> getConverter(Class<T> targetType) {
    return (Converter<S, T>) converters.get(targetType);
  }
182009
public ConverterRegistry putCustom(Type type, Class<? extends Converter<?>> converterClass) {
		return putCustom(type, ReflectUtil.newInstance(converterClass));
	}
1186900
private <A extends Annotation> AnnotationConverter<A> getConverter(Annotation annotation) {
		MappingOption mappingOption = annotation.annotationType().getAnnotation( MappingOption.class );
		if ( mappingOption == null ) {
			return null;
		}

		// wrong type would be a programming error of the annotation developer
		@SuppressWarnings("unchecked")
		Class<? extends AnnotationConverter<A>> converterClass = (Class<? extends AnnotationConverter<A>>) mappingOption.value();

		try {
			return converterClass.newInstance();
		}
		catch (Exception e) {
			throw log.cannotConvertAnnotation( converterClass, e );
		}
	}
27549
static Converter getValueTypeConverter(FacesContext facesContext, UISelectMany component)
    {
        Converter converter = null;
        
        Object valueTypeAttr = component.getAttributes().get(VALUE_TYPE_KEY);
        if (valueTypeAttr != null)
        {
            // treat the valueType attribute exactly like the collectionType attribute
            Class<?> valueType = getClassFromAttribute(facesContext, valueTypeAttr);
            if (valueType == null)
            {
                throw new FacesException(
                        "The attribute "
                                + VALUE_TYPE_KEY
                                + " of component "
                                + component.getClientId(facesContext)
                                + " does not evaluate to a "
                                + "String, a Class object or a ValueExpression pointing "
                                + "to a String or a Class object.");
            }
            // now we have a valid valueType
            // --> try to get a registered-by-class converter
            converter = facesContext.getApplication().createConverter(valueType);
            
            if (converter == null)
            {
                facesContext.getExternalContext().log("Found attribute valueType on component " +
                        _ComponentUtils.getPathToComponent(component) +
                        ", but could not get a by-type converter for type " + 
                        valueType.getName());
            }
        }
        
        return converter;
    }
981213
@SuppressWarnings("unchecked")
    private ConverterProvider findProvider(Class<?> valueType) {
        if (valueType == null) {
            return null;
        }

        if (unsupportedTypes.contains(valueType)) {
            return null;
        }

        ConverterProvider provider = providers.get(valueType);
        if (provider != null) {
            return provider;
        }

        List<Class<?>> supertypes = getSupertypes(valueType);
        for (Class<?> supertype : supertypes) {
            provider = findProvider(supertype);
            if (provider != null) {
                LOGGER.debug("Adding shortcut mapping {} -> {}", valueType.getCanonicalName(), provider.converterType().getCanonicalName());
                providers.put(valueType, provider);
                return provider;
            }
        }
        unsupportedTypes.add(valueType);
        return null;
    }
692249
public <S, T> Converter<S, T> findConverter(ConverterKey<S,T> key) {
		
		 // We check once before attempting introspection so we avoid that if possible
		@SuppressWarnings("unchecked")
		Converter<S,T> converter = (Converter<S, T>) registeredConverters.get(key);
		if (converter != null) {
			return converter;
		}
		
		// Now try introspecting the relevant class
		registerAnnotatedClasses(key.getInputClass(), key.getOutputClass());

		@SuppressWarnings("unchecked")
		Converter<S,T> myConverter = (Converter<S, T>) registeredConverters.get(key);
		return myConverter;
	}
768452
private static Converter selectSlow(ConverterSet set, Class<?> type) {
        Converter[] converters = set.iConverters;
        int length = converters.length;
        Converter converter;

        for (int i=length; --i>=0; ) {
            converter = converters[i];
            Class<?> supportedType = converter.getSupportedType();

            if (supportedType == type) {
                // Exact match.
                return converter;
            }

            if (supportedType == null || (type != null && !supportedType.isAssignableFrom(type))) {
                // Eliminate the impossible.
                set = set.remove(i, null);
                converters = set.iConverters;
                length = converters.length;
            }
        }

        // Haven't found exact match, so check what remains in the set.

        if (type == null || length == 0) {
            return null;
        }
        if (length == 1) {
            // Found the one best match.
            return converters[0];
        }

        // At this point, there exist multiple potential converters.

        // Eliminate supertypes.
        for (int i=length; --i>=0; ) {
            converter = converters[i];
            Class<?> supportedType = converter.getSupportedType();
            for (int j=length; --j>=0; ) {
                if (j != i && converters[j].getSupportedType().isAssignableFrom(supportedType)) {
                    // Eliminate supertype.
                    set = set.remove(j, null);
                    converters = set.iConverters;
                    length = converters.length;
                    i = length - 1;
                }
            }
        }        
        
        // Check what remains in the set.

        if (length == 1) {
            // Found the one best match.
            return converters[0];
        }

        // Class c implements a, b {}
        // Converters exist only for a and b. Which is better? Neither.

        StringBuilder msg = new StringBuilder();
        msg.append("Unable to find best converter for type \"");
        msg.append(type.getName());
        msg.append("\" from remaining set: ");
        for (int i=0; i<length; i++) {
            converter = converters[i];
            Class<?> supportedType = converter.getSupportedType();

            msg.append(converter.getClass().getName());
            msg.append('[');
            msg.append(supportedType == null ? null : supportedType.getName());
            msg.append("], ");
        }

        throw new IllegalStateException(msg.toString());
    }
1036209
protected static <AdapterType> AdapterType getAdapter(Resource resource, Class<AdapterType> type) {
        if (type == ResourceHandle.class) {
            return type.cast(new ResourceHandle(resource));
        }
        log.info("Unable to adapt resource on {} to type {}", resource.getPath(), type.getName());
        return null;
    }
538869
private static <T> ConvertibleType<T> of(final DynamoDBTypeConverter<?,T> converter) {
        final Class<?> clazz = converter.getClass();
        if (!clazz.isInterface()) {
            for (Class<?> c = clazz; Object.class != c; c = c.getSuperclass()) {
                for (final Type genericType : c.getGenericInterfaces()) {
                    final ConvertibleType<T> type = ConvertibleType.<T>of(genericType);
                    if (type.is(DynamoDBTypeConverter.class)) {
                        if (type.params.length == 2 && type.param(0).targetType() != Object.class) {
                            return type.param(0);
                        }
                    }
                }
            }
            final ConvertibleType<T> type = ConvertibleType.<T>of(clazz.getGenericSuperclass());
            if (type.is(DynamoDBTypeConverter.class)) {
                if (type.params.length > 0 && type.param(0).targetType() != Object.class) {
                    return type.param(0);
                }
            }
        }
        throw new DynamoDBMappingException("could not resolve type of " + clazz);
    }
119253
public PartialConverter getPartialConverter(Object object) {
        PartialConverter converter =
            (PartialConverter)iPartialConverters.select(object == null ? null : object.getClass());
        if (converter != null) {
            return converter;
        }
        throw new IllegalArgumentException("No partial converter found for type: " +
            (object == null ? "null" : object.getClass().getName()));
    }
1244131
@Override
    protected <T> ConversionStatus implicitConverters(String rawString, Class<T> type) {
        ConversionStatus status = new ConversionStatus();
        BuiltInConverter automaticConverter = getConverter(type);

        //will be null if a suitable string constructor method could not be found
        if (automaticConverter != null) {
            try {
                Object converted = automaticConverter.convert(rawString);
                status.setConverted(converted);
            } catch (IllegalArgumentException e) {
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "implicitConverters: An automatic converter for type ''{0}'' and raw String ''{1}'' threw an exception: {2}.", type, rawString, e);
                }
                throw e;
            } catch (Throwable t) {
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "implicitConverters: An automatic converter for type ''{0}'' and raw String ''{1}'' threw an exception: {2}.", type, rawString, t);
                }
                throw new ConfigException(t);
            }
        }

        return status;
    }
1340775
public Class<?> getFarType(Class<?> nearType) {
        if (!nearToFarType.containsKey(nearType)) {
            throw new IllegalStateException("Near type not registered: " + (nearType == null ? "null" : nearType.getSimpleName()));
        }
        return nearToFarType.get(nearType);
    }
641716
@SuppressWarnings("unchecked")
	public static DataFormatConverter getConverterForTypeInfo(TypeInformation typeInfo) {
		DataFormatConverter converter = TYPE_INFO_TO_CONVERTER.get(typeInfo);
		if (converter != null) {
			return converter;
		}

		if (typeInfo instanceof BasicArrayTypeInfo) {
			BasicArrayTypeInfo arrayType = (BasicArrayTypeInfo) typeInfo;
			return new ObjectArrayConverter(arrayType.getTypeClass(), arrayType.getComponentInfo());
		} else if (typeInfo instanceof ObjectArrayTypeInfo) {
			ObjectArrayTypeInfo arrayType = (ObjectArrayTypeInfo) typeInfo;
			return new ObjectArrayConverter(arrayType.getTypeClass(), arrayType.getComponentInfo());
		} else if (typeInfo instanceof MapTypeInfo) {
			MapTypeInfo mapType = (MapTypeInfo) typeInfo;
			return new MapConverter(mapType.getKeyTypeInfo(), mapType.getValueTypeInfo());
		} else if (typeInfo instanceof RowTypeInfo) {
			return new RowConverter((RowTypeInfo) typeInfo);
		} else if (typeInfo instanceof PojoTypeInfo) {
			return new PojoConverter((PojoTypeInfo) typeInfo);
		} else if (typeInfo instanceof TupleTypeInfo) {
			return new TupleConverter((TupleTypeInfo) typeInfo);
		} else if (typeInfo instanceof TupleTypeInfoBase && Product.class.isAssignableFrom(typeInfo.getTypeClass())) {
			return new CaseClassConverter((TupleTypeInfoBase) typeInfo);
		} else if (typeInfo instanceof BinaryArrayTypeInfo) {
			return BinaryArrayConverter.INSTANCE;
		} else if (typeInfo instanceof BinaryMapTypeInfo) {
			return BinaryMapConverter.INSTANCE;
		} else if (typeInfo instanceof BaseRowTypeInfo) {
			return new BaseRowConverter(typeInfo.getArity());
		} else if (typeInfo.equals(BasicTypeInfo.BIG_DEC_TYPE_INFO)) {
			return new BaseRowConverter(typeInfo.getArity());
		} else if (typeInfo instanceof DecimalTypeInfo) {
			DecimalTypeInfo decimalType = (DecimalTypeInfo) typeInfo;
			return new DecimalConverter(decimalType.precision(), decimalType.scale());
		} else if (typeInfo instanceof BigDecimalTypeInfo) {
			BigDecimalTypeInfo decimalType = (BigDecimalTypeInfo) typeInfo;
			return new BigDecimalConverter(decimalType.precision(), decimalType.scale());
		} else if (typeInfo instanceof BinaryGenericTypeInfo) {
			return BinaryGenericConverter.INSTANCE;
		} else {
			return new GenericConverter(typeInfo.createSerializer(new ExecutionConfig()));
		}
	}
179098
private GenericConverter.ConvertiblePair getRequiredTypeInfo(Object converter, Class<?> genericIfc) {
		Class<?>[] args = GenericTypeResolver.resolveTypeArguments(converter.getClass(), genericIfc);
		return (args != null ? new GenericConverter.ConvertiblePair(args[0], args[1]) : null);
	}
901620
public static @CheckForNull <T> T lookup(Class<T> type) {
        Jenkins j = Jenkins.getInstanceOrNull();
        return j != null ? j.lookup.get(type) : null;
    }
807441
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
		Assert.notNull(targetType, "targetType to convert to cannot be null");
		return canConvert((sourceType != null ? TypeDescriptor.valueOf(sourceType) : null),
				TypeDescriptor.valueOf(targetType));
	}