<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>bin/build.js</filename>
    </added>
    <added>
      <filename>bin/doc.js</filename>
    </added>
    <added>
      <filename>bin/lib/docscript.js</filename>
    </added>
    <added>
      <filename>bin/lib/packer.js</filename>
    </added>
    <added>
      <filename>bin/lib/template.html</filename>
    </added>
    <added>
      <filename>bin/lib/textile.js</filename>
    </added>
    <added>
      <filename>bin/lib/tparser.js</filename>
    </added>
    <added>
      <filename>bin/lib/utils.js</filename>
    </added>
    <added>
      <filename>bin/lib/zparse.js</filename>
    </added>
    <added>
      <filename>build/chain-0.2.js</filename>
    </added>
    <added>
      <filename>build/chain-0.2.pack.js</filename>
    </added>
    <added>
      <filename>demo/chain-self.html</filename>
    </added>
    <added>
      <filename>doc/browser/docs.js</filename>
    </added>
    <added>
      <filename>doc/static/index.html</filename>
    </added>
    <added>
      <filename>project.js</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,103 +1,239 @@
-/* This file is automatically generated */
+/**
+ * Chain.js
+ * jQuery Plugin for Data Binding
+ * 
+ * Copyright (c) 2008 Rizqi Ahmad
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the &quot;Software&quot;), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
 
-/*
-
-Copyright (c) 2008 Rizqi Ahmad
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the &quot;Software&quot;), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE. 
-
-*/
 
 /* core.js */
 (function($){
-	
+
+/**
+ * Chain Namespace
+ * 
+ * @alias jQuery.Chain
+ * @namespace
+ */ 	
 $.Chain = 
 {
-	version: '0.1.9a',
-	
+	/**
+	 * Version Number
+	 * 
+	 * @alias jQuery.Chain.version
+	 * @property {String}
+	 */ 
+	version: '0.1.9b',
+	
+	/**
+	 * Tag for use in @jQuery.Chain.parse@ (which is used in CustomUpdater).
+	 * It is can be altered.
+	 * 
+	 * @alias jQuery.Chain.tags
+	 * 
+	 * @property {Array}
+	 * 
+	 * @see jQuery.Chain.parse
+	 */ 
 	tag: ['{', '}'],
 	
+	/**
+	 * Namespace containing all defined services.
+	 * 
+	 * @namespace
+	 * 
+	 * @alias jQuery.Chain.services
+	 */ 
 	services: {},
 	
+	/**
+	 * Register a service to the service manager.
+	 * 
+	 * @alias jQuery.Chain.service
+	 * 
+	 * @param {String}	name	Service Name
+	 * @param {Object}	proto 	Service Object Prototype
+	 * 
+	 * @example Create a Custom Service
+	 * $.Chain.service('test', {
+	 * 		// Default command handler
+	 * 		handler: function(option)
+	 * 		{
+	 * 			// do something
+	 * 		},
+	 * 		// $(selector).test('what', somearg)
+	 * 		$what: function(somearg)
+	 * 		{
+	 * 			// do something
+	 * 		}
+	 * });
+	 * 
+	 * $('#element').test();
+	 * 
+	 * @see jQuery.Chain.extend
+	 */ 
 	service: function(name, proto)
 	{
 		this.services[name] = proto;
 		
+		// Creating jQuery fn module with the service
 		$.fn[name] = function(options)
 		{
-			if(!this.length) return this;
+			if(!this.length)
+				{return this;}
 			
+			// Create Chain instance
 			var instance = this.data('chain-'+name);
+			
+			// Extract arguments
 			var args = Array.prototype.slice.call(arguments, 1);
 			
+			// Create Instance if it doesn't already exist
 			if(!instance)
 			{
+			  // Return immediately if destroyed is called before Instance is created
+				if(options == 'destroy') 
+					{return this;}
+				// Create Instance
 				instance = $.extend({element: this}, $.Chain.services[name]);
 				this.data('chain-'+name, instance);
+				// Initialize if possible
 				if(instance.init)
-					instance.init();
+					{instance.init();}
 			}
 			
 			var result;
 			
+			// Check whether to execute a command
 			if(typeof options == 'string' &amp;&amp; instance['$'+options])
-				result = instance['$'+options].apply(instance, args);
+				{result = instance['$'+options].apply(instance, args);}
+			
+			// Otherwise try to execute default handler
 			else if(instance['handler'])
-				result = instance['handler'].apply(instance, [options].concat(args));
+				{result = instance['handler'].apply(instance, [options].concat(args));}
+			
+			// Otherwise do nothing
 			else
-				result = this;
+				{result = this;}
 			
+			// Remove instance on destroy
 			if(options == 'destroy')
-				this.removeData('chain-'+name);
+				{this.removeData('chain-'+name);}
 			
 			return result;
 		};
 	},
-	
+
+	/**
+	 * Extends service functionalities.
+	 * 
+	 * @alias jQuery.Chain.extend
+	 * 
+	 * @param {String}	name	Service Name
+	 * @param {Object}	proto 	Service Object Prototype
+	 * 
+	 * @see jQuery.Chain.service
+	 */ 
 	extend: function(name, proto)
 	{
 		if(this.services[name])
-			this.services[name] = $.extend(this.services[name], proto);
+			{this.services[name] = $.extend(this.services[name], proto);}
 	},
 	
+	/**
+	 * Check whether it is a jQuery Object
+	 * 
+	 * @alias jQuery.Chain.jobject
+	 * 
+	 * @param {Object} obj Object to be checked
+	 * 
+	 * @example Using @jobject@
+	 * $.Chain.jobject($()) // returns true
+	 * $.Chain.jobject(&quot;test&quot;) // returns false
+	 * 
+	 * @return {Boolean} True or False
+	 * 
+	 * @see jQuery.Chain.jindentic
+	 */ 
 	jobject: function(obj)
 	{
 		return obj &amp;&amp; obj.init == $.fn.init;
 	},
 	
+	/**
+	 * Check whether two jQuery Collection identic
+	 * 
+	 * @alias jQuery.Chain.jidentic
+	 * 
+	 * @param {Object}	j1	jQuery Object
+	 * @param {Object}	j2	jQuery Object
+	 * 
+	 * @example Using @jidentic@
+	 * a = $('div');
+	 * b = $('div');
+	 * c = $('div.test');
+	 * 
+	 * (a == b) //returns false
+	 * 
+	 * $.Chain.jidentic(a, b) // returns true
+	 * $.Chain.jidentic(a, c) // returns false
+	 * 
+	 * @return {Boolean} True or False
+	 * 
+	 * @see jQuery.Chain.jobject
+	 */ 
 	jidentic: function(j1, j2)
 	{
 		if(!j1 || !j2 || j1.length != j2.length)
-			return false;
+			{return false;}
 		
-		a1 = j1.get();
-		a2 = j2.get();
+		var a1 = j1.get();
+		var a2 = j2.get();
 		
 		for(var i=0; i&lt;a1.length; i++)
+		{
 			if(a1[i] != a2[i])
-				return false;
+				{return false;}
+		}
 		
 		return true;
 		
 	},
 	
-	parse: (function()
+	/**
+	 * Parse string contained @{something}@ to a Function
+	 * that when executed replace those with the data it refers to.
+	 * You can change the @{}@ tag by modifying @jQuery.Chain.tag@
+	 * 
+	 * @param {String} text String
+	 * 
+	 * @example Using @
+	 * var fn = $.Chain.parse(&quot;My name is {first} {last}&quot;);
+	 * fn({first:'Rizqi', last:'Ahmad'}) // returns &quot;My name is Rizqi Ahmad&quot;
+	 * 
+	 * @return {Function} template string.
+	 * 
+	 * @see jQuery.Chain.tag
+	 */ 
+	parse: function()
 	{
 		var $this = {};
 		// Function Closure
@@ -141,41 +277,45 @@ $.Chain =
 				closer = opener + text.substring(opener).indexOf(tag[1]);
 		
 				// If opener tag exists, otherwise there are no tags anymore
-				if(opener != -1){
+				if(opener != -1)
+				{
 					// Handle escape. Tag can be escaped with '\\'.
 					// If tag is escaped. it will be handled as a normal text
 					// Otherwise it will be handled as a script
-					if(text[opener-1] == '\\'){
+					if(text[opener-1] == '\\')
+					{
 						closer2 = opener+tag[0].length + text.substring(opener+tag[0].length).indexOf(tag[0]);
 						if(closer2 != opener+tag[0].length-1 &amp;&amp; text[closer2-1] == '\\')
-							closer2 = closer2-1;
+							{closer2 = closer2-1;}
 						else if(closer2 == opener+tag[0].length-1)
-							closer2 = text.length;
+							{closer2 = text.length;}
 				
 						result.push($this.textPrint(text.substring(0, opener-1)));
 						result.push($this.textPrint(text.substring(opener, closer2)));
 					}
-					else{
+					else
+					{
 						closer2 = null;
 						if(closer == opener-1)
-							closer = text.length;
+							{closer = text.length;}
 				
 						result.push($this.textPrint(text.substring(0, opener)));
 						result.push($this.scriptPrint(text.substring(opener+tag[0].length, closer)));
 					}
 					
-					text = text.substring((closer2 == null) ? closer+tag[1].length : closer2);
+					text = text.substring((closer2 === null) ? closer+tag[1].length : closer2);
 				}
 				// If there are still text, it will be pushed to array
 				// So we won't stuck in an infinite loop
-				else if(text){
+				else if(text)
+				{
 					result.push($this.textPrint(text));
 					text = '';
 				}
 			}
 	
 			return result.join('\n');	
-		}
+		};
 	
 	
 		/*
@@ -184,7 +324,7 @@ $.Chain =
 		 */
 		return function($text)
 		{
-			var $fn;
+			var $fn = function(){};
 			try
 			{
 				eval('$fn = '+ $this.closure[0]+$this.parser($text)+$this.closure[1]);
@@ -192,34 +332,99 @@ $.Chain =
 			catch(e)
 			{
 				throw &quot;Parsing Error&quot;;
-				$fn = function(){};
 			}
 			
 			return $fn;
 		};
-	})()
+	}()
 };
 	
 })(jQuery);
 
-
 /* update.js */
+/**
+ * Chain Update Service
+ * 
+ * @alias update
+ * 
+ * @syntax $(selector).update(parameters);
+ */ 
+
 (function($){
 
+/**
+ * Chain Update Service Object - Providing methods of @update@.
+ * All method listed here can only be used internally
+ * using @jQuery.Chain.service@ or @jQuery.Chain.extend@
+ * 
+ * @namespace
+ * 
+ * @alias jQuery.Chain.services.update
+ * 
+ * @see jQuery.Chain.service
+ * @see jQuery.Chain.extend
+ */ 
+
 $.Chain.service('update', {
+	/**
+	 * Default Handler
+	 * 
+	 * @alias jQuery.Chain.services.update.handler
+	 * 
+	 * @see jQuery.Chain.service
+	 * @see jQuery.Chain.services.update.bind
+	 * @see jQuery.Chain.services.update.trigger
+	 */ 
 	handler: function(opt)
 	{
 		if(typeof opt == 'function')
-			return this.bind(opt);
+			{return this.bind(opt);}
 		else
-			return this.trigger(opt);
+			{return this.trigger(opt);}
 	},
 	
+	/**
+	 * If you pass a function to update, it will bind it to the update event.
+	 * just like jQuerys @click()@ or @mouseover()@.
+	 * 
+	 * @alias update(fn)
+	 * @alias jQuery.Chain.services.update.bind
+	 * 
+	 * @param {Function} fn Listener
+	 * 
+	 * @example
+	 * // assuming #person is already chained
+	 * $('#person').update(function{
+	 * 		alert($(this).item().name);
+	 * });
+	 * 
+	 * $('#person').item({name: 'Rizqi'})
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.services.update.handler
+	 */ 
 	bind: function(fn)
 	{
 		return this.element.bind('update', fn);
 	},
 	
+	/**
+	 * If no argument or &quot;hard&quot; is passed,
+	 * it will update the element and trigger the update event.
+	 * 
+	 * @alias update(opt)
+	 * @alias jQuery.Chain.services.update.trigger
+	 * 
+	 * @param {String} opt If 'hard', it will update each of items
+	 * 
+	 * @example
+	 * $('#person').update();
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.services.update.handler
+	 */ 
 	trigger: function(opt)
 	{
 		this.element.items('update');
@@ -228,7 +433,7 @@ $.Chain.service('update', {
 		this.element.triggerHandler('preupdate', this.element.item());
 		
 		if(opt == 'hard')
-			this.element.items(true).each(function(){$(this).update();});
+			{this.element.items(true).each(function(){$(this).update();});}
 		
 		this.element.triggerHandler('update', this.element.item());
 		
@@ -238,35 +443,78 @@ $.Chain.service('update', {
 	
 })(jQuery);
 
-
 /* chain.js */
+/**
+ * Chain Binding Service.
+ * Method to activate the chaining / element rendering service.
+ * 
+ * @alias chain
+ * 
+ * @syntax $(selector).chain(parameters);
+ */ 
+
 (function($){
 
+/**
+ * Chain Binding Service Object - Providing methods of @chain@.
+ * All method listed here can only be used internally
+ * using @jQuery.Chain.service@ or @jQuery.Chain.extend@
+ * 
+ * @namespace
+ * 
+ * @alias jQuery.Chain.services.chain
+ * 
+ * @see jQuery.Chain.service
+ * @see jQuery.Chain.extend
+ */ 
+
 $.Chain.service('chain', {
+	/**
+	 * Initializer. Executed once at the first time @chain@ invoked.
+	 * 
+	 * @alias jQuery.Chain.services.chain.init
+	 * 
+	 * @see jQuery.Chain.service
+	 */ 
 	init: function()
 	{
 		this.anchor = this.element;
 		this.template = this.anchor.html();
-		this.tplNumber = 0;
+		this.tplNumber = 0; // At Default it uses the first template.
 		this.builder = this.createBuilder();
 		this.plugins = {};
 		this.isActive = false;
 		this.destroyers = [];
 		
+		// Add class 'chain-element' as identifier
 		this.element.addClass('chain-element');
 	},
 	
+	/**
+	 * Default handler.
+	 * 
+	 * @alias jQuery.Chain.services.chain.handler
+	 * 
+	 * @param {Object} obj Object to be handled
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.service
+	 * @see jQuery.Chain.services.chain.handleUpdater
+	 * @see jQuery.Chain.services.chain.handleBuilder
+	 */ 
 	handler: function(obj)
 	{
+		// Backup items and item, all items will be stored in Buffer
 		this.element.items('backup');
 		this.element.item('backup');
 		
 		if(typeof obj == 'object')
-			this.build(obj);
-		else
-			if(typeof obj == 'function')
-				this.builder = this.createBuilder(obj);
+			{this.handleUpdater(obj);}
+		else if(typeof obj == 'function')
+			{this.handleBuilder(obj);}
 		
+		// Empty element, if @item@ it will filled again later
 		this.anchor.empty();
 		
 		this.isActive = true;
@@ -275,48 +523,130 @@ $.Chain.service('chain', {
 		return this.element;
 	},
 	
-	build: function(rules)
+	/**
+	 * Updater Handler.
+	 * If you pass an object to @chain@, it will treated as a updater object.
+	 * The updater is a hash of selector and value string:
+	 * like @chain({'my css selector': 'My Content String'})@
+	 * or @chain({'my css selector': {attributes}})@
+	 * 
+	 * @alias chain(updater)
+	 * @alias jQuery.Chain.services.chain.handleUpdater
+	 * 
+	 * @param {Object} rules Updater rules to be parsed
+	 * 
+	 * @example Usage
+	 * $(selector)
+	 * 		.chain({
+	 * 			// Items anchor, where the Item iteration should be placed
+	 * 			anchor: anchor,
+	 * 			// If true, the default updater is overridden
+	 * 			override: false, 
+	 * 			// Use custom builder
+	 * 			builder: function(){},
+	 * 			// Update the element self
+	 * 			self: &quot;This is my {data}&quot;,
+	 * 			// Use css selector to update child element
+	 * 			'.element.selector': &quot;Using String Updater&quot;,
+	 * 			// Use Function as updater
+	 * 			'.element.selector': function(data, el){},
+	 * 			// Updating Attributes
+	 * 			'.element.selector': {
+	 * 				attribute1: &quot;{attribute}&quot;,
+	 * 				className: &quot;{className}&quot;,
+	 * 				content: &quot;This is the {content}&quot;,
+	 * 				value: &quot;This is the {value}&quot;
+	 * 			}
+	 * 		});
+	 * 
+	 * @example Using Default Updater
+	 * $('&lt;div&gt;&lt;span class=&quot;name&quot;&gt;Name&lt;/span&gt;&lt;/div&gt;')
+	 * 		.item({name: 'Steve Jobs'})
+	 * 		.chain()
+	 * 		.appendTo(document.body);
+	 * 
+	 * @example Using Custom Updater
+	 * $('&lt;div&gt;&lt;div class=&quot;name&quot;&gt;&lt;span class=&quot;first&quot;&gt;First&lt;/span&gt; &lt;span class=&quot;last&quot;&gt;Last&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;')
+	 * 		.item({first:'Steve', last:'Jobs'})
+	 * 		.chain({
+	 * 			'.name .first': {
+	 * 				style: 'color: blue;',
+	 * 				content: 'First Name: {first}'
+	 * 			},
+	 * 			'.name .last': 'Family Name: {last}'
+	 * 		})
+	 * 		.appendTo(document.body);
+	 * 
+	 * @example Attach Builder Inside Updater
+	 * $('&lt;div&gt;&lt;div class=&quot;name&quot;&gt;Name&lt;/div&gt;&lt;div class=&quot;address&quot;&gt;Address&lt;/div&gt;&lt;/div&gt;')
+	 * 		.item({name:'Steve Jobs', address:'Cupertino'})
+	 * 		.chain({
+	 * 			builder: function(){
+	 * 				var data = this.item();
+	 * 				this.find('.name').click(function(){alert(data.name)});
+	 * 				this.find('.address').mouseout(function(){alert(data.address)});
+	 * 			},
+	 * 			'.name': '{name}',
+	 * 			'.address': '{address}'
+	 * 		})
+	 * 		.appendTo(document.body);
+	 */ 
+	handleUpdater: function(rules)
 	{
+		// Extract Builder
 		var builder = rules.builder;
 		delete rules.builder;
 		
+		// Extract Anchor
 		if(rules.anchor)
-			this.setAnchor(rules.anchor);
+			{this.setAnchor(rules.anchor);}
 		delete rules.anchor;
 		
+		// Extract Override
 		var override = rules.override;
 		delete rules.override;
 	
 		for(var i in rules)
 		{
+			// Parse String to Function
 			if(typeof rules[i] == 'string')
 			{
 				rules[i] = $.Chain.parse(rules[i]);
 			}
+			// Parse Attributes Object to Functions
 			else if(typeof rules[i] == 'object')
 			{
 				for(var j in rules[i])
 				{
 					if(typeof rules[i][j] == 'string')
-						rules[i][j] = $.Chain.parse(rules[i][j]);
+						{rules[i][j] = $.Chain.parse(rules[i][j]);}
 				}
 			}
 		}
 	
+		// Create Updater
 		var fn = function(event, data)
 		{
 			var el, val;
 			var self = $(this);
 			for(var i in rules)
 			{
-				el = $(i, self);
-			
+				// If self, update the element itself
+				if(i == 'self')
+					{el = self;}
+				// Otherwise find element inside self
+				else
+					{el = $(i, self);}
+				
+				// Executing
+				// If no attributes, put the result to html (value if input)
 				if (typeof rules[i] == 'function')
 				{
 					val = rules[i].apply(self, [data, el]);
 					if(typeof val == 'string')
-						el.not(':input').html(val).end().filter(':input').val(val);
+						{el.not(':input').html(val).end().filter(':input').val(val);}
 				}
+				// If attributes, then execute the function for each attr.
 				else if(typeof rules[i] == 'object')
 				{
 					for(var j in rules[i])
@@ -326,16 +656,18 @@ $.Chain.service('chain', {
 							val = rules[i][j].apply(self, [data, el]);
 							if(typeof val == 'string')
 							{
+								// Some special attributes
 								if(j == 'content')
-									el.html(val);
+									{el.html(val);}
 								else if(j == 'text')
-									el.text(val);
+									{el.text(val);}
 								else if(j == 'value')
-									el.val(val);
+									{el.val(val);}
 								else if(j == 'class' || j == 'className')
-									el.addClass(val);
+									{el.addClass(val);}
+								// Otherwise fill attribute as normal
 								else
-									el.attr(j, val);
+									{el.attr(j, val);}
 							}
 							
 						}
@@ -345,44 +677,122 @@ $.Chain.service('chain', {
 		};
 		
 		var defBuilder = this.defaultBuilder;
-	
+		
+		// Define Builder
 		this.builder = function(root)
 		{
 			if(builder)
-				builder.apply(this, [root]);
+				{builder.apply(this, [root]);}
 			
 			if(!override)
-				defBuilder.apply(this);
+				{defBuilder.apply(this);}
 			
+			// Here goes the updater
 			this.update(fn);
 			
+			// This prevent infinite recursion
+			// see: jQuery.Chain.services.item.build
 			return false;
 		};
 	},
 	
-	// Builder, not executable
+	/**
+	 * Builder Handler.
+	 * If you pass a function to @chain@, it will be handled 
+	 * as @{builder: function}@, enabling you to use the default
+	 * updater while customizing the events etc.
+	 * 
+	 * @alias chain(fn)
+	 * @alias jQuery.Chain.services.chain.handleBuilder
+	 * 
+	 * @param {Function} fn Builder Function
+	 * 
+	 * @example
+	 * $('&lt;div&gt;&lt;div class=&quot;name&quot;&gt;Name&lt;/div&gt;&lt;div class=&quot;address&quot;&gt;Address&lt;/div&gt;&lt;/div&gt;')
+	 * 		.item({name:'Steve Jobs', address:'Cupertino'})
+	 * 		.chain(function(){
+	 * 			this.bind('click', function(){
+	 * 				var data = this.item();
+	 * 				alert('name:'+data.name+', address:'+data.address);
+	 * 			});
+	 * 			
+	 * 			// if you return false, default builder wont be executed
+	 * 			// You don't have to return true;
+	 * 			return true;
+	 * 		})
+	 * 		.appendTo(document.body);
+	 * 
+	 * @see jQuery.Chain.services.chain.handleUpdater
+	 * @see jQuery.Chain.services.chain.createBuilder
+	 */ 
+	handleBuilder: function(fn)
+	{
+		this.builder = this.createBuilder(fn);
+	},
+	
+	
+	/**
+	 * Default Builder - Automatic Data filler
+	 * 
+	 * @alias jQuery.Chain.services.chain.defaultBuilder
+	 * 
+	 * @param {Function} 	builder 	Builder Function
+	 * @param {Object}		root		Root Element Object
+	 * 
+	 * @see jQuery.Chain.services.chain.createBuilder
+	 */ 
 	defaultBuilder: function(builder, root)
 	{
+		// Caution:
+		// @this@ is in this function @this.element@
+		
+		// if builder return false, res will be false
+		// Otherwise true
+		// Using this, the default updater can be disabled
 		var res = builder ? (builder.apply(this, [root]) !== false) : true;
 		
+		// Default Updater
 		if(res)
-			this.update(function(event, data){
+		{
+			this.bind('update', function(event, data){
 				var self = $(this);
+				// Iterate through data
+				// Find element with the same class as data property
+				// Insert data depending of elemen type
 				for(var i in data)
+				{	
 					if(typeof data[i] != 'object' &amp;&amp; typeof data[i] != 'function')
+					{
+						// This prevents selector to select inside nested chain-element
+						// Important to support recursion &amp; nested element
+						// NEED OPTIMIZATION
 						self.find('&gt; .'+i+', *:not(.chain-element) .'+i)
 							.each(function(){
 								var match = $(this);
 								if(match.filter(':input').length)
-									match.val(data[i]);
+									{match.val(data[i]);}
 								else if(match.filter('img').length)
-									match.attr('src', data[i]);
+									{match.attr('src', data[i]);}
 								else
-									match.html(data[i]);
+									{match.html(data[i]);}
 							});
+					}
+				}
 			});
+		}
 	},
 	
+	/**
+	 * Builder Generator (Wrapper).
+	 * 
+	 * @alias jQuery.Chain.services.chain.createBuilder
+	 * 
+	 * @param {Function} builder Builder
+	 * 
+	 * @return {Function} Wrapped Builder
+	 * 
+	 * @see jQuery.Chain.services.chain.defaultBuilder;
+	 */ 
 	createBuilder: function(builder)
 	{
 		var defBuilder = this.defaultBuilder;
@@ -392,22 +802,52 @@ $.Chain.service('chain', {
 		};
 	},
 	
+	/**
+	 * Set Anchor (Container for @items@ to be populated, default: @this.element@)
+	 * 
+	 * @alias jQuery.Chain.services.chain.setAnchor
+	 * 
+	 * @param {Object} anchor Anchor element
+	 * 
+	 * @see jQuery.Chain.services.chain.$anchor
+	 */ 
 	setAnchor: function(anchor)
 	{
 		this.anchor.html(this.template);
-		this.anchor = anchor == this.element ? anchor : this.element.find(anchor);
+		this.anchor = anchor == this.element ? anchor : this.element.find(anchor).eq(0);
 		this.template = this.anchor.html();
 		this.anchor.empty();
 	},
 	
-	$anchor: function(val)
+	/**
+	 * Set new Anchor and rerender if new anchor passed.
+	 * Otherwise return current anchor.
+	 * 
+	 * If you use @items()@ with @chain()@,
+	 * you can use @chain('anchor', selector)@ to move the element,
+	 * where the items will be generated.
+	 * 
+	 * @alias chain('anchor')
+	 * @alias jQuery.Chain.services.chain.$anchor
+	 * 
+	 * @param {Object} anchor Anchor element or selector
+	 * 
+	 * @return {Object} current element (if new Anchor passed), otherwise current anchor
+	 * 
+	 * @example
+	 * $('#persons').chain('anchor', '.wrapper');
+	 * 
+	 * // Define Anchor directly while building
+	 * $('#persons').items([...]).chain({anchor:'.wrapper', builder: ...});
+	 */ 
+	$anchor: function(anchor)
 	{
-		if(val)
+		if(anchor)
 		{
 			this.element.items('backup');
 			this.element.item('backup');
 			
-			this.setAnchor(val);
+			this.setAnchor(anchor);
 			this.element.update();
 			
 			return this.element;
@@ -418,27 +858,47 @@ $.Chain.service('chain', {
 		}
 	},
 	
+	/**
+	 * Getting/Switching Template.
+	 * 
+	 * @alias chain('template')
+	 * @alias jQuery.Chain.services.chain.$template
+	 * 
+	 * @param {Number, String} arg Argument
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @example
+	 * $(selector).chain('template') // Returns current Template (jQuery Object)
+	 * $(selector).chain('template', 'raw') // Returns raw HTML Templates (all)
+	 * $(selector).chain('template', nr) // Switch to template nr (read: Number)
+	 * $(selector).chain('template', '.tree-column') // Switch by selector
+	 */ 
 	$template: function(arg)
 	{
+		// Returns current Template (jQuery Object)
 		if(!arguments.length)
-			return $('&lt;div&gt;').html(this.template).children().eq(this.tplNumber);
+			{return $('&lt;div&gt;').html(this.template).children().eq(this.tplNumber);}
 		
+		// Returns raw HTML Template
 		if(arg == 'raw')
-			return this.template;
+			{return this.template;}
 		
+		// Switch template by Number
 		if(typeof arg == 'number')
 		{
 			this.tplNumber = arg;
 		}
+		// Switch template by selector
 		else
 		{
 			var tpl = $('&lt;div&gt;').html(this.template).children();
 			var node = tpl.filter(arg).eq(0);
 			
 			if(node.length)
-				this.tplNumber = tpl.index(node);
+				{this.tplNumber = tpl.index(node);}
 			else
-				return this.element;
+				{return this.element;} // If not found do nothing
 		}
 		
 		this.element.items('backup');
@@ -448,41 +908,85 @@ $.Chain.service('chain', {
 		return this.element;
 	},
 	
+	/**
+	 * Get/Change Builder.
+	 * If you don't pass any argument, it will return the created builder.
+	 * 
+	 * @alias chain('builder')
+	 * @alias jQuery.Chain.services.chain.$builder
+	 * 
+	 * @param {Function, Object} builder (Optional)
+	 * 
+	 * @return {Function, Object} returns builder function, or jQuery Object depends on arg
+	 * 
+	 * @example
+	 * $('#el').chain('builder') // returns builder function
+	 * $('#el').chain('builder', newBuilder) // Replace Builder
+	 */ 
 	$builder: function(builder)
 	{
 		if(builder)
-			return this.handler(builder);
+			{return this.handler(builder);}
 		else
-			return this.builder;
+			{return this.builder;}
 	},
 	
+	/**
+	 * Check status
+	 * 
+	 * @alias chain('active')
+	 * @alias jQuery.Chain.services.chain.$active
+	 * 
+	 * @return {Boolean} true if active
+	 */ 
 	$active: function()
 	{
 		return this.isActive;
 	},
 	
+	/**
+	 * Add/Remove Plugins that extend builder
+	 * 
+	 * @alias chain('plugin')
+	 * @alias jQuery.Chain.services.chain.$plugin
+	 * 
+	 * @param {String} 				name 	Plugin Name
+	 * @param {Function, Boolean} 	fn 		Plugin Function / False to remove
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$plugin: function(name, fn)
 	{
 		if(fn === null)
-			delete this.plugins[name];
+			{delete this.plugins[name];}
 		else if(typeof fn == 'function')
-			this.plugins[name] = fn;
+			{this.plugins[name] = fn;}
 		else if(name &amp;&amp; !fn)
-			return this.plugins[name];
+			{return this.plugins[name];}
 		else
-			return this.plugins;
+			{return this.plugins;}
 		
 		if(typeof fn == 'function')
+		{
 			this.element.items(true).each(function(){
 				var self = $(this);
 				fn.call(self, self.item('root'));
 			});
+		}
 		
 		this.element.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Clone Element unchained, with ID removed.
+	 * 
+	 * @alias chain('clone')
+	 * @alias jQuery.Chain.services.chain.$clone
+	 * 
+	 * @return {Object} jQuery Object containing cloned Element
+	 */ 
 	$clone: function()
 	{
 		var id = this.element.attr('id');
@@ -494,24 +998,38 @@ $.Chain.service('chain', {
 		return clone;
 	},
 	
+	/**
+	 * Destroy Chain, restore Element to previous condition.
+	 * 
+	 * @alias chain('destroy')
+	 * @alias jQuery.Chain.services.chain.$destroy
+	 * 
+	 * @param {Boolean} nofollow If true, it won't destroy nested chain elements
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$destroy: function(nofollow)
 	{
 		this.element.removeClass('chain-element');
 		
 		if(!nofollow)
 		{
+			// Backup to buffer
 			this.element.items('backup');
 			this.element.item('backup');
 			
+			// Destroy nested elements
 			this.element.find('.chain-element').each(function(){
 				$(this).chain('destroy', true);
 			});
 		}
 		
+		// Trigger destroy event
 		this.element.triggerHandler('destroy');
 	
 		this.isActive = false;
 	
+		// Restore HTML
 		this.anchor.html(this.template);
 		
 		return this.element;
@@ -520,34 +1038,533 @@ $.Chain.service('chain', {
 	
 })(jQuery);
 
+/* item.js */
+/**
+ * Chain Item Service.
+ * Method to bind item to object.
+ * 
+ * @alias item
+ * 
+ * @syntax $(selector).item(parameters);
+ */ 
+
+(function($){
+
+/**
+ * Chain Item Manager - Providing methods of @item@.
+ * All method listed here can only be used internally
+ * using @jQuery.Chain.service@ or @jQuery.Chain.extend@
+ * 
+ * @namespace
+ * 
+ * @alias jQuery.Chain.services.item
+ * 
+ * @see jQuery.Chain.service
+ * @see jQuery.Chain.extend
+ */ 
+
+$.Chain.service('item', {
+	/**
+	 * Initializer. Executed once at the first time @item@ invoked.
+	 * 
+	 * @alias jQuery.Chain.services.item.init
+	 * 
+	 * @see jQuery.Chain.service
+	 */ 
+	init: function()
+	{
+		this.isActive = false;
+		this.isBuilt = false;
+		this.root = this.element;
+		this.data = false;
+		this.datafn = this.dataHandler;
+	},
+	
+	/**
+	 * Default handler.
+	 * 
+	 * @alias jQuery.Chain.services.item.handler
+	 * 
+	 * @param {Object} obj Object to be handled
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.service
+	 * @see jQuery.Chain.services.item.handleObject
+	 * @see jQuery.Chain.services.item.handleFunction
+	 * @see jQuery.Chain.services.item.handleDefault
+	 */ 
+	handler: function(obj)
+	{
+		if(typeof obj == 'object')
+			{return this.handleObject(obj);}
+		else if(typeof obj == 'function')
+			{return this.handleFunction(obj);}
+		else
+			{return this.handleDefault();}
+	},
+	
+	/**
+	 * Edit/Bind Item.
+	 * If no Object defined, it will bind the object to the Item, otherwise
+	 * it will alter the object using the provided object.
+	 * 
+	 * @alias item(object)
+	 * @alias jQuery.Chain.services.item.handleObject
+	 * 
+	 * @param {Object} obj Object to be inserted
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @example
+	 * $('#element').item({name:'Rizqi', country:'Germany'});
+	 * $('#element').item({country:'Indonesia'});
+	 * $('#element').item(); // Returns {name:'Rizqi', country:'Indonesia'}
+	 * 
+	 * @see jQuery.Chain.services.item.handler
+	 */ 
+	handleObject: function(obj)
+	{
+		this.setData(obj);
+		this.isActive = true;
+		this.update();
+		
+		return this.element;
+	},
+	
+	/**
+	 * Add setter and getter to item.
+	 * This function will change the way @item(object)@ and @item()@ works.
+	 * 
+	 * @alias item(fn)
+	 * @alias jQuery.Chain.services.item.handleFunction
+	 * 
+	 * @param {Function} fn Getter&amp;Setter Function
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @example
+	 * $(element).item(function(oldval, newval){
+	 * 		//setter
+	 * 		if(newval)
+	 * 			return $.extend(oldval, newval);
+	 * 		//getter
+	 *		else
+	 * 			return oldval;
+	 * })
+	 */ 
+	handleFunction: function(fn)
+	{
+		// datafn stores the getter/setter function
+		this.datafn = fn;
+		
+		return this.element;
+	},
+	
+	/**
+	 * Get Data if no argument passed.
+	 * 
+	 * @alias item()
+	 * @alias jQuery.Chain.services.item.handleDefault
+	 * 
+	 * @return {Object, Boolean} Returns Data Object if exist, otherwise false
+	 */ 
+	handleDefault: function()
+	{
+		if(this.isActive)
+			{return this.getData();}
+		else
+			{return false;}
+	},
+	
+	/**
+	 * Data Getter Wrapper Function
+	 * 
+	 * @alias jQuery.Chain.services.item.getData
+	 * 
+	 * @return {Object} data
+	 */ 
+	getData: function()
+	{
+		// Call Getter
+		this.data = this.datafn.call(this.element, this.data);
+		
+		return this.data;
+	},
+	
+	/**
+	 * Data Setter Wrapper Function
+	 * 
+	 * @alias jQuery.Chain.services.item.setData
+	 */ 
+	setData: function(obj)
+	{
+		var data;
+		
+		// Determine whether object is a jQuery object or a data object
+		if($.Chain.jobject(obj) &amp;&amp; obj.item())
+			{data = $.extend({}, obj.item());}
+		else if($.Chain.jobject(obj))
+			{data = {};}
+		else
+			{data = obj;}
+		
+		// Call Setter
+		this.data = this.datafn.call(this.element, this.data || data, data);
+		
+		// Handle Linked Element
+		if(this.linkElement &amp;&amp; this.linkElement[0] != obj[0])
+		{
+			var el = this.linkFunction();
+			if($.Chain.jobject(el) &amp;&amp; el.length &amp;&amp; el.item())
+				{el.item(this.data);}
+		}
+	},
+	
+	/**
+	 * Default Getter/Setter
+	 * 
+	 * @alias jQuery.Chain.services.item.dataHandler
+	 * 
+	 * @param {Object} oldval Old value
+	 * @param {Object} newval New Value
+	 * 
+	 * @return {Object} returns data value
+	 */ 
+	dataHandler: function(oldval, newval)
+	{
+		if(arguments.length == 2)
+			{return $.extend(oldval, newval);}
+		else
+			{return oldval;}
+	},
+	
+	/**
+	 * Update element. Wrapper for @jQuery.Chain.services.item.element.update@
+	 * 
+	 * @alias jQuery.Chain.services.item.update
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	update: function()
+	{
+		return this.element.update();
+	},
+	
+	/**
+	 * Build item, apply builder and plugins
+	 * 
+	 * @alias jQuery.Chain.services.item.build
+	 * 
+	 * @see jQuery.Chain.services.item.$update
+	 */ 
+	build: function()
+	{
+		// IE Fix
+		var fix = this.element.chain('template', 'raw').replace(/jQuery\d+\=\&quot;null\&quot;/gi, &quot;&quot;);
+		this.element.chain('anchor').html(fix);
+		
+		// If item has root (items)
+		if(!$.Chain.jidentic(this.root, this.element))
+		{
+			// Get plugin from root and apply them
+			var plugins = this.root.chain('plugin');
+			for(var i in plugins)
+			{
+				plugins[i].apply(this.element, [this.root]);
+			}
+			
+		}
+		
+		// Apply builder
+		this.element.chain('builder').apply(this.element, [this.root]);
+		this.isBuilt = true;
+	},
+	
+	/**
+	 * Item Updater, called within @$(element).update()@
+	 * 
+	 * @alias item('update')
+	 * @alias jQuery.Chain.services.item.$update
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	$update: function()
+	{
+		if(this.element.chain('active') &amp;&amp; this.isActive &amp;&amp; !this.isBuilt &amp;&amp; this.getData())
+			{this.build();}
+		
+		return this.element;
+	},
+	
+	/**
+	 * Replace Data with new data
+	 * 
+	 * @alias item('replace')
+	 * @alias jQuery.Chain.services.item.$replace
+	 * 
+	 * @param {Object} obj Data Object
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @example
+	 * $(element).item('replace', data);
+	 */ 
+	$replace: function(obj)
+	{
+		this.data = {};
+		this.setData(obj);
+		this.isActive = true;
+		this.update();
+		return this.element;
+	},
+	
+	/**
+	 * Remove Item And destroy it.
+	 * 
+	 * @alias item('remove')
+	 * @alias jQuery.Chain.services.item.$remove
+	 * 
+	 * @param {Boolean} noupdate If true it won't update the root element
+	 */ 
+	$remove: function(noupdate)
+	{
+		// Destroy And Remove
+		this.element.chain('destroy');
+		this.element.remove();
+		this.element.item('link', null);
+		this.element.item('destroy');
+		
+		// Update root under certain circumtances
+		if(!$.Chain.jidentic(this.root, this.element) &amp;&amp; !noupdate)
+			{this.root.update();}
+	},
+	
+	/**
+	 * Check Status of @item@
+	 * 
+	 * @alias item('active')
+	 * @alias jQuery.Chain.services.item.$active
+	 * 
+	 * @return {Boolean} Status
+	 */ 
+	$active: function()
+	{
+		return this.isActive;
+	},
+	
+	/**
+	 * Get/Set Root element.
+	 * 
+	 * @alias item('root');
+	 * @alias jQuery.Chain.services.item.$root
+	 * 
+	 * @param {Object} root New Root element
+	 * 
+	 * @return {Object} If a new root passed, it will be item Element. Otherwise current root.
+	 */ 
+	$root: function(root)
+	{
+		if(arguments.length)
+		{
+			this.root = root;
+			this.update();
+			return this.element;
+		}
+		else
+		{
+			return this.root;
+		}
+	},
+	
+	/**
+	 * Backup Item to the state before being built.
+	 * 
+	 * @alias item('backup')
+	 * @alias jQuery.Chain.services.item.$backup
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	$backup: function()
+	{
+		this.isBuilt = false;
+		
+		return this.element;
+	},
+	
+	/**
+	 * Bind Item to other (chained) element. If one of them is updated,
+	 * the linked element will be updated.
+	 * 
+	 * @alias item('link')
+	 * @alias jQuery.Chain.services.item.$link
+	 * 
+	 * @param {Object} element element/selector to be linked with
+	 * @param {String} collection Collection to be linked with (has to be @&quot;self&quot;@ if linked to item)
+	 * 
+	 * @return {Object} jQuery Element
+	 * 
+	 * @see jQuery.Chain.services.items.collection
+	 */ 
+	$link: function(element, collection)
+	{
+		// If there are previous linkElement
+		if(this.linkElement)
+		{
+			this.linkElement.unbind('update', this.linkUpdater);
+			this.linkElement = null;
+		}
+		
+		element = $(element);
+		if(element.length)
+		{
+			var self = this;
+			this.isActive = true;
+			this.linkElement = element;
+			// Function that get the linked item.
+			this.linkFunction = function()
+			{
+				if(typeof collection == 'function')
+				{
+					try{
+						return collection.call(self.element, self.linkElement);
+					}catch(e){
+						return $().eq(-1);
+					}
+				}
+				else if(typeof collection == 'string')
+				{
+					return self.linkElement.items('collection', collection);
+				}
+				else
+				{
+					return $().eq(-1);
+				}
+			};
+			
+			// Watch linked element for update, and trigger update in self
+			this.linkUpdater = function()
+			{
+				var res = self.linkFunction();
+				if(res &amp;&amp; res.length)
+					{self.element.item(res);}
+			};
+			
+			this.linkElement.bind('update', this.linkUpdater);
+			this.linkUpdater();
+		}
+		
+		return this.element;
+	},
+	
+	/**
+	 * Destroy item service.
+	 * 
+	 * @alias item('destroy')
+	 * @alias jQuery.Chain.services.item.$destroy
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
+	$destroy: function()
+	{
+		return this.element;
+	}
+});
+
+})(jQuery);
 
 /* items.js */
+/**
+ * Chain Items Service.
+ * Method to bind items to object.
+ * 
+ * @alias items
+ * 
+ * @syntax $(selector).items(parameters);
+ */ 
+
 (function($){
 
+/**
+ * Chain Items Manager - Providing methods of @items@.
+ * All method listed here can only be used internally
+ * using @jQuery.Chain.service@ or @jQuery.Chain.extend@
+ * 
+ * @namespace
+ * 
+ * @alias jQuery.Chain.services.items
+ * 
+ * @see jQuery.Chain.service
+ * @see jQuery.Chain.extend
+ */ 
+
 $.Chain.service('items', {
+	/**
+	 * Collection of Function for getting items
+	 * 
+	 * @namespace
+	 * @alias jQuery.Chain.services.items.collections
+	 * 
+	 * @see jQuery.Chain.services.items.collection
+	 */ 
 	collections: 
 	{
+		/**
+		 * Get all items, including hidden
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.all
+		 * 
+		 * @return {Object} jQuery Object containing items
+		 */ 
 		all: function()
 		{
 			return this.element.chain('anchor').children('.chain-item');
 		},
 		
+		/**
+		 * Get all visible items
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.visible
+		 * 
+		 * @return {Object} jQuery Object containing items
+		 */ 
 		visible: function()
 		{
 			return this.element.chain('anchor').children('.chain-item:visible');
 		},
 		
+		/**
+		 * Get all hidden items
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.hidden
+		 * 
+		 * @return {Object} jQuery Object containing items
+		 */ 
 		hidden: function()
 		{
 			return this.element.chain('anchor').children('.chain-item:hidden');
 		},
 		
+		/**
+		 * Get self
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.self
+		 * 
+		 * @return {Object} jQuery Object of the element
+		 */ 
 		self: function()
 		{
 			return this.element;
 		}
 	},
 	
+	/**
+	 * Initializer. Executed once at the first time @items@ invoked.
+	 * 
+	 * @alias jQuery.Chain.services.items.init
+	 * 
+	 * @see jQuery.Chain.service
+	 */ 
 	init: function()
 	{
 		this.isActive = false;
@@ -556,76 +1573,218 @@ $.Chain.service('items', {
 		this.collections = $.extend({}, this.collections);
 	},
 	
+	/**
+	 * Default handler.
+	 * 
+	 * @alias jQuery.Chain.services.items.handler
+	 * 
+	 * @param {Object} obj Object to be handled
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.service
+	 * @see jQuery.Chain.services.items.handleObject
+	 * @see jQuery.Chain.services.items.handleElement
+	 * @see jQuery.Chain.services.items.handleArray
+	 * @see jQuery.Chain.services.items.handleNumber
+	 * @see jQuery.Chain.services.items.handleTrue
+	 * @see jQuery.Chain.services.items.handleDefault
+	 */ 
 	handler: function(obj)
 	{
+		// Array
 		if(obj instanceof Array)
-			return this.$merge(obj);
+			{return this.handleArray(obj);}
+		// Inactive
 		else if(!this.isActive)
-			return $().eq(-1);
+			{return $().eq(-1);}
+		// jQuery Object
 		else if($.Chain.jobject(obj))
-			return (!$.Chain.jidentic(obj, obj.item('root')) &amp;&amp; $.Chain.jidentic(this.element, obj.item('root')))
-				? obj : $().eq(-1);
+			{return this.handleElement(obj);}
+		// Normal Object
 		else if(typeof obj == 'object')
-			return this.getByData(obj);
+			{return this.handleObject(obj);}
+		// Number
 		else if(typeof obj == 'number')
-			return this.getByNumber(obj);
+			{return this.handleNumber(obj);}
+		// True
 		else if(obj === true)
-			return this.collection('all');
+			{return this.handleTrue();}
+		// Default
+		else
+			{return this.handleDefault();}
+	},
+	
+	/**
+	 * If a Data Object is given, it will return the item element
+	 * containing the object if it exists, otherwise empty.
+	 * 
+	 * @alias items(object)
+	 * @alias jQuery.Chain.services.items.handleObject
+	 * 
+	 * @param {Object} obj Data Object
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleObject: function(obj)
+	{
+		// Get Element By Data
+		return this.collection('all').filter(function(){return $(this).item() == obj;});
+	},
+	
+	/**
+	 * If a jQuery Element is given, it will return itself if it is part of the items,
+	 * otherwise empty jQuery object.
+	 * 
+	 * @alias items(element)
+	 * @alias jQuery.Chain.services.items.handleElement
+	 * 
+	 * @param {Object} obj jQuery Object
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleElement: function(obj)
+	{
+		// Check element whether it is part of items or not.
+		if(!$.Chain.jidentic(obj, obj.item('root')) &amp;&amp; $.Chain.jidentic(this.element, obj.item('root')))
+			{return obj;}
 		else
-			return this.collection('visible');
+			{return $().eq(-1);}
 	},
 	
-	getByData: function(item)
+	/**
+	 * If array is given, it will merge it to current items
+	 * 
+	 * @alias items(array)
+	 * @alias jQuery.Chain.services.items.handleArray
+	 * 
+	 * @param {Array} array Array of Data
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleArray: function(array)
 	{
-		return this.collection('all').filter(function(){return $(this).item() == item});
+		// Array will be merged in
+		return this.$merge(array);
 	},
 	
-	getByNumber: function(number)
+	/**
+	 * If number is given, it will get the object with the current number. Use -1 to get the last number.
+	 * 
+	 * @alias items(number)
+	 * @alias jQuery.Chain.services.items.handleNumber
+	 * 
+	 * @param {Number} number Index
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleNumber: function(number)
 	{
+		// if -1, it will get the last.
 		if(number == -1)
-			return this.collection('visible').filter(':last');
+			{return this.collection('visible').filter(':last');}
 		else
-			return this.collection('visible').eq(number);
+			{return this.collection('visible').eq(number);}
 	},
 	
+	/**
+	 * If @true@ is given, it will get all items including the hidden one.
+	 * 
+	 * @alias items(true)
+	 * @alias jQuery.Chain.services.items.handleTrue
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.services.items.collections.all
+	 */ 
+	handleTrue: function()
+	{
+		return this.collection('all');
+	},
+	
+	/**
+	 * If nothing is given, it will get all visible items.
+	 * 
+	 * @alias items(true)
+	 * @alias jQuery.Chain.services.items.handleTrue
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.services.items.collections.visible
+	 */ 
+	handleDefault: function()
+	{
+		return this.collection('visible');
+	},
+	
+	/**
+	 * Update element
+	 * 
+	 * @alias jQuery.Chain.services.items.update
+	 */ 
 	update: function()
 	{
 		this.element.update();
 	},
 	
+	/**
+	 * Clear all items
+	 * 
+	 * @alias jQuery.Chain.services.items.empty
+	 */ 
 	empty: function()
 	{
 		var all = this.collection('all');
 		
+		// Remove items
 		// Make it run in the background. for responsiveness.
-		setTimeout(function(){all.each(function(){$(this).item('remove', true)});}, 1);
+		setTimeout(function(){all.each(function(){$(this).item('remove', true);});}, 1);
 		
+		// Empty anchor container
 		this.element.chain('anchor').empty();
 	},
 	
+	/**
+	 * Get collection of items. Define a collection by adding a function argument
+	 * 
+	 * @alias jQuery.Chain.services.items.collection
+	 * 
+	 * @param {String} col Collection name
+	 * @param {Function} fn Create a collection function
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	collection: function(col, fn)
 	{
 		if(arguments.length &gt; 1)
 		{
 			if(typeof fn == 'function')
-				this.collections[col] = fn;
+				{this.collections[col] = fn;}
 			
 			return this.element;
 		}
 		else
 		{
 			if(this.collections[col])
-				return this.collections[col].apply(this);
+				{return this.collections[col].apply(this);}
 			else
-				return $().eq(-1);
+				{return $().eq(-1);}
 		}
 		
 	},
 	
+	/**
+	 * Items Updater, called by @$(element).update()@
+	 * 
+	 * @alias items('update')
+	 * @alias jQuery.Chain.services.items.$update
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$update: function()
 	{
 		if(!this.element.chain('active') || !this.isActive)
-			return this.element;
+			{return this.element;}
 		
 		var self = this;
 		var builder = this.element.chain('builder');
@@ -639,9 +1798,9 @@ $.Chain.service('items', {
 				.item('root', self.element);
 			
 			if(self.linkElement &amp;&amp; $.Chain.jobject(this) &amp;&amp; this.item())
-				clone.item('link', this, 'self');
+				{clone.item('link', this, 'self');}
 			else
-				clone.item(this);
+				{clone.item(this);}
 			
 			clone.chain(builder);
 		};
@@ -658,30 +1817,27 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
-	$push: function()
-	{
-		this.isActive = true;
-		this.pushBuffer = this.pushBuffer.concat(Array.prototype.slice.call(arguments));
-		this.update();
-		
-		return this.element;
-	},
-	
-	$shift: function()
-	{
-		this.isActive = true;
-		this.shiftBuffer = this.shiftBuffer.concat(Array.prototype.slice.call(arguments));
-		this.update();
-		
-		return this.element;
-	},
-	
+	/**
+	 * Add item(s). use @items('add', 'shift', item)@ to add item at the top
+	 * 
+	 * @alias items('add')
+	 * @alias jQuery.Chain.services.items.$add
+	 * 
+	 * @param {Object} item
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$add: function()
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		var cmd;
 		var args = Array.prototype.slice.call(arguments);
+		// Extract command
 		if(typeof args[0] == 'string')
-			cmd = args.shift();
+			{cmd = args.shift();}
+		
 		var buffer = (cmd == 'shift') ? 'shiftBuffer' : 'pushBuffer';
 		
 		this.isActive = true;
@@ -691,63 +1847,126 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Merge items with array of item data
+	 * 
+	 * @alias items('merge')
+	 * @alias jQuery.Chain.services.items.$merge
+	 * 
+	 * @param {String} cmd Switch for push/shift
+	 * @param {Array} items Item Data
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$merge: function(cmd, items)
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		if(typeof cmd != 'string')
-			items = cmd;
+			{items = cmd;}
 		var buffer = (cmd == 'shift') ? 'shiftBuffer' : 'pushBuffer';
 		
 		this.isActive = true;
 		if($.Chain.jobject(items))
-			this[buffer] = this[buffer].concat(items.map(function(){return $(this)}).get());
+			{this[buffer] = this[buffer].concat(items.map(function(){return $(this);}).get());}
 		else if(items instanceof Array)
-			this[buffer] = this[buffer].concat(items);
+			{this[buffer] = this[buffer].concat(items);}
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Replace items with new items array
+	 * 
+	 * @alias items('replace')
+	 * @alias jQuery.Chain.services.items.$replace
+	 * 
+	 * @param {String} cmd Switch for push/shift
+	 * @param {Array} items Item Data
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$replace: function(cmd, items)
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		if(typeof cmd != 'string')
-			items = cmd;
+			{items = cmd;}
 		var buffer = (cmd == 'shift') ? 'shiftBuffer' : 'pushBuffer';
 		
 		this.isActive = true;
 		this.empty();
 		
 		if($.Chain.jobject(items))
-			this[buffer] = items.map(function(){return $(this)}).get();
+			{this[buffer] = items.map(function(){return $(this);}).get();}
 		else if(items instanceof Array)
-			this[buffer] = items;
+			{this[buffer] = items;}
 		
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Remove item
+	 * 
+	 * @alias items('remove')
+	 * @alias jQuery.Chain.services.items.$remove
+	 * 
+	 * @param {Object, Number} item
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$remove: function()
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		for(var i=0; i&lt;arguments.length; i++)
-			this.handler(arguments[i]).item('remove', true);
+			{this.handler(arguments[i]).item('remove', true);}
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Reorder Item
+	 * 
+	 * @alias items('reorder')
+	 * @alias jQuery.Chain.services.items.$reorder
+	 * 
+	 * @param {Object} item1 Item 1
+	 * @param {Object} item2 Item 2
+	 * 
+	 * @return {Object} jQuery object
+	 */ 
 	$reorder: function(item1, item2)
 	{
 		if(item2)
-			this.handler(item1).before(this.handler(item2));
+			{this.handler(item1).before(this.handler(item2));}
 		else
-			this.handler(item1).appendTo(this.element.chain('anchor'));
+			{this.handler(item1).appendTo(this.element.chain('anchor'));}
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Clear all items
+	 * 
+	 * @alias items('empty')
+	 * @alias jQuery.Chain.services.items.$empty
+	 * 
+	 * @return {Object} jQuery object
+	 */ 
 	$empty: function()
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		this.empty();
 		this.shiftBuffer = [];
 		this.pushBuffer = [];
@@ -756,13 +1975,36 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Like @items()@ but returns array of data instead of the jQuery object.
+	 * 
+	 * @alias items('data')
+	 * @alias jQuery.Chain.services.items.$data
+	 * 
+	 * @return {Array} list of data
+	 */ 
 	$data: function(x)
 	{
 		return this.handler(x).map(function(){return $(this).item();}).get();
 	},
 	
+	/**
+	 * Bind Items to other (chained) element. If one of them is updated,
+	 * the linked element will be updated.
+	 * 
+	 * @alias items('link')
+	 * @alias jQuery.Chain.services.items.$link
+	 * 
+	 * @param {Object} element element/selector to be linked with
+	 * @param {String} collection Collection to be linked with (has to be @&quot;self&quot;@ if linked to item)
+	 * 
+	 * @return {Object} jQuery Element
+	 * 
+	 * @see jQuery.Chain.services.items.collection
+	 */ 
 	$link: function(element, collection)
 	{
+		// Remove linked element if it already exist
 		if(this.linkElement)
 		{
 			this.linkElement.unbind('update', this.linkUpdater);
@@ -770,25 +2012,39 @@ $.Chain.service('items', {
 		}
 		
 		element = $(element);
+		// If element exists
 		if(element.length)
 		{
 			var self = this;
 			this.linkElement = element;
+			// Create Collector Function
 			this.linkFunction = function()
 			{
 				if(typeof collection == 'function')
-					try{return collection.call(self.element, self.linkElement)}catch(e){return $().eq(-1)}
+				{
+					try{
+						return collection.call(self.element, self.linkElement);
+					}catch(e){
+						return $().eq(-1);
+					}
+				}
 				else if(typeof collection == 'string')
+				{
 					return self.linkElement.items('collection', collection);
+				}
 				else
+				{
 					return $().eq(-1);
+				}
 			};
 			
+			// Create Updater Function
 			this.linkUpdater = function()
 			{
 				self.element.items('replace', self.linkFunction());
 			};
 			
+			// Bind updater to linked element
 			this.linkElement.bind('update', this.linkUpdater);
 			this.linkUpdater();
 		}
@@ -796,31 +2052,68 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Get index of an Item
+	 * 
+	 * @alias items('index')
+	 * @alias jQuery.Chain.services.items.$index
+	 * 
+	 * @param {Object} item
+	 * 
+	 * @return {Number} index
+	 */ 
 	$index: function(item)
 	{
 		return this.collection('all').index(this.handler(item));
 	},
 	
+	/**
+	 * Get collection of items. Define a collection by adding a function argument
+	 * 
+	 * @alias items('collection')
+	 * @alias jQuery.Chain.services.items.$collection
+	 * 
+	 * @param {String} col Collection name
+	 * @param {Function} fn Create a collection function
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$collection: function()
 	{
 		return this.collection.apply(this, Array.prototype.slice.call(arguments));
 	},
 	
+	/**
+	 * Check Status of @items@
+	 * 
+	 * @alias items('active')
+	 * @alias jQuery.Chain.services.items.$active
+	 * 
+	 * @return {Boolean} Status
+	 */ 
 	$active: function()
 	{
 		return this.isActive;
 	},
 	
+	/**
+	 * Backup Item to the state before being built.
+	 * 
+	 * @alias items('backup')
+	 * @alias jQuery.Chain.services.items.$backup
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$backup: function()
 	{
 		if(!this.element.chain('active') || !this.isActive)
-			return;
+			{return this.element;}
 		
 		var buffer = [];
 		this.collection('all').each(function(){
 			var item = $(this).item();
 			if(item)
-				buffer.push(item);
+				{buffer.push(item);}
 		});
 		
 		this.pushBuffer = buffer.concat(this.pushBuffer);
@@ -830,6 +2123,14 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Destroy items service.
+	 * 
+	 * @alias items('destroy')
+	 * @alias jQuery.Chain.services.items.$destroy
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$destroy: function()
 	{
 		this.empty();
@@ -839,6 +2140,11 @@ $.Chain.service('items', {
 
 // Filtering extension
 $.Chain.extend('items', {
+	/**
+	 * Filtering subroutine
+	 * 
+	 * @alias jQuery.Chain.services.items.doFilter
+	 */ 
 	doFilter: function()
 	{
 		var props = this.searchProperties;
@@ -846,24 +2152,32 @@ $.Chain.extend('items', {
 		
 		if(text)
 		{
+			// Make text lowerCase if it is a string
 			if(typeof text == 'string')
-				text = text.toLowerCase();
+				{text = text.toLowerCase();}
 			
+			// Filter items
 			var items = this.element.items(true).filter(function(){
 				var data = $(this).item();
+				// If search properties is defined, search for text in those properties
 				if(props)
 				{
 					for(var i=0; i&lt;props.length; i++)
-						if(typeof data[i] == 'string'
-							&amp;&amp; !!(typeof text == 'string' ? data[i].toLowerCase() : data[i]).match(text))
-							return true;
+					{
+						if(typeof data[props[i]] == 'string'
+							&amp;&amp; !!(typeof text == 'string' ? data[props[i]].toLowerCase() : data[props[i]]).match(text))
+							{return true;}
+					}
 				}
+				// Otherwise search in all properties
 				else
 				{
-					for(var i in data)
-						if(typeof data[i] == 'string'
-							&amp;&amp; !!(typeof text == 'string' ? data[i].toLowerCase() : data[i]).match(text))
-							return true;
+					for(var prop in data)
+					{
+						if(typeof data[prop] == 'string'
+							&amp;&amp; !!(typeof text == 'string' ? data[prop].toLowerCase() : data[prop]).match(text))
+							{return true;}
+					}
 				}
 			});
 			this.element.items(true).not(items).hide();
@@ -877,20 +2191,33 @@ $.Chain.extend('items', {
 		}
 	},
 	
+	/**
+	 * Filter items by criteria. Filtered items will be hidden.
+	 * 
+	 * @alias items('filter')
+	 * @alias jQuery.Chain.services.items.$filter
+	 * 
+	 * @param {String, RegExp} text Search keyword
+	 * @param {String, Array} properties Search properties
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$filter: function(text, properties)
 	{
-		if(arguments.length == 0)
-			return this.update();
+		// If no argument, just refilter
+		if(!arguments.length)
+			{return this.update();}
 		
 		this.searchText = text;
 		
-		if(typeof properties == 'text')
-			this.searchProperties = [properties];
+		if(typeof properties == 'string')
+			{this.searchProperties = [properties];}
 		else if(properties instanceof Array)
-			this.searchProperties = properties;
+			{this.searchProperties = properties;}
 		else
-			this.searchProperties = null;
+			{this.searchProperties = null;}
 		
+		// Bind to preupdate
 		if(!this.searchBinding)
 		{
 			var self = this;
@@ -904,6 +2231,11 @@ $.Chain.extend('items', {
 
 // Sorting extension
 $.Chain.extend('items', {
+	/**
+	 * Sorting subroutine
+	 * 
+	 * @alias jQuery.Chain.services.items.doSort
+	 */ 
 	doSort: function()
 	{
 		var name = this.sortName;
@@ -930,7 +2262,7 @@ $.Chain.extend('items', {
 			array = opt.desc ? array.reverse() : array;
 			
 			for(var i=0; i&lt;array.length; i++)
-				this.element.chain('anchor').append(array[i]);
+				{this.element.chain('anchor').append(array[i]);}
 			
 			opt.desc = opt.toggle ? !opt.desc : opt.desc;
 		}
@@ -941,15 +2273,26 @@ $.Chain.extend('items', {
 		}
 	},
 	
+	/**
+	 * Sort items by property.
+	 * 
+	 * @alias items('sort')
+	 * @alias jQuery.Chain.services.items.$sort
+	 * 
+	 * @param {String} name sorting property
+	 * @param {Object} opt {toggle:true/false, desc:true/false, type:'number/default'}
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$sort: function(name, opt)
 	{
 		if(!name &amp;&amp; name !== null &amp;&amp; name !== false)
-			return this.update();
+			{return this.update();}
 		
 		if(this.sortName != name)
-			this.sortOpt = $.extend({desc:false, type:'default', toggle:false}, opt);
+			{this.sortOpt = $.extend({desc:false, type:'default', toggle:false}, opt);}
 		else
-			$.extend(this.sortOpt, opt);
+			{$.extend(this.sortOpt, opt);}
 		
 		this.sortName = name;
 		
@@ -964,195 +2307,4 @@ $.Chain.extend('items', {
 	}
 });
 	
-})(jQuery);
-
-
-/* item.js */
-(function($){
-
-$.Chain.service('item', {
-	init: function()
-	{
-		this.isActive = false;
-		this.isBuilt = false;
-		this.root = this.element;
-		this.data = false;
-		this.datafn = this.dataHandler;
-	},
-	
-	handler: function(obj)
-	{
-		if(typeof obj == 'object')
-		{
-			this.setData(obj);
-			this.isActive = true;
-			
-			this.update();
-			return this.element;
-		}
-		else if(typeof obj == 'function')
-		{
-			this.datafn = obj;
-			
-			return this.element;
-		}
-		
-		if(this.isActive)
-			return this.getData();
-		else
-			return false;
-	},
-	
-	getData: function()
-	{
-		this.data = this.datafn.call(this.element, this.data);
-		
-		return this.data;
-	},
-	
-	setData: function(obj)
-	{
-		var data;
-		if($.Chain.jobject(obj) &amp;&amp; obj.item())
-			data = $.extend({}, obj.item());
-		else if($.Chain.jobject(obj))
-			data = {}
-		else
-			data = obj;
-		
-		this.data = this.datafn.call(this.element, this.data || data, data);
-		if(this.linkElement &amp;&amp; this.linkElement[0] != obj[0])
-		{
-			var el = this.linkFunction();
-			if($.Chain.jobject(el) &amp;&amp; el.length &amp;&amp; el.item())
-				el.item(this.data);
-		}
-	},
-	
-	dataHandler: function(a, b)
-	{
-		if(arguments.length == 2)
-			return $.extend(a, b);
-		else
-			return a;
-	},
-	
-	update: function()
-	{
-		return this.element.update();
-	},
-	
-	build: function()
-	{
-		// IE Fix
-		var fix = this.element.chain('template', 'raw').replace(/jQuery\d+\=\&quot;null\&quot;/gi, &quot;&quot;);
-		this.element.chain('anchor').html(fix);
-		
-		if(!$.Chain.jidentic(this.root, this.element))
-		{
-			var plugins = this.root.chain('plugin');
-			for(var i in plugins)
-				plugins[i].apply(this.element, [this.root]);
-			
-		}
-		
-		this.element.chain('builder').apply(this.element, [this.root]);
-		this.isBuilt = true;
-		
-		var self = this;
-	},
-	
-	$update: function()
-	{
-		if(this.element.chain('active') &amp;&amp; this.isActive &amp;&amp; !this.isBuilt &amp;&amp; this.getData())
-			this.build();
-		
-		return this.element;
-	},
-	
-	$replace: function(obj)
-	{
-		this.data = {};
-		this.setData(obj);
-		this.isActive = true;
-		this.update();
-		return this.element;
-	},
-	
-	$remove: function(noupdate)
-	{
-		this.element.chain('destroy');
-		this.element.remove();
-		
-		if(!$.Chain.jidentic(this.root, this.element) &amp;&amp; !noupdate)
-			this.root.update();
-		
-		if(this.$link)
-			this.$link(null);
-	},
-	
-	$active: function()
-	{
-		return this.isActive;
-	},
-	
-	$root: function(val)
-	{
-		if(arguments.length)
-		{
-			this.root = val;
-			this.update();
-			return this.element;
-		}
-		else
-		{
-			return this.root;
-		}
-	},
-	
-	$backup: function()
-	{
-		this.isBuilt = false;
-	},
-	
-	$link: function(element, collection)
-	{
-		if(this.linkElement)
-		{
-			this.linkElement.unbind('update', this.linkUpdater);
-			this.linkElement = null;
-		}
-		
-		element = $(element);
-		if(element.length)
-		{
-			var self = this;
-			this.isActive = true;
-			this.linkElement = element;
-			this.linkFunction = function()
-			{
-				if(typeof collection == 'function')
-					try{return collection.call(self.element, self.linkElement)}catch(e){return $().eq(-1)}
-				else if(typeof collection == 'string')
-					return self.linkElement.items('collection', collection);
-				else
-					return $().eq(-1);
-			};
-			
-			this.linkUpdater = function()
-			{
-				var res = self.linkFunction();
-				if(res &amp;&amp; res.length)
-					self.element.item(res);
-			};
-			
-			this.linkElement.bind('update', this.linkUpdater);
-			this.linkUpdater();
-		}
-		
-		return this.element;
-	}
-});
-
-})(jQuery);
-
+})(jQuery);
\ No newline at end of file</diff>
      <filename>build/chain.js</filename>
    </modified>
    <modified>
      <diff>@@ -9,9 +9,39 @@ load it together with jQuery into your page using:
 &lt;script src=&quot;path/to/jquery.js&quot; language=&quot;javascript&quot;&gt;&lt;/script&gt;
 &lt;script src=&quot;path/to/chain.js&quot; language=&quot;javascript&quot;&gt;&lt;/script&gt;
 
-FOR DEVELOPER
+DEVELOPER GUIDE
 
-to generate chain.js please do in terminal:
-$ sh generate.sh
+Code Quality
+- It is encouraged to adapt the code to the current coding style
+- Please verify the code using www.jslint.com 
+  (with tolerate eval, breaking, for in and inefficient subscripting on)
 
-It will generate a new chain.js from source. To include a new source file please open &quot;generate.sh&quot; in your texteditor and add the new source file at the end of sources list
\ No newline at end of file
+Documenting
+- Please document your code thoroughly
+- Write examples and descriptions
+- document codes, which other developers may not understand at first glance
+
+We use Rhino for shell engine, providing tools for creating documentation
+and source building. Rhino is included in the latest Java SDK.
+For mac os x, follow this instruction:
+http://peter.michaux.ca/article/2982
+
+It is very handy to create an alias for Rhino:
+$ alias js='java org.mozilla.javascript.tools.shell.Main'
+save this in your bash profile
+
+Building From Source Code
+to build from source code go to terminal, move to chain directory and do:
+$ java org.mozilla.javascript.tools.shell.Main bin/build.js
+or if you created an alias
+$ js bin/build.js
+
+Generating Documentation
+do:
+$ java org.mozilla.javascript.tools.shell.Main bin/doc.js
+or
+$ js bin/doc.js
+
+Including new source file
+to include new source file open project.js and add new source to
+profile.sources array
\ No newline at end of file</diff>
      <filename>readme.txt</filename>
    </modified>
    <modified>
      <diff>@@ -7,4 +7,8 @@ v0.2:
 - added items('add', 'push') and items('add', 'shift')
 - now chain({...}) only extend defaultBuilder, override using
   chain({override:true})
+- Updater now can update the item itself by defining
+  chain({self: &quot;{somedata}&quot;})
+- Now a packed version (using Dean Edward's packer)
+- In Code Documentation &amp; Documentation Generator
 - bug fixes
\ No newline at end of file</diff>
      <filename>release-notes.txt</filename>
    </modified>
    <modified>
      <diff>@@ -64,9 +64,9 @@ $.Chain.service('chain', {
 		this.element.item('backup');
 		
 		if(typeof obj == 'object')
-			this.handleUpdater(obj);
+			{this.handleUpdater(obj);}
 		else if(typeof obj == 'function')
-			this.handleBuilder(obj);
+			{this.handleBuilder(obj);}
 		
 		// Empty element, if @item@ it will filled again later
 		this.anchor.empty();
@@ -153,7 +153,7 @@ $.Chain.service('chain', {
 		
 		// Extract Anchor
 		if(rules.anchor)
-			this.setAnchor(rules.anchor);
+			{this.setAnchor(rules.anchor);}
 		delete rules.anchor;
 		
 		// Extract Override
@@ -173,7 +173,7 @@ $.Chain.service('chain', {
 				for(var j in rules[i])
 				{
 					if(typeof rules[i][j] == 'string')
-						rules[i][j] = $.Chain.parse(rules[i][j]);
+						{rules[i][j] = $.Chain.parse(rules[i][j]);}
 				}
 			}
 		}
@@ -187,10 +187,10 @@ $.Chain.service('chain', {
 			{
 				// If self, update the element itself
 				if(i == 'self')
-					el = self;
+					{el = self;}
 				// Otherwise find element inside self
 				else
-					el = $(i, self);
+					{el = $(i, self);}
 				
 				// Executing
 				// If no attributes, put the result to html (value if input)
@@ -198,7 +198,7 @@ $.Chain.service('chain', {
 				{
 					val = rules[i].apply(self, [data, el]);
 					if(typeof val == 'string')
-						el.not(':input').html(val).end().filter(':input').val(val);
+						{el.not(':input').html(val).end().filter(':input').val(val);}
 				}
 				// If attributes, then execute the function for each attr.
 				else if(typeof rules[i] == 'object')
@@ -212,16 +212,16 @@ $.Chain.service('chain', {
 							{
 								// Some special attributes
 								if(j == 'content')
-									el.html(val);
+									{el.html(val);}
 								else if(j == 'text')
-									el.text(val);
+									{el.text(val);}
 								else if(j == 'value')
-									el.val(val);
+									{el.val(val);}
 								else if(j == 'class' || j == 'className')
-									el.addClass(val);
+									{el.addClass(val);}
 								// Otherwise fill attribute as normal
 								else
-									el.attr(j, val);
+									{el.attr(j, val);}
 							}
 							
 						}
@@ -236,10 +236,10 @@ $.Chain.service('chain', {
 		this.builder = function(root)
 		{
 			if(builder)
-				builder.apply(this, [root]);
+				{builder.apply(this, [root]);}
 			
 			if(!override)
-				defBuilder.apply(this);
+				{defBuilder.apply(this);}
 			
 			// Here goes the updater
 			this.update(fn);
@@ -307,13 +307,16 @@ $.Chain.service('chain', {
 		
 		// Default Updater
 		if(res)
+		{
 			this.bind('update', function(event, data){
 				var self = $(this);
 				// Iterate through data
 				// Find element with the same class as data property
 				// Insert data depending of elemen type
 				for(var i in data)
+				{	
 					if(typeof data[i] != 'object' &amp;&amp; typeof data[i] != 'function')
+					{
 						// This prevents selector to select inside nested chain-element
 						// Important to support recursion &amp; nested element
 						// NEED OPTIMIZATION
@@ -321,13 +324,16 @@ $.Chain.service('chain', {
 							.each(function(){
 								var match = $(this);
 								if(match.filter(':input').length)
-									match.val(data[i]);
+									{match.val(data[i]);}
 								else if(match.filter('img').length)
-									match.attr('src', data[i]);
+									{match.attr('src', data[i]);}
 								else
-									match.html(data[i]);
+									{match.html(data[i]);}
 							});
+					}
+				}
 			});
+		}
 	},
 	
 	/**
@@ -426,11 +432,11 @@ $.Chain.service('chain', {
 	{
 		// Returns current Template (jQuery Object)
 		if(!arguments.length)
-			return $('&lt;div&gt;').html(this.template).children().eq(this.tplNumber);
+			{return $('&lt;div&gt;').html(this.template).children().eq(this.tplNumber);}
 		
 		// Returns raw HTML Template
 		if(arg == 'raw')
-			return this.template;
+			{return this.template;}
 		
 		// Switch template by Number
 		if(typeof arg == 'number')
@@ -444,9 +450,9 @@ $.Chain.service('chain', {
 			var node = tpl.filter(arg).eq(0);
 			
 			if(node.length)
-				this.tplNumber = tpl.index(node);
+				{this.tplNumber = tpl.index(node);}
 			else
-				return this.element; // If not found do nothing
+				{return this.element;} // If not found do nothing
 		}
 		
 		this.element.items('backup');
@@ -474,9 +480,9 @@ $.Chain.service('chain', {
 	$builder: function(builder)
 	{
 		if(builder)
-			return this.handler(builder);
+			{return this.handler(builder);}
 		else
-			return this.builder;
+			{return this.builder;}
 	},
 	
 	/**
@@ -506,19 +512,21 @@ $.Chain.service('chain', {
 	$plugin: function(name, fn)
 	{
 		if(fn === null)
-			delete this.plugins[name];
+			{delete this.plugins[name];}
 		else if(typeof fn == 'function')
-			this.plugins[name] = fn;
+			{this.plugins[name] = fn;}
 		else if(name &amp;&amp; !fn)
-			return this.plugins[name];
+			{return this.plugins[name];}
 		else
-			return this.plugins;
+			{return this.plugins;}
 		
 		if(typeof fn == 'function')
+		{
 			this.element.items(true).each(function(){
 				var self = $(this);
 				fn.call(self, self.item('root'));
 			});
+		}
 		
 		this.element.update();
 		</diff>
      <filename>src/chain.js</filename>
    </modified>
    <modified>
      <diff>@@ -70,7 +70,8 @@ $.Chain =
 		// Creating jQuery fn module with the service
 		$.fn[name] = function(options)
 		{
-			if(!this.length) return this;
+			if(!this.length)
+				{return this;}
 			
 			// Create Chain instance
 			var instance = this.data('chain-'+name);
@@ -83,32 +84,32 @@ $.Chain =
 			{
 			  // Return immediately if destroyed is called before Instance is created
 				if(options == 'destroy') 
-					return this;
+					{return this;}
 				// Create Instance
 				instance = $.extend({element: this}, $.Chain.services[name]);
 				this.data('chain-'+name, instance);
 				// Initialize if possible
 				if(instance.init)
-					instance.init();
+					{instance.init();}
 			}
 			
 			var result;
 			
 			// Check whether to execute a command
 			if(typeof options == 'string' &amp;&amp; instance['$'+options])
-				result = instance['$'+options].apply(instance, args);
+				{result = instance['$'+options].apply(instance, args);}
 			
 			// Otherwise try to execute default handler
 			else if(instance['handler'])
-				result = instance['handler'].apply(instance, [options].concat(args));
+				{result = instance['handler'].apply(instance, [options].concat(args));}
 			
 			// Otherwise do nothing
 			else
-				result = this;
+				{result = this;}
 			
 			// Remove instance on destroy
 			if(options == 'destroy')
-				this.removeData('chain-'+name);
+				{this.removeData('chain-'+name);}
 			
 			return result;
 		};
@@ -127,7 +128,7 @@ $.Chain =
 	extend: function(name, proto)
 	{
 		if(this.services[name])
-			this.services[name] = $.extend(this.services[name], proto);
+			{this.services[name] = $.extend(this.services[name], proto);}
 	},
 	
 	/**
@@ -175,14 +176,16 @@ $.Chain =
 	jidentic: function(j1, j2)
 	{
 		if(!j1 || !j2 || j1.length != j2.length)
-			return false;
+			{return false;}
 		
-		a1 = j1.get();
-		a2 = j2.get();
+		var a1 = j1.get();
+		var a2 = j2.get();
 		
 		for(var i=0; i&lt;a1.length; i++)
+		{
 			if(a1[i] != a2[i])
-				return false;
+				{return false;}
+		}
 		
 		return true;
 		
@@ -203,7 +206,7 @@ $.Chain =
 	 * 
 	 * @see jQuery.Chain.tag
 	 */ 
-	parse: (function()
+	parse: function()
 	{
 		var $this = {};
 		// Function Closure
@@ -247,41 +250,45 @@ $.Chain =
 				closer = opener + text.substring(opener).indexOf(tag[1]);
 		
 				// If opener tag exists, otherwise there are no tags anymore
-				if(opener != -1){
+				if(opener != -1)
+				{
 					// Handle escape. Tag can be escaped with '\\'.
 					// If tag is escaped. it will be handled as a normal text
 					// Otherwise it will be handled as a script
-					if(text[opener-1] == '\\'){
+					if(text[opener-1] == '\\')
+					{
 						closer2 = opener+tag[0].length + text.substring(opener+tag[0].length).indexOf(tag[0]);
 						if(closer2 != opener+tag[0].length-1 &amp;&amp; text[closer2-1] == '\\')
-							closer2 = closer2-1;
+							{closer2 = closer2-1;}
 						else if(closer2 == opener+tag[0].length-1)
-							closer2 = text.length;
+							{closer2 = text.length;}
 				
 						result.push($this.textPrint(text.substring(0, opener-1)));
 						result.push($this.textPrint(text.substring(opener, closer2)));
 					}
-					else{
+					else
+					{
 						closer2 = null;
 						if(closer == opener-1)
-							closer = text.length;
+							{closer = text.length;}
 				
 						result.push($this.textPrint(text.substring(0, opener)));
 						result.push($this.scriptPrint(text.substring(opener+tag[0].length, closer)));
 					}
 					
-					text = text.substring((closer2 == null) ? closer+tag[1].length : closer2);
+					text = text.substring((closer2 === null) ? closer+tag[1].length : closer2);
 				}
 				// If there are still text, it will be pushed to array
 				// So we won't stuck in an infinite loop
-				else if(text){
+				else if(text)
+				{
 					result.push($this.textPrint(text));
 					text = '';
 				}
 			}
 	
 			return result.join('\n');	
-		}
+		};
 	
 	
 		/*
@@ -290,7 +297,7 @@ $.Chain =
 		 */
 		return function($text)
 		{
-			var $fn;
+			var $fn = function(){};
 			try
 			{
 				eval('$fn = '+ $this.closure[0]+$this.parser($text)+$this.closure[1]);
@@ -298,12 +305,11 @@ $.Chain =
 			catch(e)
 			{
 				throw &quot;Parsing Error&quot;;
-				$fn = function(){};
 			}
 			
 			return $fn;
 		};
-	})()
+	}()
 };
 	
 })(jQuery);
\ No newline at end of file</diff>
      <filename>src/core.js</filename>
    </modified>
    <modified>
      <diff>@@ -56,11 +56,11 @@ $.Chain.service('item', {
 	handler: function(obj)
 	{
 		if(typeof obj == 'object')
-			return this.handleObject(obj);
+			{return this.handleObject(obj);}
 		else if(typeof obj == 'function')
-			return this.handleFunction(obj);
+			{return this.handleFunction(obj);}
 		else
-			return this.handleDefault();
+			{return this.handleDefault();}
 	},
 	
 	/**
@@ -131,9 +131,9 @@ $.Chain.service('item', {
 	handleDefault: function()
 	{
 		if(this.isActive)
-			return this.getData();
+			{return this.getData();}
 		else
-			return false;
+			{return false;}
 	},
 	
 	/**
@@ -162,11 +162,11 @@ $.Chain.service('item', {
 		
 		// Determine whether object is a jQuery object or a data object
 		if($.Chain.jobject(obj) &amp;&amp; obj.item())
-			data = $.extend({}, obj.item());
+			{data = $.extend({}, obj.item());}
 		else if($.Chain.jobject(obj))
-			data = {}
+			{data = {};}
 		else
-			data = obj;
+			{data = obj;}
 		
 		// Call Setter
 		this.data = this.datafn.call(this.element, this.data || data, data);
@@ -176,7 +176,7 @@ $.Chain.service('item', {
 		{
 			var el = this.linkFunction();
 			if($.Chain.jobject(el) &amp;&amp; el.length &amp;&amp; el.item())
-				el.item(this.data);
+				{el.item(this.data);}
 		}
 	},
 	
@@ -193,9 +193,9 @@ $.Chain.service('item', {
 	dataHandler: function(oldval, newval)
 	{
 		if(arguments.length == 2)
-			return $.extend(oldval, newval);
+			{return $.extend(oldval, newval);}
 		else
-			return oldval;
+			{return oldval;}
 	},
 	
 	/**
@@ -229,7 +229,9 @@ $.Chain.service('item', {
 			// Get plugin from root and apply them
 			var plugins = this.root.chain('plugin');
 			for(var i in plugins)
+			{
 				plugins[i].apply(this.element, [this.root]);
+			}
 			
 		}
 		
@@ -249,7 +251,7 @@ $.Chain.service('item', {
 	$update: function()
 	{
 		if(this.element.chain('active') &amp;&amp; this.isActive &amp;&amp; !this.isBuilt &amp;&amp; this.getData())
-			this.build();
+			{this.build();}
 		
 		return this.element;
 	},
@@ -294,7 +296,7 @@ $.Chain.service('item', {
 		
 		// Update root under certain circumtances
 		if(!$.Chain.jidentic(this.root, this.element) &amp;&amp; !noupdate)
-			this.root.update();
+			{this.root.update();}
 	},
 	
 	/**
@@ -346,7 +348,7 @@ $.Chain.service('item', {
 	{
 		this.isBuilt = false;
 		
-		return this.element
+		return this.element;
 	},
 	
 	/**
@@ -382,11 +384,21 @@ $.Chain.service('item', {
 			this.linkFunction = function()
 			{
 				if(typeof collection == 'function')
-					try{return collection.call(self.element, self.linkElement)}catch(e){return $().eq(-1)}
+				{
+					try{
+						return collection.call(self.element, self.linkElement);
+					}catch(e){
+						return $().eq(-1);
+					}
+				}
 				else if(typeof collection == 'string')
+				{
 					return self.linkElement.items('collection', collection);
+				}
 				else
+				{
 					return $().eq(-1);
+				}
 			};
 			
 			// Watch linked element for update, and trigger update in self
@@ -394,7 +406,7 @@ $.Chain.service('item', {
 			{
 				var res = self.linkFunction();
 				if(res &amp;&amp; res.length)
-					self.element.item(res);
+					{self.element.item(res);}
 			};
 			
 			this.linkElement.bind('update', this.linkUpdater);</diff>
      <filename>src/item.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,29 +1,94 @@
+/**
+ * Chain Items Service.
+ * Method to bind items to object.
+ * 
+ * @alias items
+ * 
+ * @syntax $(selector).items(parameters);
+ */ 
+
 (function($){
 
+/**
+ * Chain Items Manager - Providing methods of @items@.
+ * All method listed here can only be used internally
+ * using @jQuery.Chain.service@ or @jQuery.Chain.extend@
+ * 
+ * @namespace
+ * 
+ * @alias jQuery.Chain.services.items
+ * 
+ * @see jQuery.Chain.service
+ * @see jQuery.Chain.extend
+ */ 
+
 $.Chain.service('items', {
+	/**
+	 * Collection of Function for getting items
+	 * 
+	 * @namespace
+	 * @alias jQuery.Chain.services.items.collections
+	 * 
+	 * @see jQuery.Chain.services.items.collection
+	 */ 
 	collections: 
 	{
+		/**
+		 * Get all items, including hidden
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.all
+		 * 
+		 * @return {Object} jQuery Object containing items
+		 */ 
 		all: function()
 		{
 			return this.element.chain('anchor').children('.chain-item');
 		},
 		
+		/**
+		 * Get all visible items
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.visible
+		 * 
+		 * @return {Object} jQuery Object containing items
+		 */ 
 		visible: function()
 		{
 			return this.element.chain('anchor').children('.chain-item:visible');
 		},
 		
+		/**
+		 * Get all hidden items
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.hidden
+		 * 
+		 * @return {Object} jQuery Object containing items
+		 */ 
 		hidden: function()
 		{
 			return this.element.chain('anchor').children('.chain-item:hidden');
 		},
 		
+		/**
+		 * Get self
+		 * 
+		 * @alias jQuery.Chain.services.items.collections.self
+		 * 
+		 * @return {Object} jQuery Object of the element
+		 */ 
 		self: function()
 		{
 			return this.element;
 		}
 	},
 	
+	/**
+	 * Initializer. Executed once at the first time @items@ invoked.
+	 * 
+	 * @alias jQuery.Chain.services.items.init
+	 * 
+	 * @see jQuery.Chain.service
+	 */ 
 	init: function()
 	{
 		this.isActive = false;
@@ -32,76 +97,218 @@ $.Chain.service('items', {
 		this.collections = $.extend({}, this.collections);
 	},
 	
+	/**
+	 * Default handler.
+	 * 
+	 * @alias jQuery.Chain.services.items.handler
+	 * 
+	 * @param {Object} obj Object to be handled
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.service
+	 * @see jQuery.Chain.services.items.handleObject
+	 * @see jQuery.Chain.services.items.handleElement
+	 * @see jQuery.Chain.services.items.handleArray
+	 * @see jQuery.Chain.services.items.handleNumber
+	 * @see jQuery.Chain.services.items.handleTrue
+	 * @see jQuery.Chain.services.items.handleDefault
+	 */ 
 	handler: function(obj)
 	{
+		// Array
 		if(obj instanceof Array)
-			return this.$merge(obj);
+			{return this.handleArray(obj);}
+		// Inactive
 		else if(!this.isActive)
-			return $().eq(-1);
+			{return $().eq(-1);}
+		// jQuery Object
 		else if($.Chain.jobject(obj))
-			return (!$.Chain.jidentic(obj, obj.item('root')) &amp;&amp; $.Chain.jidentic(this.element, obj.item('root')))
-				? obj : $().eq(-1);
+			{return this.handleElement(obj);}
+		// Normal Object
 		else if(typeof obj == 'object')
-			return this.getByData(obj);
+			{return this.handleObject(obj);}
+		// Number
 		else if(typeof obj == 'number')
-			return this.getByNumber(obj);
+			{return this.handleNumber(obj);}
+		// True
 		else if(obj === true)
-			return this.collection('all');
+			{return this.handleTrue();}
+		// Default
+		else
+			{return this.handleDefault();}
+	},
+	
+	/**
+	 * If a Data Object is given, it will return the item element
+	 * containing the object if it exists, otherwise empty.
+	 * 
+	 * @alias items(object)
+	 * @alias jQuery.Chain.services.items.handleObject
+	 * 
+	 * @param {Object} obj Data Object
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleObject: function(obj)
+	{
+		// Get Element By Data
+		return this.collection('all').filter(function(){return $(this).item() == obj;});
+	},
+	
+	/**
+	 * If a jQuery Element is given, it will return itself if it is part of the items,
+	 * otherwise empty jQuery object.
+	 * 
+	 * @alias items(element)
+	 * @alias jQuery.Chain.services.items.handleElement
+	 * 
+	 * @param {Object} obj jQuery Object
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleElement: function(obj)
+	{
+		// Check element whether it is part of items or not.
+		if(!$.Chain.jidentic(obj, obj.item('root')) &amp;&amp; $.Chain.jidentic(this.element, obj.item('root')))
+			{return obj;}
 		else
-			return this.collection('visible');
+			{return $().eq(-1);}
 	},
 	
-	getByData: function(item)
+	/**
+	 * If array is given, it will merge it to current items
+	 * 
+	 * @alias items(array)
+	 * @alias jQuery.Chain.services.items.handleArray
+	 * 
+	 * @param {Array} array Array of Data
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleArray: function(array)
 	{
-		return this.collection('all').filter(function(){return $(this).item() == item});
+		// Array will be merged in
+		return this.$merge(array);
 	},
 	
-	getByNumber: function(number)
+	/**
+	 * If number is given, it will get the object with the current number. Use -1 to get the last number.
+	 * 
+	 * @alias items(number)
+	 * @alias jQuery.Chain.services.items.handleNumber
+	 * 
+	 * @param {Number} number Index
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
+	handleNumber: function(number)
 	{
+		// if -1, it will get the last.
 		if(number == -1)
-			return this.collection('visible').filter(':last');
+			{return this.collection('visible').filter(':last');}
 		else
-			return this.collection('visible').eq(number);
+			{return this.collection('visible').eq(number);}
+	},
+	
+	/**
+	 * If @true@ is given, it will get all items including the hidden one.
+	 * 
+	 * @alias items(true)
+	 * @alias jQuery.Chain.services.items.handleTrue
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.services.items.collections.all
+	 */ 
+	handleTrue: function()
+	{
+		return this.collection('all');
 	},
 	
+	/**
+	 * If nothing is given, it will get all visible items.
+	 * 
+	 * @alias items(true)
+	 * @alias jQuery.Chain.services.items.handleTrue
+	 * 
+	 * @return {Object} jQuery Object
+	 * 
+	 * @see jQuery.Chain.services.items.collections.visible
+	 */ 
+	handleDefault: function()
+	{
+		return this.collection('visible');
+	},
+	
+	/**
+	 * Update element
+	 * 
+	 * @alias jQuery.Chain.services.items.update
+	 */ 
 	update: function()
 	{
 		this.element.update();
 	},
 	
+	/**
+	 * Clear all items
+	 * 
+	 * @alias jQuery.Chain.services.items.empty
+	 */ 
 	empty: function()
 	{
 		var all = this.collection('all');
 		
+		// Remove items
 		// Make it run in the background. for responsiveness.
-		setTimeout(function(){all.each(function(){$(this).item('remove', true)});}, 1);
+		setTimeout(function(){all.each(function(){$(this).item('remove', true);});}, 1);
 		
+		// Empty anchor container
 		this.element.chain('anchor').empty();
 	},
 	
+	/**
+	 * Get collection of items. Define a collection by adding a function argument
+	 * 
+	 * @alias jQuery.Chain.services.items.collection
+	 * 
+	 * @param {String} col Collection name
+	 * @param {Function} fn Create a collection function
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	collection: function(col, fn)
 	{
 		if(arguments.length &gt; 1)
 		{
 			if(typeof fn == 'function')
-				this.collections[col] = fn;
+				{this.collections[col] = fn;}
 			
 			return this.element;
 		}
 		else
 		{
 			if(this.collections[col])
-				return this.collections[col].apply(this);
+				{return this.collections[col].apply(this);}
 			else
-				return $().eq(-1);
+				{return $().eq(-1);}
 		}
 		
 	},
 	
+	/**
+	 * Items Updater, called by @$(element).update()@
+	 * 
+	 * @alias items('update')
+	 * @alias jQuery.Chain.services.items.$update
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$update: function()
 	{
 		if(!this.element.chain('active') || !this.isActive)
-			return this.element;
+			{return this.element;}
 		
 		var self = this;
 		var builder = this.element.chain('builder');
@@ -115,9 +322,9 @@ $.Chain.service('items', {
 				.item('root', self.element);
 			
 			if(self.linkElement &amp;&amp; $.Chain.jobject(this) &amp;&amp; this.item())
-				clone.item('link', this, 'self');
+				{clone.item('link', this, 'self');}
 			else
-				clone.item(this);
+				{clone.item(this);}
 			
 			clone.chain(builder);
 		};
@@ -134,30 +341,27 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
-	$push: function()
-	{
-		this.isActive = true;
-		this.pushBuffer = this.pushBuffer.concat(Array.prototype.slice.call(arguments));
-		this.update();
-		
-		return this.element;
-	},
-	
-	$shift: function()
-	{
-		this.isActive = true;
-		this.shiftBuffer = this.shiftBuffer.concat(Array.prototype.slice.call(arguments));
-		this.update();
-		
-		return this.element;
-	},
-	
+	/**
+	 * Add item(s). use @items('add', 'shift', item)@ to add item at the top
+	 * 
+	 * @alias items('add')
+	 * @alias jQuery.Chain.services.items.$add
+	 * 
+	 * @param {Object} item
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$add: function()
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		var cmd;
 		var args = Array.prototype.slice.call(arguments);
+		// Extract command
 		if(typeof args[0] == 'string')
-			cmd = args.shift();
+			{cmd = args.shift();}
+		
 		var buffer = (cmd == 'shift') ? 'shiftBuffer' : 'pushBuffer';
 		
 		this.isActive = true;
@@ -167,63 +371,126 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Merge items with array of item data
+	 * 
+	 * @alias items('merge')
+	 * @alias jQuery.Chain.services.items.$merge
+	 * 
+	 * @param {String} cmd Switch for push/shift
+	 * @param {Array} items Item Data
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$merge: function(cmd, items)
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		if(typeof cmd != 'string')
-			items = cmd;
+			{items = cmd;}
 		var buffer = (cmd == 'shift') ? 'shiftBuffer' : 'pushBuffer';
 		
 		this.isActive = true;
 		if($.Chain.jobject(items))
-			this[buffer] = this[buffer].concat(items.map(function(){return $(this)}).get());
+			{this[buffer] = this[buffer].concat(items.map(function(){return $(this);}).get());}
 		else if(items instanceof Array)
-			this[buffer] = this[buffer].concat(items);
+			{this[buffer] = this[buffer].concat(items);}
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Replace items with new items array
+	 * 
+	 * @alias items('replace')
+	 * @alias jQuery.Chain.services.items.$replace
+	 * 
+	 * @param {String} cmd Switch for push/shift
+	 * @param {Array} items Item Data
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$replace: function(cmd, items)
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		if(typeof cmd != 'string')
-			items = cmd;
+			{items = cmd;}
 		var buffer = (cmd == 'shift') ? 'shiftBuffer' : 'pushBuffer';
 		
 		this.isActive = true;
 		this.empty();
 		
 		if($.Chain.jobject(items))
-			this[buffer] = items.map(function(){return $(this)}).get();
+			{this[buffer] = items.map(function(){return $(this);}).get();}
 		else if(items instanceof Array)
-			this[buffer] = items;
+			{this[buffer] = items;}
 		
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Remove item
+	 * 
+	 * @alias items('remove')
+	 * @alias jQuery.Chain.services.items.$remove
+	 * 
+	 * @param {Object, Number} item
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$remove: function()
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		for(var i=0; i&lt;arguments.length; i++)
-			this.handler(arguments[i]).item('remove', true);
+			{this.handler(arguments[i]).item('remove', true);}
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Reorder Item
+	 * 
+	 * @alias items('reorder')
+	 * @alias jQuery.Chain.services.items.$reorder
+	 * 
+	 * @param {Object} item1 Item 1
+	 * @param {Object} item2 Item 2
+	 * 
+	 * @return {Object} jQuery object
+	 */ 
 	$reorder: function(item1, item2)
 	{
 		if(item2)
-			this.handler(item1).before(this.handler(item2));
+			{this.handler(item1).before(this.handler(item2));}
 		else
-			this.handler(item1).appendTo(this.element.chain('anchor'));
+			{this.handler(item1).appendTo(this.element.chain('anchor'));}
 		this.update();
 		
 		return this.element;
 	},
 	
+	/**
+	 * Clear all items
+	 * 
+	 * @alias items('empty')
+	 * @alias jQuery.Chain.services.items.$empty
+	 * 
+	 * @return {Object} jQuery object
+	 */ 
 	$empty: function()
 	{
+		if(this.linkElement)
+			{return this.element;}
+		
 		this.empty();
 		this.shiftBuffer = [];
 		this.pushBuffer = [];
@@ -232,13 +499,36 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Like @items()@ but returns array of data instead of the jQuery object.
+	 * 
+	 * @alias items('data')
+	 * @alias jQuery.Chain.services.items.$data
+	 * 
+	 * @return {Array} list of data
+	 */ 
 	$data: function(x)
 	{
 		return this.handler(x).map(function(){return $(this).item();}).get();
 	},
 	
+	/**
+	 * Bind Items to other (chained) element. If one of them is updated,
+	 * the linked element will be updated.
+	 * 
+	 * @alias items('link')
+	 * @alias jQuery.Chain.services.items.$link
+	 * 
+	 * @param {Object} element element/selector to be linked with
+	 * @param {String} collection Collection to be linked with (has to be @&quot;self&quot;@ if linked to item)
+	 * 
+	 * @return {Object} jQuery Element
+	 * 
+	 * @see jQuery.Chain.services.items.collection
+	 */ 
 	$link: function(element, collection)
 	{
+		// Remove linked element if it already exist
 		if(this.linkElement)
 		{
 			this.linkElement.unbind('update', this.linkUpdater);
@@ -246,25 +536,39 @@ $.Chain.service('items', {
 		}
 		
 		element = $(element);
+		// If element exists
 		if(element.length)
 		{
 			var self = this;
 			this.linkElement = element;
+			// Create Collector Function
 			this.linkFunction = function()
 			{
 				if(typeof collection == 'function')
-					try{return collection.call(self.element, self.linkElement)}catch(e){return $().eq(-1)}
+				{
+					try{
+						return collection.call(self.element, self.linkElement);
+					}catch(e){
+						return $().eq(-1);
+					}
+				}
 				else if(typeof collection == 'string')
+				{
 					return self.linkElement.items('collection', collection);
+				}
 				else
+				{
 					return $().eq(-1);
+				}
 			};
 			
+			// Create Updater Function
 			this.linkUpdater = function()
 			{
 				self.element.items('replace', self.linkFunction());
 			};
 			
+			// Bind updater to linked element
 			this.linkElement.bind('update', this.linkUpdater);
 			this.linkUpdater();
 		}
@@ -272,31 +576,68 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Get index of an Item
+	 * 
+	 * @alias items('index')
+	 * @alias jQuery.Chain.services.items.$index
+	 * 
+	 * @param {Object} item
+	 * 
+	 * @return {Number} index
+	 */ 
 	$index: function(item)
 	{
 		return this.collection('all').index(this.handler(item));
 	},
 	
+	/**
+	 * Get collection of items. Define a collection by adding a function argument
+	 * 
+	 * @alias items('collection')
+	 * @alias jQuery.Chain.services.items.$collection
+	 * 
+	 * @param {String} col Collection name
+	 * @param {Function} fn Create a collection function
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$collection: function()
 	{
 		return this.collection.apply(this, Array.prototype.slice.call(arguments));
 	},
 	
+	/**
+	 * Check Status of @items@
+	 * 
+	 * @alias items('active')
+	 * @alias jQuery.Chain.services.items.$active
+	 * 
+	 * @return {Boolean} Status
+	 */ 
 	$active: function()
 	{
 		return this.isActive;
 	},
 	
+	/**
+	 * Backup Item to the state before being built.
+	 * 
+	 * @alias items('backup')
+	 * @alias jQuery.Chain.services.items.$backup
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$backup: function()
 	{
 		if(!this.element.chain('active') || !this.isActive)
-			return;
+			{return this.element;}
 		
 		var buffer = [];
 		this.collection('all').each(function(){
 			var item = $(this).item();
 			if(item)
-				buffer.push(item);
+				{buffer.push(item);}
 		});
 		
 		this.pushBuffer = buffer.concat(this.pushBuffer);
@@ -306,6 +647,14 @@ $.Chain.service('items', {
 		return this.element;
 	},
 	
+	/**
+	 * Destroy items service.
+	 * 
+	 * @alias items('destroy')
+	 * @alias jQuery.Chain.services.items.$destroy
+	 * 
+	 * @return {Object} jQuery Element
+	 */ 
 	$destroy: function()
 	{
 		this.empty();
@@ -315,6 +664,11 @@ $.Chain.service('items', {
 
 // Filtering extension
 $.Chain.extend('items', {
+	/**
+	 * Filtering subroutine
+	 * 
+	 * @alias jQuery.Chain.services.items.doFilter
+	 */ 
 	doFilter: function()
 	{
 		var props = this.searchProperties;
@@ -322,24 +676,32 @@ $.Chain.extend('items', {
 		
 		if(text)
 		{
+			// Make text lowerCase if it is a string
 			if(typeof text == 'string')
-				text = text.toLowerCase();
+				{text = text.toLowerCase();}
 			
+			// Filter items
 			var items = this.element.items(true).filter(function(){
 				var data = $(this).item();
+				// If search properties is defined, search for text in those properties
 				if(props)
 				{
 					for(var i=0; i&lt;props.length; i++)
-						if(typeof data[i] == 'string'
-							&amp;&amp; !!(typeof text == 'string' ? data[i].toLowerCase() : data[i]).match(text))
-							return true;
+					{
+						if(typeof data[props[i]] == 'string'
+							&amp;&amp; !!(typeof text == 'string' ? data[props[i]].toLowerCase() : data[props[i]]).match(text))
+							{return true;}
+					}
 				}
+				// Otherwise search in all properties
 				else
 				{
-					for(var i in data)
-						if(typeof data[i] == 'string'
-							&amp;&amp; !!(typeof text == 'string' ? data[i].toLowerCase() : data[i]).match(text))
-							return true;
+					for(var prop in data)
+					{
+						if(typeof data[prop] == 'string'
+							&amp;&amp; !!(typeof text == 'string' ? data[prop].toLowerCase() : data[prop]).match(text))
+							{return true;}
+					}
 				}
 			});
 			this.element.items(true).not(items).hide();
@@ -353,20 +715,33 @@ $.Chain.extend('items', {
 		}
 	},
 	
+	/**
+	 * Filter items by criteria. Filtered items will be hidden.
+	 * 
+	 * @alias items('filter')
+	 * @alias jQuery.Chain.services.items.$filter
+	 * 
+	 * @param {String, RegExp} text Search keyword
+	 * @param {String, Array} properties Search properties
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$filter: function(text, properties)
 	{
-		if(arguments.length == 0)
-			return this.update();
+		// If no argument, just refilter
+		if(!arguments.length)
+			{return this.update();}
 		
 		this.searchText = text;
 		
-		if(typeof properties == 'text')
-			this.searchProperties = [properties];
+		if(typeof properties == 'string')
+			{this.searchProperties = [properties];}
 		else if(properties instanceof Array)
-			this.searchProperties = properties;
+			{this.searchProperties = properties;}
 		else
-			this.searchProperties = null;
+			{this.searchProperties = null;}
 		
+		// Bind to preupdate
 		if(!this.searchBinding)
 		{
 			var self = this;
@@ -380,6 +755,11 @@ $.Chain.extend('items', {
 
 // Sorting extension
 $.Chain.extend('items', {
+	/**
+	 * Sorting subroutine
+	 * 
+	 * @alias jQuery.Chain.services.items.doSort
+	 */ 
 	doSort: function()
 	{
 		var name = this.sortName;
@@ -406,7 +786,7 @@ $.Chain.extend('items', {
 			array = opt.desc ? array.reverse() : array;
 			
 			for(var i=0; i&lt;array.length; i++)
-				this.element.chain('anchor').append(array[i]);
+				{this.element.chain('anchor').append(array[i]);}
 			
 			opt.desc = opt.toggle ? !opt.desc : opt.desc;
 		}
@@ -417,15 +797,26 @@ $.Chain.extend('items', {
 		}
 	},
 	
+	/**
+	 * Sort items by property.
+	 * 
+	 * @alias items('sort')
+	 * @alias jQuery.Chain.services.items.$sort
+	 * 
+	 * @param {String} name sorting property
+	 * @param {Object} opt {toggle:true/false, desc:true/false, type:'number/default'}
+	 * 
+	 * @return {Object} jQuery Object
+	 */ 
 	$sort: function(name, opt)
 	{
 		if(!name &amp;&amp; name !== null &amp;&amp; name !== false)
-			return this.update();
+			{return this.update();}
 		
 		if(this.sortName != name)
-			this.sortOpt = $.extend({desc:false, type:'default', toggle:false}, opt);
+			{this.sortOpt = $.extend({desc:false, type:'default', toggle:false}, opt);}
 		else
-			$.extend(this.sortOpt, opt);
+			{$.extend(this.sortOpt, opt);}
 		
 		this.sortName = name;
 		</diff>
      <filename>src/items.js</filename>
    </modified>
    <modified>
      <diff>@@ -34,14 +34,14 @@ $.Chain.service('update', {
 	handler: function(opt)
 	{
 		if(typeof opt == 'function')
-			return this.bind(opt);
+			{return this.bind(opt);}
 		else
-			return this.trigger(opt);
+			{return this.trigger(opt);}
 	},
 	
 	/**
 	 * If you pass a function to update, it will bind it to the update event.
-	 * just like jQuery&#8217;s @click()@ or @mouseover()@.
+	 * just like jQuerys @click()@ or @mouseover()@.
 	 * 
 	 * @alias update(fn)
 	 * @alias jQuery.Chain.services.update.bind
@@ -89,7 +89,7 @@ $.Chain.service('update', {
 		this.element.triggerHandler('preupdate', this.element.item());
 		
 		if(opt == 'hard')
-			this.element.items(true).each(function(){$(this).update();});
+			{this.element.items(true).each(function(){$(this).update();});}
 		
 		this.element.triggerHandler('update', this.element.item());
 		</diff>
      <filename>src/update.js</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>generate.sh</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>34c80a2858016f7eebcfe19a06e6ed9ceceae7b2</id>
    </parent>
  </parents>
  <author>
    <name>Rizqi Ahmad</name>
    <email>raid_ox@yahoo.de</email>
  </author>
  <url>http://github.com/raid-ox/chain.js/commit/b712e793aef0699e4540c235e122a4e55b0432cd</url>
  <id>b712e793aef0699e4540c235e122a4e55b0432cd</id>
  <committed-date>2008-10-18T14:51:23-07:00</committed-date>
  <authored-date>2008-10-18T14:51:23-07:00</authored-date>
  <message>Version 0.2 Final Revision. See Changelog for details. I hope this is really final...</message>
  <tree>4a611f1ef91c1b92dd6810489dc941703d3c857b</tree>
  <committer>
    <name>Rizqi Ahmad</name>
    <email>raid_ox@yahoo.de</email>
  </committer>
</commit>
