def find_and_convert(self, attr_name: str, attr_value: S, desired_attr_type: Type[T], logger: Logger,<EOL>options: Dict[str, Dict[str, Any]]) -> T:
if robust_isinstance(attr_value, desired_attr_type) and not is_collection(desired_attr_type):<EOL><INDENT>return attr_value<EOL><DEDENT>else:<EOL><INDENT>generic, approx, exact = self.get_all_conversion_chains(type(attr_value), desired_attr_type)<EOL>all_chains = generic + approx + exact<EOL>if len(all_chains) > <NUM_LIT:0>:<EOL><INDENT>all_errors = dict()<EOL>for chain in reversed(all_chains):<EOL><INDENT>try:<EOL><INDENT>return chain.convert(desired_attr_type, attr_value, logger, options)<EOL><DEDENT>except Exception as e:<EOL><INDENT>all_errors[chain] = e<EOL><DEDENT><DEDENT>raise AttrConversionException.create(attr_name, attr_value, desired_attr_type, all_errors)<EOL><DEDENT>else:<EOL><INDENT>raise NoConverterFoundForObjectType.create(self, attr_value, desired_attr_type)<EOL><DEDENT><DEDENT>
Utility method to convert some value into the desired type. It relies on get_all_conversion_chains to find the
converters, and apply them in correct order
:return: