public virtual void CopyAsync(Uri[] src, Uri[] dest, IFileOperationProgress progress) {
			if(src.Length != dest.Length) throw new ArgumentException();
			for(int i = 0; i < src.Length; ++i) {
				progress.UpdateProgress(i + 1, src.Length, (double)i/(double)src.Length, null, null);
				Copy(src[i], dest[i]);
			}
			progress.Finish();
		}
		public override void CopyAsync(Uri[] src, Uri[] dest, IFileOperationProgress progress) {
			if(OS == PluginOSType.Windows) {
				//FileSystem.CopyDirectory(
			}
			else if(OS == PluginOSType.Unix) {
				long? prev = null;
				DateTime? prevTime = null;
				
				Gnome.Vfs.Uri[] src2 = (from uri in src select new Gnome.Vfs.Uri(Gnome.Vfs.Uri.GetUriFromLocalPath(uri.GetScrubbedLocalPath()))).ToArray();
				Gnome.Vfs.Uri[] dest2 = (from uri in dest select new Gnome.Vfs.Uri(Gnome.Vfs.Uri.GetUriFromLocalPath(uri.GetScrubbedLocalPath()))).ToArray();
				Gnome.Vfs.Xfer.XferUriList(src2,
			                           dest2,
			                           Gnome.Vfs.XferOptions.Recursive, Gnome.Vfs.XferErrorMode.Query, Gnome.Vfs.XferOverwriteMode.Query,
			                           delegate(Gnome.Vfs.XferProgressInfo info) {
					switch(info.Status) {
						case Gnome.Vfs.XferProgressStatus.Ok:
							double? bitrate = null;
							TimeSpan? etr = null;
							DateTime time = DateTime.Now;
							if(prev != null && prevTime != null) {
								double sec = (time - (DateTime)prevTime).TotalSeconds;
								bitrate = ((double)info.TotalBytesCopied - (double)prev) / sec;
								try { etr = TimeSpan.FromSeconds((info.BytesTotal - info.TotalBytesCopied)/(double)bitrate); }
								catch {}
							}
							prev = info.TotalBytesCopied;
							prevTime = time;
							
							progress.UpdateProgress((int)info.FileIndex, 0, (double)info.TotalBytesCopied/(double)info.BytesTotal, bitrate, etr);
							return 1;
						case Gnome.Vfs.XferProgressStatus.Vfserror:
							Console.WriteLine(info.VfsStatus.ToString());
							switch(progress.OnError(null, null)) {
								case FileErrorAction.Abort:
									return (int)Gnome.Vfs.XferErrorAction.Abort;
								case FileErrorAction.Retry:
									return (int)Gnome.Vfs.XferErrorAction.Retry;
								case FileErrorAction.Ignore:
									return (int)Gnome.Vfs.XferErrorAction.Skip;
							}
							return (int)Gnome.Vfs.XferErrorAction.Abort;
						case Gnome.Vfs.XferProgressStatus.Overwrite:
							bool applytoall;
							bool? overwrite = progress.OnOverwrite(new Uri(info.SourceName), new Uri(info.TargetName), out applytoall);
							if(overwrite == null) return (int)Gnome.Vfs.XferOverwriteAction.Abort;
							if((bool)overwrite) {
								if(applytoall) {
									return (int)Gnome.Vfs.XferOverwriteAction.ReplaceAll;
								}
								else {
									return (int)Gnome.Vfs.XferOverwriteAction.Replace;
								}
							}
							else {
								if(applytoall) {
									return (int)Gnome.Vfs.XferOverwriteAction.SkipAll;
								}
								else {
									return (int)Gnome.Vfs.XferOverwriteAction.Skip;
								}
							}
					}
					return 0;
				});
				progress.Finish();
			}
			else {
				base.CopyAsync(src, dest, progress);
			
			}
		}