code: @SuppressWarnings("unchecked")
  	public <Input,Output> Adapter<Input,Output> findAdapter(Object in, Class<Input> input, Class<Output> output) {
  		ArrayList<Adapter> acceptInput = new ArrayList<>();
  		ArrayList<Adapter> matching = new ArrayList<>();
  		for (Adapter a : adapters) {
  			if (!a.getInputType().isAssignableFrom(input)) continue;
  			if (!a.canAdapt(in)) continue;
  			acceptInput.add(a);
  			if (output.equals(a.getOutputType()))
  				return a;
  			if (output.isAssignableFrom(a.getOutputType()))
  				matching.add(a);
  		}
  		if (acceptInput.isEmpty())
  			return null;
  		if (matching.size() == 1)
  			return matching.get(0);
  		if (!matching.isEmpty())
  			return getBest(matching);
  		LinkedList<LinkedList<Adapter>> paths = findPathsTo(input, acceptInput, output);
  		LinkedList<Adapter> best = null;
  		while (!paths.isEmpty()) {
  			LinkedList<Adapter> path = paths.removeFirst();
  			if (best != null && best.size() <= path.size()) continue;
  			Object o = in;
  			boolean valid = true;
  			int i = 0;
  			for (Adapter a : path) {
  				if (!a.canAdapt(o)) {
  					valid = false;
  					break;
  				}
  				if (i == path.size() - 1)
  					break; // we are on the last, so no need to do it
  				i++;
  				try {
  					o = a.adapt(o);
  				} catch (Exception e) {
  					valid = false;
  					break;
  				}
  			}
  			if (valid)
  				best = path;
  		}
  		if (best == null) return null;
  		return new LinkedAdapter(best);
  	}
docs: Search for an adapter.