def _check_for_mismatches(self, known_keys):
        """check for bad options from value sources"""
        for a_value_source in self.values_source_list:
            try:
                if a_value_source.always_ignore_mismatches:
                    continue
            except AttributeError:
                # ok, this values source doesn't have the concept
                # always igoring mismatches, we won't tolerate mismatches
                pass
            # we want to fetch the keys from the value sources so that we can
            # check for mismatches.  Commandline value sources, are different,
            # we never want to allow unmatched keys from the command line.
            # By detecting if this value source is a command line source, we
            # can employ the command line's own mismatch detection.  The
            # boolean 'allow_mismatches' controls application of the tollerance
            # for mismatches.
            if hasattr(a_value_source, 'command_line_value_source'):
                allow_mismatches = False
            else:
                allow_mismatches = True
            # make a set of all the keys from a value source in the form
            # of strings like this: 'x.y.z'
            value_source_mapping = a_value_source.get_values(
                self,
                allow_mismatches,
                self.value_source_object_hook
            )
            value_source_keys_set = set([
                k for k in
                DotDict(value_source_mapping).keys_breadth_first()
            ])
            # make a set of the keys that didn't match any of the known
            # keys in the requirements
            unmatched_keys = value_source_keys_set.difference(known_keys)
            # some of the unmatched keys may actually be ok because the were
            # used during acquisition.
            # remove keys of the form 'y.z' if they match a known key of the
            # form 'x.y.z'
            for key in unmatched_keys.copy():
                key_is_okay = six.moves.reduce(
                    lambda x, y: x or y,
                    (known_key.endswith(key) for known_key in known_keys)
                )
                if key_is_okay:
                    unmatched_keys.remove(key)
            # anything left in the unmatched_key set is a badly formed key.
            # issue a warning
            if unmatched_keys:
                if self.option_definitions.admin.strict.default:
                    # raise hell...
                    if len(unmatched_keys) > 1:
                        raise NotAnOptionError(
                            "%s are not valid Options" % unmatched_keys
                        )
                    elif len(unmatched_keys) == 1:
                        raise NotAnOptionError(
                            "%s is not a valid Option" % unmatched_keys.pop()
                        )
                else:
                    warnings.warn(
                        'Invalid options: %s' % ', '.join(sorted(unmatched_keys))
                    )
check for bad options from value sources