reads the paramater and returns the selected element

    args:
        dataset: the dataset to search
        param: the paramater to search by
        no_key: wheather to use the 'param' 'element' to filter the list.
                This is passed True after the first run during recurssive call
                when the key has already been used to select subset of the
                dataset

def get_reverse_json_qry_item(dataset, param, no_key=False, initial_val=None):
    """ reads the paramater and returns the selected element

    args:
        dataset: the dataset to search
        param: the paramater to search by
        no_key: wheather to use the 'param' 'element' to filter the list.
                This is passed True after the first run during recurssive call
                when the key has already been used to select subset of the
                dataset
    """

    def get_dataset_vals(ds, key, filter_tup=tuple(), initial_val=None):
        def reduce_list(value):
            if isinstance(value, list):
                if len(value) == 1:
                    return value[0]
            return value

        def merge_list(value):
            if isinstance(value, list):
                rtn_list = []
                for item in value:
                    if isinstance(item, list):
                        rtn_list += item
                    else:
                        rtn_list.append(item)
                return list(set(rtn_list))
            return value

        def test_elem(elem, filter_tup):
            search_lst = elem
            if isinstance(elem, dict):
                search_lst = elem.get(filter_tup[0], [])
            if filter_tup[2] == '=':
                try:
                    if elem.subject == filter_tup[1]:
                        return True
                except AttributeError:
                    pass
                test_lst = [item for item in search_lst \
                            if (isinstance(item, dict) \
                                and item.subject == filter_tup[1]) \
                            or item == filter_tup[1]]
                if test_lst:
                    return True
                return False

        def filter_list(ds, key, filter_tup, initial_val=None):
            rtn_list = ds
            if key:
                rtn_list = merge_list([reduce_list(reduce_list(elem)[key]) \
                                   for elem in ds if reduce_list(elem).get(key)])
            if filter_tup:
                return [elem for elem in rtn_list \
                        if test_elem(elem, filter_tup)]
            return rtn_list

        def reverse_filter_list(ds, key, filter_tup, initial_val=None):

            def get_reverse_ds_dict(ds, key, filter_tup, initial_val=None):
                if hasattr(ds, 'rmap') and initial_val:
                    # pdb.set_trace()
                    if key:
                        try:
                            return ds.rmap[initial_val][key]
                        except KeyError:
                            return []
                    else:
                        return ds.rmap[initial_val]
                data_list = UniqueList()
                if not key and not initial_val:
                    return data_list
                for sub, ds_rdf_class in ds.items():
                    for pred, obj in ds_rdf_class.items():
                        if key and pred == key:
                            if initial_val:
                                if initial_val in obj:
                                    data_list.append(ds_rdf_class)
                            else:
                                data_list.append(ds_rdf_class)
                        if not key and initial_val:
                            if initial_val in obj:
                                data_list.append(ds_rdf_class)
                # pdb.set_trace()
                return data_list

            if isinstance(ds, dict):
                return get_reverse_ds_dict(ds, key, filter_tup, initial_val)
            elif isinstance(ds, list):
                rtn_list = UniqueList()
                for item in ds:
                    rtn_list += get_reverse_ds_dict(ds,
                                                    key,
                                                    filter_tup,
                                                    initial_val)
                return rtn_list


        if isinstance(ds, list):
            return reverse_filter_list(ds, key, filter_tup, initial_val)
        elif isinstance(ds, dict):
            search_dict = ds
            if key:
                search_dict = reverse_filter_list(ds,
                                                  key,
                                                  filter_tup,
                                                  initial_val)
            # pdb.set_trace()
            if filter_tup:
                datalist = []
                for elem in search_dict:
                    if filter_tup[2] == "=":
                        # pdb.set_trace()
                        if filter_tup[1] in elem.get(filter_tup[0], []):
                            if isinstance(elem, list):
                                datalist += elem
                            else:
                                datalist.append(elem)
                    elif filter_tup[2] == "!=":
                        if filter_tup[1] not in elem.get(filter_tup[0], []):
                            datalist.append(elem)
                return datalist
            return merge_list(search_dict)



    if param == "*":
        pass
    # pdb.set_trace()
    if hasattr(param, 'parsed_tree'):
        param = param.parsed_tree

    if hasattr(param, 'selector'):

        if no_key:
            key = None
        else:
            key = get_element(param.selector)
        rtn_obj = None
        if hasattr(param, 'ident'):
            rtn_obj = get_dataset_vals(dataset,
                                       key,
                                       ('rdf_type',
                                        param.ident, "="))
        elif hasattr(param, 'attrib'):
            # if param.parsed_tree.attrib == 'bf_role':
            #     pdb.set_trace()
            rtn_obj = get_dataset_vals(dataset,
                                       key,
                                       (param.attrib,
                                        param.value,
                                        param.operator))
        if rtn_obj is not None:
            if hasattr(param, 'selector') \
                    and hasattr(param.selector, 'selector') \
                    and rtn_obj:
                rtn_obj = get_json_qry_item(rtn_obj, param.selector, True)
            return rtn_obj
        return dataset.get(key, [])
    elif hasattr(param, 'element'):
        key = param.element
        return get_dataset_vals(dataset, key, initial_val=initial_val)