// ==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 defineProperty = self.Object.defineProperty
  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 ReadableStream = self.ReadableStream
  const ReadableStreamTee = self.ReadableStreamTee
  const IsReadableStreamDisturbed = self.IsReadableStreamDisturbed
  const IsReadableStreamLocked = self.IsReadableStreamLocked

  const ABORT_ERROR = 'AbortError'
  const ABORT_MESSAGE = 'Aborted'

  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')
  const IS_ABORTED_SLOT = Symbol('is_aborted')
  const SIGNAL_SLOT = Symbol('signal')

  // 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) {
          // Create a view of the ArrayBuffer. No copy is made.
          data = new Uint8Array(results[0].buffer)
        } 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) {
    // Copy the incoming data. This is to prevent subsequent changes to |data|
    // from impacting the Body's contents, and also to prevent changes to the
    // Body's contents from impacting the original data.
    if (!data) {
    } else if (typeof data === 'string') {
      controller.enqueue(FetchInternal.encodeToUTF8(data))
    } else if (ArrayBuffer.prototype.isPrototypeOf(data)) {
      controller.enqueue(new Uint8Array(data.slice(0)))
    } else if (isArrayBufferView(data)) {
      controller.enqueue(new Uint8Array(data.buffer.slice(0)))
    } else if (data instanceof Blob) {
      controller.enqueue(new Uint8Array(FetchInternal.blobToArrayBuffer(data)))
    } 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')
        } else if (body instanceof Blob && body.type !== "") {
          this[HEADERS_SLOT].set('content-type', body.type)
        }
      }
    }

    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() {
      if (this[IS_ABORTED_SLOT]) {
        return Promise.reject(new DOMException(ABORT_MESSAGE, ABORT_ERROR))
      }
      return consumeBodyAsUint8Array(this).then(function(data) {
        return data.buffer
      })
    }

    this.text = function() {
      if (this[IS_ABORTED_SLOT]) {
        return Promise.reject(new DOMException(ABORT_MESSAGE, ABORT_ERROR))
      }
      return consumeBodyAsUint8Array(this).then(function(data) {
        return FetchInternal.decodeFromUTF8(data)
      })
    }

    this.json = function() {
      if (this[IS_ABORTED_SLOT]) {
        return Promise.reject(new DOMException(ABORT_MESSAGE, ABORT_ERROR))
      }
      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

    // AbortSignal cannot be constructed directly, so create a temporary
    // AbortController and steal its signal. This signal is only used to follow
    // another signal, so the controller isn't needed.
    var tempController = new AbortController()
    this[SIGNAL_SLOT] = tempController.signal

    // Let signal be null.
    var signal = null

    if (input instanceof Request) {
      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
      }

      // Set signal to input's signal.
      signal = input[SIGNAL_SLOT]
    } 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] = 'same-origin'
    }

    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] ||
                             'same-origin'
    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')
    }

    // If init["signal"] exists, then set signal to it.
    if ('signal' in init) {
      signal = init.signal
    }

    // If signal is not null, then make r's signal follow signal.
    if (signal) {
      this[SIGNAL_SLOT].follow(signal)
    }

    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, signal: this[SIGNAL_SLOT] })
  }

  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] } },
    'signal': { get: function() { return this[SIGNAL_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[IS_ABORTED_SLOT] = init.is_aborted || false
    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],
      is_aborted: this[IS_ABORTED_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

  // Algorithm steps for https://fetch.spec.whatwg.org/#fetch-method
  self.fetch = function(input, init) {
    // 1 Let p be a new promise.
    // ..
    // 10. Return p
    return new Promise(function(resolve, reject) {
      var cancelled = false
      var isCORSMode = false
      // 2. Let requestObject be the result of invoking the initial value of Request
      //    as constructor
      // 3.  Let request be requestObjects request.
      var request = new Request(input, init)
      var xhr = new XMLHttpRequest()
      var responseStreamController = null

      // 4. If requestObjects signals aborted flag is set, then:
      //    Abort fetch with p, request, and null.
      //    Return p.
      if (request.signal.aborted) {
        return reject(new DOMException(ABORT_MESSAGE, ABORT_ERROR))
      }

      // 5. If requests clients global object is a ServiceWorkerGlobalScope object,
      //   then set requests service-workers mode to "none".
      //   This step is skipped, as serviceWorkers are not supported

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

      var handleAbort = function() {
        if (!cancelled) {
          cancelled = true
          responseStream.cancel()
          if(responseStreamController) {
            try {
              ReadableStreamDefaultControllerError(responseStreamController,
                  new DOMException(ABORT_MESSAGE, ABORT_ERROR))
            } catch(_) {}
          }
          setTimeout(function() {
              try {
                xhr.abort()
              } catch(_) {}
            }, 0)
        }
      }

      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 {
            // 6. Let responseObject be a new Response object
            var response = new Response(responseStream, init)
            // 7. Let locallyAborted be false - done in response constructor

            request[SIGNAL_SLOT].addEventListener('abort',() => {
              // 8.1 Set locallyAborted to true.
              // 8.2 Abort fetch with p, request, and responseObject.
              // 8.3 Terminate the ongoing fetch with the aborted flag set.
              response[IS_ABORTED_SLOT] = true
              handleAbort()
              reject(new DOMException(ABORT_MESSAGE, ABORT_ERROR))
            })

            response[TYPE_SLOT] = isCORSMode ? 'cors' : 'basic'
            resolve(response)
          } catch (err) {
            reject(err)
          }
        }
      }

      // 9. Run the following in parallel:
      //    Fetch request.
      //    To process response for response, run these substeps:
      //    9.1 If locallyAborted is true, terminate these substeps
      //    9.2 If responses aborted flag is set, then abort fetch
      //       - Above are handled in responseBody methods
      xhr.onerror = function() {
        // 9.3 If response is a network error, then reject p with a TypeError and terminate these substeps.
        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 a Uint8Array. Enqueue a reference to this, rather
          // than make a copy of it, since caller no longer references it.
          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);
