def _update_scheme(self, scheme, ancestors):
        if not isinstance(ancestors, OrderedDict):
            raise TypeError("ancestors must be an OrderedDict. type: {0} was passed.".format(type(ancestors)))
        if not isinstance(scheme, dict):
            raise TypeError('scheme must be a dict. type: {0} was passed'.format(type(scheme)))
        definitions = ROOT_SCHEME.get('_')
        if 'inherit' in scheme:
            scheme = self._scheme_propagation(scheme, definitions)
        updated_scheme = {}
        for scheme_key in six.iterkeys(scheme):
            if not isinstance(scheme_key, six.string_types):
                raise TypeError('scheme keys are required to be strings. type: {0} was passed.'.format(scheme_key))
            if '@' in scheme_key:
                ref = scheme_key[1:]
                scheme_reference = self._scheme_references.get(ref)
                if not scheme_reference:
                    raise ConfigValidationException(ancestors, ref, scheme_reference, 'required', scheme)
                for reference_key in scheme_reference['keys']:
                    scheme_reference['scheme'].update(scheme[scheme_key])
                    updated_scheme[reference_key] = scheme_reference['scheme']
            elif '~' in scheme_key:
                ref = scheme_key[1:]
                scheme_reference = self._scheme_references.get(ref)
                if not scheme_reference:
                    raise LookupError("was unable to find {0} in scheme reference.".format(ref))
                for reference_key in scheme_reference['keys']:
                    updated_scheme[reference_key] = scheme[scheme_key]
        scheme.update(updated_scheme)
        return scheme