public static void Load(
            SceneList scenes,
            SceneInterface scene,
            LoadOptions options,
            Stream inputFile,
            TTY io = null)
        {
            var currentLoadState = CurrentOarLoadState.Unknown;

            using (var gzipStream = new GZipStream(inputFile, CompressionMode.Decompress))
            {
                using (var reader = new TarArchiveReader(gzipStream))
                {
                    var baseLoc = new GridVector(0, 0);
                    if (scene != null)
                    {
                        baseLoc = scene.GridPosition;
                    }

                    var  regionSize     = new GridVector(256, 256);
                    var  regionMapping  = new Dictionary <string, ArchiveXmlLoader.RegionInfo>();
                    var  regionInfos    = new List <ArchiveXmlLoader.RegionInfo>();
                    bool parcelsCleared = false;
                    var  load_sogs      = new List <ObjectGroup>();

                    for (; ;)
                    {
                        TarArchiveReader.Header header;
                        try
                        {
                            header = reader.ReadHeader();
                        }
                        catch (TarArchiveReader.EndOfTarException)
                        {
                            if ((options & LoadOptions.Merge) == 0 && scene != null)
                            {
                                scene.ClearObjects();
                            }

                            AddObjects(scene, load_sogs, options);
                            return;
                        }

                        if (header.FileType == TarFileType.File)
                        {
                            if (header.FileName == "archive.xml")
                            {
                                ArchiveXmlLoader.RegionInfo rinfo = ArchiveXmlLoader.LoadArchiveXml(new ObjectXmlStreamFilter(reader), regionInfos);

                                regionSize = rinfo.RegionSize;
                                foreach (ArchiveXmlLoader.RegionInfo reginfo in regionInfos)
                                {
                                    regionMapping.Add(reginfo.Path, reginfo);
                                }
                                if (regionInfos.Count != 0 && scene != null)
                                {
                                    throw new MultiRegionOARLoadingTriedOnRegionException();
                                }
                                else if (regionInfos.Count == 0 && scene == null)
                                {
                                    throw new OARLoadingTriedWithoutSelectedRegionException();
                                }
                            }
                            else if (header.FileName.StartsWith("assets/"))
                            {
                                if ((options & LoadOptions.NoAssets) == 0)
                                {
                                    ShowOarLoadState(ref currentLoadState, CurrentOarLoadState.Assets, io);
                                    /* Load asset */
                                    AssetData ad = reader.LoadAsset(header, scene.Owner);
                                    if (!scene.AssetService.Exists(ad.ID))
                                    {
                                        scene.AssetService.Store(ad);
                                    }
                                }
                            }
                            else
                            {
                                if (header.FileName.StartsWith("regions/"))
                                {
                                    ShowOarLoadState(ref currentLoadState, CurrentOarLoadState.Region, io);
                                    if ((options & LoadOptions.Merge) == 0 && scene != null)
                                    {
                                        scene.ClearObjects();
                                    }

                                    if (scene != null)
                                    {
                                        AddObjects(scene, load_sogs, options);
                                    }

                                    string[] pcomps = header.FileName.Split(new char[] { '/' }, 3);
                                    if (pcomps.Length < 3)
                                    {
                                        throw new OARFormatException();
                                    }
                                    string regionname = pcomps[1];
                                    header.FileName = pcomps[2];
                                    regionSize      = regionMapping[regionname].RegionSize;
                                    scene           = scenes[regionMapping[regionname].ID];
                                    parcelsCleared  = false;
                                }

                                if (header.FileName.StartsWith("objects/"))
                                {
                                    ShowOarLoadState(ref currentLoadState, CurrentOarLoadState.Objects, io);
                                    /* Load objects */
                                    List <ObjectGroup>        sogs;
                                    XmlDeserializationOptions xmloptions = XmlDeserializationOptions.ReadKeyframeMotion;
                                    if ((options & LoadOptions.PersistUuids) != 0)
                                    {
                                        xmloptions |= XmlDeserializationOptions.RestoreIDs;
                                    }
                                    try
                                    {
                                        sogs = ObjectXML.FromXml(reader, scene.Owner, xmloptions);
                                    }
                                    catch (Exception e)
                                    {
                                        throw new OARLoadingErrorException("Failed to load sog " + header.FileName, e);
                                    }

                                    foreach (ObjectGroup sog in sogs)
                                    {
                                        if (sog.Owner.ID == UUID.Zero)
                                        {
                                            sog.Owner = scene.Owner;
                                        }
                                    }
                                    load_sogs.AddRange(sogs);
                                }
                                else if (header.FileName.StartsWith("terrains/"))
                                {
                                    ShowOarLoadState(ref currentLoadState, CurrentOarLoadState.Terrain, io);
                                    /* Load terrains */
                                    if ((options & LoadOptions.Merge) == 0)
                                    {
                                        scene.Terrain.AllPatches = TerrainLoader.LoadStream(reader, (int)regionSize.X, (int)regionSize.Y);
                                        scene.StoreTerrainAsDefault();
                                    }
                                }
                                else if (header.FileName.StartsWith("landdata/"))
                                {
                                    ShowOarLoadState(ref currentLoadState, CurrentOarLoadState.Parcels, io);
                                    /* Load landdata */
                                    if ((options & LoadOptions.Merge) == 0)
                                    {
                                        if (!parcelsCleared)
                                        {
                                            scene.ClearParcels();
                                            parcelsCleared = true;
                                        }
                                        var        whiteList = new List <ParcelAccessEntry>();
                                        var        blackList = new List <ParcelAccessEntry>();
                                        ParcelInfo pinfo     = ParcelLoader.GetParcelInfo(new ObjectXmlStreamFilter(reader), regionSize, whiteList, blackList);
                                        if (pinfo.Owner.ID == UUID.Zero)
                                        {
                                            pinfo.Owner = scene.Owner;
                                        }
                                        if ((options & LoadOptions.PersistUuids) == LoadOptions.PersistUuids)
                                        {
                                            ParcelInfo check;
                                            if (scene.Parcels.TryGetValue(pinfo.ID, out check))
                                            {
                                                pinfo.ID = UUID.Random;
                                            }
                                        }
                                        else
                                        {
                                            pinfo.ID = UUID.Random;
                                        }
                                        scene.AddParcel(pinfo);
                                        scene.Parcels.WhiteList.Remove(scene.ID, pinfo.ID);
                                        scene.Parcels.BlackList.Remove(scene.ID, pinfo.ID);
                                        foreach (ParcelAccessEntry pae in whiteList)
                                        {
                                            scene.Parcels.WhiteList.Store(pae);
                                        }
                                        foreach (ParcelAccessEntry pae in blackList)
                                        {
                                            scene.Parcels.BlackList.Store(pae);
                                        }
                                    }
                                }
                                else if (header.FileName.StartsWith("settings/") && ((options & LoadOptions.Merge) == 0))
                                {
                                    ShowOarLoadState(ref currentLoadState, CurrentOarLoadState.Parcels, io);
                                    /* Load settings */
                                    RegionSettingsLoader.LoadRegionSettings(new ObjectXmlStreamFilter(reader), scene);
                                }
                            }
                        }
                    }
                }
            }
        }
        public static void Load(
            UGUI principal,
            InventoryServiceInterface inventoryService,
            AssetServiceInterface assetService,
            List <AvatarNameServiceInterface> nameServices,
            LoadOptions options,
            Stream inputFile,
            string topath,
            TTY console_io = null)
        {
            using (var gzipStream = new GZipStream(inputFile, CompressionMode.Decompress))
            {
                using (var reader = new TarArchiveReader(gzipStream))
                {
                    var inventoryPath = new Dictionary <UUID, UUID>();
                    var reassignedIds = new Dictionary <UUID, UUID>();
                    var linkItems     = new List <InventoryItem>();

                    UUID parentFolder;
                    try
                    {
                        inventoryService.CheckInventory(principal.ID);
                    }
                    catch (NotSupportedException)
                    {
                        /* some handlers may not support this call, so ignore that error */
                    }
                    parentFolder = inventoryService.Folder[principal.ID, AssetType.RootFolder].ID;

                    if (!topath.StartsWith("/"))
                    {
                        throw new InvalidInventoryPathException();
                    }

                    if (topath != "/")
                    {
                        foreach (string pathcomp in topath.Substring(1).Split('/'))
                        {
                            List <InventoryFolder> childfolders = inventoryService.Folder.GetFolders(principal.ID, parentFolder);
                            int idx;
                            for (idx = 0; idx < childfolders.Count; ++idx)
                            {
                                if (pathcomp.ToLower() == childfolders[idx].Name.ToLower())
                                {
                                    break;
                                }
                            }

                            if (idx == childfolders.Count)
                            {
                                throw new InvalidInventoryPathException();
                            }

                            parentFolder = childfolders[idx].ID;
                        }
                    }

                    inventoryPath[UUID.Zero] = parentFolder;

                    for (; ;)
                    {
                        TarArchiveReader.Header header;
                        try
                        {
                            header = reader.ReadHeader();
                        }
                        catch (TarArchiveReader.EndOfTarException)
                        {
                            if (console_io != null)
                            {
                                console_io.Write("Creating link items");
                            }
                            foreach (InventoryItem linkitem in linkItems)
                            {
                                UUID newId;
                                if (linkitem.AssetType == AssetType.Link && reassignedIds.TryGetValue(linkitem.AssetID, out newId))
                                {
                                    linkitem.AssetID = newId;
                                }
                                inventoryService.Item.Add(linkitem);
                            }
                            return;
                        }

                        if (header.FileType == TarFileType.File)
                        {
                            if (header.FileName == "archive.xml")
                            {
                                using (Stream s = new ObjectXmlStreamFilter(reader))
                                {
                                    ArchiveXmlLoader.LoadArchiveXml(s);
                                }
                            }

                            if (header.FileName.StartsWith("assets/") && (options & LoadOptions.NoAssets) == 0)
                            {
                                /* Load asset */
                                AssetData ad = reader.LoadAsset(header, principal);
                                if (!assetService.Exists(ad.ID))
                                {
                                    assetService.Store(ad);
                                }
                            }

                            if (header.FileName.StartsWith("inventory/"))
                            {
                                /* Load inventory */
                                InventoryItem item = LoadInventoryItem(reader, principal, nameServices);
                                item.ParentFolderID = GetPath(principal, inventoryService, inventoryPath, header.FileName, options);

                                UUID oldId = item.ID;
                                item.SetNewID(UUID.Random);
                                reassignedIds.Add(oldId, item.ID);

                                if (item.AssetType == AssetType.Link || item.AssetType == AssetType.LinkFolder)
                                {
                                    inventoryService.Item.Add(item);
                                }
                                else
                                {
                                    linkItems.Add(item);
                                }
                            }
                        }
                    }
                }
            }
        }