code: def find_and_convert(self, attr_name: str, attr_value: S, desired_attr_type: Type[T], logger: Logger,
                           options: Dict[str, Dict[str, Any]]) -> T:
          
  
          if robust_isinstance(attr_value, desired_attr_type) and not is_collection(desired_attr_type):
              # value is already of the correct type
              return attr_value
  
          else:
              # try to find conversion chains
              generic, approx, exact = self.get_all_conversion_chains(type(attr_value), desired_attr_type)
              all_chains = generic + approx + exact
  
              if len(all_chains) > 0:
                  all_errors = dict()
                  for chain in reversed(all_chains):
                      try:
                          return chain.convert(desired_attr_type, attr_value, logger, options)
                      except Exception as e:
                          all_errors[chain] = e
                  raise AttrConversionException.create(attr_name, attr_value, desired_attr_type, all_errors)
  
              else:
                  # did not find any conversion chain
                  raise NoConverterFoundForObjectType.create(self, attr_value, desired_attr_type)
docs: 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: