 			);
 		}
 		
+		private function generateIndexReadyForQuality(quality:int):void{
+			var rateItem:HTTPStreamingM3U8IndexRateItem = _rateVec[quality];
+			var isReady:Boolean = false;
+			
+			if (rateItem.isParsed) {
+				var keys:Vector.<HTTPStreamingM3U8IndexKey> = rateItem.key;
+				if (keys) {
+					isReady = true;
+					for (var i:int=keys.length-1; i >= 0; i--) {
+						isReady = isReady && keys[i].isReady();
+					}
+				} else {
+					isReady = true;
+				}
+				
+				// Send off notification if ready
+				if (isReady) {
+					var initialOffset:Number;
+					if(rateItem.isLive){
+						initialOffset = rateItem.totalTime - ((rateItem.totalTime/rateItem.manifest.length) * 3);
+						if(initialOffset < rateItem.totalTime - 30)
+							initialOffset = rateItem.totalTime - 30;
+					}
+					notifyIndexReady(quality, initialOffset);					
+				}
+			}
+		}
+		
 		private function notifyIndexReady(quality:int, offset:Number):void{
 			
 			if(_DVR){

					_fileHandler.initialOffset = manifest[_segment].startTime;
					//dispatchEvent(new HTTPHLSStreamingEvent(HTTPHLSStreamingEvent.DISCONTINUITY));
				}
				
				++_segment;
				++_absoluteSegment;
			}
			
			return request;
		}
		
		/*

				_reloadTime = getTimer() - _reloadTime;
				logger.info("Playlist reload time {0} sec", (_reloadTime/1000));
			}
			var quality:int;
			if(getQualifiedClassName(indexContext) == "Array") {
				// TODO: Update this to use an appropriate Object context
				data = ByteArray(data);
				var keyRequest:Array = indexContext as Array;
				var keyItem:HTTPStreamingM3U8IndexKey = keyRequest[0];
				quality = keyRequest[1];
				
				// Set key
				keyItem.key = data;
				generateIndexReadyForQuality(quality);
			} else {
				quality = indexContext as int;
				data = String(data).replace(/\\\s*[\r?\n]\s*/g, "");
				
				if(String(data).localeCompare(_prevPlaylist) == 0)
					++_matchCounter;
				
				if(_matchCounter == HLSSettings.hlsMaxErrors){ // if delivered playlist again not changed then error_event (or all what you want)
					CONFIG::LOGGING
					{
						logger.error("Stream is stuck. Playlist on server don't updated!");
					}
					dispatchEvent(new HTTPStreamingEvent(HTTPStreamingEvent.INDEX_ERROR));
				}
				
				_prevPlaylist = String(data);
				
				var lines:Vector.<String> = Vector.<String>(String(data).split(/\r?\n/));
				var rateItem:HTTPStreamingM3U8IndexRateItem = new HTTPStreamingM3U8IndexRateItem(_streamQualityRates[quality], _streamURLs[quality]);
				var indexItem:HTTPStreamingM3U8IndexItem;
				var len:int = lines.length;
				var discontinuity:Boolean = false;
				var keyExistsInIndex:Boolean = false;
				var keyExists:Boolean = false;
				var keyIndex:int = -1;
				var keyIv:String;
				var keyIvGiven:Boolean = false;
				var keyIvIndex:int = 0;
				var duration:Number = 0;
				
				for(var i:int = 0; i < len; i++){
					if(i == 0){
						if(lines[i] != '#EXTM3U'){
							dispatchEvent(new HTTPStreamingEvent(HTTPStreamingEvent.INDEX_ERROR));
							return;
						}
					}
					
					if (lines[i].indexOf("#") != 0 && lines[i].length > 0) { //non-empty line not starting with # => segment URI
						var url:String = (lines[i].search(/(ftp|file|https?):\/\//) == 0) ?  lines[i] : rateItem.url.substr(0, rateItem.url.lastIndexOf('/')+1) + lines[i];
						// spike for hidden discontinuity
						if(url.match(/SegNum(\d+)/)){
							var chunkIndex:int = parseInt(url.match(/SegNum(\d+)/)[1]);
							if(chunkIndex <= _prevChunkIndex)
								discontinuity = true;
							_prevChunkIndex = chunkIndex;
						}
						// _spike
						indexItem = new HTTPStreamingM3U8IndexItem(duration, url, discontinuity);
						// Add key if it exists
						if(keyExists) {
							indexItem.key = keyIndex;						
							// Attach correct IV
							if(keyIvGiven) {
								indexItem.iv = keyIv;
							} else {
								indexItem.iv = Padding.zeropad(keyIvIndex, 32);
								keyIvIndex++;
							}
						}
						rateItem.addIndexItem(indexItem);
						discontinuity = false;
					}
					else if(lines[i].indexOf("#EXTINF:") == 0){
						var duration:Number = parseFloat(lines[i].match(/([\d\.]+)/)[1]);						
					}else if(lines[i].indexOf("#EXT-X-KEY:") == 0){
						// Flag that encryption key exists in whole playlist
						keyExistsInIndex = true;
						// Flag that encryption key exists for this segment
						keyExists = true;
						
						// Parse for encryption key
						var keyAttributeString:String = lines[i].substring(11);
						var keyAttributes:Array = keyAttributeString.split(",");
						var keyComponent:String;
						var keyValue:String;
						var keyType:String;
						var keyUrl:String;
						
						for (var k:int=keyAttributes.length-1; k >= 0; k--) {
							var keyComponents:Array = keyAttributes[k].split("=");
							keyComponent = keyComponents[0];
							keyValue = keyComponents[1];
							if (keyComponents.length > 2) {
								for (var j:int=2; j < keyComponents.length; j++) {
									keyValue = keyValue + "=" + keyComponents[j];
								}
							}
							
							if(keyComponent == "METHOD") {
								keyType = keyValue;
							}else if(keyComponent == "URI") {
								var strip:RegExp = /"/g;
								keyUrl = keyValue.replace(strip,"");
								if (keyUrl.search(/(ftp|file|https?):\/\//) != 0) keyUrl = rateItem.url.substr(0, rateItem.url.lastIndexOf('/') + 1) + keyUrl;
							}else if(keyComponent == "IV") {
								keyIv = keyValue.substr(2);
							}
						}
						
						// TODO - Support SAMPLE-AES
						if(keyType == "AES-128") {
							var keyItem:HTTPStreamingM3U8IndexKey = new HTTPStreamingM3U8IndexKey(keyType, keyUrl);
							if(keyIv) {
								keyIvGiven = true;
							}
							rateItem.addIndexKey(keyItem);
							keyIndex++;
							var keyRequest:Array = new Array(keyItem, quality);
							dispatchEvent(new HTTPStreamingIndexHandlerEvent(HTTPStreamingIndexHandlerEvent.REQUEST_LOAD_INDEX, false, false, false, NaN, null, null, new URLRequest(keyUrl), keyRequest, true));
						}
					}else if(lines[i].indexOf("#EXT-X-ENDLIST") == 0){
						rateItem.isLive = false;
					}else if(lines[i].indexOf("#EXT-X-MEDIA-SEQUENCE:") == 0){
						keyIvIndex = parseInt(lines[i].match(/(\d+)/)[1]);
						rateItem.sequenceNumber = keyIvIndex;
					}else{
						if(lines[i].indexOf("#EXT-X-TARGETDURATION:") == 0){
							rateItem.targetDuration = parseFloat(lines[i].match(/([\d\.]+)/)[1]);
						}
						if(lines[i].indexOf("#EXT-X-DISCONTINUITY") == 0){
							discontinuity = true;
							// Reset encryption key variables
							keyExists = false;
							keyIvGiven = false;
							keyIvIndex = 0;
						}
					}
				}
				rateItem.isParsed = true;
				
				if(_DVR){
					if(isNaN(_dvrStartTime))
						_dvrStartTime = 0.0;
					else{
						var prevRateItem:HTTPStreamingM3U8IndexRateItem = _rateVec[quality];
						if(prevRateItem){
							len = rateItem.sequenceNumber-prevRateItem.sequenceNumber;
							if(len > prevRateItem.manifest.length){
								len = prevRateItem.manifest.length;
							}
							for(i = 0; i < len; i++){
								_dvrStartTime += prevRateItem.manifest[i].duration;
							}
						}
					}
				}
				
				_rateVec[quality] = rateItem;
				generateIndexReadyForQuality(quality);
				
				if(rateItem.isLive){
					notifyTotalDuration(rateItem.totalTime, rateItem.isLive);
					_quality = quality;
				}				
			}
		}
		
