// ==ClosureCompiler==
// @output_file_name fetch.js
// @compilation_level SIMPLE_OPTIMIZATIONS
// @language_out ES5_STRICT
// ==/ClosureCompiler==

// Copyright (c) 2014-2016 GitHub, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// Contact GitHub API Training Shop Blog About

// Fetch API: https://fetch.spec.whatwg.org/

(function(self) {
  'use strict';

  if (self.fetch) {
    return
  }

  const Array = self.Array
  const ArrayBuffer = self.ArrayBuffer
  const create = self.Object.create
  const defineProperties = self.Object.defineProperties
  const Error = self.Error
  const Symbol = self.Symbol
  const Symbol_iterator = Symbol.iterator
  const Map = self.Map
  const RangeError = self.RangeError
  const TypeError = self.TypeError
  const Uint8Array = self.Uint8Array

  const Promise = self.Promise
  const Promise_reject = Promise.reject
  const Promise_resolve = Promise.resolve

  const ReadableStream = self.ReadableStream
  const ReadableStreamTee = self.ReadableStreamTee
  const IsReadableStreamDisturbed = self.IsReadableStreamDisturbed
  const IsReadableStreamLocked = self.IsReadableStreamLocked

  const ERROR_INVALID_HEADERS_INIT =
      'Constructing Headers with invalid parameters'
  const ERROR_NETWORK_REQUEST_FAILED = 'Network request failed'

  // Internal slots for objects.
  const BODY_SLOT = Symbol('body')
  const BODY_USED_SLOT = Symbol('bodyUsed')
  const CACHE_SLOT = Symbol('cache')
  const CREDENTIALS_SLOT = Symbol('credentials')
  const GUARD_CALLBACK_SLOT = Symbol('guardCallback')
  const HEADERS_SLOT = Symbol('headers')
  const INTEGRITY_SLOT = Symbol('integrity')
  const MAP_SLOT = Symbol('map')
  const METHOD_SLOT = Symbol('method')
  const MODE_SLOT = Symbol('mode')
  const OK_SLOT = Symbol('ok')
  const REDIRECT_SLOT = Symbol('redirect')
  const STATUS_SLOT = Symbol('status')
  const STATUS_TEXT_SLOT = Symbol('statusText')
  const TYPE_SLOT = Symbol('type')
  const URL_SLOT = Symbol('url')

  // Forbidden headers corresponding to various header guard types.
  const INVALID_HEADERS_REQUEST = [
    'accept-charset',
    'accept-encoding',
    'access-control-request-headers',
    'access-control-request-method',
    'connection',
    'content-length',
    'cookie',
    'cookie2',
    'date',
    'dnt',
    'expect',
    'host',
    'keep-alive',
    'origin',
    'referer',    // [sic]
    'te',
    'trailer',
    'transfer-encoding',
    'upgrade',
    'via'
  ]

  const INVALID_HEADERS_RESPONSE = [
    'set-cookie',
    'set-cookie2'
  ]

  // The header guard for no-cors requests is special. Only these headers are
  // allowed. And only certain values for content-type are allowed.
  const VALID_HEADERS_NOCORS = [
    'accept',
    'accept-language',
    'content-language'
    // 'content-type' is treated specially.
  ]

  const VALID_HEADERS_NOCORS_CONTENT_TYPE = [
    'application/x-www-form-urlencoded',
    'multipart/form-data',
    'text/plain'
  ]

  // Values that are allowed for Request cache mode.
  const VALID_CACHE_MODES = [
    'default',
    'no-store',
    'reload',
    'no-cache',
    'force-cache',
    'only-if-cached'
  ]

  // Values that are allowed for Request credentials.
  const VALID_CREDENTIALS = ['omit', 'same-origin', 'include']

  // HTTP methods whose capitalization should be normalized.
  const VALID_METHODS = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']

  // Methods that are allowed for Request mode: no-cors.
  const VALID_METHODS_NOCORS = ['GET', 'HEAD', 'POST']

  // Modes that are allowed for RequestInit. Although 'navigate' is a valid
  // request mode, it is not allowed in the RequestInit parameter.
  const VALID_MODES = ['same-origin', 'no-cors', 'cors']

  // Values that are allowed for Request redirect mode.
  const VALID_REDIRECT_MODES = ['follow', 'error', 'manual']

  // Body is not allowed in responses with a null body status.
  const NULL_BODY_STATUSES = [101, 204, 205, 304 ]

  // Statuses that are allowed for Response.redirect.
  const REDIRECT_STATUSES = [301, 302, 303, 307, 308]

  const ARRAY_BUFFER_VIEW_CLASSES = [
    '[object Int8Array]',
    '[object Uint8Array]',
    '[object Uint8ClampedArray]',
    '[object Int16Array]',
    '[object Uint16Array]',
    '[object Int32Array]',
    '[object Uint32Array]',
    '[object Float32Array]',
    '[object Float64Array]'
  ]

  var isArrayBufferView = ArrayBuffer.isView || function(obj) {
    return obj && ARRAY_BUFFER_VIEW_CLASSES.indexOf(
        Object.prototype.toString.call(obj)) > -1
  }

  function normalizeName(name) {
    if (typeof name !== 'string') {
      name = String(name)
    }
    if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
      throw new TypeError('Invalid character in header field name')
    }
    return name.toLowerCase()
  }

  function normalizeValue(value) {
    if (typeof value !== 'string') {
      value = String(value)
    }

    // https://fetch.spec.whatwg.org/#concept-header-value
    // The web platform tests don't quite abide by the current spec. Use a
    // permissive approach that passes the tests while following the spirit
    // of the spec. Essentially, leading & trailing HTTP whitespace bytes
    // are trimmed first before checking validity.
    var c, first, last, i, len

    //value = value.replace(/^[ \t\n\r]+|[ \t\n\r]+$/g, '')
    for (first = 0, len = value.length; first < len; first++) {
      c = value.charCodeAt(first)
      if (c !== 9 && c !== 10 && c !== 13 && c !== 32) {
        break
      }
    }
    for (last = value.length - 1; last > first; last--) {
      c = value.charCodeAt(last)
      if (c !== 9 && c !== 10 && c !== 13 && c !== 32) {
        break
      }
    }
    value = value.substring(first, last + 1)

    // Follow the chromium implementation of IsValidHTTPHeaderValue(). This
    // should be updated once the web platform test abides by the fetch spec.
    for (i = 0, len = value.length; i < len; i++) {
      c = value.charCodeAt(i)
      if (c >= 256 || c === 0 || c === 10 || c === 13) {
        throw new TypeError('Invalid character in header field value')
      }
    }
    return value
  }

  // Callbacks to determine whether a given header name & value are forbidden
  // for various header guard types.
  function guardImmutableCallback(name, value) {
    throw new TypeError('Immutable header cannot be modified')
  }

  function guardNoneCallback(name, value) {
    return false
  }

  function guardRequestCallback(name, value) {
    var nameLower = name.toLowerCase()
    if (INVALID_HEADERS_REQUEST.indexOf(nameLower) > -1 ||
        nameLower.startsWith('proxy-') || nameLower.startsWith('sec-')) {
      return true
    }
    return false
  }

  function guardRequestNoCorsCallback(name, value) {
    var nameLower = name.toLowerCase()
    if (VALID_HEADERS_NOCORS.indexOf(nameLower) > -1) {
      return false
    }
    if (nameLower === 'content-type') {
      var mimeType = value.split(';')[0].toLowerCase()
      if (VALID_HEADERS_NOCORS_CONTENT_TYPE.indexOf(mimeType) > -1) {
        return false
      }
    }
    return true
  }

  function guardResponseCallback(name, value) {
    if (INVALID_HEADERS_RESPONSE.indexOf(name.toLowerCase()) > -1) {
      return true
    }
    return false
  }

  // https://fetch.spec.whatwg.org/#headers-class
  function Headers(init) {
    this[MAP_SLOT] = new Map();
    if (this[GUARD_CALLBACK_SLOT] === undefined) {
      this[GUARD_CALLBACK_SLOT] = guardNoneCallback
    }

    if (init === undefined) {
      return
    } else if (init === null || typeof init !== 'object') {
      throw new TypeError(ERROR_INVALID_HEADERS_INIT)
    } else if (init instanceof Headers) {
      // TODO: Use for..of in case |init| has a custom Symbol.iterator.
      // However, this results in the ClosureCompiler polyfilling Symbol, so
      // use forEach until ClosureCompiler supports ES6 output.
      init.forEach(function(value, name) {
        this.append(name, value)
      }, this)
    } else if (Array.isArray(init)) {
      init.forEach(function(header) {
        if (header.length !== 2) {
          throw new TypeError(ERROR_INVALID_HEADERS_INIT)
        }
        this.append(header[0], header[1])
      }, this)
    } else {
      Object.getOwnPropertyNames(init).forEach(function(name) {
        this.append(name, init[name])
      }, this)
    }
  }

  function CreateHeadersWithGuard(headersInit, guardCallback) {
    var headers = create(Headers.prototype)
    headers[GUARD_CALLBACK_SLOT] = guardCallback
    Headers.call(headers, headersInit)
    return headers
  }

  Headers.prototype.append = function(name, value) {
    if (arguments.length !== 2) {
      throw TypeError('Invalid parameters to append')
    }
    name = normalizeName(name)
    value = normalizeValue(value)
    if (this[GUARD_CALLBACK_SLOT](name, value)) {
      return
    }
    if (this[MAP_SLOT].has(name)) {
      this[MAP_SLOT].set(name, this[MAP_SLOT].get(name) + ', ' + value)
    } else {
      this[MAP_SLOT].set(name, value)
    }
  }

  Headers.prototype['delete'] = function(name) {
    if (arguments.length !== 1) {
      throw TypeError('Invalid parameters to delete')
    }
    if (this[GUARD_CALLBACK_SLOT](name, 'invalid')) {
      return
    }
    this[MAP_SLOT].delete(normalizeName(name))
  }

  Headers.prototype.get = function(name) {
    if (arguments.length !== 1) {
      throw TypeError('Invalid parameters to get')
    }
    name = normalizeName(name)
    var value = this[MAP_SLOT].get(name)
    return value !== undefined ? value : null
  }

  Headers.prototype.has = function(name) {
    if (arguments.length !== 1) {
      throw TypeError('Invalid parameters to has')
    }
    return this[MAP_SLOT].has(normalizeName(name))
  }

  Headers.prototype.set = function(name, value) {
    if (arguments.length !== 2) {
      throw TypeError('Invalid parameters to set')
    }
    name = normalizeName(name)
    value = normalizeValue(value)
    if (this[GUARD_CALLBACK_SLOT](name, value)) {
      return
    }
    this[MAP_SLOT].set(name, value)
  }

  Headers.prototype.forEach = function(callback, thisArg) {
    var sorted_array = Array.from(this[MAP_SLOT].entries()).sort()
    var that = this
    sorted_array.forEach(function(value) {
      callback.call(thisArg, value[1], value[0], that)
    })
  }

  Headers.prototype.keys = function() {
    var sorted_map = new Map(Array.from(this[MAP_SLOT].entries()).sort())
    return sorted_map.keys()
  }

  Headers.prototype.values = function() {
    var sorted_map = new Map(Array.from(this[MAP_SLOT].entries()).sort())
    return sorted_map.values()
  }

  Headers.prototype.entries = function() {
    var sorted_map = new Map(Array.from(this[MAP_SLOT].entries()).sort())
    return sorted_map.entries()
  }

  Headers.prototype[Symbol_iterator] = Headers.prototype.entries

  function consumeBodyAsUint8Array(body) {
    if (body.bodyUsed) {
      return Promise_reject(new TypeError('Body was already read'))
    }

    if (body.body === null) {
      return Promise_resolve(new Uint8Array(0))
    }

    if (IsReadableStreamLocked(body.body)) {
      return Promise_reject(new TypeError('ReadableStream was already locked'))
    }

    var reader = body.body.getReader()
    var results = []
    var resultsLength = 0
    return reader.read().then(function addResult(result) {
      if (result.done) {
        var data
        if (results.length === 0) {
          data = new Uint8Array(0)
        } else if (results.length === 1) {
          data = new Uint8Array(results[0])
        } else {
          data = new Uint8Array(resultsLength)
          for (var i = 0, len = results.length, offset = 0; i < len; i++) {
            data.set(results[i], offset)
            offset += results[i].length
          }
        }
        return data
      } else if (result.value instanceof Uint8Array) {
        resultsLength += result.value.length
        results.push(result.value)
        return reader.read().then(addResult)
      } else {
        return Promise_reject(new TypeError('Invalid stream data type'))
      }
    })
  }

  // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
  function extractBody(controller, data, errorString) {
    if (!data) {
    } else if (typeof data === 'string') {
      controller.enqueue(FetchInternal.encodeToUTF8(data))
    } else if (ArrayBuffer.prototype.isPrototypeOf(data)) {
      controller.enqueue(new Uint8Array(data))
    } else if (isArrayBufferView(data)) {
      controller.enqueue(new Uint8Array(data.buffer))
    } else {
      throw new TypeError(errorString)
    }
  }

  // https://fetch.spec.whatwg.org/#body-mixin
  // However, our engine does not fully support URLSearchParams, FormData, nor
  //   Blob types. So only support text(), arrayBuffer(), and json().
  function Body() {
    this._initBody = function(body) {
      this[BODY_USED_SLOT] = false
      if (body === null || body === undefined) {
        this[BODY_SLOT] = null
      } else if (body instanceof ReadableStream) {
        this[BODY_SLOT] = body
      } else {
        this[BODY_SLOT] = new ReadableStream({
          start(controller) {
            extractBody(controller, body, 'Unsupported BodyInit type')
            controller.close()
          }
        })
      }

      if (!this[HEADERS_SLOT].get('content-type')) {
        if (typeof body === 'string') {
          this[HEADERS_SLOT].set('content-type', 'text/plain;charset=UTF-8')
        }
      }
    }

    defineProperties(this, {
      'body': { get: function() { return this[BODY_SLOT] } },
      'bodyUsed': {
        get: function() {
          if (this[BODY_USED_SLOT]) {
            return true
          } else if (this[BODY_SLOT]) {
            return !!IsReadableStreamDisturbed(this[BODY_SLOT])
          } else {
            return false
          }
        }
      }
    })

    this.arrayBuffer = function() {
      return consumeBodyAsUint8Array(this).then(function(data) {
        return data.buffer
      })
    }

    this.text = function() {
      return consumeBodyAsUint8Array(this).then(function(data) {
        return FetchInternal.decodeFromUTF8(data)
      })
    }

    this.json = function() {
      return this.text().then(JSON.parse)
    }

    return this
  }

  function normalizeMethod(method) {
    var upcased = method.toUpperCase()
    if (VALID_METHODS.indexOf(upcased) === -1) {
      throw new TypeError('Invalid request method')
    }
    return upcased
  }

  // https://fetch.spec.whatwg.org/#request-class
  function Request(input, init) {
    // When cloning a request, |init| will have the non-standard member
    // |cloneBody|. This signals that the "!hasInit" path should be used.
    var hasInit = init !== undefined && init !== null &&
                  init.cloneBody === undefined
    init = init || {}
    var body = init.body || init.cloneBody
    var headersInit = init.headers

    if (input instanceof Request) {
      if (input.bodyUsed) {
        throw new TypeError('Request body was already read')
      }
      this[URL_SLOT] = input.url
      this[CACHE_SLOT] = input.cache
      this[CREDENTIALS_SLOT] = input.credentials
      if (headersInit === undefined) {
        headersInit = input.headers
      }
      this[INTEGRITY_SLOT] = input.integrity
      this[METHOD_SLOT] = input.method
      this[MODE_SLOT] = input.mode
      if (hasInit && this[MODE_SLOT] === 'navigate') {
        this[MODE_SLOT] = 'same-origin'
      }
      this[REDIRECT_SLOT] = input.redirect
      if (!body && input.body !== null) {
        // Take ownership of the stream and mark |input| as disturbed.
        body = input.body
        input[BODY_USED_SLOT] = true
      }
    } else {
      this[URL_SLOT] = String(input)
      if (!FetchInternal.isUrlValid(this[URL_SLOT],
                                    false /* allowCredentials */)) {
        throw new TypeError('Invalid request URL')
      }
      this[MODE_SLOT] = 'cors'
      this[CREDENTIALS_SLOT] = 'omit'
    }

    if (init.window !== undefined && init.window !== null) {
      throw new TypeError('Invalid request window')
    }

    this[CACHE_SLOT] = init.cache || this[CACHE_SLOT] || 'default'
    if (VALID_CACHE_MODES.indexOf(this[CACHE_SLOT]) === -1) {
      throw new TypeError('Invalid request cache mode')
    }

    this[CREDENTIALS_SLOT] = init.credentials || this[CREDENTIALS_SLOT] ||
                             'omit'
    if (VALID_CREDENTIALS.indexOf(this[CREDENTIALS_SLOT]) === -1) {
      throw new TypeError('Invalid request credentials')
    }

    if (init.integrity !== undefined) {
      this[INTEGRITY_SLOT] = init.integrity
    } else if (this[INTEGRITY_SLOT] === undefined) {
      this[INTEGRITY_SLOT] = ''
    }
    this[METHOD_SLOT] = normalizeMethod(init.method || this[METHOD_SLOT] ||
                                        'GET')

    if (init.mode && VALID_MODES.indexOf(init.mode) === -1) {
      throw new TypeError('Invalid request mode')
    }
    this[MODE_SLOT] = init.mode || this[MODE_SLOT] || 'no-cors'
    if (this[MODE_SLOT] === 'no-cors') {
      if (VALID_METHODS_NOCORS.indexOf(this[METHOD_SLOT]) === -1) {
        throw new TypeError('Invalid request method for no-cors')
      }
      if (this[INTEGRITY_SLOT] !== '') {
        throw new TypeError(
            'Request integrity data is not allowed with no-cors')
      }
    }
    if (this[MODE_SLOT] !== 'same-origin' &&
        this[CACHE_SLOT] === 'only-if-cached') {
      throw new TypeError(
          'Request mode must be same-origin for only-if-cached')
    }

    this[REDIRECT_SLOT] = init.redirect || this[REDIRECT_SLOT] || 'follow'
    if (VALID_REDIRECT_MODES.indexOf(this[REDIRECT_SLOT]) === -1) {
      throw new TypeError('Invalid request redirect mode')
    }

    if (this[MODE_SLOT] === 'no-cors') {
      this[HEADERS_SLOT] =
          CreateHeadersWithGuard(headersInit, guardRequestNoCorsCallback)
    } else {
      this[HEADERS_SLOT] =
          CreateHeadersWithGuard(headersInit, guardRequestCallback)
    }

    if ((this[METHOD_SLOT] === 'GET' || this[METHOD_SLOT] === 'HEAD') && body) {
      throw new TypeError('Request body is not allowed for GET or HEAD')
    }
    this._initBody(body)
  }

  Request.prototype.clone = function() {
    var cloneBody = null
    if (this[BODY_SLOT] !== null) {
      var streams = ReadableStreamTee(this[BODY_SLOT],
                                      true /* cloneForBranch2 */)
      this[BODY_SLOT] = streams[0]
      cloneBody = streams[1]
    }
    return new Request(this, { cloneBody: cloneBody })
  }

  defineProperties(Request.prototype, {
    'cache': { get: function() { return this[CACHE_SLOT] } },
    'credentials': { get: function() { return this[CREDENTIALS_SLOT] } },
    'headers': { get: function() { return this[HEADERS_SLOT] } },
    'integrity': { get: function() { return this[INTEGRITY_SLOT] } },
    'method': { get: function() { return this[METHOD_SLOT] } },
    'mode': { get: function() { return this[MODE_SLOT] } },
    'redirect': { get: function() { return this[REDIRECT_SLOT] } },
    'url': { get: function() { return this[URL_SLOT] } }
  })

  function parseHeaders(rawHeaders, guardCallback) {
    var headers = CreateHeadersWithGuard(undefined, guardCallback)
    // Replace instances of \r\n and \n followed by at least one space or
    // horizontal tab with a space.
    // https://tools.ietf.org/html/rfc7230#section-3.2
    var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ')
    preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
      var parts = line.split(':')
      var key = parts.shift().trim()
      if (key) {
        var value = parts.join(':').trim()
        headers.append(key, value)
      }
    })
    return headers
  }

  Body.call(Request.prototype)

  // Status text must be a reason-phrase token.
  // https://tools.ietf.org/html/rfc7230#section-3.1.2
  function parseStatusText(text) {
    for (var i = 0, len = text.length, c; i < len; i++) {
      c = text.charCodeAt(i)
      if (c !== 9 && (c < 32 || c > 255 || c === 127)) {
        throw TypeError('Invalid response status text')
      }
    }
    return text
  }

  // https://fetch.spec.whatwg.org/#response-class
  function Response(body, init) {
    if (!init) {
      init = {}
    }

    this[TYPE_SLOT] = 'default'
    this[STATUS_SLOT] = 'status' in init ? init.status : 200
    if (this[STATUS_SLOT] < 200 || this[STATUS_SLOT] > 599) {
      throw new RangeError('Invalid response status')
    }
    this[OK_SLOT] = this[STATUS_SLOT] >= 200 && this[STATUS_SLOT] < 300
    this[STATUS_TEXT_SLOT] = 'statusText' in init ?
                             parseStatusText(init.statusText) : 'OK'
    this[HEADERS_SLOT] =
        CreateHeadersWithGuard(init.headers, guardResponseCallback)
    this[URL_SLOT] = init.url || ''
    if (body && NULL_BODY_STATUSES.indexOf(this[STATUS_SLOT]) > -1) {
      throw new TypeError(
          'Response body is not allowed with a null body status')
    }
    this._initBody(body)
  }

  Body.call(Response.prototype)

  Response.prototype.clone = function() {
    var cloneBody = null
    if (this[BODY_SLOT] !== null) {
      var streams = ReadableStreamTee(this[BODY_SLOT],
                                      true /* cloneForBranch2 */)
      this[BODY_SLOT] = streams[0]
      cloneBody = streams[1]
    }
    return new Response(cloneBody, {
      status: this[STATUS_SLOT],
      statusText: this[STATUS_TEXT_SLOT],
      headers: CreateHeadersWithGuard(this[HEADERS_SLOT],
                                      guardResponseCallback),
      url: this[URL_SLOT]
    })
  }

  defineProperties(Response.prototype, {
    'headers': { get: function() { return this[HEADERS_SLOT] } },
    'ok': { get: function() { return this[OK_SLOT] } },
    'status': { get: function() { return this[STATUS_SLOT] } },
    'statusText': { get: function() { return this[STATUS_TEXT_SLOT] } },
    'type': { get: function() { return this[TYPE_SLOT] } },
    'url': { get: function() { return this[URL_SLOT] } }
  })

  Response.error = function() {
    var response = new Response(null)
    response[HEADERS_SLOT][GUARD_CALLBACK_SLOT] = guardImmutableCallback
    response[TYPE_SLOT] = 'error'
    response[STATUS_SLOT] = 0
    response[STATUS_TEXT_SLOT] = ''
    return response
  }

  Response.redirect = function(url, status) {
    if (!FetchInternal.isUrlValid(url, true /* allowCredentials */)) {
      throw new TypeError('Invalid URL for response redirect')
    }
    if (status === undefined) {
      status = 302
    }
    if (REDIRECT_STATUSES.indexOf(status) === -1) {
      throw new RangeError('Invalid status code for response redirect')
    }

    return new Response(null, {status: status, headers: {location: url}})
  }

  self.Headers = Headers
  self.Request = Request
  self.Response = Response

  self.fetch = function(input, init) {
    return new Promise(function(resolve, reject) {
      var cancelled = false
      var isCORSMode = false
      var request = new Request(input, init)
      var xhr = new XMLHttpRequest()

      var responseStreamController = null
      var responseStream = new ReadableStream({
        start(controller) {
          responseStreamController = controller
        },
        cancel(controller) {
          cancelled = true
          xhr.abort()
        }
      })

      xhr.onload = function() {
        responseStreamController.close()
      }

      xhr.onreadystatechange = function() {
        if (xhr.readyState === xhr.HEADERS_RECEIVED) {
          var init = {
            status: xhr.status,
            statusText: xhr.statusText,
            headers: parseHeaders(xhr.getAllResponseHeaders() || '',
                                  guardResponseCallback)
          }
          init.url = 'responseURL' in xhr ?
                     xhr.responseURL : init.headers.get('X-Request-URL')
          try {
            var response = new Response(responseStream, init)
            response[TYPE_SLOT] = isCORSMode ? 'cors' : 'basic'
            resolve(response)
          } catch (err) {
            reject(err)
          }
        }
      }

      xhr.onerror = function() {
        responseStreamController.error(
            new TypeError(ERROR_NETWORK_REQUEST_FAILED))
        reject(new TypeError(ERROR_NETWORK_REQUEST_FAILED))
      }

      xhr.ontimeout = function() {
        responseStreamController.error(
            new TypeError(ERROR_NETWORK_REQUEST_FAILED))
        reject(new TypeError(ERROR_NETWORK_REQUEST_FAILED))
      }

      xhr.open(request.method, request.url, true)

      if (request.credentials === 'include') {
        xhr.withCredentials = true
      }

      request.headers.forEach(function(value, name) {
        xhr.setRequestHeader(name, value)
      })

      var fetchUpdate = function(data) {
        if (!cancelled) {
          // Data is already an Uint8Array.
          responseStreamController.enqueue(data)
        }
      }

      var modeUpdate = function(iscorsmode) {
        isCORSMode = iscorsmode
      }

      if (request.body === null) {
        xhr.fetch(fetchUpdate, modeUpdate, null)
      } else {
        consumeBodyAsUint8Array(request).then(function(data) {
          xhr.fetch(fetchUpdate, modeUpdate, data)
        })
      }
    })
  }
  self.fetch.polyfill = true
})(this);
