docs: def execute(input_params, engine, cwd=None):
      """
      Execute a task with the provided input parameters
  
      :param input_params: Python dictionary containg all input parameters.
                           This will be converted to JSON before being passed
                           to the task engine.
      :param engine: String specifying Task Engine type to run (ENVI, IDL, etc.)
      :param cwd: Optionally specify the current working directory to be used
                  when spawning the task engine.
      :return: A python dictionary representing the results JSON string generated
               by the Task Engine.
      """
  
      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.")
  
      # Get any arguments for the taskengine
      engine_args = None
      try:
          engine_args = config.get('engine-args')
      except NoConfigOptionError:
          pass
  
      # Get environment overrides if they exist
      environment = None
      config_environment = config.get_environment()
      if config_environment:
          environment = os.environ.copy()
          environment.update(config_environment)
  
      # Build up the args vector for popen
      args = [taskengine_exe, engine]
      if engine_args:
          args.append(engine_args)
  
      # Hide the Console Window on Windows OS
      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)
      # taskengine output is in UTF8.  Encode/Decode to UTF8                
      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)