 				minMaxChanged = true;
 			}
 			
-			_changed.execute(this, null);
-			_boundsChanged.execute(this);
-		}
-		
-		public function lockData(): Vector.<Number> {
-			if (_dataLocked) 
-				throw new Error("Data lock is already active");
+			if (_locked)
+			{
+				_invalidMinMax = minMaxChanged;
+			}
+			else
+			{
+				_changed.execute(this, null);
+				if (minMaxChanged)
+					_boundsChanged.execute(this);
+			}
+		}
+		
+		public function lock() : Vector.<Number>
+		{
+			if (_locked) 
+				throw new Error("The stream is already locked.");
 			if (_localDispose)
-				throw new Error("Can not lock stream data which is marked for disposal");
+				throw new Error("Cannot lock stream data which is already disposed.");
+			
 			checkWriteUsage(this);
-			_dataLocked = true;
+			
+			_locked = true;
+			_invalidMinMax = false;
+			
 			return _data;
 		}
 		
-		public function unlockData(): void {
-			if (!_dataLocked)
+		public function unlock() : void
+		{
+			if (!_locked)
 				throw new Error("Data is not locked");
-			_dataLocked = false;
+			
+			_locked = false;
 			_invalidMinMax = true;
 			_changed.execute(this, null);
 		}

		{
			checkWriteUsage(this);
			
			var dataLength : int = data.length;

			if (dataLength % _format.dwordsPerVertex)
				throw new Error("Invalid data length.");

			for (var i : int = 0; i < dataLength; i++)
				_data.push(data[i]);

			_invalidMinMax = true;
			_changed.execute(this, null);
		}

		public function disposeLocalData(waitForUpload : Boolean = true) : void
		{
			if (_dataLocked)
				throw new Error("Stream data can not be disposed since it's locked for update");
			if (waitForUpload)
				_localDispose = true;

		{
			_data = value;
			_changed.execute(this, null);
		}
		
		public function get locked() : Boolean
		{
			return _locked;
		}
		
		public function get changed() : Signal
