'use strict';

var assign             = require('es5-ext/object/assign-multiple')
  , d                  = require('d/d')
  , autoBind           = require('d/auto-bind')
  , lazy               = require('d/lazy')
  , toStringTagSymbol  = require('es6-symbol').toStringTag
  , ee                 = require('event-emitter/lib/core')
  , is                 = require('./is-observable-value')
  , isObservableSymbol = require('./symbol-is-observable')

  , defineProperty = Object.defineProperty
  , Observable;

module.exports = Observable = function (value) {
	if (!(this instanceof Observable)) return new Observable(value);
	if (is(value)) {
		defineProperty(this, '__link__', d(value));
		value.on('change', this._mutableListener);
		value = value.value;
	}
	defineProperty(this, '__value__', d('w', value));
};
Object.defineProperties(ee(Observable.prototype), assign({
	value: d.gs(function () { return this.__value__; }, function (nu) {
		var old = this.__value__, isOldObservable = this.hasOwnProperty('__link__');
		if (isOldObservable) {
			if (nu === this.__link__) return;
			this.__link__.off('change', this._mutableListener);
		}
		if (is(nu)) {
			if (isOldObservable) this.__link__ = nu;
			else defineProperty(this, '__link__', d(nu));
			nu.on('change', this._mutableListener);
			this.__value__ = nu = nu.value;
		} else {
			if (isOldObservable) delete this.__link__;
			this.__value__ = nu;
		}
		if (nu !== old) this._emit_(nu, old);
	}),
	_emit_: d(function (nu, old) {
		if (!this.__deferred__) {
			this.emit('change', { type: 'change', newValue: nu, oldValue: old });
			return;
		}
		if (this.__deferredEvent__) {
			if (this.__deferredEvent__.oldValue === nu) this.__deferredEvent__ = null;
			else this.__deferredEvent__.newValue = nu;
			return;
		}
		this.__deferredEvent__ = { newValue: nu, oldValue: old };
	}),
	toString: d(function () { return String(this.__value__); }),
	_deferred_: d.gs(function () { return this.__deferred__; }, function (value) {
		var event;
		this.__deferred__ = value;
		if (value) return;
		event = this.__deferredEvent__;
		if (!event) return;
		this.__deferredEvent__ = null;
		event.type = 'change';
		this.emit('change', event);
	})
}, autoBind({
	_mutableListener: d('', function (event) {
		this.__value__ = event.newValue;
		this.emit('change', event);
	})
}), lazy({
	__deferred__: d('w', 0),
	__deferredEvent__: d('w', null)
})));
defineProperty(Observable.prototype, toStringTagSymbol,
	d('c', 'ObservableValue'));
defineProperty(Observable.prototype, isObservableSymbol, d('', true));

@@ -1493,30 +1493,31 @@
 if (!this.__
-deferr
+postpon
 ed__) %7B%0A%09%09%09t
@@ -1605,38 +1605,39 @@
 %09%7D%0A%09%09if (this.__
-deferr
+postpon
 edEvent__) %7B%0A%09%09%09
@@ -1643,30 +1643,31 @@
 %09if (this.__
-deferr
+postpon
 edEvent__.ol
@@ -1681,29 +1681,36 @@
 === nu) 
+%7B%0A%09%09%09%09
 this.__
-deferr
+postpon
 edEvent_
@@ -1726,26 +1726,35 @@
 %0A%09%09%09
+%7D 
 else 
+%7B%0A%09%09%09%09
 this.__
-deferr
+postpon
 edEv
@@ -1774,16 +1774,21 @@
 e = nu;%0A
+%09%09%09%7D%0A
 %09%09%09retur
@@ -1795,38 +1795,39 @@
 n;%0A%09%09%7D%0A%09%09this.__
-deferr
+postpon
 edEvent__ = %7B ne
@@ -1924,22 +1924,23 @@
 ; %7D),%0A%09_
-deferr
+postpon
 ed_: d.g
@@ -1946,33 +1946,35 @@
 gs(function () %7B
- 
+%0A%09%09
 return this.__de
@@ -1975,20 +1975,22 @@
 s.__
-deferr
+postpon
 ed__;
- 
+%0A%09
 %7D, f
@@ -2029,22 +2029,23 @@
 %09this.__
-deferr
+postpon
 ed__ = v
@@ -2084,30 +2084,31 @@
 nt = this.__
-deferr
+postpon
 edEvent__;%0A%09
@@ -2137,22 +2137,23 @@
 %09this.__
-deferr
+postpon
 edEvent_
@@ -2362,22 +2362,23 @@
 zy(%7B%0A%09__
-deferr
+postpon
 ed__: d(
@@ -2393,14 +2393,15 @@
 %0A%09__
-deferr
+postpon
 edEv

Use 'postponed' instead of 'deferred'