public void CheckSubDir(World world, SegmentCoords coords)
        {
            var    subCoords = new SubdirectoryCoords(coords);
            string subDir    = "d-" + subCoords.X.ToString("X") + "-" + subCoords.Y.ToString("X") + "-" + subCoords.Z.ToString("X");
            string path      = world.SegmentManager.SegmentPath + subDir;

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }
        public World ConvertWorld(String mcDirectory)
        {
            String segmentDirectory = Path.Combine(FCEDirectory, "Segments");

            if (!Directory.Exists(FCEDirectory))
            {
                Directory.CreateDirectory(FCEDirectory);
            }
            if (!Directory.Exists(Path.Combine(FCEDirectory, segmentDirectory)))
            {
                Directory.CreateDirectory(segmentDirectory);
            }

            Boolean anvil = true;

            NbtWorld      nbtWorld     = AnvilWorld.Open(mcDirectory);
            String        worldName    = nbtWorld.Level.LevelName;
            IChunkManager chunkManager = nbtWorld.GetChunkManager();

            try
            {
                // Try to test for mc world type
                // Don't know how this is supposed to work, but it presumably throws an exception
                // on a non-Anvil world.
                chunkManager.Count();
            }
            catch
            {
                anvil        = false;
                nbtWorld     = BetaWorld.Open(mcDirectory);
                worldName    = nbtWorld.Level.LevelName;
                chunkManager = nbtWorld.GetChunkManager();
            }
            Int32 spawnChunkX = nbtWorld.Level.Spawn.X >> 4;
            Int32 spawnChunkZ = nbtWorld.Level.Spawn.Z >> 4;

            WorldSettings settings = new WorldSettings();

            settings.Name = worldName;
            var fceWorld       = World.Create(FCEDirectory, settings);
            var segmentManager = fceWorld.SegmentManager;

            _totalSegments = chunkManager.LongCount() * (anvil ? 16 : 8);
            _segmentsLeft  = _totalSegments;
            StartSaveThread(fceWorld);
            foreach (ChunkRef chunk in chunkManager)
            {
                // If the save thread is too slow, wait until it has caught up before adding to it to prevent high ram usage
                while (_saveQueue.Count > 5000)
                {
                    Thread.Sleep(500);
                }

                if (chunk.Blocks == null)
                {
                    _segmentsLeft -= (anvil ? 16 : 8);
                    continue;
                }

                Int32 spawnOffsetX = UseSpawnAsOrigin ? spawnChunkX - chunk.X : -chunk.X;
                Int32 spawnOffsetZ = UseSpawnAsOrigin ? spawnChunkZ - chunk.Z : -chunk.Z;

                // Minecraft has different x/y directions so we must reverse z so the world isn't mirrored
                var chunkCoords = new SegmentCoords(spawnOffsetX, 0, -spawnOffsetZ) + SegmentCoords.WorldCenter;
                for (Int32 i = 0; i < (anvil ? 16 : 8); i++)
                {
                    SegmentCoords segCoords = chunkCoords + SegmentCoords.Above * i;
                    var           segment   = new Segment(segmentManager, segCoords);
                    var           array     = new Cube[16, 16, 16];
                    for (Byte x = 0; x < 16; x++)
                    {
                        for (Byte y = 0; y < 16; y++)
                        {
                            for (Byte z = 0; z < 16; z++)
                            {
                                // Minecraft has different x/y directions so we must reverse z so the world isn't mirrored
                                AlphaBlock block    = chunk.Blocks.GetBlock(15 - z, y + i * 16, x);
                                UInt32     mcIdData = (UInt32)block.ID << 16 | (UInt16)block.Data;

                                Cube cube;
                                if (!_mcIdDataToFCECube.TryGetValue(mcIdData, out cube))
                                {
                                    cube = new Cube(1, 0, 0, 0);
                                    if (!UnknownBlocks.ContainsKey((UInt16)block.ID))
                                    {
                                        UnknownBlocks.Add((UInt16)block.ID, block.Info.Name);
                                    }
                                }
                                array[z, y, x] = cube;
                            }
                        }
                    }

                    segment.CubeData = array;
                    _segmentsLeft--;
                    _saveQueue.Enqueue(segment);
                }
                // Pad the area above the converted world with 11 blank segments to prevent world gen from occuring
                // Possibly replace this in the future with simply shifting the world up
                for (Int32 i = (anvil ? 16 : 8); i < 27; i++)
                {
                    var padding = new Segment(segmentManager, chunkCoords + SegmentCoords.Above * i);
                    padding.CubeData = Segment.GetBlankSegment().CubeData;
                    padding.IsEmpty  = true;
                    _saveQueue.Enqueue(padding);
                }
            }
            Task.WaitAll(_saveTask);

            return(fceWorld);
        }