'POST /api/tools
Executes tool using specified inputs and returns tool\'s outputs.'

@expose_api_anonymous
def create(self, trans, payload, **kwd):

    action = payload.get('action', None)
    if (action == 'rerun'):
        return self._rerun_tool(trans, payload, **kwd)
    tool_version = payload.get('tool_version', None)
    tool = (trans.app.toolbox.get_tool(payload['tool_id'], tool_version) if ('tool_id' in payload) else None)
    if ((not tool) or (not tool.allow_user_access(trans.user))):
        raise exceptions.MessageException('Tool    not    found    or    not    accessible.')
    if trans.app.config.user_activation_on:
        if (not trans.user):
            log.warning('Anonymous    user    attempts    to    execute    tool,    but    account    activation    is    turned    on.')
        elif (not trans.user.active):
            log.warning(('User    "%s"    attempts    to    execute    tool,    but    account    activation    is    turned    on    and    user    account    is    not    active.' % trans.user.email))
    history_id = payload.get('history_id', None)
    if history_id:
        decoded_id = self.decode_id(history_id)
        target_history = self.history_manager.get_owned(decoded_id, trans.user, current_history=trans.history)
    else:
        target_history = None
    inputs = payload.get('inputs', {})
    for (k, v) in payload.iteritems():
        if (k.startswith('files_') or k.startswith('__files_')):
            inputs[k] = v
    input_patch = {}
    for (k, v) in inputs.iteritems():
        if (isinstance(v, dict) and (v.get('src', '') == 'ldda') and ('id' in v)):
            ldda = trans.sa_session.query(trans.app.model.LibraryDatasetDatasetAssociation).get(self.decode_id(v['id']))
            if (trans.user_is_admin() or trans.app.security_agent.can_access_dataset(trans.get_current_user_roles(), ldda.dataset)):
                input_patch[k] = ldda.to_history_dataset_association(target_history, add_to_history=True)
    for (k, v) in input_patch.iteritems():
        inputs[k] = v
    params = util.Params(inputs, sanitize=False)
    incoming = params.__dict__
    vars = tool.handle_input(trans, incoming, history=target_history)
    output_datasets = vars.get('out_data', [])
    rval = {'outputs': [], 'output_collections': [], 'jobs': [], 'implicit_collections': []}
    job_errors = vars.get('job_errors', [])
    if job_errors:
        rval['errors'] = job_errors
    outputs = rval['outputs']
    for (output_name, output) in output_datasets:
        output_dict = output.to_dict()
        output_dict['output_name'] = output_name
        outputs.append(trans.security.encode_dict_ids(output_dict, skip_startswith='metadata_'))
    for job in vars.get('jobs', []):
        rval['jobs'].append(self.encode_all_ids(trans, job.to_dict(view='collection'), recursive=True))
    for (output_name, collection_instance) in vars.get('output_collections', []):
        history = (target_history or trans.history)
        output_dict = dictify_dataset_collection_instance(collection_instance, security=trans.security, parent=history)
        output_dict['output_name'] = output_name
        rval['output_collections'].append(output_dict)
    for (output_name, collection_instance) in vars.get('implicit_collections', {}).iteritems():
        history = (target_history or trans.history)
        output_dict = dictify_dataset_collection_instance(collection_instance, security=trans.security, parent=history)
        output_dict['output_name'] = output_name
        rval['implicit_collections'].append(output_dict)
    return rval
