'use strict';

var noop = require('es5-ext/lib/Function/noop')

  , deferred, promise, callback, pass, then, resolve, throwError, end;

callback = function (callback, value) {
	if (this.done) {
		return;
	}
	this.done = true;
	if (callback) {
		try {
			value = callback(value);
		} catch (e) {
			value = e;
		}
	}
	this.resolve(value);
};

pass = function (callbacks) {
	this.then.apply(this, callbacks);
};

then = function (win, fail) {
	var d = deferred()
	  , callbacks = [callback.bind(d, win), callback.bind(d, fail)];

	if (this.pending) {
		this.pending.push(callbacks);
	} else {
		pass.call(this.value, callbacks);
	}
	return d.promise;
};

resolve = function (value) {
	if (this.value) {
		throw new Error("Promise is already resolved");
	}

	var pending = this.pending;
	this.value = promise(value);
	delete this.pending;
	clearTimeout(this.timeout);

	pending.forEach(pass.bind(this.value));
	if (this.end) {
		this.value.end(this.end);
	}
};

end = function (handler) {
	if (this.pending) {
		this.end = handler || true;
	} else {
		this.value.end(handler);
	}
};

module.exports = deferred = function () {
	var o = { pending: [] }
	  , promise = then.bind(o);

	o.timeout = setTimeout(noop, Infinity);

	promise.then = promise;
	promise.end = end.bind(o);
	return {
		resolve: resolve.bind(o),
		promise: promise
	};
};

promise = require('./promise');

@@ -114,20 +114,8 @@
 lve,
- throwError,
  end
@@ -932,24 +932,46 @@
 is.end);%0A%09%7D%0A
+%09return this.promise;%0A
 %7D;%0A%0Aend = fu
@@ -1136,17 +1136,19 @@
 ar o = %7B
- 
+%0A%09%09
 pending:
@@ -1154,53 +1154,20 @@
 : %5B%5D
- %7D%0A%09  , promise = then.bind(o);%0A%0A%09o.
+,%0A%09%09
 timeout
- =
+:
  set
@@ -1193,44 +1193,60 @@
 ity)
+%0A%09%7D
 ;%0A%0A%09
+((o.
 promise
-.then = promise;%0A%09
+ = then.bind(o)).then = o.
 promise
+)
 .end
@@ -1261,16 +1261,17 @@
 ind(o);%0A
+%0A
 %09return 
@@ -1311,16 +1311,18 @@
 romise: 
+o.
 promise%0A

Resolve returns promise