function CrossStorageClient(url, opts) {
    opts = opts || {};

    this._id        = CrossStorageClient._generateUUID();
    this._promise   = opts.promise || Promise;
    this._frameId   = opts.frameId || 'CrossStorageClient-' + this._id;
    this._origin    = CrossStorageClient._getOrigin(url);
    this._requests  = {};
    this._connected = false;
    this._closed    = false;
    this._count     = 0;
    this._timeout   = opts.timeout || 5000;
    this._listener  = null;

    this._installListener();

    var frame;
    if (opts.frameId) {
      frame = document.getElementById(opts.frameId);
    }

    // If using a passed iframe, poll the hub for a ready message
    if (frame) {
      this._poll();
    }

    // Create the frame if not found or specified
    frame = frame || this._createFrame(url);
    this._hub = frame.contentWindow;
  }
Constructs a new cross storage client given the url to a hub. By default,
an iframe is created within the document body that points to the url. It
also accepts an options object, which may include a timeout, frameId, and
promise. The timeout, in milliseconds, is applied to each request and
defaults to 5000ms. The options object may also include a frameId,
identifying an existing frame on which to install its listeners. If the
promise key is supplied the constructor for a Promise, that Promise library
will be used instead of the default window.Promise.

@example
var storage = new CrossStorageClient('https://store.example.com/hub.html');

@example
var storage = new CrossStorageClient('https://store.example.com/hub.html', {
  timeout: 5000,
  frameId: 'storageFrame'
});

@constructor

@param {string} url    The url to a cross storage hub
@param {object} [opts] An optional object containing additional options,
                       including timeout, frameId, and promise

@property {string}   _id        A UUID v4 id
@property {function} _promise   The Promise object to use
@property {string}   _frameId   The id of the iFrame pointing to the hub url
@property {string}   _origin    The hub's origin
@property {object}   _requests  Mapping of request ids to callbacks
@property {bool}     _connected Whether or not it has connected
@property {bool}     _closed    Whether or not the client has closed
@property {int}      _count     Number of requests sent
@property {function} _listener  The listener added to the window
@property {Window}   _hub       The hub window