'search( trans, payload )
* POST /api/jobs/search:
return jobs for current user
:type   payload: dict
:param  payload: Dictionary containing description of requested job. This is in the same format as
a request to POST /apt/tools would take to initiate a job
:rtype:     list
:returns:   list of dictionaries containing summary job information of the jobs that match the requested job run
This method is designed to scan the list of previously run jobs and find records of jobs that had
the exact some input parameters and datasets. This can be used to minimize the amount of repeated work, and simply
recycle the old results.'

@expose_api
def search(self, trans, payload, **kwd):

    tool_id = None
    if ('tool_id' in payload):
        tool_id = payload.get('tool_id')
    if (tool_id is None):
        raise exceptions.ObjectAttributeMissingException('No    tool    id')
    tool = trans.app.toolbox.get_tool(tool_id)
    if (tool is None):
        raise exceptions.ObjectNotFound('Requested    tool    not    found')
    if ('inputs' not in payload):
        raise exceptions.ObjectAttributeMissingException('No    inputs    defined')
    inputs = payload['inputs']
    input_data = {}
    input_param = {}
    for (k, v) in inputs.items():
        if isinstance(v, dict):
            if ('id' in v):
                if (('src' not in v) or (v['src'] == 'hda')):
                    hda_id = self.decode_id(v['id'])
                    dataset = self.hda_manager.get_accessible(hda_id, trans.user)
                else:
                    dataset = self.get_library_dataset_dataset_association(trans, v['id'])
                if (dataset is None):
                    raise exceptions.ObjectNotFound(('Dataset    %s    not    found' % v['id']))
                input_data[k] = dataset.dataset_id
        else:
            input_param[k] = json.dumps(str(v))
    query = trans.sa_session.query(trans.app.model.Job).filter((trans.app.model.Job.tool_id == tool_id), (trans.app.model.Job.user == trans.user))
    if ('state' not in payload):
        query = query.filter(or_((trans.app.model.Job.state == 'running'), (trans.app.model.Job.state == 'queued'), (trans.app.model.Job.state == 'waiting'), (trans.app.model.Job.state == 'running'), (trans.app.model.Job.state == 'ok')))
    elif isinstance(payload['state'], string_types):
        query = query.filter((trans.app.model.Job.state == payload['state']))
    elif isinstance(payload['state'], list):
        o = []
        for s in payload['state']:
            o.append((trans.app.model.Job.state == s))
        query = query.filter(or_(*o))
    for (k, v) in input_param.items():
        a = aliased(trans.app.model.JobParameter)
        query = query.filter(and_((trans.app.model.Job.id == a.job_id), (a.name == k), (a.value == v)))
    for (k, v) in input_data.items():
        a = aliased(trans.app.model.JobToInputDatasetAssociation)
        b = aliased(trans.app.model.HistoryDatasetAssociation)
        query = query.filter(and_((trans.app.model.Job.id == a.job_id), (a.dataset_id == b.id), (b.deleted == false()), (b.dataset_id == v)))
    out = []
    for job in query.all():
        if all(list(((a.dataset.deleted is False) for a in job.output_datasets))):
            out.append(self.encode_all_ids(trans, job.to_dict('element'), True))
    return out
