diff -ruN uppsrc/ide/ide.lay uppsrc/ide/ide.lay
--- uppsrc/ide/ide.lay	2011-11-06 09:29:12 +0600
+++ uppsrc/ide/ide.lay	2011-11-08 13:36:45 +0600
@@ -622,6 +622,7 @@
 	ITEM(EditString, folder, LeftPosZ(80, 312).TopPosZ(8, 19))
 	ITEM(Label, dv___2, SetLabel(t_("Import files")).LeftPosZ(8, 72).TopPosZ(32, 19))
 	ITEM(EditString, files, LeftPosZ(80, 312).TopPosZ(32, 19))
+	ITEM(Option, tree, SetLabel(t_("Including tree structure")).LeftPosZ(8, 192).TopPosZ(56, 19))
 	ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(260, 64).TopPosZ(60, 24))
 	ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(328, 64).TopPosZ(60, 24))
 END_LAYOUT
diff -ruN uppsrc/ide/UppDlg.h uppsrc/ide/UppDlg.h
--- uppsrc/ide/UppDlg.h	2011-11-08 03:26:22 +0600
+++ uppsrc/ide/UppDlg.h	2011-11-08 13:36:45 +0600
@@ -218,8 +218,11 @@
 	void AddItem(const String& name, bool separator, bool readonly);
 	void AddTopicGroup();
 	void AddSeparator();
-	void Import();
+	void DoImportTree(const String& dir, const String& mask, bool sep, Progress& pi, int from);
+	void DoImportTree(const String& dir, const String& mask, bool sep, Progress& pi);
 	void DoImport(const String& dir, const String& mask, bool sep, Progress& pi);
+	void DoImport(const String& dir, const String& mask, bool sep, Progress& pi, bool tree);
+	void Import();
 	void RemoveFile();
 	void DelFile();
 	void RenameFile();
diff -ruN uppsrc/ide/UppWspc.cpp uppsrc/ide/UppWspc.cpp
--- uppsrc/ide/UppWspc.cpp	2011-11-08 03:26:22 +0600
+++ uppsrc/ide/UppWspc.cpp	2011-11-08 14:11:33 +0600
@@ -435,13 +435,60 @@
 	files <<= "*.cpp *.h *.hpp *.c *.C *.cxx *.cc";
 }
 
+void WorkspaceWork::DoImportTree(const String& dir, const String& mask, bool sep, Progress& pi, int from)
+{
+	String active = GetActivePackage();
+	if(active.IsEmpty()) return;
+	FindFile ff(AppendFileName(dir, "*.*"));
+	Vector<String> dirs, files;
+	while(ff) {
+		String p = AppendFileName(dir, ff.GetName());
+		if(ff.IsFile() && PatternMatchMulti(mask, ff.GetName()))
+			files.Add(p);
+		if(ff.IsFolder())
+			dirs.Add(p);
+		ff.Next();
+	}
+	String relPath(dir.Mid(from)),
+		absPath = SourcePath(active, relPath);
+	if(sep && files.GetCount()) {
+		if(!DirectoryExists(absPath))
+			if(!RealizeDirectory(absPath))
+				throw Format("An error occurred while creating the directory:&\1%s", absPath);
+		Package::File& f = actual.file.Add();
+		f = relPath;
+		f.separator = f.readonly = true;
+	}
+	Sort(files, GetLanguageInfo());
+	Sort(dirs, GetLanguageInfo());
+	for(int i = 0; i < files.GetCount(); i++) {
+		if(pi.StepCanceled())
+			throw String();
+		String name = GetFileName(files[i]);
+		if(FileCopy(files[i], AppendFileName(absPath, name))) {
+			Package::File& f = actual.file.Add();
+			f = AppendFileName(relPath, name);
+			f.separator = f.readonly = false;
+		}
+		else
+			throw Format("An error occurred while copying the file:&\1%s", files[i]);
+	}
+	for(int i = 0; i < dirs.GetCount(); i++)
+		DoImportTree(dirs[i], mask, true, pi, from);
+}
+
+void WorkspaceWork::DoImportTree(const String& dir, const String& mask, bool sep, Progress& pi)
+{
+	int from = dir.EndsWith(AsString(DIR_SEP)) ? dir.GetCount() : dir.GetCount() + 1;
+	DoImportTree(dir, mask, sep, pi, from);
+}
+
 void WorkspaceWork::DoImport(const String& dir, const String& mask, bool sep, Progress& pi)
 {
 	String active = GetActivePackage();
 	if(active.IsEmpty()) return;
 	FindFile ff(AppendFileName(dir, "*.*"));
-	Vector<String> files;
-	Vector<String> dirs;
+	Vector<String> dirs, files;
 	while(ff) {
 		String p = AppendFileName(dir, ff.GetName());
 		if(ff.IsFile() && PatternMatchMulti(mask, ff.GetName()))
@@ -454,23 +501,33 @@
 		Package::File& f = actual.file.Add();
 		f = GetFileTitle(dir);
 		f.separator = f.readonly = true;
-		sep = false;
 	}
-	Sort(files);
-	Sort(dirs);
+	Sort(files, GetLanguageInfo());
+	Sort(dirs, GetLanguageInfo());
 	for(int i = 0; i < files.GetCount(); i++) {
 		if(pi.StepCanceled())
 			throw String();
 		String name = GetFileName(files[i]);
-		SaveFile(SourcePath(active, name), LoadFile(files[i]));
-		Package::File& f = actual.file.Add();
-		f = name;
-		f.separator = f.readonly = false;
+		if(FileCopy(files[i], SourcePath(active, name))) {
+			Package::File& f = actual.file.Add();
+			f = name;
+			f.separator = f.readonly = false;
+		}
+		else
+			throw Format("An error occurred while copying the file:&\1%s", files[i]);
 	}
 	for(int i = 0; i < dirs.GetCount(); i++)
 		DoImport(dirs[i], mask, true, pi);
 }
 
+void WorkspaceWork::DoImport(const String& dir, const String& mask, bool sep, Progress& pi, bool tree)
+{
+	if(tree)
+		DoImportTree(dir, mask, sep, pi);
+	else
+		DoImport(dir, mask, sep, pi);
+}
+
 void WorkspaceWork::Import()
 {
 	String active = GetActivePackage();
@@ -482,9 +539,12 @@
 	int fci = filelist.GetCursor();
 	int cs = filelist.GetSbPos();
 	try {
-		DoImport(~dlg.folder, ~dlg.files, false, pi);
+		DoImport(~dlg.folder, ~dlg.files, false, pi, ~dlg.tree);
+	}
+	catch(String msg) {
+		if(!msg.IsEmpty())
+			Exclamation(msg);
 	}
-	catch(String) {}
 	SaveLoadPackage();
 	filelist.SetSbPos(cs);
 	filelist.SetCursor(fci >= 0 ? fci : filelist.GetCount() - 1);
