 
 		public function CSVDataSource()
 		{
-		}
-
-		public const metadata:LinkableVariable = registerLinkableChild(this, new LinkableVariable(null, typeofIsObject));
-		public const url:LinkableString = newLinkableChild(this, LinkableString);
+			registerLinkableChild(rawDataPromise, url);
+		}
+
 		public const csvData:LinkableVariable = registerLinkableChild(this, new LinkableVariable(Array), handleCSVDataChange);
 		public const keyType:LinkableString = newLinkableChild(this, LinkableString, updateKeys);
 		public const keyColName:LinkableString = newLinkableChild(this, LinkableString, updateKeys);
 		
+		public const metadata:LinkableVariable = registerLinkableChild(this, new LinkableVariable(null, typeofIsObject));
 		private function typeofIsObject(value:Object):Boolean { return typeof value == 'object'; }
 		
-		private const asyncParser:CSVParser = registerLinkableChild(this, new CSVParser(true), handleCSVParser);
+		public const url:LinkableString = newLinkableChild(this, LinkableString);
+		
+		public const delimiter:LinkableString = registerLinkableChild(this, new LinkableString(',', verifyDelimiter), parseRawData);
+		private function verifyDelimiter(value:String):Boolean { return value && value.length == 1 && value != '"'; }
+		
+		private const rawDataPromise:LinkablePromise = registerLinkableChild(this, new LinkablePromise(getRawData, null, "Downloading CSV data"), parseRawData);
+		private function getRawData():AsyncToken
+		{
+			if (!url.value)
+				return null;
+			return WeaveAPI.URLRequestUtils.getURL(rawDataPromise, new URLRequest(url.value));
+		}
+		private function parseRawData():void
+		{
+			if (rawDataPromise.error)
+				reportError(rawDataPromise.error);
+			
+			if (detectLinkableObjectChange(parseRawData, delimiter))
+			{
+				if (csvParser)
+					disposeObject(csvParser);
+				csvParser = registerLinkableChild(this, new CSVParser(true, delimiter.value), handleCSVParser);
+			}
+			
+			/*if (linkableObjectIsBusy(rawDataPromise))
+				return;*/
+			
+			csvParser.parseCSV(String(rawDataPromise.result || ''));
+		}
+		
+		private var csvParser:CSVParser;
+		
 		/**
 		 * Called when csv parser finishes its task
 		 */

	import flash.net.URLRequest;
	import flash.utils.getQualifiedClassName;
	
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.utils.StringUtil;

		}
		
		/**
		 * This gets called as a grouped callback.
		 */		
		override protected function initialize():void
		{
			// if url is specified, do not use csvDataString
			if (url.value)
				csvData.setSessionState(null);
			
			// recalculate all columns previously requested because CSV data may have changed.
			refreshAllProxyColumns();
