# Path: invenio_records/dictutils.py
# def dict_lookup(source, lookup_key, parent=False):
#     """Make a lookup into a dict based on a dot notation.
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a']``
#     - ``'a.b'`` - Equivalent to ``source['a']['b']``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0]`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to perform the lookup in.
#     :param parent: If parent argument is True, returns the parent node of
#                    matched object.
#     :param lookup_key: A string using dot notation, or a list of keys.
#     """
#     # Copied from dictdiffer (CERN contributed part) and slightly modified.
#     keys = parse_lookup_key(lookup_key)
# 
#     if parent:
#         keys = keys[:-1]
# 
#     # Lookup the key
#     value = source
#     for key in keys:
#         try:
#             if isinstance(value, list):
#                 key = int(key)
#             value = value[key]
#         except (TypeError, IndexError, ValueError) as exc:
#             raise KeyError(lookup_key) from exc
#     return value
# 
# def dict_set(source, key, value):
#     """Set a value into a dict via a dot-notated key.
# 
#     This also creates missing key "paths".
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a'] = value``
#     - ``'a.b'`` - Equivalent to ``source['a']['b'] = value``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0] = value`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to set the value in.
#     :param key: A string using dot notation, or a list of keys.
#     :param value: The value to be set.
#     """
#     keys = parse_lookup_key(key)
#     parent = source
#     for key in keys[:-1]:
#         if isinstance(key, int):
#             parent = parent[key]
#         else:
#             parent = parent.setdefault(key, {})
#     parent[keys[-1]] = value
# 
# def parse_lookup_key(lookup_key):
#     """Parse a lookup key."""
#     if not lookup_key:
#         raise KeyError("No lookup key specified")
# 
#     # Parse the list of keys
#     if isinstance(lookup_key, str):
#         keys = lookup_key.split('.')
#     elif isinstance(lookup_key, list):
#         keys = lookup_key
#     else:
#         raise TypeError('lookup must be string or list')
# 
#     return keys
# 
# Path: invenio_records/systemfields/relations/errors.py
# class InvalidCheckValue(RelationError):
#     """Invalid check value."""
# 
# class InvalidRelationValue(RelationError):
#     """Invalid relation value."""


from ...dictutils import dict_lookup, dict_set, parse_lookup_key
from .errors import InvalidCheckValue, InvalidRelationValue
            return obj
        except KeyError:
            return None

    def __getattr__(self, name):
        """Proxy attribute access to field."""
        return getattr(self.field, name)

    def _value_check(self, value_to_check, object):
        """Checks if the value is present in the object."""
        for key, value in value_to_check.items():
            if key not in object:
                raise InvalidCheckValue(f'Invalid key {key}.')
            if isinstance(value, dict):
                self._value_check(value, object[key])
            else:
                if not isinstance(value, list):
                    raise InvalidCheckValue(
                        f"Invalid value_check value: {value}; it must be "
                        "a list"
                    )
                elif isinstance(object[key], list):
                    value_exist = set(object[key]).intersection(set(value))
                    if not value_exist:
                        raise InvalidCheckValue(
                            f"Failed cross checking value_check value "
                            f"{value} with record value {object[key]}."
                        )
                else:
                    if object[key] not in value:

# Path: invenio_records/dictutils.py
# def dict_lookup(source, lookup_key, parent=False):
#     """Make a lookup into a dict based on a dot notation.
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a']``
#     - ``'a.b'`` - Equivalent to ``source['a']['b']``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0]`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to perform the lookup in.
#     :param parent: If parent argument is True, returns the parent node of
#                    matched object.
#     :param lookup_key: A string using dot notation, or a list of keys.
#     """
#     # Copied from dictdiffer (CERN contributed part) and slightly modified.
#     keys = parse_lookup_key(lookup_key)
# 
#     if parent:
#         keys = keys[:-1]
# 
#     # Lookup the key
#     value = source
#     for key in keys:
#         try:
#             if isinstance(value, list):
#                 key = int(key)
#             value = value[key]
#         except (TypeError, IndexError, ValueError) as exc:
#             raise KeyError(lookup_key) from exc
#     return value
# 
# def dict_set(source, key, value):
#     """Set a value into a dict via a dot-notated key.
# 
#     This also creates missing key "paths".
# 
#     Examples of the supported dot notation:
# 
#     - ``'a'`` - Equivalent to ``source['a'] = value``
#     - ``'a.b'`` - Equivalent to ``source['a']['b'] = value``
#     - ``'a.b.0'`` - Equivalent to ``source['a']['b'][0] = value`` (for lists)
# 
#     List notation is also supported:
# 
#     - `['a']``
#     - ``['a','b']``
#     - ``['a','b', 0]``
# 
#     :param source: The dictionary object to set the value in.
#     :param key: A string using dot notation, or a list of keys.
#     :param value: The value to be set.
#     """
#     keys = parse_lookup_key(key)
#     parent = source
#     for key in keys[:-1]:
#         if isinstance(key, int):
#             parent = parent[key]
#         else:
#             parent = parent.setdefault(key, {})
#     parent[keys[-1]] = value
# 
# def parse_lookup_key(lookup_key):
#     """Parse a lookup key."""
#     if not lookup_key:
#         raise KeyError("No lookup key specified")
# 
#     # Parse the list of keys
#     if isinstance(lookup_key, str):
#         keys = lookup_key.split('.')
#     elif isinstance(lookup_key, list):
#         keys = lookup_key
#     else:
#         raise TypeError('lookup must be string or list')
# 
#     return keys
# 
# Path: invenio_records/systemfields/relations/errors.py
# class InvalidCheckValue(RelationError):
#     """Invalid check value."""
# 
# class InvalidRelationValue(RelationError):
#     """Invalid relation value."""


# Path: invenio_records/systemfields/relations/results.py
from ...dictutils import dict_lookup, dict_set, parse_lookup_key
from .errors import InvalidCheckValue, InvalidRelationValue

            return obj
        except KeyError:
            return None

    def __getattr__(self, name):
        """Proxy attribute access to field."""
        return getattr(self.field, name)

    def _value_check(self, value_to_check, object):
        """Checks if the value is present in the object."""
        for key, value in value_to_check.items():
            if key not in object:
                raise InvalidCheckValue(f'Invalid key {key}.')
            if isinstance(value, dict):
                self._value_check(value, object[key])
            else:
                if not isinstance(value, list):
                    raise InvalidCheckValue(
                        f"Invalid value_check value: {value}; it must be "
                        "a list"
                    )
                elif isinstance(object[key], list):
                    value_exist = set(object[key]).intersection(set(value))
                    if not value_exist:
                        raise InvalidCheckValue(
                            f"Failed cross checking value_check value "
                            f"{value} with record value {object[key]}."
                        )
                else:
                    if object[key] not in value:

                        raise InvalidCheckValue(