public async Task CanOpenAndCloseWithUpdate()
		{
			var storage = await NewStorageAsync();
			var name = storage.Name;

			var str1 = "test1";
			var str2 = "test2";

			var s1 = new MemoryStream(Encoding.UTF8.GetBytes(str1));
			var s2 = new MemoryStream(Encoding.UTF8.GetBytes(str2));

			var writeBatch = new WriteBatch();
			writeBatch.Put("A", s1);
			await storage.Writer.WriteAsync(writeBatch);

			writeBatch = new WriteBatch();
			writeBatch.Put("A", s2);
			await storage.Writer.WriteAsync(writeBatch);

			var fileSystem = storage.StorageState.FileSystem;

			storage.Dispose();


			using (var newStorage = new Storage(new StorageState(name, new StorageOptions())
			{
				FileSystem = fileSystem
			}))
			{
				await newStorage.InitAsync();
				AssertEqual(str2, newStorage.Reader.Read("A"));
			}
		}
		public async Task CanGetLatestVersion()
		{
			var storage = await NewStorageAsync();
			var name = storage.Name;

			for (int j = 0; j < 3; j++)
			{
				for (int i = 0; i < 65; i++)
				{
					for (int k = 0; k < 4; k++)
					{
						var writeBatch = new WriteBatch();
						writeBatch.Put("A" + k, new MemoryStream(new[] { (byte)i, (byte)k }));
						await storage.Writer.WriteAsync(writeBatch);
					}
				}
			}

			var fileSystem = storage.StorageState.FileSystem;

			storage.Dispose();

			using (var newStorage = new Storage(new StorageState(name, new StorageOptions())
			{
				FileSystem = fileSystem
			}))
			{
				await newStorage.InitAsync();
				var stream = newStorage.Reader.Read("A2");
				Assert.Equal(64, stream.ReadByte());
			}
		}
		public async Task ShouldRecoverDataFromLogFile()
		{
			var storage = await NewStorageAsync();

			var name = storage.Name;

			var writeBatch = new WriteBatch();
			writeBatch.Put("A", new MemoryStream(Encoding.UTF8.GetBytes("123")));
			writeBatch.Put("B", new MemoryStream(Encoding.UTF8.GetBytes("123")));
			writeBatch.Put("D", new MemoryStream(Encoding.UTF8.GetBytes("123")));
			storage.Writer.WriteAsync(writeBatch).Wait();

			var fileSystem = storage.StorageState.FileSystem;

			storage.Dispose();

			using (var newStorage = new Storage(new StorageState(name, new StorageOptions())
			{
				FileSystem = fileSystem
			}))
			{
				await newStorage.InitAsync();
				
				using(var it = newStorage.Reader.NewIterator(new ReadOptions()))
				{
					it.Seek("C");
					Assert.True(it.IsValid);
					it.Prev();
					Assert.True(it.IsValid);
					Assert.Equal("B", it.Key);
				}
			}
		} 
		private async Task OpenAsync()
		{
			if (!options.UseExistingDatabase)
				Close();

			Debug.Assert(!string.IsNullOrEmpty(options.DatabaseName));
			Debug.Assert(storage == null);

			var filterPolicy = options.BloomBits >= 0 ? new BloomFilterPolicy(options.BloomBits) : null;

			var storageOptions = new StorageOptions
									 {
										 CreateIfMissing = !options.UseExistingDatabase,
										 WriteBatchSize = options.WriteBatchSize,
										 FilterPolicy = filterPolicy,
										 //Comparator = new ByteWiseComparator()
									 };

			if (options.CacheSize > 0)
			{
				storageOptions.CacheSizeInMegabytes = options.CacheSize;
			}

			storage = new Storage(options.DatabaseName, storageOptions);
			await storage.InitAsync();
		}