module Mixlib::ShellOut::Windows

def _run_directly(command, exe)

def _run_directly(command, exe)
  [ exe, command ]
end

def _run_under_cmd(command)

http://ss64.com/nt/syntax-esc.html
https://github.com/opscode/mixlib-shellout/pull/2#issuecomment-4837859
cmd does not parse multiple quotes well unless the whole thing is wrapped up in quotes.
def _run_under_cmd(command)
  [ ENV['COMSPEC'], "cmd /c \"#{command}\"" ]
end

def candidate_executable_for_command(command)

def candidate_executable_for_command(command)
  if command =~ /^\s*"(.*?)"/
    # If we have quotes, do an exact match
    $1
  else
    # Otherwise check everything up to the first space
    unquoted_executable_path(command).strip
  end
end

def command_to_run(command)

def command_to_run(command)
  return _run_under_cmd(command) if Utils.should_run_under_cmd?(command)
  candidate = candidate_executable_for_command(command)
  # Don't do searching for empty commands.  Let it fail when it runs.
  return [ nil, command ] if candidate.length == 0
  # Check if the exe exists directly.  Otherwise, search PATH.
  exe = Utils.find_executable(candidate)
  exe = Utils.which(unquoted_executable_path(command)) if exe.nil? && exe !~ /[\\\/]/
  # Batch files MUST use cmd; and if we couldn't find the command we're looking for,
  # we assume it must be a cmd builtin.
  if exe.nil? || exe =~ IS_BATCH_FILE
    _run_under_cmd(command)
  else
    _run_directly(command, exe)
  end
end

def consume_output(open_streams, stdout_read, stderr_read)

def consume_output(open_streams, stdout_read, stderr_read)
  return false if open_streams.length == 0
  ready = IO.select(open_streams, nil, nil, READ_WAIT_TIME)
  return true if ! ready
  if ready.first.include?(stdout_read)
    begin
      next_chunk = stdout_read.readpartial(READ_SIZE)
      @stdout << next_chunk
      @live_stream << next_chunk if @live_stream
    rescue EOFError
      stdout_read.close
      open_streams.delete(stdout_read)
    end
  end
  if ready.first.include?(stderr_read)
    begin
      next_chunk = stderr_read.readpartial(READ_SIZE)
      @stderr << next_chunk
      @live_stderr << next_chunk if @live_stderr
    rescue EOFError
      stderr_read.close
      open_streams.delete(stderr_read)
    end
  end
  return true
end

def inherit_environment

def inherit_environment
  result = {}
  ENV.each_pair do |k,v|
    result[k] = v
  end
  environment.each_pair do |k,v|
    if v == nil
      result.delete(k)
    else
      result[k] = v
    end
  end
  result
end

def run_command

uid, etc.
Missing lots of features from the UNIX version, such as
--
def run_command
  #
  # Create pipes to capture stdout and stderr,
  #
  stdout_read, stdout_write = IO.pipe
  stderr_read, stderr_write = IO.pipe
  stdin_read, stdin_write = IO.pipe
  open_streams = [ stdout_read, stderr_read ]
  begin
    #
    # Set cwd, environment, appname, etc.
    #
    app_name, command_line = command_to_run(self.command)
    create_process_args = {
      :app_name => app_name,
      :command_line => command_line,
      :startup_info => {
        :stdout => stdout_write,
        :stderr => stderr_write,
        :stdin => stdin_read
      },
      :environment => inherit_environment.map { |k,v| "#{k}=#{v}" },
      :close_handles => false
    }
    create_process_args[:cwd] = cwd if cwd
    # default to local account database if domain is not specified
    create_process_args[:domain] = domain.nil? ? "." : domain
    create_process_args[:with_logon] = with_logon if with_logon
    create_process_args[:password] = password if password
    #
    # Start the process
    #
    process = Process.create(create_process_args)
    begin
      # Start pushing data into input
      stdin_write << input if input
      # Close pipe to kick things off
      stdin_write.close
      #
      # Wait for the process to finish, consuming output as we go
      #
      start_wait = Time.now
      while true
        wait_status = WaitForSingleObject(process.process_handle, 0)
        case wait_status
        when WAIT_OBJECT_0
          # Get process exit code
          exit_code = [0].pack('l')
          unless GetExitCodeProcess(process.process_handle, exit_code)
            raise get_last_error
          end
          @status = ThingThatLooksSortOfLikeAProcessStatus.new
          @status.exitstatus = exit_code.unpack('l').first
          return self
        when WAIT_TIMEOUT
          # Kill the process
          if (Time.now - start_wait) > timeout
            raise Mixlib::ShellOut::CommandTimeout, "command timed out:\n#{format_for_exception}"
          end
          consume_output(open_streams, stdout_read, stderr_read)
        else
          raise "Unknown response from WaitForSingleObject(#{process.process_handle}, #{timeout*1000}): #{wait_status}"
        end
      end
    ensure
      CloseHandle(process.thread_handle) if process.thread_handle
      CloseHandle(process.process_handle) if process.process_handle
    end
  ensure
    #
    # Consume all remaining data from the pipes until they are closed
    #
    stdout_write.close
    stderr_write.close
    while consume_output(open_streams, stdout_read, stderr_read)
    end
  end
end

def unquoted_executable_path(command)

def unquoted_executable_path(command)
  command[0,command.index(/\s/) || command.length]
end

def validate_options(opts)

Option validation that is windows specific
def validate_options(opts)
  if opts[:user]
    unless opts[:password]
      raise InvalidCommandOption, "You must supply both a username and password when supplying a user in windows"
    end
  end
end