var CleanJS = window.CleanJS = (function () {
	var augment = function (obj, membs) {
			var m;
			for (m in membs) {
				if (!obj.hasOwnProperty(m)) {
					obj[m] = membs[m];
				}
			}
			return obj;
		},
		override = function (obj, membs) {
			var m;
			for (m in membs) {
				obj[m] = membs[m];
			}
			return obj;
		},
		beget = function (o, membs) {
			var F = function () {}, self;
			F.prototype = o;
			self = new F();
			return membs? Prolific.augment(self, membs): self;
		},
		thisify = function (fn, argNum) {
			var argNum = argNum || 0;
			return function () {
				var args = Array.prototype.slice.call(arguments, 0);
				args.splice(argNum, 0, this);
				return fn.apply(this, args);
			};
		},
		dopple = function (obj) {
			return augment({}, obj);
		},
		extender = function (extension) {
			var extension = dopple(extension);
			return function (name, fn) {
				var self = this[name] = dopple(extension);
				fn.call(self, self);
				return this;
			};
		},
		modulizer = function () {
			return function (name, fn) {
				var self = fn();
				if (typeof self !== 'undefined') {
					this[name] = self;
				}
				return this;
			};
		},
		stdExt = {
			augment: thisify(augment),
			override: thisify(override),
			method: function (name, fn) {
				this[name] = fn;
				return this;
			}
		},
		namespace = function (specs) {
			var global = specs.global? override(dopple(stdExt), namespace(specs.global)): dopple(stdExt),
				self = {},
				s,
				spec;
			for (s in specs) {
				if (s !== 'global') {
					spec = specs[s];
					if (spec === 'modulizer') {
						self[s] = modulizer();
					} else if (spec === 'extender') {
						self[s] = extender(global);
					} else if (typeof spec === 'object') {
						augment(spec, specs.global);
						if (spec.hasOwnProperty('global')) {
							augment(spec.global, specs.global);
						}
						self[s] = spec.branch === true?
							augment(namespace(spec), global):
							extender(augment(namespace(spec), global));
					} else if (typeof spec === 'function') {
						self[s] = spec;
					}
				}
			}
			return augment(self, global);
		};
	
	augment(Object, {
		beget: Object.beget || beget,
		augment: Object.augment || augment,
		override: Object.override || override
	});
		

	return {
		namespace: namespace,
		beget: beget,
		augment: augment,
		override: override
	};
}());

var Prolific = window.Prolific = CleanJS.namespace({
	global: {
		module: 'modulizer',
		addClass: 'modulizer',
		ui: {
			branch: true,
			element: {
				event: 'modulizer'
			},
			addClass: 'modulizer'
		}
	},
	app: {
		feature: 'extender'
	}
});

