From e9cc22fea48a6d80fccbd624fd9710dfa3830980 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 16 Feb 2013 00:26:21 +0000
Subject: Add regression test TestSaveNonRootFolderToIar

---
 .../Archiver/InventoryArchiveReadRequest.cs        |   4 +-
 .../Inventory/Archiver/InventoryArchiveUtils.cs    |  86 ++++++++++++++--
 .../Archiver/InventoryArchiveWriteRequest.cs       |   2 +-
 .../Archiver/Tests/InventoryArchiverTests.cs       |  84 +++++++++++++++-
 .../Avatar/Inventory/Archiver/Tests/PathTests.cs   |  30 +++---
 .../Tests/InventoryAccessModuleTests.cs            |   4 +-
 .../CoreModules/World/Archiver/AssetsRequest.cs    |   2 +
 .../Scenes/Tests/SceneObjectDeRezTests.cs          |   2 +-
 .../Framework/Scenes/Tests/TaskInventoryTests.cs   |   2 +-
 .../Framework/Scenes/Tests/UserInventoryTests.cs   |   6 +-
 .../Tests/Common/Helpers/UserInventoryHelpers.cs   | 109 +++++++++++++++++----
 11 files changed, 277 insertions(+), 54 deletions(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index ecbd07f..98285e9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -161,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                 string filePath = "ERROR";
                
                 List<InventoryFolderBase> folderCandidates
-                    = InventoryArchiveUtils.FindFolderByPath(
+                    = InventoryArchiveUtils.FindFoldersByPath(
                         m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
     
                 if (folderCandidates.Count == 0)
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                         // iar name and try to find that instead.
                         string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath);
                         List<InventoryFolderBase> folderCandidates
-                            = InventoryArchiveUtils.FindFolderByPath(
+                            = InventoryArchiveUtils.FindFoldersByPath(
                                 m_scene.InventoryService, m_userInfo.PrincipalID, plainPath);
             
                         if (folderCandidates.Count != 0)
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index 0d90a15..dbaf2aa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -52,13 +52,82 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
         /// <summary>
         /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder
         /// </summary>
+        /// <remarks>
+        /// This method does not handle paths that contain multiple delimitors
+        ///
+        /// FIXME: We have no way of distinguishing folders with the same path
         ///
+        /// FIXME: Delimitors which occur in names themselves are not currently escapable.
+        /// </remarks>
+        /// <param name="inventoryService">
+        /// Inventory service to query
+        /// </param>
+        /// <param name="userId">
+        /// User id to search
+        /// </param>
+        /// <param name="path">
+        /// The path to the required folder.
+        /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
+        /// </param>
+        /// <returns>The folder found.  Please note that if there are multiple folders with the same name then an 
+        /// unspecified one will be returned.  If no such folder eixsts then null is returned</returns>
+        public static InventoryFolderBase FindFolderByPath(
+            IInventoryService inventoryService, UUID userId, string path)
+        {
+            List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, userId, path);
+
+            if (folders.Count == 0)
+                return null;
+            else
+                return folders[0];
+        }
+
+        /// <summary>
+        /// Find a folder given a PATH_DELIMITER delimited path starting from a given folder
+        /// </summary>
+        /// <remarks>
         /// This method does not handle paths that contain multiple delimitors
         ///
         /// FIXME: We have no way of distinguishing folders with the same path
         ///
         /// FIXME: Delimitors which occur in names themselves are not currently escapable.
+        /// </remarks>
+        /// <param name="inventoryService">
+        /// Inventory service to query
+        /// </param>
+        /// <param name="startFolder">
+        /// The folder from which the path starts
+        /// </param>
+        /// <param name="path">
+        /// The path to the required folder.
+        /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
+        /// </param>
+        /// <returns>The folder found.  Please note that if there are multiple folders with the same name then an 
+        /// unspecified one will be returned.  If no such folder eixsts then null is returned</returns>
+        public static InventoryFolderBase FindFolderByPath(
+            IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
+        {
+            if (null == startFolder)
+                return null;
+
+            List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, startFolder, path);
+
+            if (folders.Count == 0)
+                return null;
+            else
+                return folders[0];
+        }
+
+        /// <summary>
+        /// Find a set of folders given a PATH_DELIMITER delimited path starting from a user's root folder
+        /// </summary>
+        /// <remarks>
+        /// This method does not handle paths that contain multiple delimitors
+        ///
+        /// FIXME: We have no way of distinguishing folders with the same path
         ///
+        /// FIXME: Delimitors which occur in names themselves are not currently escapable.
+        /// </remarks>
         /// <param name="inventoryService">
         /// Inventory service to query
         /// </param>
@@ -70,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
         /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
         /// </param>
         /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns>
-        public static List<InventoryFolderBase> FindFolderByPath(
+        public static List<InventoryFolderBase> FindFoldersByPath(
             IInventoryService inventoryService, UUID userId, string path)
         {
             InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
@@ -78,19 +147,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
             if (null == rootFolder)
                 return new List<InventoryFolderBase>();
 
-            return FindFolderByPath(inventoryService, rootFolder, path);
+            return FindFoldersByPath(inventoryService, rootFolder, path);
         }
         
         /// <summary>
-        /// Find a folder given a PATH_DELIMITER delimited path starting from this folder
+        /// Find a set of folders given a PATH_DELIMITER delimited path starting from this folder
         /// </summary>
-        ///
+        /// <remarks>
         /// This method does not handle paths that contain multiple delimitors
         ///
         /// FIXME: We have no way of distinguishing folders with the same path.
         ///
         /// FIXME: Delimitors which occur in names themselves are not currently escapable.
-        ///
+        /// </remarks>
         /// <param name="inventoryService">
         /// Inventory service to query
         /// </param>
@@ -102,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
         /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
         /// </param>
         /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns>
-        public static List<InventoryFolderBase> FindFolderByPath(
+        public static List<InventoryFolderBase> FindFoldersByPath(
             IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
         {
             List<InventoryFolderBase> foundFolders = new List<InventoryFolderBase>();
@@ -133,12 +202,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
             
             InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
 
+//            m_log.DebugFormat(
+//                "Found {0} folders in {1} for {2}", contents.Folders.Count, startFolder.Name, startFolder.Owner);
+
             foreach (InventoryFolderBase folder in contents.Folders)
             {
                 if (folder.Name == components[0])
                 {
                     if (components.Length > 1)
-                        foundFolders.AddRange(FindFolderByPath(inventoryService, folder, components[1]));
+                        foundFolders.AddRange(FindFoldersByPath(inventoryService, folder, components[1]));
                     else
                         foundFolders.Add(folder);
                 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 4c85637..d703498 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -289,7 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
                 {
                     m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
                     List<InventoryFolderBase> candidateFolders
-                        = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath);
+                        = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, rootFolder, m_invPath);
                     if (candidateFolders.Count > 0)
                         inventoryFolder = candidateFolders[0];
                 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 06f6e49..38254e5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -121,6 +121,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             
             Assert.That(iarr.ControlFileLoaded, Is.True);
         }
+
+        [Test]
+        public void TestSaveNonRootFolderToIar()
+        {
+            TestHelpers.InMethod();
+            TestHelpers.EnableLogging();
+
+            string userFirstName = "Jock";
+            string userLastName = "Stirrup";
+            string userPassword = "troll";
+            UUID userId = TestHelpers.ParseTail(0x20);
+
+            UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
+
+            // Create base folder
+            InventoryFolderBase f1 
+                = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1", true);
+            
+            // Create item1
+            SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Dog Object", 0x5);         
+            InventoryItemBase i1 = UserInventoryHelpers.AddInventoryItem(m_scene, so1, 0x50, 0x60, "f1");
+
+            // Create embedded folder
+            InventoryFolderBase f1_1 
+                = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1/f1.1", true);
+
+            // Create embedded item
+            SceneObjectGroup so1_1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Cat Object", 0x6);         
+            InventoryItemBase i2 = UserInventoryHelpers.AddInventoryItem(m_scene, so1_1, 0x500, 0x600, "f1/f1.1");
+
+            MemoryStream archiveWriteStream = new MemoryStream();
+            m_archiverModule.OnInventoryArchiveSaved += SaveCompleted;
+
+            mre.Reset();
+            m_archiverModule.ArchiveInventory(
+                Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream);
+            mre.WaitOne(60000, false);
+
+            // Test created iar
+            byte[] archive = archiveWriteStream.ToArray();
+            MemoryStream archiveReadStream = new MemoryStream(archive);
+            TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
+
+//            InventoryArchiveUtils.
+            bool gotf1 = false, gotf1_1 = false, gotso1 = false, gotso2 = false;
+
+            string f1FileName 
+                = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1));
+            string f1_1FileName 
+                = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1_1));
+            string so1FileName 
+                = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i1));
+            string so2FileName
+                = string.Format("{0}{1}", f1_1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i2));
+
+            string filePath;
+            TarArchiveReader.TarEntryType tarEntryType;
+            
+            while (tar.ReadEntry(out filePath, out tarEntryType) != null)
+            {
+//                Console.WriteLine("Got {0}", filePath);
+
+                if (filePath == f1FileName)
+                    gotf1 = true;
+                else if (filePath == f1_1FileName)
+                    gotf1_1 = true;
+                else if (filePath == so1FileName)
+                    gotso1 = true;
+                else if (filePath == so2FileName)
+                    gotso2 = true;
+            }
+
+//            Assert.That(gotControlFile, Is.True, "No control file in archive");
+            Assert.That(gotf1, Is.True);
+            Assert.That(gotf1_1, Is.True);
+            Assert.That(gotso1, Is.True);
+            Assert.That(gotso2, Is.True);
+
+            // TODO: Test presence of more files and contents of files.
+        }
         
         /// <summary>
         /// Test saving a single inventory item to an IAR
@@ -155,7 +235,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             item1.AssetID = asset1.FullID;
             item1.ID = item1Id;
             InventoryFolderBase objsFolder 
-                = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0];
+                = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0];
             item1.Folder = objsFolder.ID;
             m_scene.AddInventoryItem(item1);
 
@@ -250,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             item1.AssetID = asset1.FullID;
             item1.ID = item1Id;
             InventoryFolderBase objsFolder
-                = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0];
+                = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0];
             item1.Folder = objsFolder.ID;
             m_scene.AddInventoryItem(item1);
 
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
index 6eb3605..1871576 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             item1.AssetID = asset1.FullID;
             item1.ID = item1Id;
             InventoryFolderBase objsFolder 
-                = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
+                = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0];
             item1.Folder = objsFolder.ID;
             scene.AddInventoryItem(item1);
 
@@ -193,7 +193,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");            
 
             // Now try loading to a root child folder
-            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA");
+            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false);
             MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
             archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
 
@@ -202,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
 
             // Now try loading to a more deeply nested folder
-            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC");
+            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false);
             archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
             archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
 
@@ -287,7 +287,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             item1.AssetID = asset1.FullID;
             item1.ID = item1Id;
             InventoryFolderBase objsFolder 
-                = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
+                = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0];
             item1.Folder = objsFolder.ID;
             scene.AddInventoryItem(item1);
 
@@ -351,12 +351,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
                         foldersCreated, nodesLoaded);
     
                 List<InventoryFolderBase> folder1Candidates
-                    = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
+                    = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
                 Assert.That(folder1Candidates.Count, Is.EqualTo(1));
                 
                 InventoryFolderBase folder1 = folder1Candidates[0];
                 List<InventoryFolderBase> folder2aCandidates 
-                    = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName);
+                    = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName);
                 Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
             }
             
@@ -368,17 +368,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
                         foldersCreated, nodesLoaded);
     
                 List<InventoryFolderBase> folder1Candidates
-                    = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
+                    = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name);
                 Assert.That(folder1Candidates.Count, Is.EqualTo(1));
                 
                 InventoryFolderBase folder1 = folder1Candidates[0]; 
                 
                 List<InventoryFolderBase> folder2aCandidates 
-                    = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName);
+                    = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName);
                 Assert.That(folder2aCandidates.Count, Is.EqualTo(1));
                 
                 List<InventoryFolderBase> folder2bCandidates 
-                    = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2bName);
+                    = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2bName);
                 Assert.That(folder2bCandidates.Count, Is.EqualTo(1));
             }
         }
@@ -401,7 +401,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             
             InventoryFolderBase folder1 
                 = UserInventoryHelpers.CreateInventoryFolder(
-                    scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
+                    scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false);
             
             string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
             string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
@@ -414,7 +414,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
                     new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
 
             List<InventoryFolderBase> folder1PostCandidates 
-                = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
+                = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
             Assert.That(folder1PostCandidates.Count, Is.EqualTo(2));
             
             // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder.
@@ -430,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
 //            Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID));
 
             List<InventoryFolderBase> folder2PostCandidates 
-                = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b");
+                = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1Post, "b");
             Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
         }
         
@@ -452,7 +452,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
             
             InventoryFolderBase folder1 
                 = UserInventoryHelpers.CreateInventoryFolder(
-                    scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
+                    scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false);
             
             string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random());
             string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
@@ -465,12 +465,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
                     new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
 
             List<InventoryFolderBase> folder1PostCandidates 
-                = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
+                = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName);
             Assert.That(folder1PostCandidates.Count, Is.EqualTo(1));
             Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID));
 
             List<InventoryFolderBase> folder2PostCandidates 
-                = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b");
+                = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1PostCandidates[0], "b");
             Assert.That(folder2PostCandidates.Count, Is.EqualTo(1));
         }
     }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index ac25a93..ad1a0e1 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
             item1.AssetID = asset1.FullID;
             item1.ID = item1Id;
             InventoryFolderBase objsFolder 
-                = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0];
+                = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
             item1.Folder = objsFolder.ID;
             m_scene.AddInventoryItem(item1);
             
@@ -159,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
             item1.AssetID = asset1.FullID;
             item1.ID = item1Id;
             InventoryFolderBase objsFolder 
-                = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0];
+                = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
             item1.Folder = objsFolder.ID;
             m_scene.AddInventoryItem(item1);
             
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index b22bcf9..9600023 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -156,6 +156,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
 
             foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
             {
+//                m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key);
+
 //                m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
                 AssetBase asset = m_assetService.Get(kvp.Key.ToString());
                 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index c1522e7..52ad538 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -164,7 +164,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
 
             UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId);
             InventoryFolderBase folder1
-                = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1");
+                = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1", false);
 
             IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
             scene.DeRezObjects(client, new List<uint>() { so.LocalId }, UUID.Zero, DeRezAction.Take, folder1.ID);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index 0b461f5..df819ec 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -133,7 +133,7 @@ namespace OpenSim.Region.Framework.Tests
                     scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900));
 
             InventoryFolderBase folder 
-                = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0];
+                = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0];
             
             // Perform test
             scene.MoveTaskInventoryItem(user1.PrincipalID, folder.ID, sop1, sopItem1.ItemID);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 9457ebb..e50b4da 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Tests
             Scene scene = new SceneHelpers().SetupScene();
             UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
 
-            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
+            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName, false);
 
             List<InventoryFolderBase> oneFolder
                 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Tests
             InventoryFolderBase firstRetrievedFolder = oneFolder[0];
             Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName));
 
-            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
+            UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName, false);
 
             List<InventoryFolderBase> twoFolders
                 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
@@ -121,7 +121,7 @@ namespace OpenSim.Region.Framework.Tests
             UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
             UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
             InventoryFolderBase folder1
-                = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1");
+                = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1", false);
 
             scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero);
 
diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
index 87d9410..a1794c9 100644
--- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
@@ -45,6 +45,9 @@ namespace OpenSim.Tests.Common
         /// <summary>
         /// Add an existing scene object as an item in the user's inventory.
         /// </summary>
+        /// <remarks>
+        /// Will be added to the system Objects folder.
+        /// </remarks>
         /// <param name='scene'></param>
         /// <param name='so'></param>
         /// <param name='inventoryIdTail'></param>
@@ -63,7 +66,29 @@ namespace OpenSim.Tests.Common
         }
 
         /// <summary>
-        /// Creates a notecard in the objects folder and specify an item id.
+        /// Add an existing scene object as an item in the user's inventory at the given path.
+        /// </summary>
+        /// <param name='scene'></param>
+        /// <param name='so'></param>
+        /// <param name='inventoryIdTail'></param>
+        /// <param name='assetIdTail'></param>
+        /// <returns>The inventory item created.</returns>
+        public static InventoryItemBase AddInventoryItem(
+            Scene scene, SceneObjectGroup so, int inventoryIdTail, int assetIdTail, string path)
+        {
+            return AddInventoryItem(
+                scene,
+                so.Name,
+                TestHelpers.ParseTail(inventoryIdTail),
+                InventoryType.Object,
+                AssetHelpers.CreateAsset(TestHelpers.ParseTail(assetIdTail), so),
+                so.OwnerID,
+                path);
+        }
+
+        /// <summary>
+        /// Adds the given item to the existing system folder for its type (e.g. an object will go in the "Objects"
+        /// folder).
         /// </summary>
         /// <param name="scene"></param>
         /// <param name="itemName"></param>
@@ -75,6 +100,25 @@ namespace OpenSim.Tests.Common
         private static InventoryItemBase AddInventoryItem(
             Scene scene, string itemName, UUID itemId, InventoryType itemType, AssetBase asset, UUID userId)
         {
+            return AddInventoryItem(
+                scene, itemName, itemId, itemType, asset, userId, 
+                scene.InventoryService.GetFolderForType(userId, (AssetType)asset.Type).Name);
+        }
+
+        /// <summary>
+        /// Adds the given item to an inventory folder
+        /// </summary>
+        /// <param name="scene"></param>
+        /// <param name="itemName"></param>
+        /// <param name="itemId"></param>
+        /// <param name="itemType"></param>
+        /// <param name="asset">The serialized asset for this item</param>
+        /// <param name="userId"></param>
+        /// <param name="path">Existing inventory path at which to add.</param>
+        /// <returns></returns>
+        private static InventoryItemBase AddInventoryItem(
+            Scene scene, string itemName, UUID itemId, InventoryType itemType, AssetBase asset, UUID userId, string path)
+        {
             scene.AssetService.Store(asset);
 
             InventoryItemBase item = new InventoryItemBase();
@@ -85,7 +129,7 @@ namespace OpenSim.Tests.Common
             item.AssetType = asset.Type;
             item.InvType = (int)itemType;
 
-            InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, (AssetType)asset.Type);
+            InventoryFolderBase folder = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, path)[0];
 
             item.Folder = folder.ID;
             scene.AddInventoryItem(item);
@@ -156,58 +200,83 @@ namespace OpenSim.Tests.Common
         /// <summary>
         /// Create inventory folders starting from the user's root folder.
         /// </summary>
-        ///
-        /// Ignores any existing folders with the same name
-        /// 
         /// <param name="inventoryService"></param>
         /// <param name="userId"></param>
         /// <param name="path">
         /// The folders to create.  Multiple folders can be specified on a path delimited by the PATH_DELIMITER
         /// </param>
+        /// <param name="useExistingFolders">
+        /// If true, then folders in the path which already the same name are
+        /// used.  This applies to the terminal folder as well.  
+        /// If false, then all folders in the path are created, even if there is already a folder at a particular
+        /// level with the same name.
+        /// </param>
         /// <returns>
         /// The folder created.  If the path contains multiple folders then the last one created is returned.
         /// Will return null if the root folder could not be found.
         /// </returns>
         public static InventoryFolderBase CreateInventoryFolder(
-            IInventoryService inventoryService, UUID userId, string path)
+            IInventoryService inventoryService, UUID userId, string path, bool useExistingFolders)
         {
             InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
 
             if (null == rootFolder)
                 return null;
 
-            return CreateInventoryFolder(inventoryService, rootFolder, path);
+            return CreateInventoryFolder(inventoryService, rootFolder, path, useExistingFolders);
         }
 
         /// <summary>
         /// Create inventory folders starting from a given parent folder
         /// </summary>
-        ///
-        /// Ignores any existing folders with the same name
-        /// 
+        /// <remarks>
+        /// If any stem of the path names folders that already exist then these are not recreated.  This includes the 
+        /// final folder.
+        /// TODO: May need to make it an option to create duplicate folders.
+        /// </remarks>
         /// <param name="inventoryService"></param>
         /// <param name="parentFolder"></param>
         /// <param name="path">
-        /// The folders to create.  Multiple folders can be specified on a path delimited by the PATH_DELIMITER
+        /// The folder to create.
+        /// </param>
+        /// <param name="useExistingFolders">
+        /// If true, then folders in the path which already the same name are
+        /// used.  This applies to the terminal folder as well.  
+        /// If false, then all folders in the path are created, even if there is already a folder at a particular
+        /// level with the same name.
         /// </param>
         /// <returns>
         /// The folder created.  If the path contains multiple folders then the last one created is returned.
         /// </returns>
         public static InventoryFolderBase CreateInventoryFolder(
-            IInventoryService inventoryService, InventoryFolderBase parentFolder, string path)
+            IInventoryService inventoryService, InventoryFolderBase parentFolder, string path, bool useExistingFolders)
         {
             string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
 
-            InventoryFolderBase newFolder 
-                = new InventoryFolderBase(
-                    UUID.Random(), components[0], parentFolder.Owner, (short)AssetType.Unknown, parentFolder.ID, 0);
-            
-            inventoryService.AddFolder(newFolder);
+            InventoryFolderBase folder = null;
+
+            if (useExistingFolders)
+                folder = InventoryArchiveUtils.FindFolderByPath(inventoryService, parentFolder, components[0]);
+
+            if (folder == null)
+            {
+//                Console.WriteLine("Creating folder {0} at {1}", components[0], parentFolder.Name);
+
+                folder 
+                    = new InventoryFolderBase(
+                        UUID.Random(), components[0], parentFolder.Owner, (short)AssetType.Unknown, parentFolder.ID, 0);
+                
+                inventoryService.AddFolder(folder);
+            }
+//            else
+//            {
+//                Console.WriteLine("Found existing folder {0}", folder.Name);
+//            }
 
             if (components.Length > 1)
-                return CreateInventoryFolder(inventoryService, newFolder, components[1]);
+                return CreateInventoryFolder(inventoryService, folder, components[1], useExistingFolders);
             else
-                return newFolder;
+                return folder;
         }
 
         /// <summary>
@@ -237,7 +306,7 @@ namespace OpenSim.Tests.Common
         /// <returns>An empty list if no matching folders were found</returns>
         public static List<InventoryFolderBase> GetInventoryFolders(IInventoryService inventoryService, UUID userId, string path)
         {
-            return InventoryArchiveUtils.FindFolderByPath(inventoryService, userId, path);
+            return InventoryArchiveUtils.FindFoldersByPath(inventoryService, userId, path);
         }
 
         /// <summary>
-- 
cgit v1.1