def _decode_instance(encoded_data, decoded_objects, data_to_decode):
    """ Decode a data structure

    Args:
        encoded_data (:obj:`dict`, :obj:`list`, or scalar): data structure with
            encoded objects
        decoded_objects (:obj:`dict`): dictionary that maps the unique ids of
            encoded objects to dictionaries that represent the decoded objects
        data_to_decode (:obj:`list`): list of tuples of data structures that still
            need to decoded. The first element represents the data structure that
            needs to be decoded. The second element represents the object that will
            represent the decoded data structure.

    Returns:
        :obj:`dict`, :obj:`list`, or scalar: decoded data structure
    """
    if isinstance(encoded_data, dict) and '__type' in encoded_data:
        obj_type = encoded_data.get('__type')
        obj = decoded_objects.get(encoded_data['__id'], None)
        if obj is None:
            obj = {'__type': obj_type}
            decoded_objects[encoded_data['__id']] = obj
        data_to_decode.append((encoded_data, obj))
    elif isinstance(encoded_data, list):
        obj = []
        data_to_decode.append((encoded_data, obj))
    elif isinstance(encoded_data, dict):
        obj = {}
        data_to_decode.append((encoded_data, obj))
    else:
        obj = encoded_data

    return obj