 				getSessionState(this)
 			);
 		}
+		
+		private function setChain(root:Object, property_chain:Array, value:Object):*
+		{
+			property_chain = [].concat(property_chain); // makes a copy and converts a single string into an array
+			var last_property:String = property_chain.pop();
+			for each (var prop:String in property_chain)
+				root = root[prop] || (root[prop] = {});
+			// if value not given, return current value
+			if (arguments.length == 2)
+				return root[last_property];
+			// set the value and return it
+			return root[last_property] = value;
+		};
+
 		
 		private function handleScriptResult(event:ResultEvent, sessionState:Object):void
 		{


package weave.data.DataSources
{
	import flash.events.ErrorEvent;
	
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	
	import weave.api.core.ILinkableObject;
	import weave.api.data.ColumnMetadata;
	import weave.api.data.IAttributeColumn;

				return;
			
			var keyType:String;
			var columnArray:Array;
			var simpleInputs:Object = {};
			var columnsByKeyType:Object = {}; // Object(keyType -> Array of IAttributeColumn)
			for each (var obj:ILinkableObject in inputs.getObjects())
			{
				var name:String = inputs.getName(obj);
				var column:IAttributeColumn = obj as IAttributeColumn;
				var hashMap:ILinkableHashMap = obj as ILinkableHashMap;
				if (column || hashMap)
				{
					var columnDescendants:Array = null;
					if (column)
						columnDescendants = [column];
					else if (hashMap)
						columnDescendants = getLinkableDescendants(hashMap, IAttributeColumn);
					
					for each (column in columnDescendants)
					{
						keyType = column.getMetadata(ColumnMetadata.KEY_TYPE);
						columnArray = columnsByKeyType[keyType] || (columnsByKeyType[keyType] = [])
						columnArray.push(column);
					}
				}
				else
				{
