/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.poifs.filesystem;

import static org.hamcrest.core.IsCollectionContaining.hasItem;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;

import org.apache.poi.POIDataSamples;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.property.DirectoryProperty;
import org.apache.poi.poifs.property.NPropertyTable;
import org.apache.poi.poifs.property.Property;
import org.apache.poi.poifs.property.RootProperty;
import org.apache.poi.poifs.storage.HeaderBlock;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.TempFile;
import org.junit.Test;

/**
 * Tests for the new NIO POIFSFileSystem implementation
 */
public final class TestNPOIFSFileSystem {
   private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance();
   
   /**
    * Returns test files with 512 byte and 4k block sizes, loaded
    *  both from InputStreams and Files
    */
   protected NPOIFSFileSystem[] get512and4kFileAndInput() throws IOException {
       NPOIFSFileSystem fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
       NPOIFSFileSystem fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
       NPOIFSFileSystem fsC = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
       NPOIFSFileSystem fsD = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
       return new NPOIFSFileSystem[] {fsA,fsB,fsC,fsD};
   }

   protected static void assertBATCount(NPOIFSFileSystem fs, int expectedBAT, int expectedXBAT) throws IOException {
       int foundBAT = 0;
       int foundXBAT = 0;
       int sz = (int)(fs.size() / fs.getBigBlockSize());
       for (int i=0; i<sz; i++) {
           if(fs.getNextBlock(i) == POIFSConstants.FAT_SECTOR_BLOCK) {
               foundBAT++;
           }
           if(fs.getNextBlock(i) == POIFSConstants.DIFAT_SECTOR_BLOCK) {
               foundXBAT++;
           }
       }
       assertEquals("Wrong number of BATs", expectedBAT, foundBAT);
       assertEquals("Wrong number of XBATs with " + expectedBAT + " BATs", expectedXBAT, foundXBAT);
   }
   protected void assertContentsMatches(byte[] expected, DocumentEntry doc) throws IOException {
       NDocumentInputStream inp = new NDocumentInputStream(doc);
       byte[] contents = new byte[doc.getSize()];
       assertEquals(doc.getSize(), inp.read(contents));
       inp.close();
       
       if (expected != null) {
        assertThat(expected, equalTo(contents));
    }
   }
   
   protected static HeaderBlock writeOutAndReadHeader(NPOIFSFileSystem fs) throws IOException {
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       fs.writeFilesystem(baos);
       
       HeaderBlock header = new HeaderBlock(new ByteArrayInputStream(baos.toByteArray()));
       return header;
   }

    protected static NPOIFSFileSystem writeOutAndReadBack(NPOIFSFileSystem original) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        original.writeFilesystem(baos);
        return new NPOIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
    }

    protected static NPOIFSFileSystem writeOutFileAndReadBack(NPOIFSFileSystem original) throws IOException {
        final File file = TempFile.createTempFile("TestPOIFS", ".ole2");
        final OutputStream fout = new FileOutputStream(file);
        try {
            original.writeFilesystem(fout);
        } finally {
            fout.close();
        }
        return new NPOIFSFileSystem(file, false);
    }
   
   @Test
   public void basicOpen() throws IOException {
      NPOIFSFileSystem fsA, fsB;
      
      // With a simple 512 block file
      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         assertEquals(512, fs.getBigBlockSize());
      }
      fsA.close();
      fsB.close();
      
      // Now with a simple 4096 block file
      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         assertEquals(4096, fs.getBigBlockSize());
      }
      fsA.close();
      fsB.close();
   }

   @Test
   public void propertiesAndFatOnRead() throws IOException {
      NPOIFSFileSystem fsA, fsB;
      
      // With a simple 512 block file
      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         // Check the FAT was properly processed:
         // Verify we only got one block
         fs.getBATBlockAndIndex(0);
         fs.getBATBlockAndIndex(1);
         try {
            fs.getBATBlockAndIndex(140);
            fail("Should only be one BAT, but a 2nd was found");
         } catch(IndexOutOfBoundsException e) {}
         
         // Verify a few next offsets
         // 97 -> 98 -> END
         assertEquals(98, fs.getNextBlock(97));
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98));
         
         
         // Check the properties
         NPropertyTable props = fs._get_property_table();
         assertEquals(90, props.getStartBlock());
         assertEquals(7, props.countBlocks());
         
         // Root property tells us about the Mini Stream
         RootProperty root = props.getRoot();
         assertEquals("Root Entry", root.getName());
         assertEquals(11564, root.getSize());
         assertEquals(0, root.getStartBlock());
         
         // Check its children too
         Property prop;
         Iterator<Property> pi = root.getChildren();
         prop = pi.next();
         assertEquals("Thumbnail", prop.getName());
         prop = pi.next();
         assertEquals("\u0005DocumentSummaryInformation", prop.getName());
         prop = pi.next();
         assertEquals("\u0005SummaryInformation", prop.getName());
         prop = pi.next();
         assertEquals("Image", prop.getName());
         prop = pi.next();
         assertEquals("Tags", prop.getName());
         assertEquals(false, pi.hasNext());
         
         
         // Check the SBAT (Small Blocks FAT) was properly processed
         NPOIFSMiniStore ministore = fs.getMiniStore();
         
         // Verify we only got two SBAT blocks
         ministore.getBATBlockAndIndex(0);
         ministore.getBATBlockAndIndex(128);
         try {
            ministore.getBATBlockAndIndex(256);
            fail("Should only be two SBATs, but a 3rd was found");
         } catch(IndexOutOfBoundsException e) {}
         
         // Verify a few offsets: 0->50 is a stream
         for(int i=0; i<50; i++) {
            assertEquals(i+1, ministore.getNextBlock(i));
         }
         assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(50));
         
         fs.close();
      }
      
      // Now with a simple 4096 block file
      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         // Check the FAT was properly processed
         // Verify we only got one block
         fs.getBATBlockAndIndex(0);
         fs.getBATBlockAndIndex(1);
         try {
            fs.getBATBlockAndIndex(1040);
            fail("Should only be one BAT, but a 2nd was found");
         } catch(IndexOutOfBoundsException e) {}
         
         // Verify a few next offsets
         // 0 -> 1 -> 2 -> END
         assertEquals(1, fs.getNextBlock(0));
         assertEquals(2, fs.getNextBlock(1));
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));

         
         // Check the properties
         NPropertyTable props = fs._get_property_table();
         assertEquals(12, props.getStartBlock());
         assertEquals(1, props.countBlocks());
         
         // Root property tells us about the Mini Stream
         RootProperty root = props.getRoot();
         assertEquals("Root Entry", root.getName());
         assertEquals(11564, root.getSize());
         assertEquals(0, root.getStartBlock());
         
         // Check its children too
         Property prop;
         Iterator<Property> pi = root.getChildren();
         prop = pi.next();
         assertEquals("Thumbnail", prop.getName());
         prop = pi.next();
         assertEquals("\u0005DocumentSummaryInformation", prop.getName());
         prop = pi.next();
         assertEquals("\u0005SummaryInformation", prop.getName());
         prop = pi.next();
         assertEquals("Image", prop.getName());
         prop = pi.next();
         assertEquals("Tags", prop.getName());
         assertEquals(false, pi.hasNext());
         
         
         // Check the SBAT (Small Blocks FAT) was properly processed
         NPOIFSMiniStore ministore = fs.getMiniStore();
         
         // Verify we only got one SBAT block
         ministore.getBATBlockAndIndex(0);
         ministore.getBATBlockAndIndex(128);
         ministore.getBATBlockAndIndex(1023);
         try {
            ministore.getBATBlockAndIndex(1024);
            fail("Should only be one SBAT, but a 2nd was found");
         } catch(IndexOutOfBoundsException e) {}
         
         // Verify a few offsets: 0->50 is a stream
         for(int i=0; i<50; i++) {
            assertEquals(i+1, ministore.getNextBlock(i));
         }
         assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(50));
         
         fs.close();
      }
   }
   
   /**
    * Check that for a given block, we can correctly figure
    *  out what the next one is
    */
   @Test
   public void nextBlock() throws IOException {
      NPOIFSFileSystem fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      NPOIFSFileSystem fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         // 0 -> 21 are simple
         for(int i=0; i<21; i++) {
            assertEquals(i+1, fs.getNextBlock(i));
         }
         // 21 jumps to 89, then ends
         assertEquals(89, fs.getNextBlock(21));
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(89));
         
         // 22 -> 88 simple sequential stream
         for(int i=22; i<88; i++) {
            assertEquals(i+1, fs.getNextBlock(i));
         }
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(88));
         
         // 90 -> 96 is another stream
         for(int i=90; i<96; i++) {
            assertEquals(i+1, fs.getNextBlock(i));
         }
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(96));
         
         // 97+98 is another
         assertEquals(98, fs.getNextBlock(97));
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98));
         
         // 99 is our FAT block
         assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
         
         // 100 onwards is free
         for(int i=100; i<fs.getBigBlockSizeDetails().getBATEntriesPerBlock(); i++) {
            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(i));
         }
         
         fs.close();
      }
      
      // Quick check on 4096 byte blocks too
      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         // 0 -> 1 -> 2 -> end
         assertEquals(1, fs.getNextBlock(0));
         assertEquals(2, fs.getNextBlock(1));
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
         
         // 4 -> 11 then end
         for(int i=4; i<11; i++) {
            assertEquals(i+1, fs.getNextBlock(i));
         }
         assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(11));
         
         fs.close();
      }
   }

   /**
    * Check we get the right data back for each block
    */
   @Test
   public void getBlock() throws IOException {
      NPOIFSFileSystem fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      NPOIFSFileSystem fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         ByteBuffer b;
         
         // The 0th block is the first data block
         b = fs.getBlockAt(0);
         assertEquals((byte)0x9e, b.get());
         assertEquals((byte)0x75, b.get());
         assertEquals((byte)0x97, b.get());
         assertEquals((byte)0xf6, b.get());
         
         // And the next block
         b = fs.getBlockAt(1);
         assertEquals((byte)0x86, b.get());
         assertEquals((byte)0x09, b.get());
         assertEquals((byte)0x22, b.get());
         assertEquals((byte)0xfb, b.get());
         
         // Check the final block too
         b = fs.getBlockAt(99);
         assertEquals((byte)0x01, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x02, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         
         fs.close();
      }
      
      // Quick check on 4096 byte blocks too
      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
         ByteBuffer b;
         
         // The 0th block is the first data block
         b = fs.getBlockAt(0);
         assertEquals((byte)0x9e, b.get());
         assertEquals((byte)0x75, b.get());
         assertEquals((byte)0x97, b.get());
         assertEquals((byte)0xf6, b.get());
         
         // And the next block
         b = fs.getBlockAt(1);
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x03, b.get());
         assertEquals((byte)0x00, b.get());

         // The 14th block is the FAT
         b = fs.getBlockAt(14);
         assertEquals((byte)0x01, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x02, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         assertEquals((byte)0x00, b.get());
         
         fs.close();
      }
   }
   
   /**
    * Ask for free blocks where there are some already
    *  to be had from the FAT
    */
   @Test
   public void getFreeBlockWithSpare() throws IOException {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      
      // Our first BAT block has spares
      assertEquals(true, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
      
      // First free one is 100
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
      
      // Ask, will get 100
      assertEquals(100, fs.getFreeBlock());
      
      // Ask again, will still get 100 as not written to
      assertEquals(100, fs.getFreeBlock());
      
      // Allocate it, then ask again
      fs.setNextBlock(100, POIFSConstants.END_OF_CHAIN);
      assertEquals(101, fs.getFreeBlock());
      
      // All done
      fs.close();
   }

   /**
    * Ask for free blocks where no free ones exist, and so the
    *  file needs to be extended and another BAT/XBAT added
    */
   @Test
   public void getFreeBlockWithNoneSpare() throws IOException {
      NPOIFSFileSystem fs1 = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      int free;

      // We have one BAT at block 99
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(99));
      assertBATCount(fs1, 1, 0);
      
      // We've spare ones from 100 to 128
      for(int i=100; i<128; i++) {
         assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(i));
      }
      
      // Check our BAT knows it's free
      assertEquals(true, fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
      
      // Allocate all the spare ones
      for(int i=100; i<128; i++) {
         fs1.setNextBlock(i, POIFSConstants.END_OF_CHAIN);
      }
      
      // BAT is now full, but there's only the one
      assertEquals(false, fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
      try {
         assertEquals(false, fs1.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
         fail("Should only be one BAT");
      } catch(IndexOutOfBoundsException e) {}
      assertBATCount(fs1, 1, 0);

      
      // Now ask for a free one, will need to extend the file
      assertEquals(129, fs1.getFreeBlock());
      
      assertEquals(false, fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
      assertEquals(true, fs1.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(128));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(129));
      
      // We now have 2 BATs, but no XBATs
      assertBATCount(fs1, 2, 0);
      
      
      // Fill up to hold 109 BAT blocks
      for(int i=0; i<109; i++) {
         fs1.getFreeBlock();
         int startOffset = i*128;
         while( fs1.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors() ) {
            free = fs1.getFreeBlock();
            fs1.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
         }
      }
      
      assertEquals(false, fs1.getBATBlockAndIndex(109*128-1).getBlock().hasFreeSectors());
      try {
         assertEquals(false, fs1.getBATBlockAndIndex(109*128).getBlock().hasFreeSectors());
         fail("Should only be 109 BATs");
      } catch(IndexOutOfBoundsException e) {}
      
      // We now have 109 BATs, but no XBATs
      assertBATCount(fs1, 109, 0);
      
      
      // Ask for it to be written out, and check the header
      HeaderBlock header = writeOutAndReadHeader(fs1);
      assertEquals(109, header.getBATCount());
      assertEquals(0, header.getXBATCount());
      
      
      // Ask for another, will get our first XBAT
      free = fs1.getFreeBlock();
      assertEquals(false, fs1.getBATBlockAndIndex(109*128-1).getBlock().hasFreeSectors());
      assertEquals(true, fs1.getBATBlockAndIndex(110*128-1).getBlock().hasFreeSectors());
      try {
         assertEquals(false, fs1.getBATBlockAndIndex(110*128).getBlock().hasFreeSectors());
         fail("Should only be 110 BATs");
      } catch(IndexOutOfBoundsException e) {}
      assertBATCount(fs1, 110, 1);
      
      header = writeOutAndReadHeader(fs1);
      assertEquals(110, header.getBATCount());
      assertEquals(1, header.getXBATCount());

      
      // Fill the XBAT, which means filling 127 BATs
      for(int i=109; i<109+127; i++) {
         fs1.getFreeBlock();
         int startOffset = i*128;
         while( fs1.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors() ) {
            free = fs1.getFreeBlock();
            fs1.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
         }
         assertBATCount(fs1, i+1, 1);
      }
      
      // Should now have 109+127 = 236 BATs
      assertEquals(false, fs1.getBATBlockAndIndex(236*128-1).getBlock().hasFreeSectors());
      try {
         assertEquals(false, fs1.getBATBlockAndIndex(236*128).getBlock().hasFreeSectors());
         fail("Should only be 236 BATs");
      } catch(IndexOutOfBoundsException e) {}
      assertBATCount(fs1, 236, 1);

      
      // Ask for another, will get our 2nd XBAT
      free = fs1.getFreeBlock();
      assertEquals(false, fs1.getBATBlockAndIndex(236*128-1).getBlock().hasFreeSectors());
      assertEquals(true, fs1.getBATBlockAndIndex(237*128-1).getBlock().hasFreeSectors());
      try {
         assertEquals(false, fs1.getBATBlockAndIndex(237*128).getBlock().hasFreeSectors());
         fail("Should only be 237 BATs");
      } catch(IndexOutOfBoundsException e) {}
      
      
      // Check the counts now
      assertBATCount(fs1, 237, 2);

      // Check the header
      header = writeOutAndReadHeader(fs1);
      
      
      // Now, write it out, and read it back in again fully
      NPOIFSFileSystem fs2 = writeOutAndReadBack(fs1);
      fs1.close();

      // Check that it is seen correctly
      assertBATCount(fs2, 237, 2);

      assertEquals(false, fs2.getBATBlockAndIndex(236*128-1).getBlock().hasFreeSectors());
      assertEquals(true, fs2.getBATBlockAndIndex(237*128-1).getBlock().hasFreeSectors());
      try {
         assertEquals(false, fs2.getBATBlockAndIndex(237*128).getBlock().hasFreeSectors());
         fail("Should only be 237 BATs");
      } catch(IndexOutOfBoundsException e) {}

      
      // All done
      fs2.close();
   }
   
   /**
    * Test that we can correctly get the list of directory
    *  entries, and the details on the files in them
    */
   @Test
   public void listEntries() throws IOException {
      for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
         DirectoryEntry root = fs.getRoot();
         assertEquals(5, root.getEntryCount());
         
         // Check by the names
         Entry thumbnail = root.getEntry("Thumbnail");
         Entry dsi = root.getEntry("\u0005DocumentSummaryInformation");
         Entry si = root.getEntry("\u0005SummaryInformation");
         Entry image = root.getEntry("Image");
         Entry tags = root.getEntry("Tags");
         
         assertEquals(false, thumbnail.isDirectoryEntry());
         assertEquals(false, dsi.isDirectoryEntry());
         assertEquals(false, si.isDirectoryEntry());
         assertEquals(true, image.isDirectoryEntry());
         assertEquals(false, tags.isDirectoryEntry());
         
         // Check via the iterator
         Iterator<Entry> it = root.getEntries();
         assertEquals(thumbnail.getName(), it.next().getName());
         assertEquals(dsi.getName(), it.next().getName());
         assertEquals(si.getName(), it.next().getName());
         assertEquals(image.getName(), it.next().getName());
         assertEquals(tags.getName(), it.next().getName());
         
         // Look inside another
         DirectoryEntry imageD = (DirectoryEntry)image;
         assertEquals(7, imageD.getEntryCount());
         
         fs.close();
      }
   }
   
   /**
    * Tests that we can get the correct contents for
    *  a document in the filesystem 
    */
   @Test
   public void getDocumentEntry() throws Exception {
      for(NPOIFSFileSystem fs : get512and4kFileAndInput()) {
         DirectoryEntry root = fs.getRoot();
         Entry si = root.getEntry("\u0005SummaryInformation");
         
         assertEquals(true, si.isDocumentEntry());
         DocumentNode doc = (DocumentNode)si;
         
         // Check we can read it
         assertContentsMatches(null, doc);
         
         // Now try to build the property set
         DocumentInputStream inp = new NDocumentInputStream(doc);
         PropertySet ps = PropertySetFactory.create(inp);
         SummaryInformation inf = (SummaryInformation)ps;
         
         // Check some bits in it
         assertEquals(null, inf.getApplicationName());
         assertEquals(null, inf.getAuthor());
         assertEquals(null, inf.getSubject());
         assertEquals(131333, inf.getOSVersion());
         
         // Finish with this one
         inp.close();
         
         
         // Try the other summary information
         si = root.getEntry("\u0005DocumentSummaryInformation");
         assertEquals(true, si.isDocumentEntry());
         doc = (DocumentNode)si;
         assertContentsMatches(null, doc);
         
         inp = new NDocumentInputStream(doc);
         ps = PropertySetFactory.create(inp);
         DocumentSummaryInformation dinf = (DocumentSummaryInformation)ps;
         assertEquals(131333, dinf.getOSVersion());
         
         fs.close();
      }
   }
   
   /**
    * Read a file, write it and read it again.
    * Then, alter+add some streams, write and read
    */
   @Test
   public void readWriteRead() throws Exception {
       SummaryInformation sinf = null;
       DocumentSummaryInformation dinf = null;
       DirectoryEntry root = null, testDir = null;
       
       for(NPOIFSFileSystem fs1 : get512and4kFileAndInput()) {
           // Check we can find the entries we expect
           root = fs1.getRoot();
           assertEquals(5, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Tags"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));

           
           // Write out, re-load
           NPOIFSFileSystem fs2 = writeOutAndReadBack(fs1);
           fs1.close();
           
           // Check they're still there
           root = fs2.getRoot();
           assertEquals(5, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Tags"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
           
           
           // Check the contents of them - parse the summary block and check
           sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, sinf.getOSVersion());
           
           dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, dinf.getOSVersion());
           
           
           // Add a test mini stream
           testDir = root.createDirectory("Testing 123");
           testDir.createDirectory("Testing 456");
           testDir.createDirectory("Testing 789");
           byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
           testDir.createDocument("Mini", new ByteArrayInputStream(mini));
           
           
           // Write out, re-load
           NPOIFSFileSystem fs3 = writeOutAndReadBack(fs2);
           fs2.close();
           
           root = fs3.getRoot();
           testDir = (DirectoryEntry)root.getEntry("Testing 123");
           assertEquals(6, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Tags"));
           assertThat(root.getEntryNames(), hasItem("Testing 123"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));

           
           // Check old and new are there
           sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, sinf.getOSVersion());
           
           dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, dinf.getOSVersion());

           assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
           
           
           // Write out and read once more, just to be sure
           NPOIFSFileSystem fs4 = writeOutAndReadBack(fs3);
           fs3.close();
           
           root = fs4.getRoot();
           testDir = (DirectoryEntry)root.getEntry("Testing 123");
           assertEquals(6, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Tags"));
           assertThat(root.getEntryNames(), hasItem("Testing 123"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));

           sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, sinf.getOSVersion());
           
           dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, dinf.getOSVersion());

           assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
           
           
           // Add a full stream, delete a full stream
           byte[] main4096 = new byte[4096];
           main4096[0] = -10;
           main4096[4095] = -11;
           testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));
           
           root.getEntry("Tags").delete();
           
           
           // Write out, re-load
           NPOIFSFileSystem fs5 = writeOutAndReadBack(fs4);
           fs4.close();

           // Check it's all there
           root = fs5.getRoot();
           testDir = (DirectoryEntry)root.getEntry("Testing 123");
           assertEquals(5, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Testing 123"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));

           
           // Check old and new are there
           sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, sinf.getOSVersion());
           
           dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(
                   (DocumentEntry)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
           assertEquals(131333, dinf.getOSVersion());

           assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
           assertContentsMatches(main4096, (DocumentEntry)testDir.getEntry("Normal4096"));

           
           // Delete a directory, and add one more
           testDir.getEntry("Testing 456").delete();
           testDir.createDirectory("Testing ABC");
           
           
           // Save
           NPOIFSFileSystem fs6 = writeOutAndReadBack(fs5);
           fs5.close();

           // Check
           root = fs6.getRoot();
           testDir = (DirectoryEntry)root.getEntry("Testing 123");
           
           assertEquals(5, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Testing 123"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
           
           assertEquals(4, testDir.getEntryCount());
           assertThat(testDir.getEntryNames(), hasItem("Mini"));
           assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
           assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
           assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));
           
           
           // Add another mini stream
           byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
           testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
           
           // Save, load, check
           NPOIFSFileSystem fs7 = writeOutAndReadBack(fs6);
           fs6.close();
           
           root = fs7.getRoot();
           testDir = (DirectoryEntry)root.getEntry("Testing 123");
           
           assertEquals(5, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Testing 123"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
           
           assertEquals(5, testDir.getEntryCount());
           assertThat(testDir.getEntryNames(), hasItem("Mini"));
           assertThat(testDir.getEntryNames(), hasItem("Mini2"));
           assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
           assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
           assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));

           assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini"));
           assertContentsMatches(mini2, (DocumentEntry)testDir.getEntry("Mini2"));
           assertContentsMatches(main4096, (DocumentEntry)testDir.getEntry("Normal4096"));

           
           // Delete a mini stream, add one more
           testDir.getEntry("Mini").delete();
           
           byte[] mini3 = new byte[] { 42, 0, 42, 0, 42, 0, 42 };
           testDir.createDocument("Mini3", new ByteArrayInputStream(mini3));

           
           // Save, load, check
           NPOIFSFileSystem fs8 = writeOutAndReadBack(fs7);
           fs7.close();
           
           root = fs8.getRoot();
           testDir = (DirectoryEntry)root.getEntry("Testing 123");
           
           assertEquals(5, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Testing 123"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
           
           assertEquals(5, testDir.getEntryCount());
           assertThat(testDir.getEntryNames(), hasItem("Mini2"));
           assertThat(testDir.getEntryNames(), hasItem("Mini3"));
           assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
           assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
           assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));

           assertContentsMatches(mini2, (DocumentEntry)testDir.getEntry("Mini2"));
           assertContentsMatches(mini3, (DocumentEntry)testDir.getEntry("Mini3"));
           assertContentsMatches(main4096, (DocumentEntry)testDir.getEntry("Normal4096"));
           
           
           // Change some existing streams
           NPOIFSDocument mini2Doc = new NPOIFSDocument((DocumentNode)testDir.getEntry("Mini2"));
           mini2Doc.replaceContents(new ByteArrayInputStream(mini));
           
           byte[] main4106 = new byte[4106];
           main4106[0] = 41;
           main4106[4105] = 42;
           NPOIFSDocument mainDoc = new NPOIFSDocument((DocumentNode)testDir.getEntry("Normal4096"));
           mainDoc.replaceContents(new ByteArrayInputStream(main4106));
           
           
           // Re-check
           NPOIFSFileSystem fs9 = writeOutAndReadBack(fs8);
           fs8.close();
           
           root = fs9.getRoot();
           testDir = (DirectoryEntry)root.getEntry("Testing 123");
           
           assertEquals(5, root.getEntryCount());
           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
           assertThat(root.getEntryNames(), hasItem("Image"));
           assertThat(root.getEntryNames(), hasItem("Testing 123"));
           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
           
           assertEquals(5, testDir.getEntryCount());
           assertThat(testDir.getEntryNames(), hasItem("Mini2"));
           assertThat(testDir.getEntryNames(), hasItem("Mini3"));
           assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
           assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
           assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));

           assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini2"));
           assertContentsMatches(mini3, (DocumentEntry)testDir.getEntry("Mini3"));
           assertContentsMatches(main4106, (DocumentEntry)testDir.getEntry("Normal4096"));
           
           
           // All done
           fs9.close();
       }
   }
   
   /**
    * Create a new file, write it and read it again
    * Then, add some streams, write and read
    */
   @Test
   public void createWriteRead() throws IOException {
      NPOIFSFileSystem fs1 = new NPOIFSFileSystem();
      DocumentEntry miniDoc;
      DocumentEntry normDoc;
      
      // Initially has Properties + BAT but not SBAT
      assertEquals(POIFSConstants.END_OF_CHAIN, fs1.getNextBlock(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(1));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(2));
      
      // Check that the SBAT is empty
      assertEquals(POIFSConstants.END_OF_CHAIN, fs1.getRoot().getProperty().getStartBlock());
      
      // Check that properties table was given block 0
      assertEquals(0, fs1._get_property_table().getStartBlock());

      // Write and read it
      NPOIFSFileSystem fs2 = writeOutAndReadBack(fs1);
      fs1.close();
      
      // No change, SBAT remains empty 
      assertEquals(POIFSConstants.END_OF_CHAIN,     fs2.getNextBlock(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs2.getNextBlock(1));
      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs2.getNextBlock(2));
      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs2.getNextBlock(3));
      assertEquals(POIFSConstants.END_OF_CHAIN,     fs2.getRoot().getProperty().getStartBlock());
      assertEquals(0, fs2._get_property_table().getStartBlock());
      fs2.close();
      
      // Check the same but with saving to a file
      NPOIFSFileSystem fs3 = new NPOIFSFileSystem();
      NPOIFSFileSystem fs4 = writeOutFileAndReadBack(fs3);
      fs3.close();
      
      // Same, no change, SBAT remains empty 
      assertEquals(POIFSConstants.END_OF_CHAIN,     fs4.getNextBlock(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs4.getNextBlock(1));
      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs4.getNextBlock(2));
      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs4.getNextBlock(3));
      assertEquals(POIFSConstants.END_OF_CHAIN,     fs4.getRoot().getProperty().getStartBlock());
      assertEquals(0, fs4._get_property_table().getStartBlock());

      
      
      // Put everything within a new directory
      DirectoryEntry testDir = fs4.createDirectory("Test Directory");
      
      // Add a new Normal Stream (Normal Streams minimum 4096 bytes)
      byte[] main4096 = new byte[4096];
      main4096[0] = -10;
      main4096[4095] = -11;
      testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));

      assertEquals(POIFSConstants.END_OF_CHAIN,     fs4.getNextBlock(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs4.getNextBlock(1));
      assertEquals(3, fs4.getNextBlock(2));
      assertEquals(4, fs4.getNextBlock(3));
      assertEquals(5, fs4.getNextBlock(4));
      assertEquals(6, fs4.getNextBlock(5));
      assertEquals(7, fs4.getNextBlock(6));
      assertEquals(8, fs4.getNextBlock(7));
      assertEquals(9, fs4.getNextBlock(8));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getNextBlock(9));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs4.getNextBlock(10));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs4.getNextBlock(11));
      // SBAT still unused
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getRoot().getProperty().getStartBlock());

      
      // Add a bigger Normal Stream
      byte[] main5124 = new byte[5124];
      main5124[0] = -22;
      main5124[5123] = -33;
      testDir.createDocument("Normal5124", new ByteArrayInputStream(main5124));

      assertEquals(POIFSConstants.END_OF_CHAIN,     fs4.getNextBlock(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs4.getNextBlock(1));
      assertEquals(3, fs4.getNextBlock(2));
      assertEquals(4, fs4.getNextBlock(3));
      assertEquals(5, fs4.getNextBlock(4));
      assertEquals(6, fs4.getNextBlock(5));
      assertEquals(7, fs4.getNextBlock(6));
      assertEquals(8, fs4.getNextBlock(7));
      assertEquals(9, fs4.getNextBlock(8));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getNextBlock(9));

      assertEquals(11, fs4.getNextBlock(10));
      assertEquals(12, fs4.getNextBlock(11));
      assertEquals(13, fs4.getNextBlock(12));
      assertEquals(14, fs4.getNextBlock(13));
      assertEquals(15, fs4.getNextBlock(14));
      assertEquals(16, fs4.getNextBlock(15));
      assertEquals(17, fs4.getNextBlock(16));
      assertEquals(18, fs4.getNextBlock(17));
      assertEquals(19, fs4.getNextBlock(18));
      assertEquals(20, fs4.getNextBlock(19));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getNextBlock(20));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs4.getNextBlock(21));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs4.getNextBlock(22));

      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getRoot().getProperty().getStartBlock());
      
      
      // Now Add a mini stream
      byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
      testDir.createDocument("Mini", new ByteArrayInputStream(mini));
      
      // Mini stream will get one block for fat + one block for data
      assertEquals(POIFSConstants.END_OF_CHAIN,     fs4.getNextBlock(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs4.getNextBlock(1));
      assertEquals(3, fs4.getNextBlock(2));
      assertEquals(4, fs4.getNextBlock(3));
      assertEquals(5, fs4.getNextBlock(4));
      assertEquals(6, fs4.getNextBlock(5));
      assertEquals(7, fs4.getNextBlock(6));
      assertEquals(8, fs4.getNextBlock(7));
      assertEquals(9, fs4.getNextBlock(8));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getNextBlock(9));

      assertEquals(11, fs4.getNextBlock(10));
      assertEquals(12, fs4.getNextBlock(11));
      assertEquals(13, fs4.getNextBlock(12));
      assertEquals(14, fs4.getNextBlock(13));
      assertEquals(15, fs4.getNextBlock(14));
      assertEquals(16, fs4.getNextBlock(15));
      assertEquals(17, fs4.getNextBlock(16));
      assertEquals(18, fs4.getNextBlock(17));
      assertEquals(19, fs4.getNextBlock(18));
      assertEquals(20, fs4.getNextBlock(19));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getNextBlock(20));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getNextBlock(21));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs4.getNextBlock(22));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs4.getNextBlock(23));

      // Check the mini stream location was set
      // (21 is mini fat, 22 is first mini stream block)
      assertEquals(22, fs4.getRoot().getProperty().getStartBlock());
      
      
      // Write and read back
      NPOIFSFileSystem fs5 = writeOutAndReadBack(fs4);
      fs4.close();
      HeaderBlock header = writeOutAndReadHeader(fs5);
      
      // Check the header has the right points in it
      assertEquals(1, header.getBATCount());
      assertEquals(1, header.getBATArray()[0]);
      assertEquals(0, header.getPropertyStart());
      assertEquals(1, header.getSBATCount());
      assertEquals(21, header.getSBATStart());
      assertEquals(22, fs5._get_property_table().getRoot().getStartBlock());
      
      // Block use should be almost the same, except the properties
      //  stream will have grown out to cover 2 blocks
      // Check the block use is all unchanged
      assertEquals(23, fs5.getNextBlock(0)); // Properties now extends over 2 blocks
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs5.getNextBlock(1));
      
      assertEquals(3, fs5.getNextBlock(2));
      assertEquals(4, fs5.getNextBlock(3));
      assertEquals(5, fs5.getNextBlock(4));
      assertEquals(6, fs5.getNextBlock(5));
      assertEquals(7, fs5.getNextBlock(6));
      assertEquals(8, fs5.getNextBlock(7));
      assertEquals(9, fs5.getNextBlock(8));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs5.getNextBlock(9)); // End of normal4096

      assertEquals(11, fs5.getNextBlock(10));
      assertEquals(12, fs5.getNextBlock(11));
      assertEquals(13, fs5.getNextBlock(12));
      assertEquals(14, fs5.getNextBlock(13));
      assertEquals(15, fs5.getNextBlock(14));
      assertEquals(16, fs5.getNextBlock(15));
      assertEquals(17, fs5.getNextBlock(16));
      assertEquals(18, fs5.getNextBlock(17));
      assertEquals(19, fs5.getNextBlock(18));
      assertEquals(20, fs5.getNextBlock(19));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs5.getNextBlock(20)); // End of normal5124 
      
      assertEquals(POIFSConstants.END_OF_CHAIN, fs5.getNextBlock(21)); // Mini Stream FAT
      assertEquals(POIFSConstants.END_OF_CHAIN, fs5.getNextBlock(22)); // Mini Stream data
      assertEquals(POIFSConstants.END_OF_CHAIN, fs5.getNextBlock(23)); // Properties #2
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs5.getNextBlock(24));

      
      // Check some data
      assertEquals(1, fs5.getRoot().getEntryCount());
      testDir = (DirectoryEntry)fs5.getRoot().getEntry("Test Directory");
      assertEquals(3, testDir.getEntryCount());

      miniDoc = (DocumentEntry)testDir.getEntry("Mini");
      assertContentsMatches(mini, miniDoc);
      
      normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
      assertContentsMatches(main4096, normDoc);

      normDoc = (DocumentEntry)testDir.getEntry("Normal5124");
      assertContentsMatches(main5124, normDoc);
      
      
      // Delete a couple of streams
      miniDoc.delete();
      normDoc.delete();

      
      // Check - will have un-used sectors now
      NPOIFSFileSystem fs6 = writeOutAndReadBack(fs5);
      fs5.close();
      
      assertEquals(POIFSConstants.END_OF_CHAIN,     fs6.getNextBlock(0)); // Props back in 1 block
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs6.getNextBlock(1));
      
      assertEquals(3, fs6.getNextBlock(2));
      assertEquals(4, fs6.getNextBlock(3));
      assertEquals(5, fs6.getNextBlock(4));
      assertEquals(6, fs6.getNextBlock(5));
      assertEquals(7, fs6.getNextBlock(6));
      assertEquals(8, fs6.getNextBlock(7));
      assertEquals(9, fs6.getNextBlock(8));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs6.getNextBlock(9)); // End of normal4096

      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(10));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(11));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(12));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(13));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(14));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(15));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(16));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(17));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(18));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(19));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(20));
      
      assertEquals(POIFSConstants.END_OF_CHAIN, fs6.getNextBlock(21)); // Mini Stream FAT
      assertEquals(POIFSConstants.END_OF_CHAIN, fs6.getNextBlock(22)); // Mini Stream data
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(23)); // Properties gone
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(24));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs6.getNextBlock(25));
      
      // All done
      fs6.close();
   }
   
   @Test
   public void addBeforeWrite() throws IOException {
       NPOIFSFileSystem fs1 = new NPOIFSFileSystem();
       DocumentEntry miniDoc;
       DocumentEntry normDoc;
       HeaderBlock hdr;
       
       // Initially has Properties + BAT but nothing else
       assertEquals(POIFSConstants.END_OF_CHAIN, fs1.getNextBlock(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(1));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(2));
       
       hdr = writeOutAndReadHeader(fs1);
       // No mini stream, and no xbats
       // Will have fat then properties stream
       assertEquals(1, hdr.getBATCount());
       assertEquals(1, hdr.getBATArray()[0]);
       assertEquals(0, hdr.getPropertyStart());
       assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getSBATStart());
       assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getXBATIndex());
       assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*3, fs1.size());
       fs1.close();
       
       // Get a clean filesystem to start with
       fs1 = new NPOIFSFileSystem();
       
       // Put our test files in a non-standard place
       DirectoryEntry parentDir = fs1.createDirectory("Parent Directory");
       DirectoryEntry testDir = parentDir.createDirectory("Test Directory");
       
       
       // Add to the mini stream
       byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
       testDir.createDocument("Mini", new ByteArrayInputStream(mini));
       
       // Add to the main stream
       byte[] main4096 = new byte[4096];
       main4096[0] = -10;
       main4096[4095] = -11;
       testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));

       
       // Check the mini stream was added, then the main stream
       assertEquals(POIFSConstants.END_OF_CHAIN, fs1.getNextBlock(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(1)); 
       assertEquals(POIFSConstants.END_OF_CHAIN, fs1.getNextBlock(2)); // Mini Fat
       assertEquals(POIFSConstants.END_OF_CHAIN, fs1.getNextBlock(3)); // Mini Stream
       assertEquals(5,                           fs1.getNextBlock(4)); // Main Stream
       assertEquals(6,                           fs1.getNextBlock(5));
       assertEquals(7,                           fs1.getNextBlock(6));
       assertEquals(8,                           fs1.getNextBlock(7));
       assertEquals(9,                           fs1.getNextBlock(8));
       assertEquals(10,                          fs1.getNextBlock(9));
       assertEquals(11,                          fs1.getNextBlock(10));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs1.getNextBlock(11));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(12));
       assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*13, fs1.size());
       
       
       // Check that we can read the right data pre-write
       miniDoc = (DocumentEntry)testDir.getEntry("Mini");
       assertContentsMatches(mini, miniDoc);

       normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
       assertContentsMatches(main4096, normDoc);
       
       
       // Write, read, check
       hdr = writeOutAndReadHeader(fs1);
       NPOIFSFileSystem fs2 = writeOutAndReadBack(fs1);
       fs1.close();
       
       // Check the header details - will have the sbat near the start,
       //  then the properties at the end
       assertEquals(1, hdr.getBATCount());
       assertEquals(1, hdr.getBATArray()[0]);
       assertEquals(2, hdr.getSBATStart());
       assertEquals(0, hdr.getPropertyStart());
       assertEquals(POIFSConstants.END_OF_CHAIN, hdr.getXBATIndex());
       
       // Check the block allocation is unchanged, other than
       //  the properties stream going in at the end
       assertEquals(12,                          fs2.getNextBlock(0)); // Properties
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs2.getNextBlock(1));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs2.getNextBlock(2));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs2.getNextBlock(3));
       assertEquals(5,                           fs2.getNextBlock(4));
       assertEquals(6,                           fs2.getNextBlock(5));
       assertEquals(7,                           fs2.getNextBlock(6));
       assertEquals(8,                           fs2.getNextBlock(7));
       assertEquals(9,                           fs2.getNextBlock(8));
       assertEquals(10,                          fs2.getNextBlock(9));
       assertEquals(11,                          fs2.getNextBlock(10));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs2.getNextBlock(11));
       assertEquals(POIFSConstants.END_OF_CHAIN, fs2.getNextBlock(12));
       assertEquals(POIFSConstants.UNUSED_BLOCK, fs2.getNextBlock(13));
       assertEquals(POIFSConstants.SMALLER_BIG_BLOCK_SIZE*14, fs2.size());
       
       
       // Check the data
       DirectoryEntry fsRoot = fs2.getRoot();
       assertEquals(1, fsRoot.getEntryCount());
       
       parentDir = (DirectoryEntry)fsRoot.getEntry("Parent Directory");
       assertEquals(1, parentDir.getEntryCount());
       
       testDir = (DirectoryEntry)parentDir.getEntry("Test Directory");
       assertEquals(2, testDir.getEntryCount());

       miniDoc = (DocumentEntry)testDir.getEntry("Mini");
       assertContentsMatches(mini, miniDoc);

       normDoc = (DocumentEntry)testDir.getEntry("Normal4096");
       assertContentsMatches(main4096, normDoc);
       
       
       // Add one more stream to each, then save and re-load
       byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
       testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
       
       // Add to the main stream
       byte[] main4106 = new byte[4106];
       main4106[0] = 41;
       main4106[4105] = 42;
       testDir.createDocument("Normal4106", new ByteArrayInputStream(main4106));
       
       
       // Recheck the data in all 4 streams
       NPOIFSFileSystem fs3 = writeOutAndReadBack(fs2);
       fs2.close();
       
       fsRoot = fs3.getRoot();
       assertEquals(1, fsRoot.getEntryCount());
       
       parentDir = (DirectoryEntry)fsRoot.getEntry("Parent Directory");
       assertEquals(1, parentDir.getEntryCount());
       
       testDir = (DirectoryEntry)parentDir.getEntry("Test Directory");
       assertEquals(4, testDir.getEntryCount());

       miniDoc = (DocumentEntry)testDir.getEntry("Mini");
       assertContentsMatches(mini, miniDoc);

       miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
       assertContentsMatches(mini2, miniDoc);

       normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
       assertContentsMatches(main4106, normDoc);
       
       // All done
       fs3.close();
   }
   
   @Test
   public void readZeroLengthEntries() throws IOException {
       NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("only-zero-byte-streams.ole2"));
       DirectoryNode testDir = fs.getRoot();
       assertEquals(3, testDir.getEntryCount());
       DocumentEntry entry;
       
       entry = (DocumentEntry)testDir.getEntry("test-zero-1");
       assertNotNull(entry);
       assertEquals(0, entry.getSize());
       
       entry = (DocumentEntry)testDir.getEntry("test-zero-2");
       assertNotNull(entry);
       assertEquals(0, entry.getSize());
       
       entry = (DocumentEntry)testDir.getEntry("test-zero-3");
       assertNotNull(entry);
       assertEquals(0, entry.getSize());
       
       // Check properties, all have zero length, no blocks
       NPropertyTable props = fs._get_property_table();
       assertEquals(POIFSConstants.END_OF_CHAIN, props.getRoot().getStartBlock());
       for (Property prop : props.getRoot()) {
           assertEquals("test-zero-", prop.getName().substring(0, 10));
           assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
       }
       
       // All done
       fs.close();
   }
   
   @Test
   public void writeZeroLengthEntries() throws IOException {
       NPOIFSFileSystem fs1 = new NPOIFSFileSystem();
       DirectoryNode testDir = fs1.getRoot();
       DocumentEntry miniDoc;
       DocumentEntry normDoc;
       DocumentEntry emptyDoc;
       
       // Add mini and normal sized entries to start
       byte[] mini2 = new byte[] { -42, 0, -1, -2, -3, -4, -42 };
       testDir.createDocument("Mini2", new ByteArrayInputStream(mini2));
       
       // Add to the main stream
       byte[] main4106 = new byte[4106];
       main4106[0] = 41;
       main4106[4105] = 42;
       testDir.createDocument("Normal4106", new ByteArrayInputStream(main4106));
       
       // Now add some empty ones
       byte[] empty = new byte[0];
       testDir.createDocument("empty-1", new ByteArrayInputStream(empty));
       testDir.createDocument("empty-2", new ByteArrayInputStream(empty));
       testDir.createDocument("empty-3", new ByteArrayInputStream(empty));
       
       // Check
       miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
       assertContentsMatches(mini2, miniDoc);

       normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
       assertContentsMatches(main4106, normDoc);
       
       emptyDoc = (DocumentEntry)testDir.getEntry("empty-1");
       assertContentsMatches(empty, emptyDoc);
       
       emptyDoc = (DocumentEntry)testDir.getEntry("empty-2");
       assertContentsMatches(empty, emptyDoc);
       
       emptyDoc = (DocumentEntry)testDir.getEntry("empty-3");
       assertContentsMatches(empty, emptyDoc);
       
       // Look at the properties entry, and check the empty ones
       //  have zero size and no start block
       NPropertyTable props = fs1._get_property_table();
       Iterator<Property> propsIt = props.getRoot().getChildren();
       
       Property prop = propsIt.next();
       assertEquals("Mini2", prop.getName());
       assertEquals(0, prop.getStartBlock());
       assertEquals(7, prop.getSize());
       
       prop = propsIt.next();
       assertEquals("Normal4106", prop.getName());
       assertEquals(4, prop.getStartBlock()); // BAT, Props, SBAT, MIni
       assertEquals(4106, prop.getSize());
       
       prop = propsIt.next();
       assertEquals("empty-1", prop.getName());
       assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
       assertEquals(0, prop.getSize());
       
       prop = propsIt.next();
       assertEquals("empty-2", prop.getName());
       assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
       assertEquals(0, prop.getSize());
       
       prop = propsIt.next();
       assertEquals("empty-3", prop.getName());
       assertEquals(POIFSConstants.END_OF_CHAIN, prop.getStartBlock());
       assertEquals(0, prop.getSize());
       
       
       // Save and re-check
       NPOIFSFileSystem fs2 = writeOutAndReadBack(fs1);
       fs1.close();
       testDir = fs2.getRoot();
       
       miniDoc = (DocumentEntry)testDir.getEntry("Mini2");
       assertContentsMatches(mini2, miniDoc);

       normDoc = (DocumentEntry)testDir.getEntry("Normal4106");
       assertContentsMatches(main4106, normDoc);
       
       emptyDoc = (DocumentEntry)testDir.getEntry("empty-1");
       assertContentsMatches(empty, emptyDoc);
       
       emptyDoc = (DocumentEntry)testDir.getEntry("empty-2");
       assertContentsMatches(empty, emptyDoc);
       
       emptyDoc = (DocumentEntry)testDir.getEntry("empty-3");
       assertContentsMatches(empty, emptyDoc);
       
       // Check that a mini-stream was assigned, with one block used
       assertEquals(3, testDir.getProperty().getStartBlock()); 
       assertEquals(64, testDir.getProperty().getSize()); 
       
       // All done
       fs2.close();
   }

   /**
    * Test that we can read a file with NPOIFS, create a new NPOIFS instance,
    *  write it out, read it with POIFS, and see the original data
    */
   @Test
   public void NPOIFSReadCopyWritePOIFSRead() throws IOException {
       File testFile = POIDataSamples.getSpreadSheetInstance().getFile("Simple.xls");
       NPOIFSFileSystem src = new NPOIFSFileSystem(testFile);
       byte wbDataExp[] = IOUtils.toByteArray(src.createDocumentInputStream("Workbook"));
       
       NPOIFSFileSystem nfs = new NPOIFSFileSystem();
       EntryUtils.copyNodes(src.getRoot(), nfs.getRoot());
       src.close();

       ByteArrayOutputStream bos = new ByteArrayOutputStream();
       nfs.writeFilesystem(bos);
       nfs.close();
       
       POIFSFileSystem pfs = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray()));
       byte wbDataAct[] = IOUtils.toByteArray(pfs.createDocumentInputStream("Workbook"));
       
       assertThat(wbDataExp, equalTo(wbDataAct));
       pfs.close();
   }
   
   /**
    * Ensure that you can recursively delete directories and their
    *  contents
    */
   @Test
   public void RecursiveDelete() throws IOException {
       File testFile = POIDataSamples.getSpreadSheetInstance().getFile("SimpleMacro.xls");
       NPOIFSFileSystem src = new NPOIFSFileSystem(testFile);

       // Starts out with 5 entries:
       //  _VBA_PROJECT_CUR
       //  SummaryInformation <(0x05)SummaryInformation>
       //  DocumentSummaryInformation <(0x05)DocumentSummaryInformation>
       //  Workbook
       //  CompObj <(0x01)CompObj>
       assertEquals(5, _countChildren(src._get_property_table().getRoot()));
       assertEquals(5, src.getRoot().getEntryCount());
       
       // Grab the VBA project root
       DirectoryEntry vbaProj = (DirectoryEntry)src.getRoot().getEntry("_VBA_PROJECT_CUR");
       assertEquals(3, vbaProj.getEntryCount());
       // Can't delete yet, has stuff
       assertEquals(false, vbaProj.delete());
       // Recursively delete
       _recursiveDeletee(vbaProj);
       
       // Entries gone
       assertEquals(4, _countChildren(src._get_property_table().getRoot()));
       assertEquals(4, src.getRoot().getEntryCount());
       
       // Done
       src.close();
   }
   private void _recursiveDeletee(Entry entry) throws IOException {
       if (entry.isDocumentEntry()) {
           assertEquals(true, entry.delete());
           return;
       }
       
       DirectoryEntry dir = (DirectoryEntry)entry;
       String[] names = dir.getEntryNames().toArray(new String[dir.getEntryCount()]);
       for (String name : names) {
           Entry ce = dir.getEntry(name);
           _recursiveDeletee(ce);
       }
       assertEquals(true, dir.delete());
   }
   @SuppressWarnings("unused")
   private int _countChildren(DirectoryProperty p) {
       int count = 0;
       for (Property cp : p) { count++; }
       return count;
   }
}
