Will updated a scheme based on inheritance.  This is defined in a scheme objects with ``'inherit': '$definition'``.
        Will also updated parent objects for nested inheritance.

        Usage::
            >>> SCHEME = {
            >>>     'thing1': {
            >>>         'inherit': '$thing2'
            >>>     },
            >>>     '_': {
            >>>         'thing2': {
            >>>             'this_is': 'thing2 is a definition'
            >>>         }
            >>>     }
            >>> }
            >>> scheme = SCHEME.get('thing1')
            >>> if 'inherit' in scheme:
            >>>     scheme = self._scheme_propagation(scheme, SCHEME.get('_'))
            >>>
            >>> scheme.get('some_data')

        :param scheme: A dict, should be a scheme defining validation.
        :param definitions: A dict, should be defined in the scheme using '_'.
        :rtype: A :dict: will return a updated copy of the scheme.

def _scheme_propagation(self, scheme, definitions):
        """ Will updated a scheme based on inheritance.  This is defined in a scheme objects with ``'inherit': '$definition'``.
        Will also updated parent objects for nested inheritance.

        Usage::
            >>> SCHEME = {
            >>>     'thing1': {
            >>>         'inherit': '$thing2'
            >>>     },
            >>>     '_': {
            >>>         'thing2': {
            >>>             'this_is': 'thing2 is a definition'
            >>>         }
            >>>     }
            >>> }
            >>> scheme = SCHEME.get('thing1')
            >>> if 'inherit' in scheme:
            >>>     scheme = self._scheme_propagation(scheme, SCHEME.get('_'))
            >>>
            >>> scheme.get('some_data')

        :param scheme: A dict, should be a scheme defining validation.
        :param definitions: A dict, should be defined in the scheme using '_'.
        :rtype: A :dict: will return a updated copy of the scheme.
        """
        if not isinstance(scheme, dict):
            raise TypeError('scheme must be a dict to propagate.')

        inherit_from = scheme.get('inherit')

        if isinstance(inherit_from, six.string_types):
            if not inherit_from.startswith('$'):
                raise AttributeError('When inheriting from an object it must start with a $.')

            if inherit_from.count('$') > 1:
                raise AttributeError('When inheriting an object it can only have one $.')

            if not isinstance(definitions, dict):
                raise AttributeError("Must define definitions in the root of the SCHEME. "
                                     "It is done so with  '_': { objs }.")
            name = inherit_from[1:]
            definition = definitions.copy().get(name)

            if not definition:
                raise LookupError(
                    'Was unable to find {0} in definitions. The follow are available: {1}.'.format(name, definitions)
                )

        else:
            raise AttributeError('inherit must be defined in your scheme and be a string value. format: $variable.')

        updated_scheme = {key: value for key, value in six.iteritems(scheme) if key not in definition}
        nested_scheme = None
        for key, value in six.iteritems(definition):
            if key in scheme:
                updated_scheme[key] = scheme[key]
            else:
                updated_scheme[key] = value

            if key == 'inherit':
                nested_scheme = self._scheme_propagation(definition, definitions)

        # remove inherit key
        if 'inherit' in updated_scheme:
            del updated_scheme['inherit']

        if nested_scheme is not None:
            updated_scheme.update(nested_scheme)

        return updated_scheme