polyfillPromise(P) {
		if (!utils.isFunction(P.method)) {
			// Based on https://github.com/petkaantonov/bluebird/blob/master/src/method.js#L8
			P.method = function (fn) {
				return function () {
					try {
						const val = fn.apply(this, arguments);
						return P.resolve(val);
					} catch (err) {
						return P.reject(err);
					}
				};
			};
		}

		if (!utils.isFunction(P.delay)) {
			// Based on https://github.com/petkaantonov/bluebird/blob/master/src/timers.js#L15
			P.delay = function (ms) {
				return new P(resolve => setTimeout(resolve, +ms));
			};
			P.prototype.delay = function (ms) {
				return this.then(res => P.delay(ms).then(() => res));
				//return this.then(res => new P(resolve => setTimeout(() => resolve(res), +ms)));
			};
		}

		if (!utils.isFunction(P.prototype.timeout)) {
			P.TimeoutError = TimeoutError;

			P.prototype.timeout = function (ms, message) {
				let timer;
				const timeout = new P((resolve, reject) => {
					timer = setTimeout(() => reject(new P.TimeoutError(message)), +ms);
				});

				return P.race([timeout, this])
					.then(value => {
						clearTimeout(timer);
						return value;
					})
					.catch(err => {
						clearTimeout(timer);
						throw err;
					});
			};
		}

		if (!utils.isFunction(P.mapSeries)) {
			P.mapSeries = function (arr, fn) {
				const promFn = Promise.method(fn);
				const res = [];

				return arr
					.reduce((p, item, i) => {
						return p.then(r => {
							res[i] = r;
							return promFn(item, i);
						});
					}, P.resolve())
					.then(r => {
						res[arr.length] = r;
						return res.slice(1);
					});
			};
		}
	}
Polyfill a Promise library with missing Bluebird features.


@param {PromiseClass} P