def execute(input_params, engine, cwd=None):
    try:
        taskengine_exe = config.get('engine')
    except NoConfigOptionError:
        raise TaskEngineNotFoundError(
            "Task Engine config option not set." +
            "\nPlease verify the 'engine' configuration setting.")
    if not os.path.exists(taskengine_exe):
        raise TaskEngineNotFoundError(
            "Task Engine executable not found." +
            "\nPlease verify the 'engine' configuration setting.")
    engine_args = None
    try:
        engine_args = config.get('engine-args')
    except NoConfigOptionError:
        pass
    environment = None
    config_environment = config.get_environment()
    if config_environment:
        environment = os.environ.copy()
        environment.update(config_environment)
    args = [taskengine_exe, engine]
    if engine_args:
        args.append(engine_args)
    startupinfo = None
    if sys.platform.startswith('win'):
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    input_json = json.dumps(input_params)
    process = Popen(args,
                    stdout=PIPE,
                    stdin=PIPE,
                    stderr=PIPE,
                    cwd=cwd,
                    env=environment,
                    startupinfo=startupinfo)
    stdout, stderr = process.communicate(input=input_json.encode('utf-8'))
    if process.returncode != 0:
        if stderr != '':
            raise TaskEngineExecutionError(stderr.decode('utf-8'))
        else:
            raise TaskEngineExecutionError(
                'Task Engine exited with code: ' + str(process.returncode))
    else:
        return json.loads(stdout.decode('utf-8'), object_pairs_hook=OrderedDict)