Bug 1350646: Part 13 - Remove most SDK io modules. r=Mossop
authorKris Maglione <maglione.k@gmail.com>
Sat, 05 Aug 2017 22:05:06 -0700
changeset 373945 43af8f3bb5a160f2c45c5a3bca37a46016bff0dc
parent 373944 da41fb3ea7a667c7b04888e917f29de84d7a73db
child 373946 61c5837621eca4182dc9e8f6d004b94f23710115
push id32311
push userkwierso@gmail.com
push dateFri, 11 Aug 2017 01:14:57 +0000
treeherdermozilla-central@253a8560dc34 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs1350646
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1350646: Part 13 - Remove most SDK io modules. r=Mossop MozReview-Commit-ID: LoAVInRE6Nt
addon-sdk/moz.build
addon-sdk/source/lib/sdk/fs/path.js
addon-sdk/source/lib/sdk/io/buffer.js
addon-sdk/source/lib/sdk/io/byte-streams.js
addon-sdk/source/lib/sdk/io/fs.js
addon-sdk/source/lib/sdk/io/stream.js
addon-sdk/source/lib/sdk/io/text-streams.js
addon-sdk/source/test/fixtures/native-overrides-test/index.js
addon-sdk/source/test/fixtures/native-overrides-test/package.json
addon-sdk/source/test/test-native-loader.js
--- a/addon-sdk/moz.build
+++ b/addon-sdk/moz.build
@@ -53,24 +53,18 @@ modules = [
     'sdk/dom/events-shimmed.js',
     'sdk/dom/events.js',
     'sdk/event/chrome.js',
     'sdk/event/core.js',
     'sdk/event/dom.js',
     'sdk/event/target.js',
     'sdk/event/utils.js',
     'sdk/frame/utils.js',
-    'sdk/fs/path.js',
     'sdk/indexed-db.js',
-    'sdk/io/buffer.js',
-    'sdk/io/byte-streams.js',
     'sdk/io/file.js',
-    'sdk/io/fs.js',
-    'sdk/io/stream.js',
-    'sdk/io/text-streams.js',
     'sdk/lang/functional.js',
     'sdk/lang/functional/concurrent.js',
     'sdk/lang/functional/core.js',
     'sdk/lang/functional/helpers.js',
     'sdk/lang/type.js',
     'sdk/lang/weak-set.js',
     'sdk/messaging.js',
     'sdk/model/core.js',
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/fs/path.js
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// 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.
-
-// Adapted version of:
-// https://github.com/joyent/node/blob/v0.11.3/lib/path.js
-
-// Shim process global from node.
-var process = Object.create(require('../system'));
-process.cwd = process.pathFor.bind(process, 'CurProcD');
-
-// Update original check in node `process.platform === 'win32'` since in SDK it's `winnt`.
-var isWindows = process.platform.indexOf('win') === 0;
-
-
-
-// resolves . and .. elements in a path array with directory names there
-// must be no slashes, empty elements, or device names (c:\) in the array
-// (so also no leading and trailing slashes - it does not distinguish
-// relative and absolute paths)
-function normalizeArray(parts, allowAboveRoot) {
-  // if the path tries to go above the root, `up` ends up > 0
-  var up = 0;
-  for (var i = parts.length - 1; i >= 0; i--) {
-    var last = parts[i];
-    if (last === '.') {
-      parts.splice(i, 1);
-    } else if (last === '..') {
-      parts.splice(i, 1);
-      up++;
-    } else if (up) {
-      parts.splice(i, 1);
-      up--;
-    }
-  }
-
-  // if the path is allowed to go above the root, restore leading ..s
-  if (allowAboveRoot) {
-    for (; up--; up) {
-      parts.unshift('..');
-    }
-  }
-
-  return parts;
-}
-
-
-if (isWindows) {
-  // Regex to split a windows path into three parts: [*, device, slash,
-  // tail] windows-only
-  var splitDeviceRe =
-      /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
-
-  // Regex to split the tail part of the above into [*, dir, basename, ext]
-  var splitTailRe =
-      /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
-
-  // Function to split a filename into [root, dir, basename, ext]
-  // windows version
-  var splitPath = function(filename) {
-    // Separate device+slash from tail
-    var result = splitDeviceRe.exec(filename),
-        device = (result[1] || '') + (result[2] || ''),
-        tail = result[3] || '';
-    // Split the tail into dir, basename and extension
-    var result2 = splitTailRe.exec(tail),
-        dir = result2[1],
-        basename = result2[2],
-        ext = result2[3];
-    return [device, dir, basename, ext];
-  };
-
-  var normalizeUNCRoot = function(device) {
-    return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
-  };
-
-  // path.resolve([from ...], to)
-  // windows version
-  exports.resolve = function() {
-    var resolvedDevice = '',
-        resolvedTail = '',
-        resolvedAbsolute = false;
-
-    for (var i = arguments.length - 1; i >= -1; i--) {
-      var path;
-      if (i >= 0) {
-        path = arguments[i];
-      } else if (!resolvedDevice) {
-        path = process.cwd();
-      } else {
-        // Windows has the concept of drive-specific current working
-        // directories. If we've resolved a drive letter but not yet an
-        // absolute path, get cwd for that drive. We're sure the device is not
-        // an unc path at this points, because unc paths are always absolute.
-        path = process.env['=' + resolvedDevice];
-        // Verify that a drive-local cwd was found and that it actually points
-        // to our drive. If not, default to the drive's root.
-        if (!path || path.substr(0, 3).toLowerCase() !==
-            resolvedDevice.toLowerCase() + '\\') {
-          path = resolvedDevice + '\\';
-        }
-      }
-
-      // Skip empty and invalid entries
-      if (typeof path !== 'string') {
-        throw new TypeError('Arguments to path.resolve must be strings');
-      } else if (!path) {
-        continue;
-      }
-
-      var result = splitDeviceRe.exec(path),
-          device = result[1] || '',
-          isUnc = device && device.charAt(1) !== ':',
-          isAbsolute = exports.isAbsolute(path),
-          tail = result[3];
-
-      if (device &&
-          resolvedDevice &&
-          device.toLowerCase() !== resolvedDevice.toLowerCase()) {
-        // This path points to another device so it is not applicable
-        continue;
-      }
-
-      if (!resolvedDevice) {
-        resolvedDevice = device;
-      }
-      if (!resolvedAbsolute) {
-        resolvedTail = tail + '\\' + resolvedTail;
-        resolvedAbsolute = isAbsolute;
-      }
-
-      if (resolvedDevice && resolvedAbsolute) {
-        break;
-      }
-    }
-
-    // Convert slashes to backslashes when `resolvedDevice` points to an UNC
-    // root. Also squash multiple slashes into a single one where appropriate.
-    if (isUnc) {
-      resolvedDevice = normalizeUNCRoot(resolvedDevice);
-    }
-
-    // At this point the path should be resolved to a full absolute path,
-    // but handle relative paths to be safe (might happen when process.cwd()
-    // fails)
-
-    // Normalize the tail path
-
-    function f(p) {
-      return !!p;
-    }
-
-    resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
-                                  !resolvedAbsolute).join('\\');
-
-    return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
-           '.';
-  };
-
-  // windows version
-  exports.normalize = function(path) {
-    var result = splitDeviceRe.exec(path),
-        device = result[1] || '',
-        isUnc = device && device.charAt(1) !== ':',
-        isAbsolute = exports.isAbsolute(path),
-        tail = result[3],
-        trailingSlash = /[\\\/]$/.test(tail);
-
-    // If device is a drive letter, we'll normalize to lower case.
-    if (device && device.charAt(1) === ':') {
-      device = device[0].toLowerCase() + device.substr(1);
-    }
-
-    // Normalize the tail path
-    tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
-      return !!p;
-    }), !isAbsolute).join('\\');
-
-    if (!tail && !isAbsolute) {
-      tail = '.';
-    }
-    if (tail && trailingSlash) {
-      tail += '\\';
-    }
-
-    // Convert slashes to backslashes when `device` points to an UNC root.
-    // Also squash multiple slashes into a single one where appropriate.
-    if (isUnc) {
-      device = normalizeUNCRoot(device);
-    }
-
-    return device + (isAbsolute ? '\\' : '') + tail;
-  };
-
-  // windows version
-  exports.isAbsolute = function(path) {
-    var result = splitDeviceRe.exec(path),
-        device = result[1] || '',
-        isUnc = device && device.charAt(1) !== ':';
-    // UNC paths are always absolute
-    return !!result[2] || isUnc;
-  };
-
-  // windows version
-  exports.join = function() {
-    function f(p) {
-      if (typeof p !== 'string') {
-        throw new TypeError('Arguments to path.join must be strings');
-      }
-      return p;
-    }
-
-    var paths = Array.prototype.filter.call(arguments, f);
-    var joined = paths.join('\\');
-
-    // Make sure that the joined path doesn't start with two slashes, because
-    // normalize() will mistake it for an UNC path then.
-    //
-    // This step is skipped when it is very clear that the user actually
-    // intended to point at an UNC path. This is assumed when the first
-    // non-empty string arguments starts with exactly two slashes followed by
-    // at least one more non-slash character.
-    //
-    // Note that for normalize() to treat a path as an UNC path it needs to
-    // have at least 2 components, so we don't filter for that here.
-    // This means that the user can use join to construct UNC paths from
-    // a server name and a share name; for example:
-    //   path.join('//server', 'share') -> '\\\\server\\share\')
-    if (!/^[\\\/]{2}[^\\\/]/.test(paths[0])) {
-      joined = joined.replace(/^[\\\/]{2,}/, '\\');
-    }
-
-    return exports.normalize(joined);
-  };
-
-  // path.relative(from, to)
-  // it will solve the relative path from 'from' to 'to', for instance:
-  // from = 'C:\\orandea\\test\\aaa'
-  // to = 'C:\\orandea\\impl\\bbb'
-  // The output of the function should be: '..\\..\\impl\\bbb'
-  // windows version
-  exports.relative = function(from, to) {
-    from = exports.resolve(from);
-    to = exports.resolve(to);
-
-    // windows is not case sensitive
-    var lowerFrom = from.toLowerCase();
-    var lowerTo = to.toLowerCase();
-
-    function trim(arr) {
-      var start = 0;
-      for (; start < arr.length; start++) {
-        if (arr[start] !== '') break;
-      }
-
-      var end = arr.length - 1;
-      for (; end >= 0; end--) {
-        if (arr[end] !== '') break;
-      }
-
-      if (start > end) return [];
-      return arr.slice(start, end - start + 1);
-    }
-
-    var toParts = trim(to.split('\\'));
-
-    var lowerFromParts = trim(lowerFrom.split('\\'));
-    var lowerToParts = trim(lowerTo.split('\\'));
-
-    var length = Math.min(lowerFromParts.length, lowerToParts.length);
-    var samePartsLength = length;
-    for (var i = 0; i < length; i++) {
-      if (lowerFromParts[i] !== lowerToParts[i]) {
-        samePartsLength = i;
-        break;
-      }
-    }
-
-    if (samePartsLength == 0) {
-      return to;
-    }
-
-    var outputParts = [];
-    for (var i = samePartsLength; i < lowerFromParts.length; i++) {
-      outputParts.push('..');
-    }
-
-    outputParts = outputParts.concat(toParts.slice(samePartsLength));
-
-    return outputParts.join('\\');
-  };
-
-  exports.sep = '\\';
-  exports.delimiter = ';';
-
-} else /* posix */ {
-
-  // Split a filename into [root, dir, basename, ext], unix version
-  // 'root' is just a slash, or nothing.
-  var splitPathRe =
-      /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
-  var splitPath = function(filename) {
-    return splitPathRe.exec(filename).slice(1);
-  };
-
-  // path.resolve([from ...], to)
-  // posix version
-  exports.resolve = function() {
-    var resolvedPath = '',
-        resolvedAbsolute = false;
-
-    for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
-      var path = (i >= 0) ? arguments[i] : process.cwd();
-
-      // Skip empty and invalid entries
-      if (typeof path !== 'string') {
-        throw new TypeError('Arguments to path.resolve must be strings');
-      } else if (!path) {
-        continue;
-      }
-
-      resolvedPath = path + '/' + resolvedPath;
-      resolvedAbsolute = path.charAt(0) === '/';
-    }
-
-    // At this point the path should be resolved to a full absolute path, but
-    // handle relative paths to be safe (might happen when process.cwd() fails)
-
-    // Normalize the path
-    resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
-      return !!p;
-    }), !resolvedAbsolute).join('/');
-
-    return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
-  };
-
-  // path.normalize(path)
-  // posix version
-  exports.normalize = function(path) {
-    var isAbsolute = exports.isAbsolute(path),
-        trailingSlash = path.substr(-1) === '/';
-
-    // Normalize the path
-    path = normalizeArray(path.split('/').filter(function(p) {
-      return !!p;
-    }), !isAbsolute).join('/');
-
-    if (!path && !isAbsolute) {
-      path = '.';
-    }
-    if (path && trailingSlash) {
-      path += '/';
-    }
-
-    return (isAbsolute ? '/' : '') + path;
-  };
-
-  // posix version
-  exports.isAbsolute = function(path) {
-    return path.charAt(0) === '/';
-  };
-
-  // posix version
-  exports.join = function() {
-    var paths = Array.prototype.slice.call(arguments, 0);
-    return exports.normalize(paths.filter(function(p, index) {
-      if (typeof p !== 'string') {
-        throw new TypeError('Arguments to path.join must be strings');
-      }
-      return p;
-    }).join('/'));
-  };
-
-
-  // path.relative(from, to)
-  // posix version
-  exports.relative = function(from, to) {
-    from = exports.resolve(from).substr(1);
-    to = exports.resolve(to).substr(1);
-
-    function trim(arr) {
-      var start = 0;
-      for (; start < arr.length; start++) {
-        if (arr[start] !== '') break;
-      }
-
-      var end = arr.length - 1;
-      for (; end >= 0; end--) {
-        if (arr[end] !== '') break;
-      }
-
-      if (start > end) return [];
-      return arr.slice(start, end - start + 1);
-    }
-
-    var fromParts = trim(from.split('/'));
-    var toParts = trim(to.split('/'));
-
-    var length = Math.min(fromParts.length, toParts.length);
-    var samePartsLength = length;
-    for (var i = 0; i < length; i++) {
-      if (fromParts[i] !== toParts[i]) {
-        samePartsLength = i;
-        break;
-      }
-    }
-
-    var outputParts = [];
-    for (var i = samePartsLength; i < fromParts.length; i++) {
-      outputParts.push('..');
-    }
-
-    outputParts = outputParts.concat(toParts.slice(samePartsLength));
-
-    return outputParts.join('/');
-  };
-
-  exports.sep = '/';
-  exports.delimiter = ':';
-}
-
-exports.dirname = function(path) {
-  var result = splitPath(path),
-      root = result[0],
-      dir = result[1];
-
-  if (!root && !dir) {
-    // No dirname whatsoever
-    return '.';
-  }
-
-  if (dir) {
-    // It has a dirname, strip trailing slash
-    dir = dir.substr(0, dir.length - 1);
-  }
-
-  return root + dir;
-};
-
-
-exports.basename = function(path, ext) {
-  var f = splitPath(path)[2];
-  // TODO: make this comparison case-insensitive on windows?
-  if (ext && f.substr(-1 * ext.length) === ext) {
-    f = f.substr(0, f.length - ext.length);
-  }
-  return f;
-};
-
-
-exports.extname = function(path) {
-  return splitPath(path)[3];
-};
-
-if (isWindows) {
-  exports._makeLong = function(path) {
-    // Note: this will *probably* throw somewhere.
-    if (typeof path !== 'string')
-      return path;
-
-    if (!path) {
-      return '';
-    }
-
-    var resolvedPath = exports.resolve(path);
-
-    if (/^[a-zA-Z]\:\\/.test(resolvedPath)) {
-      // path is local filesystem path, which needs to be converted
-      // to long UNC path.
-      return '\\\\?\\' + resolvedPath;
-    } else if (/^\\\\[^?.]/.test(resolvedPath)) {
-      // path is network UNC path, which needs to be converted
-      // to long UNC path.
-      return '\\\\?\\UNC\\' + resolvedPath.substring(2);
-    }
-
-    return path;
-  };
-} else {
-  exports._makeLong = function(path) {
-    return path;
-  };
-}
\ No newline at end of file
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/io/buffer.js
+++ /dev/null
@@ -1,351 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-module.metadata = {
-  'stability': 'experimental'
-};
-
-/*
- * Encodings supported by TextEncoder/Decoder:
- * utf-8, utf-16le, utf-16be
- * http://encoding.spec.whatwg.org/#interface-textencoder
- *
- * Node however supports the following encodings:
- * ascii, utf-8, utf-16le, usc2, base64, hex
- */
-
-const { Cu } = require('chrome');
-lazyRequire(this, 'sdk/lang/type', "isNumber");
-Cu.importGlobalProperties(["TextEncoder", "TextDecoder"]);
-
-exports.TextEncoder = TextEncoder;
-exports.TextDecoder = TextDecoder;
-
-/**
- * Use WeakMaps to work around Bug 929146, which prevents us from adding
- * getters or values to typed arrays
- * https://bugzilla.mozilla.org/show_bug.cgi?id=929146
- */
-const parents = new WeakMap();
-const views = new WeakMap();
-
-function Buffer(subject, encoding /*, bufferLength */) {
-
-  // Allow invocation without `new` constructor
-  if (!(this instanceof Buffer))
-    return new Buffer(subject, encoding, arguments[2]);
-
-  var type = typeof(subject);
-
-  switch (type) {
-    case 'number':
-      // Create typed array of the given size if number.
-      try {
-        let buffer = new Uint8Array(subject > 0 ? Math.floor(subject) : 0);
-        return buffer;
-      } catch (e) {
-        if (/invalid array length/.test(e.message) ||
-            /invalid arguments/.test(e.message))
-          throw new RangeError('Could not instantiate buffer: size of buffer may be too large');
-        else
-          throw new Error('Could not instantiate buffer');
-      }
-      break;
-    case 'string':
-      // If string encode it and use buffer for the returned Uint8Array
-      // to create a local patched version that acts like node buffer.
-      encoding = encoding || 'utf8';
-      return new Uint8Array(new TextEncoder(encoding).encode(subject).buffer);
-    case 'object':
-      // This form of the constructor uses the form of
-      // new Uint8Array(buffer, offset, length);
-      // So we can instantiate a typed array within the constructor
-      // to inherit the appropriate properties, where both the
-      // `subject` and newly instantiated buffer share the same underlying
-      // data structure.
-      if (arguments.length === 3)
-        return new Uint8Array(subject, encoding, arguments[2]);
-      // If array or alike just make a copy with a local patched prototype.
-      else
-        return new Uint8Array(subject);
-    default:
-      throw new TypeError('must start with number, buffer, array or string');
-  }
-}
-exports.Buffer = Buffer;
-
-// Tests if `value` is a Buffer.
-Buffer.isBuffer = value => value instanceof Buffer
-
-// Returns true if the encoding is a valid encoding argument & false otherwise
-Buffer.isEncoding = function (encoding) {
-  if (!encoding) return false;
-  try {
-    new TextDecoder(encoding);
-  } catch(e) {
-    return false;
-  }
-  return true;
-}
-
-// Gives the actual byte length of a string. encoding defaults to 'utf8'.
-// This is not the same as String.prototype.length since that returns the
-// number of characters in a string.
-Buffer.byteLength = (value, encoding = 'utf8') =>
-  new TextEncoder(encoding).encode(value).byteLength
-
-// Direct copy of the nodejs's buffer implementation:
-// https://github.com/joyent/node/blob/b255f4c10a80343f9ce1cee56d0288361429e214/lib/buffer.js#L146-L177
-Buffer.concat = function(list, length) {
-  if (!Array.isArray(list))
-    throw new TypeError('Usage: Buffer.concat(list[, length])');
-
-  if (typeof length === 'undefined') {
-    length = 0;
-    for (var i = 0; i < list.length; i++)
-      length += list[i].length;
-  } else {
-    length = ~~length;
-  }
-
-  if (length < 0)
-    length = 0;
-
-  if (list.length === 0)
-    return new Buffer(0);
-  else if (list.length === 1)
-    return list[0];
-
-  if (length < 0)
-    throw new RangeError('length is not a positive number');
-
-  var buffer = new Buffer(length);
-  var pos = 0;
-  for (var i = 0; i < list.length; i++) {
-    var buf = list[i];
-    buf.copy(buffer, pos);
-    pos += buf.length;
-  }
-
-  return buffer;
-};
-
-// Node buffer is very much like Uint8Array although it has bunch of methods
-// that typically can be used in combination with `DataView` while preserving
-// access by index. Since in SDK each module has it's own set of bult-ins it
-// ok to patch ours to make it nodejs Buffer compatible.
-const Uint8ArraySet = Uint8Array.prototype.set
-Buffer.prototype = Uint8Array.prototype;
-Object.defineProperties(Buffer.prototype, {
-  parent: {
-    get: function() { return parents.get(this, undefined); }
-  },
-  view: {
-    get: function () {
-      let view = views.get(this, undefined);
-      if (view) return view;
-      view = new DataView(this.buffer);
-      views.set(this, view);
-      return view;
-    }
-  },
-  toString: {
-    value: function(encoding, start, end) {
-      encoding = !!encoding ? (encoding + '').toLowerCase() : 'utf8';
-      start = Math.max(0, ~~start);
-      end = Math.min(this.length, end === void(0) ? this.length : ~~end);
-      return new TextDecoder(encoding).decode(this.subarray(start, end));
-    }
-  },
-  toJSON: {
-    value: function() {
-      return { type: 'Buffer', data: Array.slice(this, 0) };
-    }
-  },
-  get: {
-    value: function(offset) {
-      return this[offset];
-    }
-  },
-  set: {
-    value: function(offset, value) { this[offset] = value; }
-  },
-  copy: {
-    value: function(target, offset, start, end) {
-      let length = this.length;
-      let targetLength = target.length;
-      offset = isNumber(offset) ? offset : 0;
-      start = isNumber(start) ? start : 0;
-
-      if (start < 0)
-        throw new RangeError('sourceStart is outside of valid range');
-      if (end < 0)
-        throw new RangeError('sourceEnd is outside of valid range');
-
-      // If sourceStart > sourceEnd, or targetStart > targetLength,
-      // zero bytes copied
-      if (start > end ||
-          offset > targetLength
-          )
-        return 0;
-
-      // If `end` is not defined, or if it is defined
-      // but would overflow `target`, redefine `end`
-      // so we can copy as much as we can
-      if (end - start > targetLength - offset ||
-          end == null) {
-        let remainingTarget = targetLength - offset;
-        let remainingSource = length - start;
-        if (remainingSource <= remainingTarget)
-          end = length;
-        else
-          end = start + remainingTarget;
-      }
-
-      Uint8ArraySet.call(target, this.subarray(start, end), offset);
-      return end - start;
-    }
-  },
-  slice: {
-    value: function(start, end) {
-      let length = this.length;
-      start = ~~start;
-      end = end != null ? end : length;
-
-      if (start < 0) {
-        start += length;
-        if (start < 0) start = 0;
-      } else if (start > length)
-        start = length;
-
-      if (end < 0) {
-        end += length;
-        if (end < 0) end = 0;
-      } else if (end > length)
-        end = length;
-
-      if (end < start)
-        end = start;
-
-      // This instantiation uses the new Uint8Array(buffer, offset, length) version
-      // of construction to share the same underling data structure
-      let buffer = new Buffer(this.buffer, start, end - start);
-
-      // If buffer has a value, assign its parent value to the
-      // buffer it shares its underlying structure with. If a slice of
-      // a slice, then use the root structure
-      if (buffer.length > 0)
-        parents.set(buffer, this.parent || this);
-
-      return buffer;
-    }
-  },
-  write: {
-    value: function(string, offset, length, encoding = 'utf8') {
-      // write(string, encoding);
-      if (typeof(offset) === 'string' && Number.isNaN(parseInt(offset))) {
-        [offset, length, encoding] = [0, null, offset];
-      }
-      // write(string, offset, encoding);
-      else if (typeof(length) === 'string')
-        [length, encoding] = [null, length];
-
-      if (offset < 0 || offset > this.length)
-        throw new RangeError('offset is outside of valid range');
-
-      offset = ~~offset;
-
-      // Clamp length if it would overflow buffer, or if its
-      // undefined
-      if (length == null || length + offset > this.length)
-        length = this.length - offset;
-
-      let buffer = new TextEncoder(encoding).encode(string);
-      let result = Math.min(buffer.length, length);
-      if (buffer.length !== length)
-        buffer = buffer.subarray(0, length);
-
-      Uint8ArraySet.call(this, buffer, offset);
-      return result;
-    }
-  },
-  fill: {
-    value: function fill(value, start, end) {
-      let length = this.length;
-      value = value || 0;
-      start = start || 0;
-      end = end || length;
-
-      if (typeof(value) === 'string')
-        value = value.charCodeAt(0);
-      if (typeof(value) !== 'number' || isNaN(value))
-        throw TypeError('value is not a number');
-      if (end < start)
-        throw new RangeError('end < start');
-
-      // Fill 0 bytes; we're done
-      if (end === start)
-        return 0;
-      if (length == 0)
-        return 0;
-
-      if (start < 0 || start >= length)
-        throw RangeError('start out of bounds');
-
-      if (end < 0 || end > length)
-        throw RangeError('end out of bounds');
-
-      let index = start;
-      while (index < end) this[index++] = value;
-    }
-  }
-});
-
-// Define nodejs Buffer's getter and setter functions that just proxy
-// to internal DataView's equivalent methods.
-
-// TODO do we need to check architecture to see if it's default big/little endian?
-[['readUInt16LE', 'getUint16', true],
- ['readUInt16BE', 'getUint16', false],
- ['readInt16LE', 'getInt16', true],
- ['readInt16BE', 'getInt16', false],
- ['readUInt32LE', 'getUint32', true],
- ['readUInt32BE', 'getUint32', false],
- ['readInt32LE', 'getInt32', true],
- ['readInt32BE', 'getInt32', false],
- ['readFloatLE', 'getFloat32', true],
- ['readFloatBE', 'getFloat32', false],
- ['readDoubleLE', 'getFloat64', true],
- ['readDoubleBE', 'getFloat64', false],
- ['readUInt8', 'getUint8'],
- ['readInt8', 'getInt8']].forEach(([alias, name, littleEndian]) => {
-  Object.defineProperty(Buffer.prototype, alias, {
-    value: function(offset) {
-      return this.view[name](offset, littleEndian);
-    }
-  });
-});
-
-[['writeUInt16LE', 'setUint16', true],
- ['writeUInt16BE', 'setUint16', false],
- ['writeInt16LE', 'setInt16', true],
- ['writeInt16BE', 'setInt16', false],
- ['writeUInt32LE', 'setUint32', true],
- ['writeUInt32BE', 'setUint32', false],
- ['writeInt32LE', 'setInt32', true],
- ['writeInt32BE', 'setInt32', false],
- ['writeFloatLE', 'setFloat32', true],
- ['writeFloatBE', 'setFloat32', false],
- ['writeDoubleLE', 'setFloat64', true],
- ['writeDoubleBE', 'setFloat64', false],
- ['writeUInt8', 'setUint8'],
- ['writeInt8', 'setInt8']].forEach(([alias, name, littleEndian]) => {
-  Object.defineProperty(Buffer.prototype, alias, {
-    value: function(value, offset) {
-      return this.view[name](offset, value, littleEndian);
-    }
-  });
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/io/byte-streams.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-exports.ByteReader = ByteReader;
-exports.ByteWriter = ByteWriter;
-
-const {Cc, Ci} = require("chrome");
-
-// This just controls the maximum number of bytes we read in at one time.
-const BUFFER_BYTE_LEN = 0x8000;
-
-function ByteReader(inputStream) {
-  const self = this;
-
-  let stream = Cc["@mozilla.org/binaryinputstream;1"].
-               createInstance(Ci.nsIBinaryInputStream);
-  stream.setInputStream(inputStream);
-
-  let manager = new StreamManager(this, stream);
-
-  this.read = function ByteReader_read(numBytes) {
-    manager.ensureOpened();
-    if (typeof(numBytes) !== "number")
-      numBytes = Infinity;
-
-    let data = "";
-    let read = 0;
-    try {
-      while (true) {
-        let avail = stream.available();
-        let toRead = Math.min(numBytes - read, avail, BUFFER_BYTE_LEN);
-        if (toRead <= 0)
-          break;
-        data += stream.readBytes(toRead);
-        read += toRead;
-      }
-    }
-    catch (err) {
-      throw new Error("Error reading from stream: " + err);
-    }
-
-    return data;
-  };
-}
-
-function ByteWriter(outputStream) {
-  const self = this;
-
-  let stream = Cc["@mozilla.org/binaryoutputstream;1"].
-               createInstance(Ci.nsIBinaryOutputStream);
-  stream.setOutputStream(outputStream);
-
-  let manager = new StreamManager(this, stream);
-
-  this.write = function ByteWriter_write(str) {
-    manager.ensureOpened();
-    try {
-      stream.writeBytes(str, str.length);
-    }
-    catch (err) {
-      throw new Error("Error writing to stream: " + err);
-    }
-  };
-}
-
-
-// This manages the lifetime of stream, a ByteReader or ByteWriter.  It defines
-// closed and close() on stream and registers an unload listener that closes
-// rawStream if it's still opened.  It also provides ensureOpened(), which
-// throws an exception if the stream is closed.
-function StreamManager(stream, rawStream) {
-  const self = this;
-  this.rawStream = rawStream;
-  this.opened = true;
-
-  stream.__defineGetter__("closed", function stream_closed() {
-    return !self.opened;
-  });
-
-  stream.close = function stream_close() {
-    self.ensureOpened();
-    self.unload();
-  };
-
-  require("../system/unload").ensure(this);
-}
-
-StreamManager.prototype = {
-  ensureOpened: function StreamManager_ensureOpened() {
-    if (!this.opened)
-      throw new Error("The stream is closed and cannot be used.");
-  },
-  unload: function StreamManager_unload() {
-    this.rawStream.close();
-    this.opened = false;
-  }
-};
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/io/fs.js
+++ /dev/null
@@ -1,985 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-const { Cc, Ci, CC } = require("chrome");
-
-lazyRequire(this, "../timers", "setTimeout");
-lazyRequire(this, "./stream", "Stream", "InputStream", "OutputStream");
-lazyRequire(this, "../event/core", "emit", "on");
-lazyRequire(this, "./buffer", "Buffer");
-
-const { ns } = require("../core/namespace");
-const { Class } = require("../core/heritage");
-
-
-const LocalFile = CC("@mozilla.org/file/local;1", "nsIFile",
-                        "initWithPath");
-const FileOutputStream = CC("@mozilla.org/network/file-output-stream;1",
-                            "nsIFileOutputStream", "init");
-const FileInputStream = CC("@mozilla.org/network/file-input-stream;1",
-                           "nsIFileInputStream", "init");
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
-                             "nsIBinaryInputStream", "setInputStream");
-const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1",
-                              "nsIBinaryOutputStream", "setOutputStream");
-const StreamPump = CC("@mozilla.org/network/input-stream-pump;1",
-                      "nsIInputStreamPump", "init");
-
-const { createOutputTransport, createInputTransport } =
-  Cc["@mozilla.org/network/stream-transport-service;1"].
-  getService(Ci.nsIStreamTransportService);
-
-const { OPEN_UNBUFFERED } = Ci.nsITransport;
-
-
-const { REOPEN_ON_REWIND, DEFER_OPEN } = Ci.nsIFileInputStream;
-const { DIRECTORY_TYPE, NORMAL_FILE_TYPE } = Ci.nsIFile;
-const { NS_SEEK_SET, NS_SEEK_CUR, NS_SEEK_END } = Ci.nsISeekableStream;
-
-const FILE_PERMISSION = 0o666;
-const PR_UINT32_MAX = 0xfffffff;
-// Values taken from:
-// http://mxr.mozilla.org/mozilla-central/source/nsprpub/pr/include/prio.h#615
-const PR_RDONLY =       0x01;
-const PR_WRONLY =       0x02;
-const PR_RDWR =         0x04;
-const PR_CREATE_FILE =  0x08;
-const PR_APPEND =       0x10;
-const PR_TRUNCATE =     0x20;
-const PR_SYNC =         0x40;
-const PR_EXCL =         0x80;
-
-const FLAGS = {
-  "r":                  PR_RDONLY,
-  "r+":                 PR_RDWR,
-  "w":                  PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY,
-  "w+":                 PR_CREATE_FILE | PR_TRUNCATE | PR_RDWR,
-  "a":                  PR_APPEND | PR_CREATE_FILE | PR_WRONLY,
-  "a+":                 PR_APPEND | PR_CREATE_FILE | PR_RDWR
-};
-
-function accessor() {
-  let map = new WeakMap();
-  return function(fd, value) {
-    if (value === null) map.delete(fd);
-    if (value !== undefined) map.set(fd, value);
-    return map.get(fd);
-  }
-}
-
-var nsIFile = accessor();
-var nsIFileInputStream = accessor();
-var nsIFileOutputStream = accessor();
-var nsIBinaryInputStream = accessor();
-var nsIBinaryOutputStream = accessor();
-
-// Just a contstant object used to signal that all of the file
-// needs to be read.
-const ALL = new String("Read all of the file");
-
-function isWritable(mode) {
-  return !!(mode & PR_WRONLY || mode & PR_RDWR);
-}
-function isReadable(mode) {
-  return !!(mode & PR_RDONLY || mode & PR_RDWR);
-}
-
-function isString(value) {
-  return typeof(value) === "string";
-}
-function isFunction(value) {
-  return typeof(value) === "function";
-}
-
-function toArray(enumerator) {
-  let value = [];
-  while(enumerator.hasMoreElements())
-    value.push(enumerator.getNext())
-  return value
-}
-
-function getFileName(file) {
-  return file.QueryInterface(Ci.nsIFile).leafName;
-}
-
-
-function remove(path, recursive) {
-  let fd = new LocalFile(path)
-  if (fd.exists()) {
-    fd.remove(recursive || false);
-  }
-  else {
-    throw FSError("remove", "ENOENT", 34, path);
-  }
-}
-
-/**
- * Utility function to convert either an octal number or string
- * into an octal number
- * 0777 => 0o777
- * "0644" => 0o644
- */
-function Mode(mode, fallback) {
-  return isString(mode) ? parseInt(mode, 8) : mode || fallback;
-}
-function Flags(flag) {
-  return !isString(flag) ? flag :
-         FLAGS[flag] || Error("Unknown file open flag: " + flag);
-}
-
-
-function FSError(op, code, errno, path, file, line) {
-  let error = Error(code + ", " + op + " " + path, file, line);
-  error.code = code;
-  error.path = path;
-  error.errno = errno;
-  return error;
-}
-
-const ReadStream = Class({
-  extends: InputStream,
-  initialize: function initialize(path, options) {
-    this.position = -1;
-    this.length = -1;
-    this.flags = "r";
-    this.mode = FILE_PERMISSION;
-    this.bufferSize = 64 * 1024;
-
-    options = options || {};
-
-    if ("flags" in options && options.flags)
-      this.flags = options.flags;
-    if ("bufferSize" in options && options.bufferSize)
-      this.bufferSize = options.bufferSize;
-    if ("length" in options && options.length)
-      this.length = options.length;
-    if ("position" in options && options.position !== undefined)
-      this.position = options.position;
-
-    let { flags, mode, position, length } = this;
-    let fd = isString(path) ? openSync(path, flags, mode) : path;
-    this.fd = fd;
-
-    let input = nsIFileInputStream(fd);
-    // Setting a stream position, unless it"s `-1` which means current position.
-    if (position >= 0)
-      input.QueryInterface(Ci.nsISeekableStream).seek(NS_SEEK_SET, position);
-    // We use `nsIStreamTransportService` service to transform blocking
-    // file input stream into a fully asynchronous stream that can be written
-    // without blocking the main thread.
-    let transport = createInputTransport(input, position, length, false);
-    // Open an input stream on a transport. We don"t pass flags to guarantee
-    // non-blocking stream semantics. Also we use defaults for segment size &
-    // count.
-    InputStream.prototype.initialize.call(this, {
-      asyncInputStream: transport.openInputStream(null, 0, 0)
-    });
-
-    // Close file descriptor on end and destroy the stream.
-    on(this, "end", _ => {
-      this.destroy();
-      emit(this, "close");
-    });
-
-    this.read();
-  },
-  destroy: function() {
-    closeSync(this.fd);
-    InputStream.prototype.destroy.call(this);
-  }
-});
-exports.ReadStream = ReadStream;
-exports.createReadStream = function createReadStream(path, options) {
-  return new ReadStream(path, options);
-};
-
-const WriteStream = Class({
-  extends: OutputStream,
-  initialize: function initialize(path, options) {
-    this.drainable = true;
-    this.flags = "w";
-    this.position = -1;
-    this.mode = FILE_PERMISSION;
-
-    options = options || {};
-
-    if ("flags" in options && options.flags)
-      this.flags = options.flags;
-    if ("mode" in options && options.mode)
-      this.mode = options.mode;
-    if ("position" in options && options.position !== undefined)
-      this.position = options.position;
-
-    let { position, flags, mode } = this;
-    // If pass was passed we create a file descriptor out of it. Otherwise
-    // we just use given file descriptor.
-    let fd = isString(path) ? openSync(path, flags, mode) : path;
-    this.fd = fd;
-
-    let output = nsIFileOutputStream(fd);
-    // Setting a stream position, unless it"s `-1` which means current position.
-    if (position >= 0)
-      output.QueryInterface(Ci.nsISeekableStream).seek(NS_SEEK_SET, position);
-    // We use `nsIStreamTransportService` service to transform blocking
-    // file output stream into a fully asynchronous stream that can be written
-    // without blocking the main thread.
-    let transport = createOutputTransport(output, position, -1, false);
-    // Open an output stream on a transport. We don"t pass flags to guarantee
-    // non-blocking stream semantics. Also we use defaults for segment size &
-    // count.
-    OutputStream.prototype.initialize.call(this, {
-      asyncOutputStream: transport.openOutputStream(OPEN_UNBUFFERED, 0, 0),
-      output: output
-    });
-
-    // For write streams "finish" basically means close.
-    on(this, "finish", _ => {
-       this.destroy();
-       emit(this, "close");
-    });
-  },
-  destroy: function() {
-    OutputStream.prototype.destroy.call(this);
-    closeSync(this.fd);
-  }
-});
-exports.WriteStream = WriteStream;
-exports.createWriteStream = function createWriteStream(path, options) {
-  return new WriteStream(path, options);
-};
-
-const Stats = Class({
-  initialize: function initialize(path) {
-    let file = new LocalFile(path);
-    if (!file.exists()) throw FSError("stat", "ENOENT", 34, path);
-    nsIFile(this, file);
-  },
-  isDirectory: function() {
-    return nsIFile(this).isDirectory();
-  },
-  isFile: function() {
-    return nsIFile(this).isFile();
-  },
-  isSymbolicLink: function() {
-    return nsIFile(this).isSymlink();
-  },
-  get mode() {
-    return nsIFile(this).permissions;
-  },
-  get size() {
-    return nsIFile(this).fileSize;
-  },
-  get mtime() {
-    return nsIFile(this).lastModifiedTime;
-  },
-  isBlockDevice: function() {
-    return nsIFile(this).isSpecial();
-  },
-  isCharacterDevice: function() {
-    return nsIFile(this).isSpecial();
-  },
-  isFIFO: function() {
-    return nsIFile(this).isSpecial();
-  },
-  isSocket: function() {
-    return nsIFile(this).isSpecial();
-  },
-  // non standard
-  get exists() {
-    return nsIFile(this).exists();
-  },
-  get hidden() {
-    return nsIFile(this).isHidden();
-  },
-  get writable() {
-    return nsIFile(this).isWritable();
-  },
-  get readable() {
-    return nsIFile(this).isReadable();
-  }
-});
-exports.Stats = Stats;
-
-const LStats = Class({
-  extends: Stats,
-  get size() {
-    return this.isSymbolicLink() ? nsIFile(this).fileSizeOfLink :
-                                   nsIFile(this).fileSize;
-  },
-  get mtime() {
-    return this.isSymbolicLink() ? nsIFile(this).lastModifiedTimeOfLink :
-                                   nsIFile(this).lastModifiedTime;
-  },
-  // non standard
-  get permissions() {
-    return this.isSymbolicLink() ? nsIFile(this).permissionsOfLink :
-                                   nsIFile(this).permissions;
-  }
-});
-
-const FStat = Class({
-  extends: Stats,
-  initialize: function initialize(fd) {
-    nsIFile(this, nsIFile(fd));
-  }
-});
-
-function noop() {}
-function Async(wrapped) {
-  return function (path, callback) {
-    let args = Array.slice(arguments);
-    callback = args.pop();
-    // If node is not given a callback argument
-    // it just does not calls it.
-    if (typeof(callback) !== "function") {
-      args.push(callback);
-      callback = noop;
-    }
-    setTimeout(function() {
-      try {
-        var result = wrapped.apply(this, args);
-        if (result === undefined) callback(null);
-        else callback(null, result);
-      } catch (error) {
-        callback(error);
-      }
-    }, 0);
-  }
-}
-
-
-/**
- * Synchronous rename(2)
- */
-function renameSync(oldPath, newPath) {
-  let source = new LocalFile(oldPath);
-  let target = new LocalFile(newPath);
-  if (!source.exists()) throw FSError("rename", "ENOENT", 34, oldPath);
-  return source.moveTo(target.parent, target.leafName);
-};
-exports.renameSync = renameSync;
-
-/**
- * Asynchronous rename(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var rename = Async(renameSync);
-exports.rename = rename;
-
-/**
- * Test whether or not the given path exists by checking with the file system.
- */
-function existsSync(path) {
-  return new LocalFile(path).exists();
-}
-exports.existsSync = existsSync;
-
-var exists = Async(existsSync);
-exports.exists = exists;
-
-/**
- * Synchronous ftruncate(2).
- */
-function truncateSync(path, length) {
-  let fd = openSync(path, "w");
-  ftruncateSync(fd, length);
-  closeSync(fd);
-}
-exports.truncateSync = truncateSync;
-
-/**
- * Asynchronous ftruncate(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-function truncate(path, length, callback) {
-  open(path, "w", function(error, fd) {
-    if (error) return callback(error);
-    ftruncate(fd, length, function(error) {
-      if (error) {
-        closeSync(fd);
-        callback(error);
-      }
-      else {
-        close(fd, callback);
-      }
-    });
-  });
-}
-exports.truncate = truncate;
-
-function ftruncate(fd, length, callback) {
-  write(fd, new Buffer(length), 0, length, 0, function(error) {
-    callback(error);
-  });
-}
-exports.ftruncate = ftruncate;
-
-function ftruncateSync(fd, length = 0) {
-  writeSync(fd, new Buffer(length), 0, length, 0);
-}
-exports.ftruncateSync = ftruncateSync;
-
-function chownSync(path, uid, gid) {
-  throw Error("Not implemented yet!!");
-}
-exports.chownSync = chownSync;
-
-var chown = Async(chownSync);
-exports.chown = chown;
-
-function lchownSync(path, uid, gid) {
-  throw Error("Not implemented yet!!");
-}
-exports.lchownSync = chownSync;
-
-var lchown = Async(lchown);
-exports.lchown = lchown;
-
-/**
- * Synchronous chmod(2).
- */
-function chmodSync (path, mode) {
-  let file;
-  try {
-    file = new LocalFile(path);
-  } catch(e) {
-    throw FSError("chmod", "ENOENT", 34, path);
-  }
-
-  file.permissions = Mode(mode);
-}
-exports.chmodSync = chmodSync;
-/**
- * Asynchronous chmod(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var chmod = Async(chmodSync);
-exports.chmod = chmod;
-
-/**
- * Synchronous chmod(2).
- */
-function fchmodSync(fd, mode) {
-  throw Error("Not implemented yet!!");
-};
-exports.fchmodSync = fchmodSync;
-/**
- * Asynchronous chmod(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var fchmod = Async(fchmodSync);
-exports.fchmod = fchmod;
-
-
-/**
- * Synchronous stat(2). Returns an instance of `fs.Stats`
- */
-function statSync(path) {
-  return new Stats(path);
-};
-exports.statSync = statSync;
-
-/**
- * Asynchronous stat(2). The callback gets two arguments (err, stats) where
- * stats is a `fs.Stats` object. It looks like this:
- */
-var stat = Async(statSync);
-exports.stat = stat;
-
-/**
- * Synchronous lstat(2). Returns an instance of `fs.Stats`.
- */
-function lstatSync(path) {
-  return new LStats(path);
-};
-exports.lstatSync = lstatSync;
-
-/**
- * Asynchronous lstat(2). The callback gets two arguments (err, stats) where
- * stats is a fs.Stats object. lstat() is identical to stat(), except that if
- * path is a symbolic link, then the link itself is stat-ed, not the file that
- * it refers to.
- */
-var lstat = Async(lstatSync);
-exports.lstat = lstat;
-
-/**
- * Synchronous fstat(2). Returns an instance of `fs.Stats`.
- */
-function fstatSync(fd) {
-  return new FStat(fd);
-};
-exports.fstatSync = fstatSync;
-
-/**
- * Asynchronous fstat(2). The callback gets two arguments (err, stats) where
- * stats is a fs.Stats object.
- */
-var fstat = Async(fstatSync);
-exports.fstat = fstat;
-
-/**
- * Synchronous link(2).
- */
-function linkSync(source, target) {
-  throw Error("Not implemented yet!!");
-};
-exports.linkSync = linkSync;
-
-/**
- * Asynchronous link(2). No arguments other than a possible exception are given
- * to the completion callback.
- */
-var link = Async(linkSync);
-exports.link = link;
-
-/**
- * Synchronous symlink(2).
- */
-function symlinkSync(source, target) {
-  throw Error("Not implemented yet!!");
-};
-exports.symlinkSync = symlinkSync;
-
-/**
- * Asynchronous symlink(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var symlink = Async(symlinkSync);
-exports.symlink = symlink;
-
-/**
- * Synchronous readlink(2). Returns the resolved path.
- */
-function readlinkSync(path) {
-  return new LocalFile(path).target;
-};
-exports.readlinkSync = readlinkSync;
-
-/**
- * Asynchronous readlink(2). The callback gets two arguments
- * `(error, resolvedPath)`.
- */
-var readlink = Async(readlinkSync);
-exports.readlink = readlink;
-
-/**
- * Synchronous realpath(2). Returns the resolved path.
- */
-function realpathSync(path) {
-  return new LocalFile(path).path;
-};
-exports.realpathSync = realpathSync;
-
-/**
- * Asynchronous realpath(2). The callback gets two arguments
- * `(err, resolvedPath)`.
- */
-var realpath = Async(realpathSync);
-exports.realpath = realpath;
-
-/**
- * Synchronous unlink(2).
- */
-var unlinkSync = remove;
-exports.unlinkSync = unlinkSync;
-
-/**
- * Asynchronous unlink(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var unlink = Async(remove);
-exports.unlink = unlink;
-
-/**
- * Synchronous rmdir(2).
- */
-var rmdirSync = remove;
-exports.rmdirSync = rmdirSync;
-
-/**
- * Asynchronous rmdir(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var rmdir = Async(rmdirSync);
-exports.rmdir = rmdir;
-
-/**
- * Synchronous mkdir(2).
- */
-function mkdirSync(path, mode) {
-  try {
-    return LocalFile(path).create(DIRECTORY_TYPE, Mode(mode));
-  } catch (error) {
-    // Adjust exception thorw to match ones thrown by node.
-    if (error.name === "NS_ERROR_FILE_ALREADY_EXISTS") {
-      let { fileName, lineNumber } = error;
-      error = FSError("mkdir", "EEXIST", 47, path, fileName, lineNumber);
-    }
-    throw error;
-  }
-};
-exports.mkdirSync = mkdirSync;
-
-/**
- * Asynchronous mkdir(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var mkdir = Async(mkdirSync);
-exports.mkdir = mkdir;
-
-/**
- * Synchronous readdir(3). Returns an array of filenames excluding `"."` and
- * `".."`.
- */
-function readdirSync(path) {
-  try {
-    return toArray(new LocalFile(path).directoryEntries).map(getFileName);
-  }
-  catch (error) {
-    // Adjust exception thorw to match ones thrown by node.
-    if (error.name === "NS_ERROR_FILE_TARGET_DOES_NOT_EXIST" ||
-        error.name === "NS_ERROR_FILE_NOT_FOUND")
-    {
-      let { fileName, lineNumber } = error;
-      error = FSError("readdir", "ENOENT", 34, path, fileName, lineNumber);
-    }
-    throw error;
-  }
-};
-exports.readdirSync = readdirSync;
-
-/**
- * Asynchronous readdir(3). Reads the contents of a directory. The callback
- * gets two arguments `(error, files)` where `files` is an array of the names
- * of the files in the directory excluding `"."` and `".."`.
- */
-var readdir = Async(readdirSync);
-exports.readdir = readdir;
-
-/**
- * Synchronous close(2).
- */
- function closeSync(fd) {
-   let input = nsIFileInputStream(fd);
-   let output = nsIFileOutputStream(fd);
-
-   // Closing input stream and removing reference.
-   if (input) input.close();
-   // Closing output stream and removing reference.
-   if (output) output.close();
-
-   nsIFile(fd, null);
-   nsIFileInputStream(fd, null);
-   nsIFileOutputStream(fd, null);
-   nsIBinaryInputStream(fd, null);
-   nsIBinaryOutputStream(fd, null);
-};
-exports.closeSync = closeSync;
-/**
- * Asynchronous close(2). No arguments other than a possible exception are
- * given to the completion callback.
- */
-var close = Async(closeSync);
-exports.close = close;
-
-/**
- * Synchronous open(2).
- */
-function openSync(aPath, aFlag, aMode) {
-  let [ fd, flags, mode, file ] =
-      [ { path: aPath }, Flags(aFlag), Mode(aMode), LocalFile(aPath) ];
-
-  nsIFile(fd, file);
-
-  // If trying to open file for just read that does not exists
-  // need to throw exception as node does.
-  if (!file.exists() && !isWritable(flags))
-    throw FSError("open", "ENOENT", 34, aPath);
-
-  // If we want to open file in read mode we initialize input stream.
-  if (isReadable(flags)) {
-    let input = FileInputStream(file, flags, mode, DEFER_OPEN);
-    nsIFileInputStream(fd, input);
-  }
-
-  // If we want to open file in write mode we initialize output stream for it.
-  if (isWritable(flags)) {
-    let output = FileOutputStream(file, flags, mode, DEFER_OPEN);
-    nsIFileOutputStream(fd, output);
-  }
-
-  return fd;
-}
-exports.openSync = openSync;
-/**
- * Asynchronous file open. See open(2). Flags can be
- * `"r", "r+", "w", "w+", "a"`, or `"a+"`. mode defaults to `0666`.
- * The callback gets two arguments `(error, fd).
- */
-var open = Async(openSync);
-exports.open = open;
-
-/**
- * Synchronous version of buffer-based fs.write(). Returns the number of bytes
- * written.
- */
-function writeSync(fd, buffer, offset, length, position) {
-  if (length + offset > buffer.length) {
-    throw Error("Length is extends beyond buffer");
-  }
-  else if (length + offset !== buffer.length) {
-    buffer = buffer.slice(offset, offset + length);
-  }
-
-  let output = BinaryOutputStream(nsIFileOutputStream(fd));
-  nsIBinaryOutputStream(fd, output);
-  // We write content as a byte array as this will avoid any transcoding
-  // if content was a buffer.
-  output.writeByteArray(buffer.valueOf(), buffer.length);
-  output.flush();
-};
-exports.writeSync = writeSync;
-
-/**
- * Write buffer to the file specified by fd.
- *
- * `offset` and `length` determine the part of the buffer to be written.
- *
- * `position` refers to the offset from the beginning of the file where this
- * data should be written. If `position` is `null`, the data will be written
- * at the current position. See pwrite(2).
- *
- * The callback will be given three arguments `(error, written, buffer)` where
- * written specifies how many bytes were written into buffer.
- *
- * Note that it is unsafe to use `fs.write` multiple times on the same file
- * without waiting for the callback.
- */
-function write(fd, buffer, offset, length, position, callback) {
-  if (!Buffer.isBuffer(buffer)) {
-    // (fd, data, position, encoding, callback)
-    let encoding = null;
-    [ position, encoding, callback ] = Array.slice(arguments, 1);
-    buffer = new Buffer(String(buffer), encoding);
-    offset = 0;
-  } else if (length + offset > buffer.length) {
-    throw Error("Length is extends beyond buffer");
-  } else if (length + offset !== buffer.length) {
-    buffer = buffer.slice(offset, offset + length);
-  }
-
-  let writeStream = new WriteStream(fd, { position: position,
-                                          length: length });
-  writeStream.on("error", callback);
-  writeStream.write(buffer, function onEnd() {
-    writeStream.destroy();
-    if (callback)
-      callback(null, buffer.length, buffer);
-  });
-};
-exports.write = write;
-
-/**
- * Synchronous version of string-based fs.read. Returns the number of
- * bytes read.
- */
-function readSync(fd, buffer, offset, length, position) {
-  let input = nsIFileInputStream(fd);
-  // Setting a stream position, unless it"s `-1` which means current position.
-  if (position >= 0)
-    input.QueryInterface(Ci.nsISeekableStream).seek(NS_SEEK_SET, position);
-  // We use `nsIStreamTransportService` service to transform blocking
-  // file input stream into a fully asynchronous stream that can be written
-  // without blocking the main thread.
-  let binaryInputStream = BinaryInputStream(input);
-  let count = length === ALL ? binaryInputStream.available() : length;
-  if (offset === 0) binaryInputStream.readArrayBuffer(count, buffer.buffer);
-  else {
-    let chunk = new Buffer(count);
-    binaryInputStream.readArrayBuffer(count, chunk.buffer);
-    chunk.copy(buffer, offset);
-  }
-
-  return buffer.slice(offset, offset + count);
-};
-exports.readSync = readSync;
-
-/**
- * Read data from the file specified by `fd`.
- *
- * `buffer` is the buffer that the data will be written to.
- * `offset` is offset within the buffer where writing will start.
- *
- * `length` is an integer specifying the number of bytes to read.
- *
- * `position` is an integer specifying where to begin reading from in the file.
- * If `position` is `null`, data will be read from the current file position.
- *
- * The callback is given the three arguments, `(error, bytesRead, buffer)`.
- */
-function read(fd, buffer, offset, length, position, callback) {
-  let bytesRead = 0;
-  let readStream = new ReadStream(fd, { position: position, length: length });
-  readStream.on("data", function onData(data) {
-      data.copy(buffer, offset + bytesRead);
-      bytesRead += data.length;
-  });
-  readStream.on("end", function onEnd() {
-    callback(null, bytesRead, buffer);
-    readStream.destroy();
-  });
-};
-exports.read = read;
-
-/**
- * Asynchronously reads the entire contents of a file.
- * The callback is passed two arguments `(error, data)`, where data is the
- * contents of the file.
- */
-function readFile(path, encoding, callback) {
-  if (isFunction(encoding)) {
-    callback = encoding
-    encoding = null
-  }
-
-  let buffer = null;
-  try {
-    let readStream = new ReadStream(path);
-    readStream.on("data", function(data) {
-      if (!buffer) buffer = data;
-      else buffer = Buffer.concat([buffer, data], 2);
-    });
-    readStream.on("error", function onError(error) {
-      callback(error);
-    });
-    readStream.on("end", function onEnd() {
-      // Note: Need to destroy before invoking a callback
-      // so that file descriptor is released.
-      readStream.destroy();
-      callback(null, buffer);
-    });
-  }
-  catch (error) {
-    setTimeout(callback, 0, error);
-  }
-};
-exports.readFile = readFile;
-
-/**
- * Synchronous version of `fs.readFile`. Returns the contents of the path.
- * If encoding is specified then this function returns a string.
- * Otherwise it returns a buffer.
- */
-function readFileSync(path, encoding) {
-  let fd = openSync(path, "r");
-  let size = fstatSync(fd).size;
-  let buffer = new Buffer(size);
-  try {
-    readSync(fd, buffer, 0, ALL, 0);
-  }
-  finally {
-    closeSync(fd);
-  }
-  return buffer;
-};
-exports.readFileSync = readFileSync;
-
-/**
- * Asynchronously writes data to a file, replacing the file if it already
- * exists. data can be a string or a buffer.
- */
-function writeFile(path, content, encoding, callback) {
-  if (!isString(path))
-    throw new TypeError('path must be a string');
-
-  try {
-    if (isFunction(encoding)) {
-      callback = encoding
-      encoding = null
-    }
-    if (isString(content))
-      content = new Buffer(content, encoding);
-
-    let writeStream = new WriteStream(path);
-    let error = null;
-
-    writeStream.end(content, function() {
-      writeStream.destroy();
-      callback(error);
-    });
-
-    writeStream.on("error", function onError(reason) {
-      error = reason;
-      writeStream.destroy();
-    });
-  } catch (error) {
-    callback(error);
-  }
-};
-exports.writeFile = writeFile;
-
-/**
- * The synchronous version of `fs.writeFile`.
- */
-function writeFileSync(filename, data, encoding) {
-  // TODO: Implement this in bug 1148209 https://bugzilla.mozilla.org/show_bug.cgi?id=1148209
-  throw Error("Not implemented");
-};
-exports.writeFileSync = writeFileSync;
-
-
-function utimesSync(path, atime, mtime) {
-  throw Error("Not implemented");
-}
-exports.utimesSync = utimesSync;
-
-var utimes = Async(utimesSync);
-exports.utimes = utimes;
-
-function futimesSync(fd, atime, mtime, callback) {
-  throw Error("Not implemented");
-}
-exports.futimesSync = futimesSync;
-
-var futimes = Async(futimesSync);
-exports.futimes = futimes;
-
-function fsyncSync(fd, atime, mtime, callback) {
-  throw Error("Not implemented");
-}
-exports.fsyncSync = fsyncSync;
-
-var fsync = Async(fsyncSync);
-exports.fsync = fsync;
-
-
-/**
- * Watch for changes on filename. The callback listener will be called each
- * time the file is accessed.
- *
- * The second argument is optional. The options if provided should be an object
- * containing two members a boolean, persistent, and interval, a polling value
- * in milliseconds. The default is { persistent: true, interval: 0 }.
- */
-function watchFile(path, options, listener) {
-  throw Error("Not implemented");
-};
-exports.watchFile = watchFile;
-
-
-function unwatchFile(path, listener) {
-  throw Error("Not implemented");
-}
-exports.unwatchFile = unwatchFile;
-
-function watch(path, options, listener) {
-  throw Error("Not implemented");
-}
-exports.watch = watch;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/io/stream.js
+++ /dev/null
@@ -1,441 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-const { CC, Cc, Ci, Cu, Cr, components } = require("chrome");
-const { EventTarget } = require("../event/target");
-const { Class } = require("../core/heritage");
-
-lazyRequire(this, "../event/core", "emit");
-lazyRequire(this, "./buffer", "Buffer");
-lazyRequire(this, "../timers", "setTimeout");
-
-
-const MultiplexInputStream = CC("@mozilla.org/io/multiplex-input-stream;1",
-                                "nsIMultiplexInputStream");
-const AsyncStreamCopier = CC("@mozilla.org/network/async-stream-copier;1",
-                             "nsIAsyncStreamCopier", "init");
-const StringInputStream = CC("@mozilla.org/io/string-input-stream;1",
-                             "nsIStringInputStream");
-const ArrayBufferInputStream = CC("@mozilla.org/io/arraybuffer-input-stream;1",
-                                  "nsIArrayBufferInputStream");
-
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
-                             "nsIBinaryInputStream", "setInputStream");
-const InputStreamPump = CC("@mozilla.org/network/input-stream-pump;1",
-                           "nsIInputStreamPump", "init");
-
-const threadManager = Cc["@mozilla.org/thread-manager;1"].
-                      getService(Ci.nsIThreadManager);
-
-const eventTarget = Cc["@mozilla.org/network/stream-transport-service;1"].
-                    getService(Ci.nsIEventTarget);
-
-var isFunction = value => typeof(value) === "function"
-
-function accessor() {
-  let map = new WeakMap();
-  return function(target, value) {
-    if (value)
-      map.set(target, value);
-    return map.get(target);
-  }
-}
-
-const Stream = Class({
-  extends: EventTarget,
-  initialize: function() {
-    this.readable = false;
-    this.writable = false;
-    this.encoding = null;
-  },
-  setEncoding: function setEncoding(encoding) {
-    this.encoding = String(encoding).toUpperCase();
-  },
-  pipe: function pipe(target, options) {
-    let source = this;
-    function onData(chunk) {
-      if (target.writable) {
-        if (false === target.write(chunk))
-          source.pause();
-      }
-    }
-    function onDrain() {
-      if (source.readable)
-        source.resume();
-    }
-    function onEnd() {
-      target.end();
-    }
-    function onPause() {
-      source.pause();
-    }
-    function onResume() {
-      if (source.readable)
-        source.resume();
-    }
-
-    function cleanup() {
-      source.removeListener("data", onData);
-      target.removeListener("drain", onDrain);
-      source.removeListener("end", onEnd);
-
-      target.removeListener("pause", onPause);
-      target.removeListener("resume", onResume);
-
-      source.removeListener("end", cleanup);
-      source.removeListener("close", cleanup);
-
-      target.removeListener("end", cleanup);
-      target.removeListener("close", cleanup);
-    }
-
-    if (!options || options.end !== false)
-      target.on("end", onEnd);
-
-    source.on("data", onData);
-    target.on("drain", onDrain);
-    target.on("resume", onResume);
-    target.on("pause", onPause);
-
-    source.on("end", cleanup);
-    source.on("close", cleanup);
-
-    target.on("end", cleanup);
-    target.on("close", cleanup);
-
-    emit(target, "pipe", source);
-  },
-  pause: function pause() {
-    emit(this, "pause");
-  },
-  resume: function resume() {
-    emit(this, "resume");
-  },
-  destroySoon: function destroySoon() {
-    this.destroy();
-  }
-});
-exports.Stream = Stream;
-
-
-var nsIStreamListener = accessor();
-var nsIInputStreamPump = accessor();
-var nsIAsyncInputStream = accessor();
-var nsIBinaryInputStream = accessor();
-
-const StreamListener = Class({
-  initialize: function(stream) {
-    this.stream = stream;
-  },
-
-  // Next three methods are part of `nsIStreamListener` interface and are
-  // invoked by `nsIInputStreamPump.asyncRead`.
-  onDataAvailable: function(request, context, input, offset, count) {
-    let stream = this.stream;
-    let buffer = new ArrayBuffer(count);
-    nsIBinaryInputStream(stream).readArrayBuffer(count, buffer);
-    emit(stream, "data", new Buffer(buffer));
-  },
-
-  // Next two methods implement `nsIRequestObserver` interface and are invoked
-  // by `nsIInputStreamPump.asyncRead`.
-  onStartRequest: function() {},
-  // Called to signify the end of an asynchronous request. We only care to
-  // discover errors.
-  onStopRequest: function(request, context, status) {
-    let stream = this.stream;
-    stream.readable = false;
-    if (!components.isSuccessCode(status))
-      emit(stream, "error", status);
-    else
-      emit(stream, "end");
-  }
-});
-
-
-const InputStream = Class({
-  extends: Stream,
-  readable: false,
-  paused: false,
-  initialize: function initialize(options) {
-    let { asyncInputStream } = options;
-
-    this.readable = true;
-
-    let binaryInputStream = new BinaryInputStream(asyncInputStream);
-    let inputStreamPump = new InputStreamPump(asyncInputStream,
-                                              -1, -1, 0, 0, false);
-    let streamListener = new StreamListener(this);
-
-    nsIAsyncInputStream(this, asyncInputStream);
-    nsIInputStreamPump(this, inputStreamPump);
-    nsIBinaryInputStream(this, binaryInputStream);
-    nsIStreamListener(this, streamListener);
-
-    this.asyncInputStream = asyncInputStream;
-    this.inputStreamPump = inputStreamPump;
-    this.binaryInputStream = binaryInputStream;
-  },
-  get status() {
-    return nsIInputStreamPump(this).status;
-  },
-  read: function() {
-    nsIInputStreamPump(this).asyncRead(nsIStreamListener(this), null);
-  },
-  pause: function pause() {
-    this.paused = true;
-    nsIInputStreamPump(this).suspend();
-    emit(this, "paused");
-  },
-  resume: function resume() {
-    this.paused = false;
-    if (nsIInputStreamPump(this).isPending()) {
-        nsIInputStreamPump(this).resume();
-        emit(this, "resume");
-    }
-  },
-  close: function close() {
-    this.readable = false;
-    nsIInputStreamPump(this).cancel(Cr.NS_OK);
-    nsIBinaryInputStream(this).close();
-    nsIAsyncInputStream(this).close();
-  },
-  destroy: function destroy() {
-    this.close();
-
-    nsIInputStreamPump(this);
-    nsIAsyncInputStream(this);
-    nsIBinaryInputStream(this);
-    nsIStreamListener(this);
-  }
-});
-exports.InputStream = InputStream;
-
-
-
-var nsIRequestObserver = accessor();
-var nsIAsyncOutputStream = accessor();
-var nsIAsyncStreamCopier = accessor();
-var nsIMultiplexInputStream = accessor();
-
-const RequestObserver = Class({
-  initialize: function(stream) {
-    this.stream = stream;
-  },
-  // Method is part of `nsIRequestObserver` interface that is
-  // invoked by `nsIAsyncStreamCopier.asyncCopy`.
-  onStartRequest: function() {},
-  // Method is part of `nsIRequestObserver` interface that is
-  // invoked by `nsIAsyncStreamCopier.asyncCopy`.
-  onStopRequest: function(request, context, status) {
-    let stream = this.stream;
-    stream.drained = true;
-
-    // Remove copied chunk.
-    let multiplexInputStream = nsIMultiplexInputStream(stream);
-    multiplexInputStream.removeStream(0);
-
-    // If there was an error report.
-    if (!components.isSuccessCode(status))
-      emit(stream, "error", status);
-
-    // If there more chunks in queue then flush them.
-    else if (multiplexInputStream.count)
-      stream.flush();
-
-    // If stream is still writable notify that queue has drained.
-    else if (stream.writable)
-      emit(stream, "drain");
-
-    // If stream is no longer writable close it.
-    else {
-      nsIAsyncStreamCopier(stream).cancel(Cr.NS_OK);
-      nsIMultiplexInputStream(stream).close();
-      nsIAsyncOutputStream(stream).close();
-      nsIAsyncOutputStream(stream).flush();
-    }
-  }
-});
-
-const OutputStreamCallback = Class({
-  initialize: function(stream) {
-    this.stream = stream;
-  },
-  // Method is part of `nsIOutputStreamCallback` interface that
-  // is invoked by `nsIAsyncOutputStream.asyncWait`. It is registered
-  // with `WAIT_CLOSURE_ONLY` flag that overrides the default behavior,
-  // causing the `onOutputStreamReady` notification to be suppressed until
-  // the stream becomes closed.
-  onOutputStreamReady: function(nsIAsyncOutputStream) {
-    emit(this.stream, "finish");
-  }
-});
-
-const OutputStream = Class({
-  extends: Stream,
-  writable: false,
-  drained: true,
-  get bufferSize() {
-    let multiplexInputStream = nsIMultiplexInputStream(this);
-    return multiplexInputStream && multiplexInputStream.available();
-  },
-  initialize: function initialize(options) {
-    let { asyncOutputStream, output } = options;
-    this.writable = true;
-
-    // Ensure that `nsIAsyncOutputStream` was provided.
-    asyncOutputStream.QueryInterface(Ci.nsIAsyncOutputStream);
-
-    // Create a `nsIMultiplexInputStream` and `nsIAsyncStreamCopier`. Former
-    // is used to queue written data chunks that `asyncStreamCopier` will
-    // asynchronously drain into `asyncOutputStream`.
-    let multiplexInputStream = MultiplexInputStream();
-    let asyncStreamCopier = AsyncStreamCopier(multiplexInputStream,
-                                              output || asyncOutputStream,
-                                              eventTarget,
-                                              // nsIMultiplexInputStream
-                                              // implemnts .readSegments()
-                                              true,
-                                              // nsIOutputStream may or
-                                              // may not implemnet
-                                              // .writeSegments().
-                                              false,
-                                              // Use default buffer size.
-                                              null,
-                                              // Should not close an input.
-                                              false,
-                                              // Should not close an output.
-                                              false);
-
-    // Create `requestObserver` implementing `nsIRequestObserver` interface
-    // in the constructor that's gonna be reused across several flushes.
-    let requestObserver = RequestObserver(this);
-
-
-    // Create observer that implements `nsIOutputStreamCallback` and register
-    // using `WAIT_CLOSURE_ONLY` flag. That way it will be notfied once
-    // `nsIAsyncOutputStream` is closed.
-    asyncOutputStream.asyncWait(OutputStreamCallback(this),
-                                asyncOutputStream.WAIT_CLOSURE_ONLY,
-                                0,
-                                threadManager.currentThread);
-
-    nsIRequestObserver(this, requestObserver);
-    nsIAsyncOutputStream(this, asyncOutputStream);
-    nsIMultiplexInputStream(this, multiplexInputStream);
-    nsIAsyncStreamCopier(this, asyncStreamCopier);
-
-    this.asyncOutputStream = asyncOutputStream;
-    this.multiplexInputStream = multiplexInputStream;
-    this.asyncStreamCopier = asyncStreamCopier;
-  },
-  write: function write(content, encoding, callback) {
-    if (isFunction(encoding)) {
-      callback = encoding;
-      encoding = callback;
-    }
-
-    // If stream is not writable we throw an error.
-    if (!this.writable) throw Error("stream is not writable");
-
-    let chunk = null;
-
-    // If content is not a buffer then we create one out of it.
-    if (Buffer.isBuffer(content)) {
-      chunk = new ArrayBufferInputStream();
-      chunk.setData(content.buffer, 0, content.length);
-    }
-    else {
-      chunk = new StringInputStream();
-      chunk.setData(content, content.length);
-    }
-
-    if (callback)
-      this.once("drain", callback);
-
-    // Queue up chunk to be copied to output sync.
-    nsIMultiplexInputStream(this).appendStream(chunk);
-    this.flush();
-
-    return this.drained;
-  },
-  flush: function() {
-    if (this.drained) {
-      this.drained = false;
-      nsIAsyncStreamCopier(this).asyncCopy(nsIRequestObserver(this), null);
-    }
-  },
-  end: function end(content, encoding, callback) {
-    if (isFunction(content)) {
-      callback = content
-      content = callback
-    }
-    if (isFunction(encoding)) {
-      callback = encoding
-      encoding = callback
-    }
-
-    // Setting a listener to "finish" event if passed.
-    if (isFunction(callback))
-      this.once("finish", callback);
-
-
-    if (content)
-      this.write(content, encoding);
-    this.writable = false;
-
-    // Close `asyncOutputStream` only if output has drained. If it's
-    // not drained than `asyncStreamCopier` is busy writing, so let
-    // it finish. Note that since `this.writable` is false copier will
-    // close `asyncOutputStream` once output drains.
-    if (this.drained)
-      nsIAsyncOutputStream(this).close();
-  },
-  destroy: function destroy() {
-    nsIAsyncOutputStream(this).close();
-    nsIAsyncOutputStream(this);
-    nsIMultiplexInputStream(this);
-    nsIAsyncStreamCopier(this);
-    nsIRequestObserver(this);
-  }
-});
-exports.OutputStream = OutputStream;
-
-const DuplexStream = Class({
-  extends: Stream,
-  implements: [InputStream, OutputStream],
-  allowHalfOpen: true,
-  initialize: function initialize(options) {
-    options = options || {};
-    let { readable, writable, allowHalfOpen } = options;
-
-    InputStream.prototype.initialize.call(this, options);
-    OutputStream.prototype.initialize.call(this, options);
-
-    if (readable === false)
-      this.readable = false;
-
-    if (writable === false)
-      this.writable = false;
-
-    if (allowHalfOpen === false)
-      this.allowHalfOpen = false;
-
-    // If in a half open state and it's disabled enforce end.
-    this.once("end", () => {
-      if (!this.allowHalfOpen && (!this.readable || !this.writable))
-        this.end();
-    });
-  },
-  destroy: function destroy(error) {
-    InputStream.prototype.destroy.call(this);
-    OutputStream.prototype.destroy.call(this);
-  }
-});
-exports.DuplexStream = DuplexStream;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/io/text-streams.js
+++ /dev/null
@@ -1,235 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-const { Cc, Ci, Cu, components } = require("chrome");
-const { ensure } = require("../system/unload");
-const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
-
-// NetUtil.asyncCopy() uses this buffer length, and since we call it, for best
-// performance we use it, too.
-const BUFFER_BYTE_LEN = 0x8000;
-const PR_UINT32_MAX = 0xffffffff;
-const DEFAULT_CHARSET = "UTF-8";
-
-
-/**
- * An input stream that reads text from a backing stream using a given text
- * encoding.
- *
- * @param inputStream
- *        The stream is backed by this nsIInputStream.  It must already be
- *        opened.
- * @param charset
- *        Text in inputStream is expected to be in this character encoding.  If
- *        not given, "UTF-8" is assumed.  See nsICharsetConverterManager.idl for
- *        documentation on how to determine other valid values for this.
- */
-function TextReader(inputStream, charset) {
-  charset = checkCharset(charset);
-
-  let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].
-               createInstance(Ci.nsIConverterInputStream);
-  stream.init(inputStream, charset, BUFFER_BYTE_LEN,
-              Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
-  let manager = new StreamManager(this, stream);
-
-  /**
-   * Reads a string from the stream.  If the stream is closed, an exception is
-   * thrown.
-   *
-   * @param  numChars
-   *         The number of characters to read.  If not given, the remainder of
-   *         the stream is read.
-   * @return The string read.  If the stream is already at EOS, returns the
-   *         empty string.
-   */
-  this.read = function TextReader_read(numChars) {
-    manager.ensureOpened();
-
-    let readAll = false;
-    if (typeof(numChars) === "number")
-      numChars = Math.max(numChars, 0);
-    else
-      readAll = true;
-
-    let str = "";
-    let totalRead = 0;
-    let chunkRead = 1;
-
-    // Read in numChars or until EOS, whichever comes first.  Note that the
-    // units here are characters, not bytes.
-    while (true) {
-      let chunk = {};
-      let toRead = readAll ?
-                   PR_UINT32_MAX :
-                   Math.min(numChars - totalRead, PR_UINT32_MAX);
-      if (toRead <= 0 || chunkRead <= 0)
-        break;
-
-      // The converter stream reads in at most BUFFER_BYTE_LEN bytes in a call
-      // to readString, enough to fill its byte buffer.  chunkRead will be the
-      // number of characters encoded by the bytes in that buffer.
-      chunkRead = stream.readString(toRead, chunk);
-      str += chunk.value;
-      totalRead += chunkRead;
-    }
-
-    return str;
-  };
-}
-exports.TextReader = TextReader;
-
-/**
- * A buffered output stream that writes text to a backing stream using a given
- * text encoding.
- *
- * @param outputStream
- *        The stream is backed by this nsIOutputStream.  It must already be
- *        opened.
- * @param charset
- *        Text will be written to outputStream using this character encoding.
- *        If not given, "UTF-8" is assumed.  See nsICharsetConverterManager.idl
- *        for documentation on how to determine other valid values for this.
- */
-function TextWriter(outputStream, charset) {
-  charset = checkCharset(charset);
-
-  let stream = outputStream;
-
-  // Buffer outputStream if it's not already.
-  let ioUtils = Cc["@mozilla.org/io-util;1"].getService(Ci.nsIIOUtil);
-  if (!ioUtils.outputStreamIsBuffered(outputStream)) {
-    stream = Cc["@mozilla.org/network/buffered-output-stream;1"].
-             createInstance(Ci.nsIBufferedOutputStream);
-    stream.init(outputStream, BUFFER_BYTE_LEN);
-  }
-
-  // I'd like to use nsIConverterOutputStream.  But NetUtil.asyncCopy(), which
-  // we use below in writeAsync(), naturally expects its sink to be an instance
-  // of nsIOutputStream, which nsIConverterOutputStream's only implementation is
-  // not.  So we use uconv and manually convert all strings before writing to
-  // outputStream.
-  let uconv = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
-              createInstance(Ci.nsIScriptableUnicodeConverter);
-  uconv.charset = charset;
-
-  let manager = new StreamManager(this, stream);
-
-  /**
-   * Flushes the backing stream's buffer.
-   */
-  this.flush = function TextWriter_flush() {
-    manager.ensureOpened();
-    stream.flush();
-  };
-
-  /**
-   * Writes a string to the stream.  If the stream is closed, an exception is
-   * thrown.
-   *
-   * @param str
-   *        The string to write.
-   */
-  this.write = function TextWriter_write(str) {
-    manager.ensureOpened();
-    let istream = uconv.convertToInputStream(str);
-    let len = istream.available();
-    while (len > 0) {
-      stream.writeFrom(istream, len);
-      len = istream.available();
-    }
-    istream.close();
-  };
-
-  /**
-   * Writes a string on a background thread.  After the write completes, the
-   * backing stream's buffer is flushed, and both the stream and the backing
-   * stream are closed, also on the background thread.  If the stream is already
-   * closed, an exception is thrown immediately.
-   *
-   * @param str
-   *        The string to write.
-   * @param callback
-   *        An optional function.  If given, it's called as callback(error) when
-   *        the write completes.  error is an Error object or undefined if there
-   *        was no error.  Inside callback, |this| is the stream object.
-   */
-  this.writeAsync = function TextWriter_writeAsync(str, callback) {
-    manager.ensureOpened();
-    let istream = uconv.convertToInputStream(str);
-    NetUtil.asyncCopy(istream, stream, (result) => {
-        let err = components.isSuccessCode(result) ? undefined :
-        new Error("An error occured while writing to the stream: " + result);
-      if (err)
-        console.error(err);
-
-      // asyncCopy() closes its output (and input) stream.
-      manager.opened = false;
-
-      if (typeof(callback) === "function") {
-        try {
-          callback.call(this, err);
-        }
-        catch (exc) {
-          console.exception(exc);
-        }
-      }
-    });
-  };
-}
-exports.TextWriter = TextWriter;
-
-// This manages the lifetime of stream, a TextReader or TextWriter.  It defines
-// closed and close() on stream and registers an unload listener that closes
-// rawStream if it's still opened.  It also provides ensureOpened(), which
-// throws an exception if the stream is closed.
-function StreamManager(stream, rawStream) {
-  this.rawStream = rawStream;
-  this.opened = true;
-
-  /**
-   * True iff the stream is closed.
-   */
-  stream.__defineGetter__("closed", () => !this.opened);
-
-  /**
-   * Closes both the stream and its backing stream.  If the stream is already
-   * closed, an exception is thrown.  For TextWriters, this first flushes the
-   * backing stream's buffer.
-   */
-  stream.close = () => {
-    this.ensureOpened();
-    this.unload();
-  };
-
-  ensure(this);
-}
-
-StreamManager.prototype = {
-  ensureOpened: function StreamManager_ensureOpened() {
-    if (!this.opened)
-      throw new Error("The stream is closed and cannot be used.");
-  },
-  unload: function StreamManager_unload() {
-    // TextWriter.writeAsync() causes rawStream to close and therefore sets
-    // opened to false, so check that we're still opened.
-    if (this.opened) {
-      // Calling close() on both an nsIUnicharInputStream and
-      // nsIBufferedOutputStream closes their backing streams.  It also forces
-      // nsIOutputStreams to flush first.
-      this.rawStream.close();
-      this.opened = false;
-    }
-  }
-};
-
-function checkCharset(charset) {
-  return typeof(charset) === "string" ? charset : DEFAULT_CHARSET;
-}
--- a/addon-sdk/source/test/fixtures/native-overrides-test/index.js
+++ b/addon-sdk/source/test/fixtures/native-overrides-test/index.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 'use strict';
 
 var foo = require("foo");
 var coolTabs = require("cool-tabs");
 
 exports.foo = foo.fs;
 exports.bar = foo.bar;
-exports.fs = require("sdk/io/fs");
+exports.fs = require("sdk/io/file");
 exports.extra = require("fs-extra").extra;
 exports.overload = require("overload");
 exports.overloadLib = require("overload/lib/foo.js");
 exports.internal = require("internal").internal;
 exports.Tabs = require("sdk/tabs").Tabs;
 exports.CoolTabs = coolTabs.Tabs;
 exports.CoolTabsLib = coolTabs.TabsLib;
 exports.ignore = require("./lib/ignore").foo;
--- a/addon-sdk/source/test/fixtures/native-overrides-test/package.json
+++ b/addon-sdk/source/test/fixtures/native-overrides-test/package.json
@@ -3,16 +3,16 @@
   "main": "index.js",
   "dependencies": {
     "cool-tabs": "*",
     "foo": "*",
     "fs-extra": "*"
   },
   "jetpack": {
     "overrides": {
-      "fs": "sdk/io/fs",
+      "fs": "sdk/io/file",
       "overload": "foo",
       "internal": "./lib/internal",
       "sdk/tabs": "./lib/tabs",
       "../ignore": "foo"
     }
   }
 }
--- a/addon-sdk/source/test/test-native-loader.js
+++ b/addon-sdk/source/test/test-native-loader.js
@@ -106,17 +106,17 @@ for (let variant of variants) {
   /*
   // TODO not working in current env
   exports[`test bundle (${variant.description`] = function (assert, done) {
     loadAddon('/native-addons/native-addon-test/')
   };
   */
 
   exports[`test native Loader overrides (${variant.description})`] = function*(assert) {
-    const expectedKeys = Object.keys(require("sdk/io/fs")).join(", ");
+    const expectedKeys = Object.keys(require("sdk/io/file")).join(", ");
     const manifest = yield getJSON('/fixtures/native-overrides-test/package.json');
     const rootURI = variant.getRootURI('native-overrides-test');
 
     let loader = Loader({
       paths: makePaths(rootURI),
       rootURI: rootURI,
       manifest: manifest,
       metadata: manifest,
@@ -125,20 +125,20 @@ for (let variant of variants) {
 
     let program = main(loader);
     let fooKeys = Object.keys(program.foo).join(", ");
     let barKeys = Object.keys(program.foo).join(", ");
     let fsKeys = Object.keys(program.fs).join(", ");
     let overloadKeys = Object.keys(program.overload.fs).join(", ");
     let overloadLibKeys = Object.keys(program.overloadLib.fs).join(", ");
 
-    assert.equal(fooKeys, expectedKeys, "foo exports sdk/io/fs");
-    assert.equal(barKeys, expectedKeys, "bar exports sdk/io/fs");
-    assert.equal(fsKeys, expectedKeys, "sdk/io/fs exports sdk/io/fs");
-    assert.equal(overloadKeys, expectedKeys, "overload exports foo which exports sdk/io/fs");
+    assert.equal(fooKeys, expectedKeys, "foo exports sdk/io/file");
+    assert.equal(barKeys, expectedKeys, "bar exports sdk/io/file");
+    assert.equal(fsKeys, expectedKeys, "sdk/io/file exports sdk/io/file");
+    assert.equal(overloadKeys, expectedKeys, "overload exports foo which exports sdk/io/file");
     assert.equal(overloadLibKeys, expectedKeys, "overload/lib/foo exports foo/lib/foo");
     assert.equal(program.internal, "test", "internal exports ./lib/internal");
     assert.equal(program.extra, true, "fs-extra was exported properly");
 
     assert.equal(program.Tabs, "no tabs exist", "sdk/tabs exports ./lib/tabs from the add-on");
     assert.equal(program.CoolTabs, "no tabs exist", "sdk/tabs exports ./lib/tabs from the node_modules");
     assert.equal(program.CoolTabsLib, "a cool tabs implementation", "./lib/tabs true relative path from the node_modules");