UA: allow callback-based mediaHandlerFactory to be used

This is done by promisifying getDescription/setDescription of the MediaHandlers
produced by the factory.

For reference, here are the commits where the API changed:
  setDescription: 52f88f9db87aad71a4a83282dde8296dcb001b10
  getDescription: 1368a6976d4c6c88d9fa2ee665bdb6f598dfefc6

The behavior can be verified using the following code:

var ua = new SIP.UA({
  mediaHandlerFactory: function makeCallbackHandler () {
    var MediaHandler = SIP.WebRTC.MediaHandler;
    var handler = MediaHandler.defaultFactory.apply(this, arguments);

    handler.getDescription = function getDescription (onSuccess, onFailure, mediaHint) {
      console.trace();
      MediaHandler.prototype.getDescription.call(handler, mediaHint)
        .then(onSuccess, onFailure);
    };

    handler.setDescription = function setDescription (sdp, onSuccess, onFailure) {
      console.trace();
      MediaHandler.prototype.setDescription.call(handler, sdp)
        .then(onSuccess, onFailure);
    };

    return handler;
  }
});
var session = ua.invite('welcome@onsip.com', new Audio());
dedupe Promise creation into Utils.promisify

promisify combines most of the former behavior of addPromise and callbacksLast
from commit 06db90a1624282849aa18fdd76f1f6f729fde9e9
Add an ice checking state timeout
WebRTC.MediaStreamManager.render: work if passed single stream

addresses #131
Media Handler: renderHint local/remote is an (Array of) HTMLMediaElement

MediaStreamManager.render renders each MediaStream to the corresponding
HTMLMediaElement in the array, wrapping around if needed.

This removes one layer of nesting from the invite/accept mediaHint.

Note that <video>s no longer get muted if an <audio> is provided alongside.

Usage (compare with 4096365):

  var session = new SIP.UA().invite('welcome@onsip.com', {
    media: {
      render: {
        remote: [
          document.createElement('audio'), // included to demo array support
          document.createElement('video')
        ],
        local: document.createElement('video')
      }
    }
  });
Utils.desugarSessionOptions: renderHint local/remote is an HTMLMediaElement