diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..45f9615
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,23 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed 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.
+
+LOCAL_PATH := $(call my-dir)
+# Build a host-side library
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
+LOCAL_MODULE := fat32lib
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..b84e1b6
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,49 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/src/main/java/de/waldheinz/fs/AbstractFileSystem.java b/src/main/java/de/waldheinz/fs/AbstractFileSystem.java
new file mode 100644
index 0000000..85be4db
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/AbstractFileSystem.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc., 
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+import java.io.IOException;
+
+/**
+ * Abstract class with common things in different FileSystem implementations.
+ * 
+ * @author Fabien DUMINY
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public abstract class AbstractFileSystem implements FileSystem {
+    private final boolean readOnly;
+    private boolean closed;
+    
+    /**
+     * Creates a new {@code AbstractFileSystem}.
+     * 
+     * @param readOnly if the file system should be read-only
+     */
+    public AbstractFileSystem(boolean readOnly) {
+        this.closed = false;
+        this.readOnly = readOnly;
+    }
+    
+    @Override
+    public void close() throws IOException {
+        if (!isClosed()) {
+            if (!isReadOnly()) {
+                flush();
+            }
+            
+            closed = true;
+        }
+    }
+    
+    @Override
+    public final boolean isClosed() {
+        return closed;
+    }
+    
+    @Override
+    public final boolean isReadOnly() {
+        return readOnly;
+    }
+
+    /**
+     * Checks if this {@code FileSystem} was already closed, and throws an
+     * exception if it was.
+     *
+     * @throws IllegalStateException if this {@code FileSystem} was
+     *      already closed
+     * @see #isClosed()
+     * @see #close() 
+     */
+    protected final void checkClosed() throws IllegalStateException {
+        if (isClosed()) {
+            throw new IllegalStateException("file system was already closed");
+        }
+    }
+    
+    /**
+     * Checks if this {@code FileSystem} is read-only, and throws an
+     * exception if it is.
+     *
+     * @throws ReadOnlyException if this {@code FileSystem} is read-only
+     * @see #isReadOnly() 
+     */
+    protected final void checkReadOnly() throws ReadOnlyException {
+        if (isReadOnly()) {
+            throw new ReadOnlyException();
+        }
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/AbstractFsObject.java b/src/main/java/de/waldheinz/fs/AbstractFsObject.java
new file mode 100644
index 0000000..fea022a
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/AbstractFsObject.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+/**
+ * A base class that helps to implement the {@code FsObject} interface.
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ * @since 0.6
+ */
+public class AbstractFsObject implements FsObject {
+
+    /**
+     * Holds the read-only state of this object.
+     */
+    private final boolean readOnly;
+    
+    /**
+     * Remembers if this object still valid.
+     */
+    private boolean valid;
+
+    /**
+     * Creates a new instance of {@code AbstractFsObject} which will be valid
+     * and have the specified read-only state.
+     *
+     * @param readOnly if the new object will be read-only
+     */
+    protected AbstractFsObject(boolean readOnly) {
+        this.valid = true;
+        this.readOnly = readOnly;
+    }
+    
+    /** 
+     * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
+     * @see #checkValid()
+     * @see #invalidate() 
+     */
+    @Override
+    public final boolean isValid() {
+        return this.valid;
+    }
+
+    /**
+     * Marks this object as invalid.
+     * 
+     * @see #isValid()
+     * @see #checkValid()
+     */
+    protected final void invalidate() {
+        this.valid = false;
+    }
+
+    /**
+     * Convience method to check if this object is still valid and throw an
+     * {@code IllegalStateException} if it is not.
+     *
+     * @throws IllegalStateException if this object was invalidated
+     * @since 0.6
+     * @see #isValid()
+     * @see #invalidate() 
+     */
+    protected final void checkValid() throws IllegalStateException {
+        if (!isValid()) throw new IllegalStateException(
+                this + " is not valid");
+    }
+
+    /**
+     * Convience method to check if this object is writable. An object is
+     * writable if it is both, valid and not read-only. 
+     *
+     * @throws IllegalStateException if this object was invalidated
+     * @throws ReadOnlyException if this object was created with the read-only
+     *      flag set
+     * @since 0.6
+     */
+    protected final void checkWritable()
+            throws IllegalStateException, ReadOnlyException {
+        
+        checkValid();
+
+        if (isReadOnly()) {
+            throw new ReadOnlyException();
+        }
+    }
+    
+    @Override
+    public final boolean isReadOnly() {
+        return this.readOnly;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/BlockDevice.java b/src/main/java/de/waldheinz/fs/BlockDevice.java
new file mode 100644
index 0000000..88f05c9
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/BlockDevice.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * This is the abstraction used for a device that can hold a {@link FileSystem}.
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public interface BlockDevice {
+
+    /**
+     * Gets the total length of this device in bytes.
+     *
+     * @return the total number of bytes on this device
+     * @throws IOException on error getting the size of this device
+     */
+    public abstract long getSize() throws IOException;
+
+    /**
+     * Read a block of data from this device.
+     *
+     * @param devOffset the byte offset where to read the data from
+     * @param dest the destination buffer where to store the data read
+     * @throws IOException on read error
+     */
+    public abstract void read(long devOffset, ByteBuffer dest)
+            throws IOException;
+
+    /**
+     * Writes a block of data to this device.
+     *
+     * @param devOffset the byte offset where to store the data
+     * @param src the source {@code ByteBuffer} to write to the device
+     * @throws ReadOnlyException if this {@code BlockDevice} is read-only
+     * @throws IOException on write error
+     * @throws IllegalArgumentException if the {@code devOffset} is negative
+     *      or the write would go beyond the end of the device
+     * @see #isReadOnly()
+     */
+    public abstract void write(long devOffset, ByteBuffer src)
+            throws ReadOnlyException, IOException,
+            IllegalArgumentException;
+            
+    /**
+     * Flushes data in caches to the actual storage.
+     *
+     * @throws IOException on write error
+     */
+    public abstract void flush() throws IOException;
+
+    /**
+     * Returns the size of a sector on this device.
+     *
+     * @return the sector size in bytes
+     * @throws IOException on error determining the sector size
+     */
+    public int getSectorSize() throws IOException;
+
+    /**
+     * Closes this {@code BlockDevice}. No methods of this device may be
+     * accesses after this method was called.
+     *
+     * @throws IOException on error closing this device
+     * @see #isClosed() 
+     */
+    public void close() throws IOException;
+
+    /**
+     * Checks if this device was already closed. No methods may be called
+     * on a closed device (except this method).
+     *
+     * @return if this device is closed
+     */
+    public boolean isClosed();
+
+    /**
+     * Checks if this {@code BlockDevice} is read-only.
+     *
+     * @return if this {@code BlockDevice} is read-only
+     */
+    public boolean isReadOnly();
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/FileSystem.java b/src/main/java/de/waldheinz/fs/FileSystem.java
new file mode 100644
index 0000000..f84baae
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/FileSystem.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+import java.io.IOException;
+
+/**
+ * The interface common to all file system implementations.
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public interface FileSystem {
+    
+    /**
+     * Gets the root entry of this filesystem. This is usually a directory, but
+     * this is not required.
+     * 
+     * @return the file system's root entry
+     * @throws IOException on read error
+     */
+    public FsDirectory getRoot() throws IOException;
+
+    /**
+     * Returns if this {@code FileSystem} is in read-only mode.
+     *
+     * @return if this {@code FileSystem} is read-only
+     */
+    public boolean isReadOnly();
+
+    /**
+     * Close this file system. After a close, all invocations of methods of
+     * this file system or objects created by this file system will throw an
+     * {@link IllegalStateException}.
+     * 
+     * @throws IOException on error closing the file system
+     */
+    public void close() throws IOException;
+    
+    /**
+     * Returns {@code true} if this file system is closed. If the file system
+     * is closed, no more operations may be performed on it.
+     * 
+     * @return if this file system is closed
+     */
+    public boolean isClosed();
+
+    /**
+     * The total size of this file system.
+     *
+     * @return if -1 this feature is unsupported
+     * @throws IOException if an I/O error occurs
+     */
+    public long getTotalSpace() throws IOException;
+
+    /**
+     * The free space of this file system.
+     *
+     * @return if -1 this feature is unsupported
+     * @throws IOException if an I/O error occurs
+     */
+    public long getFreeSpace() throws IOException;
+
+    /**
+     * The usable space of this file system.
+     *
+     * @return if -1 this feature is unsupported
+     * @throws IOException if an I/O error occurs
+     */
+    public long getUsableSpace() throws IOException;
+
+    /**
+     * Flushes any modified file system structures to the underlying storage.
+     *
+     * @throws IOException
+     */
+    public void flush() throws IOException;
+}
diff --git a/src/main/java/de/waldheinz/fs/FileSystemFactory.java b/src/main/java/de/waldheinz/fs/FileSystemFactory.java
new file mode 100644
index 0000000..47cc438
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/FileSystemFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+import de.waldheinz.fs.fat.FatFileSystem;
+import java.io.IOException;
+
+/**
+ * Factory for {@link FileSystem} instances.
+ *
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public class FileSystemFactory {
+    
+    private FileSystemFactory() { }
+    
+    /**
+     * <p>
+     * Creates a new {@link FileSystem} for the specified {@code device}. When
+     * using this method, care must be taken that there is only one
+     * {@code FileSystems} accessing the specified {@link BlockDevice}.
+     * Otherwise severe file system corruption may occur.
+     * </p>
+     *
+     * @param device the device to create the file system for
+     * @param readOnly if the file system should be openend read-only
+     * @return a new {@code FileSystem} instance for the specified device
+     * @throws UnknownFileSystemException if the file system type could
+     *      not be determined
+     * @throws IOException on read error
+     */
+    public static FileSystem create(BlockDevice device, boolean readOnly)
+            throws UnknownFileSystemException, IOException {
+            
+        return FatFileSystem.read(device, readOnly);
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/FsDirectory.java b/src/main/java/de/waldheinz/fs/FsDirectory.java
new file mode 100644
index 0000000..c3d9b94
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/FsDirectory.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * Base class for all {@link FileSystem} directories.
+ *
+ * @author Ewout Prangsma &lt; epr at jnode.org&gt;
+ * @author Matthias Treydte
+ */
+public interface FsDirectory extends Iterable<FsDirectoryEntry>, FsObject {
+    
+    /**
+     * Gets an iterator to iterate over the entries of this directory.
+     *
+     * @return the directory iterator
+     */
+    @Override
+    public Iterator<FsDirectoryEntry> iterator();
+
+    /**
+     * Gets the entry with the given name.
+     * 
+     * @param name the name of the entry to get
+     * @return the entry, if it existed
+     * @throws IOException on error retrieving the entry
+     */
+    public FsDirectoryEntry getEntry(String name) throws IOException;
+
+    /**
+     * Add a new file with a given name to this directory.
+     * 
+     * @param name the name of the file to add
+     * @return the entry pointing to the new file
+     * @throws IOException on error creating the file
+     */
+    public FsDirectoryEntry addFile(String name) throws IOException;
+
+    /**
+     * Add a new (sub-)directory with a given name to this directory.
+     * 
+     * @param name the name of the sub-directory to add
+     * @return the entry pointing to the new directory
+     * @throws IOException on error creating the directory
+     */
+    public FsDirectoryEntry addDirectory(String name) throws IOException;
+
+    /**
+     * Remove the entry with the given name from this directory.
+     * 
+     * @param name name of the entry to remove
+     * @throws IOException on error deleting the entry
+     */
+    public void remove(String name) throws IOException;
+
+    /**
+     * Save all dirty (unsaved) data to the device.
+     * 
+     * @throws IOException on write error
+     */
+    public void flush() throws IOException;
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/FsDirectoryEntry.java b/src/main/java/de/waldheinz/fs/FsDirectoryEntry.java
new file mode 100644
index 0000000..c071bfe
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/FsDirectoryEntry.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+import java.io.IOException;
+import java.util.Comparator;
+
+/**
+ * Represents one entry in a {@link FsDirectory}.
+ * 
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public interface FsDirectoryEntry extends FsObject {
+
+    /**
+     * Compares directory entries alphabetically, with all directories coming
+     * before all files.
+     */
+    public final static Comparator<FsDirectoryEntry> DIRECTORY_ENTRY_COMPARATOR =
+            new Comparator<FsDirectoryEntry>() {
+
+        @Override
+        public int compare(FsDirectoryEntry e1, FsDirectoryEntry e2) {
+            if (e2.isDirectory() == e1.isDirectory()) {
+                /* compare names */
+                return e1.getName().compareTo(e2.getName());
+            } else {
+                if (e2.isDirectory()) return 1;
+                else return -1;
+            }
+        }
+    };
+    
+    /**
+     * Gets the name of this entry.
+     *
+     * @return this entrys name
+     */
+    public String getName();
+    
+    /**
+     * Gets the last modification time of this entry.
+     *
+     * @return the last modification time of the entry as milliseconds
+     *      since 1970, or {@code 0} if this filesystem does not support
+     *      getting the last modification time
+     * @throws IOException if an error occurs retrieving the time stamp
+     */
+    public long getLastModified() throws IOException;
+
+    /**
+     * Returns the time when this entry was created as ms since 1970.
+     *
+     * @return the creation time, or 0 if this feature is not supported
+     * @throws IOException on error retrieving the time stamp
+     */
+    public long getCreated() throws IOException;
+
+    /**
+     * Returns the time when this entry was last accessed as ms since 1970.
+     *
+     * @return the last access time, or 0 if this feature is not supported
+     * @throws IOException on error retrieving the last access time
+     */
+    public long getLastAccessed() throws IOException;
+    
+    /**
+     * Is this entry refering to a file?
+     * 
+     * @return if this entry refers to a file
+     */
+    public boolean isFile();
+
+    /**
+     * Is this entry refering to a (sub-)directory?
+     *
+     * @return if this entry refers to a directory
+     */
+    public boolean isDirectory();
+
+    /**
+     * Sets the name of this entry.
+     * 
+     * @param newName the new name of this entry
+     * @throws IOException on error setting the new name
+     */
+    public void setName(String newName) throws IOException;
+
+    /**
+     * Sets the last modification time of this entry.
+     * 
+     * @param lastModified the new last modification time of this entry
+     * @throws IOException on write error
+     */
+    public void setLastModified(long lastModified) throws IOException;
+
+    /**
+     * Gets the file this entry refers to. This method can only be called if
+     * {@code isFile} returns {@code true}.
+     * 
+     * @return the file described by this entry
+     * @throws IOException on error accessing the file
+     * @throws UnsupportedOperationException if this entry is a directory
+     */
+    public FsFile getFile()
+            throws IOException, UnsupportedOperationException;
+    
+    /**
+     * Gets the directory this entry refers to. This method can only be called
+     * if <code>isDirectory</code> returns true.
+     * 
+     * @return The directory described by this entry
+     * @throws IOException on read error
+     * @throws UnsupportedOperationException if this entry is a file
+     */
+    public FsDirectory getDirectory()
+            throws IOException, UnsupportedOperationException;
+    
+    /**
+     * Indicate if the entry has been modified in memory (ie need to be saved)
+     * 
+     * @return true if the entry needs to be saved
+     */
+    public boolean isDirty();
+}
diff --git a/src/main/java/de/waldheinz/fs/FsFile.java b/src/main/java/de/waldheinz/fs/FsFile.java
new file mode 100644
index 0000000..dfaa998
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/FsFile.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * A FsFile is a representation of a single block of bytes on a filesystem. It
+ * is comparable to an inode in Unix.
+ * 
+ * An FsFile does not have any knowledge of who is using this file. It is also
+ * possible that the system uses a single FsFile instance to create two
+ * inputstream's for two different principals.
+ * 
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ */
+public interface FsFile extends FsObject {
+
+    /**
+     * Gets the length (in bytes) of this file.
+     * 
+     * @return the file size
+     */
+    public long getLength();
+
+    /**
+     * Sets the length of this file.
+     * 
+     * @param length the new length of this file
+     * @throws IOException on error updating the file size
+     */
+    public void setLength(long length) throws IOException;
+
+    /**
+     * Reads from this file into the specified {@code ByteBuffer}. The
+     * first byte read will be put into the buffer at it's
+     * {@link ByteBuffer#position() position}, and the number of bytes read
+     * will equal the buffer's {@link ByteBuffer#remaining() remaining} bytes.
+     * 
+     * @param offset the offset into the file where to start reading
+     * @param dest the destination buffer where to put the bytes that were read
+     * @throws IOException on read error
+     */
+    public void read(long offset, ByteBuffer dest) throws IOException;
+
+    /**
+     * Writes to this file taking the data to write from the specified
+     * {@code ByteBuffer}. This method will read the buffer's
+     * {@link ByteBuffer#remaining() remaining} bytes starting at it's
+     * {@link ByteBuffer#position() position}.
+     * 
+     * @param offset the offset into the file where the first byte will be
+     *      written
+     * @param src the source buffer to read the data from
+     * @throws ReadOnlyException if the file is read-only
+     * @throws IOException on write error
+     */
+    public void write(long offset, ByteBuffer src)
+            throws ReadOnlyException, IOException;
+            
+    /**
+     * Flush any possibly cached data to the disk.
+     * 
+     * @throws IOException on error flushing
+     */
+    public void flush() throws IOException;
+}
diff --git a/src/main/java/de/waldheinz/fs/FsObject.java b/src/main/java/de/waldheinz/fs/FsObject.java
new file mode 100644
index 0000000..72d7d50
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/FsObject.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs;
+
+/**
+ * This interface is the base interface for objects that are part of a
+ * {@link FileSystem}.
+ * 
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public interface FsObject {
+    
+    /**
+     * Checks if this {@code FsObject} is still valid.
+     * 
+     * An object is not valid anymore if it has been removed from the
+     * filesystem. All invocations on methods (except this method and the
+     * methods inherited from {@link java.lang.Object}) of
+     * invalid objects must throw an {@link IllegalStateException}.
+     * 
+     * @return if this {@code FsObject} is still valid
+     */
+    public boolean isValid();
+    
+    /**
+     * Checks if this {@code FsObject} is read-only. Any attempt to modify a
+     * read-only {@code FsObject} must result in a {@link ReadOnlyException}
+     * being thrown, and the modification must not be performed.
+     *
+     * @return if this {@code FsObject} is read-only
+     * @since 0.6
+     */
+    public boolean isReadOnly();
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/ReadOnlyException.java b/src/main/java/de/waldheinz/fs/ReadOnlyException.java
new file mode 100644
index 0000000..f786d64
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/ReadOnlyException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs;
+
+/**
+ * This exception is thrown when an attempt is made to write to a read-only
+ * {@link BlockDevice}, {@link FileSystem} or other file system object. This is
+ * an unchecked exception, as it should always be possible to query the object
+ * about it's read-only state using it's {@code isReadOnly()} method.
+ * 
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ * @see FileSystem#isReadOnly()
+ * @see BlockDevice#isReadOnly() 
+ */
+public final class ReadOnlyException extends RuntimeException {
+
+    private final static long serialVersionUID = 1;
+    
+    /**
+     * Creates a new instance of {@code ReadOnlyException}.
+     *
+     */
+    public ReadOnlyException() {
+        super("read-only");
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/UnknownFileSystemException.java b/src/main/java/de/waldheinz/fs/UnknownFileSystemException.java
new file mode 100644
index 0000000..0e27baf
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/UnknownFileSystemException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs;
+
+import java.io.IOException;
+
+/**
+ * Indicates that it was not possible to determine the type of the file
+ * system being used on a block device.
+ *
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public final class UnknownFileSystemException extends IOException {
+    private final static long serialVersionUID = 1;
+    
+    private final BlockDevice device;
+    
+    /**
+     * Creates a new instance of {@code UnknownFileSystemException}.
+     * 
+     * @param device the {@code BlockDevice} whose file system could not
+     *      be determined
+     */
+    public UnknownFileSystemException(BlockDevice device) {
+        super("can not determin file system type"); //NOI18N
+        this.device = device;
+    }
+
+    /**
+     * Returns the {@code BlockDevice} whose file system could not be
+     * determined.
+     *
+     * @return the {@code BlockDevice} with an unknown file system
+     */
+    public BlockDevice getDevice() {
+        return this.device;
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/AbstractDirectory.java b/src/main/java/de/waldheinz/fs/fat/AbstractDirectory.java
new file mode 100644
index 0000000..d3445b7
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/AbstractDirectory.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is the abstract base class for all directory implementations.
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+abstract class AbstractDirectory {
+
+    /**
+     * The maximum length of the volume label.
+     *
+     * @see #setLabel(java.lang.String) 
+     */
+    public static final int MAX_LABEL_LENGTH = 11;
+    
+    private final List<FatDirectoryEntry> entries;
+    private final boolean readOnly;
+    private final boolean isRoot;
+    
+    private boolean dirty;
+    private int capacity;
+    private String volumeLabel;
+
+    /**
+     * Creates a new instance of {@code AbstractDirectory}.
+     *
+     * @param capacity the initial capacity of the new instance
+     * @param readOnly if the instance should be read-only
+     * @param isRoot if the new {@code AbstractDirectory} represents a root
+     *      directory
+     */
+    protected AbstractDirectory(
+            int capacity, boolean readOnly, boolean isRoot) {
+        
+        this.entries = new ArrayList<FatDirectoryEntry>();
+        this.capacity = capacity;
+        this.readOnly = readOnly;
+        this.isRoot = isRoot;
+    }
+
+    /**
+     * Gets called when the {@code AbstractDirectory} must read it's content
+     * off the backing storage. This method must always fill the buffer's
+     * remaining space with the bytes making up this directory, beginning with
+     * the first byte.
+     *
+     * @param data the {@code ByteBuffer} to fill
+     * @throws IOException on read error
+     */
+    protected abstract void read(ByteBuffer data) throws IOException;
+
+    /**
+     * Gets called when the {@code AbstractDirectory} wants to write it's
+     * contents to the backing storage. This method is expected to write the
+     * buffer's remaining data to the storage, beginning with the first byte.
+     *
+     * @param data the {@code ByteBuffer} to write
+     * @throws IOException on write error
+     */
+    protected abstract void write(ByteBuffer data) throws IOException;
+
+    /**
+     * Returns the number of the cluster where this directory is stored. This
+     * is important when creating the ".." entry in a sub-directory, as this
+     * entry must poing to the storage cluster of it's parent.
+     *
+     * @return this directory's storage cluster
+     */
+    protected abstract long getStorageCluster();
+
+    /**
+     * Gets called by the {@code AbstractDirectory} when it has determined that
+     * it should resize because the number of entries has changed.
+     *
+     * @param entryCount the new number of entries this directory needs to store
+     * @throws IOException on write error
+     * @throws DirectoryFullException if the FAT12/16 root directory is full
+     * @see #sizeChanged(long)
+     * @see #checkEntryCount(int) 
+     */
+    protected abstract void changeSize(int entryCount)
+            throws DirectoryFullException, IOException;
+            
+    /**
+     * Replaces all entries in this directory.
+     *
+     * @param newEntries the new directory entries
+     */
+    public void setEntries(List<FatDirectoryEntry> newEntries) {
+        if (newEntries.size() > capacity)
+            throw new IllegalArgumentException("too many entries");
+        
+        this.entries.clear();
+        this.entries.addAll(newEntries);
+    }
+    
+    /**
+     * 
+     *
+     * @param newSize the new storage space for the directory in bytes
+     * @see #changeSize(int) 
+     */
+    protected final void sizeChanged(long newSize) throws IOException {
+        final long newCount = newSize / FatDirectoryEntry.SIZE;
+        if (newCount > Integer.MAX_VALUE)
+            throw new IOException("directory too large");
+        
+        this.capacity = (int) newCount;
+    }
+
+    public final FatDirectoryEntry getEntry(int idx) {
+        return this.entries.get(idx);
+    }
+    
+    /**
+     * Returns the current capacity of this {@code AbstractDirectory}.
+     *
+     * @return the number of entries this directory can hold in its current
+     *      storage space
+     * @see #changeSize(int)
+     */
+    public final int getCapacity() {
+        return this.capacity;
+    }
+
+    /**
+     * The number of entries that are currently stored in this
+     * {@code AbstractDirectory}.
+     *
+     * @return the current number of directory entries
+     */
+    public final int getEntryCount() {
+        return this.entries.size();
+    }
+    
+    public boolean isReadOnly() {
+        return readOnly;
+    }
+
+    public final boolean isRoot() {
+        return this.isRoot;
+    }
+    
+    /**
+     * Gets the number of directory entries in this directory. This is the
+     * number of "real" entries in this directory, possibly plus one if a
+     * volume label is set.
+     * 
+     * @return the number of entries in this directory
+     */
+    public int getSize() {
+        return entries.size() + ((this.volumeLabel != null) ? 1 : 0);
+    }
+    
+    /**
+     * Mark this directory as dirty.
+     */
+    protected final void setDirty() {
+        this.dirty = true;
+    }
+
+    /**
+     * Checks if this {@code AbstractDirectory} is a root directory.
+     *
+     * @throws UnsupportedOperationException if this is not a root directory
+     * @see #isRoot() 
+     */
+    private void checkRoot() throws UnsupportedOperationException {
+        if (!isRoot()) {
+            throw new UnsupportedOperationException(
+                    "only supported on root directories");
+        }
+    }
+    
+    /**
+     * Mark this directory as not dirty.
+     */
+    private void resetDirty() {
+        this.dirty = false;
+    }
+    
+    /**
+     * Flush the contents of this directory to the persistent storage
+     */
+    public void flush() throws IOException {
+        
+        final ByteBuffer data = ByteBuffer.allocate(
+                getCapacity() * FatDirectoryEntry.SIZE);
+        
+        for (int i=0; i < entries.size(); i++) {
+            final FatDirectoryEntry entry = entries.get(i);
+            
+            if (entry != null) {
+                entry.write(data);
+            }
+        }
+        
+        /* TODO: the label could be placed directly the dot entries */
+        
+        if (this.volumeLabel != null) {
+            final FatDirectoryEntry labelEntry =
+                    FatDirectoryEntry.createVolumeLabel(volumeLabel);
+
+            labelEntry.write(data);
+        }
+        
+        if (data.hasRemaining()) {
+            FatDirectoryEntry.writeNullEntry(data);
+        }
+
+        data.flip();
+        
+        write(data);
+        resetDirty();
+    }
+    
+    protected final void read() throws IOException {
+        final ByteBuffer data = ByteBuffer.allocate(
+                getCapacity() * FatDirectoryEntry.SIZE);
+                
+        read(data);
+        data.flip();
+        
+        for (int i=0; i < getCapacity(); i++) {
+            final FatDirectoryEntry e =
+                    FatDirectoryEntry.read(data, isReadOnly());
+            
+            if (e == null) break;
+            
+            if (e.isVolumeLabel()) {
+                if (!this.isRoot) throw new IOException(
+                        "volume label in non-root directory");
+                
+                this.volumeLabel = e.getVolumeLabel();
+            } else {
+                entries.add(e);
+            }
+        }
+    }
+    
+    public void addEntry(FatDirectoryEntry e) throws IOException {
+        assert (e != null);
+        
+        if (getSize() == getCapacity()) {
+            changeSize(getCapacity() + 1);
+        }
+
+        entries.add(e);
+    }
+    
+    public void addEntries(FatDirectoryEntry[] entries)
+            throws IOException {
+        
+        if (getSize() + entries.length > getCapacity()) {
+            changeSize(getSize() + entries.length);
+        }
+
+        this.entries.addAll(Arrays.asList(entries));
+    }
+    
+    public void removeEntry(FatDirectoryEntry entry) throws IOException {
+        assert (entry != null);
+        
+        this.entries.remove(entry);
+        changeSize(getSize());
+    }
+
+    /**
+     * Returns the volume label that is stored in this directory. Reading the
+     * volume label is only supported for the root directory.
+     *
+     * @return the volume label stored in this directory, or {@code null}
+     * @throws UnsupportedOperationException if this is not a root directory
+     * @see #isRoot() 
+     */
+    public String getLabel() throws UnsupportedOperationException {
+        checkRoot();
+        
+        return volumeLabel;
+    }
+
+    public FatDirectoryEntry createSub(Fat fat) throws IOException {
+        final ClusterChain chain = new ClusterChain(fat, false);
+        chain.setChainLength(1);
+
+        final FatDirectoryEntry entry = FatDirectoryEntry.create(true);
+        entry.setStartCluster(chain.getStartCluster());
+        
+        final ClusterChainDirectory dir =
+                new ClusterChainDirectory(chain, false);
+
+        /* add "." entry */
+
+        final FatDirectoryEntry dot = FatDirectoryEntry.create(true);
+        dot.setShortName(ShortName.DOT);
+        dot.setStartCluster(dir.getStorageCluster());
+        copyDateTimeFields(entry, dot);
+        dir.addEntry(dot);
+
+        /* add ".." entry */
+
+        final FatDirectoryEntry dotDot = FatDirectoryEntry.create(true);
+        dotDot.setShortName(ShortName.DOT_DOT);
+        dotDot.setStartCluster(getStorageCluster());
+        copyDateTimeFields(entry, dotDot);
+        dir.addEntry(dotDot);
+
+        dir.flush();
+
+        return entry;
+    }
+    
+    private static void copyDateTimeFields(
+            FatDirectoryEntry src, FatDirectoryEntry dst) {
+        
+        dst.setCreated(src.getCreated());
+        dst.setLastAccessed(src.getLastAccessed());
+        dst.setLastModified(src.getLastModified());
+    }
+
+    /**
+     * Sets the volume label that is stored in this directory. Setting the
+     * volume label is supported on the root directory only.
+     *
+     * @param label the new volume label
+     * @throws IllegalArgumentException if the label is too long
+     * @throws UnsupportedOperationException if this is not a root directory
+     * @see #isRoot() 
+     */
+    public void setLabel(String label) throws IllegalArgumentException,
+            UnsupportedOperationException, IOException {
+
+        checkRoot();
+
+        if (label.length() > MAX_LABEL_LENGTH) throw new
+                IllegalArgumentException("label too long");
+
+        if (this.volumeLabel != null) {
+            if (label == null) {
+                changeSize(getSize() - 1);
+                this.volumeLabel = null;
+            } else {
+                ShortName.checkValidChars(label.toCharArray());
+                this.volumeLabel = label;
+            }
+        } else {
+            if (label != null) {
+                changeSize(getSize() + 1);
+                ShortName.checkValidChars(label.toCharArray());
+                this.volumeLabel = label;
+            }
+        }
+
+        this.dirty = true;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/BootSector.java b/src/main/java/de/waldheinz/fs/fat/BootSector.java
new file mode 100644
index 0000000..d1aa398
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/BootSector.java
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * The boot sector.
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public abstract class BootSector extends Sector {
+
+    /**
+     * Offset to the byte specifying the number of FATs.
+     *
+     * @see #getNrFats()
+     * @see #setNrFats(int) 
+     */
+    public static final int FAT_COUNT_OFFSET = 16;
+    public static final int RESERVED_SECTORS_OFFSET = 14;
+    
+    public static final int TOTAL_SECTORS_16_OFFSET = 19;
+    public static final int TOTAL_SECTORS_32_OFFSET = 32;
+
+    /**
+     * The length of the file system type string.
+     *
+     * @see #getFileSystemType()
+     */
+    public static final int FILE_SYSTEM_TYPE_LENGTH = 8;
+
+    /**
+     * The offset to the sectors per cluster value stored in a boot sector.
+     * 
+     * @see #getSectorsPerCluster()
+     * @see #setSectorsPerCluster(int)
+     */
+    public static final int SECTORS_PER_CLUSTER_OFFSET = 0x0d;
+    
+    public static final int EXTENDED_BOOT_SIGNATURE = 0x29;
+
+    /**
+     * The size of a boot sector in bytes.
+     */
+    public final static int SIZE = 512;
+    
+    protected BootSector(BlockDevice device) {
+        super(device, 0, SIZE);
+        markDirty();
+    }
+    
+    public static BootSector read(BlockDevice device) throws IOException {
+        final ByteBuffer bb = ByteBuffer.allocate(512);
+        bb.order(ByteOrder.LITTLE_ENDIAN);
+        device.read(0, bb);
+        
+        if ((bb.get(510) & 0xff) != 0x55 ||
+                (bb.get(511) & 0xff) != 0xaa) throw new IOException(
+                "missing boot sector signature");
+                
+        final byte sectorsPerCluster = bb.get(SECTORS_PER_CLUSTER_OFFSET);
+
+        if (sectorsPerCluster <= 0) throw new IOException(
+                "suspicious sectors per cluster count " + sectorsPerCluster);
+                
+        final int rootDirEntries = bb.getShort(
+                Fat16BootSector.ROOT_DIR_ENTRIES_OFFSET);
+        final int rootDirSectors = ((rootDirEntries * 32) +
+                (device.getSectorSize() - 1)) / device.getSectorSize();
+
+        final int total16 =
+                bb.getShort(TOTAL_SECTORS_16_OFFSET) & 0xffff;
+        final long total32 =
+                bb.getInt(TOTAL_SECTORS_32_OFFSET) & 0xffffffffl;
+        
+        final long totalSectors = total16 == 0 ? total32 : total16;
+        
+        final int fatSz16 =
+                bb.getShort(Fat16BootSector.SECTORS_PER_FAT_OFFSET)  & 0xffff;
+        final long fatSz32 =
+                bb.getInt(Fat32BootSector.SECTORS_PER_FAT_OFFSET) & 0xffffffffl;
+                
+        final long fatSz = fatSz16 == 0 ? fatSz32 : fatSz16;
+        final int reservedSectors = bb.getShort(RESERVED_SECTORS_OFFSET);
+        final int fatCount = bb.get(FAT_COUNT_OFFSET);
+        final long dataSectors = totalSectors - (reservedSectors +
+                (fatCount * fatSz) + rootDirSectors);
+                
+        final long clusterCount = dataSectors / sectorsPerCluster;
+        
+        final BootSector result =
+                (clusterCount > Fat16BootSector.MAX_FAT16_CLUSTERS) ?
+            new Fat32BootSector(device) : new Fat16BootSector(device);
+            
+        result.read();
+        return result;
+    }
+    
+    public abstract FatType getFatType();
+    
+    /**
+     * Gets the number of sectors per FAT.
+     * 
+     * @return the sectors per FAT
+     */
+    public abstract long getSectorsPerFat();
+    
+    /**
+     * Sets the number of sectors/fat
+     * 
+     * @param v  the new number of sectors per fat
+     */
+    public abstract void setSectorsPerFat(long v);
+
+    public abstract void setSectorCount(long count);
+
+    public abstract int getRootDirEntryCount();
+    
+    public abstract long getSectorCount();
+
+    /**
+     * Returns the offset to the file system type label, as this differs
+     * between FAT12/16 and FAT32.
+     *
+     * @return the offset to the file system type label
+     */
+    public abstract int getFileSystemTypeLabelOffset();
+    
+    public abstract int getExtendedBootSignatureOffset();
+    
+    public void init() throws IOException {
+        setBytesPerSector(getDevice().getSectorSize());
+        setSectorCount(getDevice().getSize() / getDevice().getSectorSize());
+        set8(getExtendedBootSignatureOffset(), EXTENDED_BOOT_SIGNATURE);
+
+        /* magic bytes needed by some windows versions to recognize a boot
+         * sector. these are x86 jump instructions which lead into
+         * nirvana when executed, but we're currently unable to produce really
+         * bootable images anyway. So... */
+        set8(0x00, 0xeb);
+        set8(0x01, 0x3c);
+        set8(0x02, 0x90);
+        
+        /* the boot sector signature */
+        set8(0x1fe, 0x55);
+        set8(0x1ff, 0xaa);
+    }
+    
+    /**
+     * Returns the file system type label string.
+     *
+     * @return the file system type string
+     * @see #setFileSystemTypeLabel(java.lang.String)
+     * @see #getFileSystemTypeLabelOffset() 
+     * @see #FILE_SYSTEM_TYPE_LENGTH
+     */
+    public String getFileSystemTypeLabel() {
+        final StringBuilder sb = new StringBuilder(FILE_SYSTEM_TYPE_LENGTH);
+
+        for (int i=0; i < FILE_SYSTEM_TYPE_LENGTH; i++) {
+            sb.append ((char) get8(getFileSystemTypeLabelOffset() + i));
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * 
+     *
+     * @param fsType the
+     * @throws IllegalArgumentException if the length of the specified string
+     *      does not equal {@link #FILE_SYSTEM_TYPE_LENGTH}
+     */
+    public void setFileSystemTypeLabel(String fsType)
+            throws IllegalArgumentException {
+
+        if (fsType.length() != FILE_SYSTEM_TYPE_LENGTH) {
+            throw new IllegalArgumentException();
+        }
+
+        for (int i=0; i < FILE_SYSTEM_TYPE_LENGTH; i++) {
+            set8(getFileSystemTypeLabelOffset() + i, fsType.charAt(i));
+        }
+    }
+
+    /**
+     * Returns the number of clusters that are really needed to cover the
+     * data-caontaining portion of the file system.
+     *
+     * @return the number of clusters usable for user data
+     * @see #getDataSize() 
+     */
+    public final long getDataClusterCount() {
+        return getDataSize() / getBytesPerCluster();
+    }
+
+    /**
+     * Returns the size of the data-containing portion of the file system.
+     *
+     * @return the number of bytes usable for storing user data
+     */
+    private long getDataSize() {
+        return (getSectorCount() * getBytesPerSector()) -
+                FatUtils.getFilesOffset(this);
+    }
+
+    /**
+     * Gets the OEM name
+     * 
+     * @return String
+     */
+    public String getOemName() {
+        StringBuilder b = new StringBuilder(8);
+        
+        for (int i = 0; i < 8; i++) {
+            int v = get8(0x3 + i);
+            if (v == 0) break;
+            b.append((char) v);
+        }
+        
+        return b.toString();
+    }
+
+
+    /**
+     * Sets the OEM name, must be at most 8 characters long.
+     *
+     * @param name the new OEM name
+     */
+    public void setOemName(String name) {
+        if (name.length() > 8) throw new IllegalArgumentException(
+                "only 8 characters are allowed");
+
+        for (int i = 0; i < 8; i++) {
+            char ch;
+            if (i < name.length()) {
+                ch = name.charAt(i);
+            } else {
+                ch = (char) 0;
+            }
+
+            set8(0x3 + i, ch);
+        }
+    }
+    
+    /**
+     * Gets the number of bytes/sector
+     * 
+     * @return int
+     */
+    public int getBytesPerSector() {
+        return get16(0x0b);
+    }
+
+    /**
+     * Sets the number of bytes/sector
+     * 
+     * @param v the new value for bytes per sector
+     */
+    public void setBytesPerSector(int v) {
+        if (v == getBytesPerSector()) return;
+
+        switch (v) {
+            case 512: case 1024: case 2048: case 4096:
+                set16(0x0b, v);
+                break;
+                
+            default:
+                throw new IllegalArgumentException();
+        }
+    }
+
+    private static boolean isPowerOfTwo(int n) {
+        return ((n!=0) && (n&(n-1))==0);
+    }
+
+    /**
+     * Returns the number of bytes per cluster, which is calculated from the
+     * {@link #getSectorsPerCluster() sectors per cluster} and the
+     * {@link #getBytesPerSector() bytes per sector}.
+     *
+     * @return the number of bytes per cluster
+     */
+    public int getBytesPerCluster() {
+        return this.getSectorsPerCluster() * this.getBytesPerSector();
+    }
+
+    /**
+     * Gets the number of sectors/cluster
+     * 
+     * @return int
+     */
+    public int getSectorsPerCluster() {
+        return get8(SECTORS_PER_CLUSTER_OFFSET);
+    }
+
+    /**
+     * Sets the number of sectors/cluster
+     *
+     * @param v the new number of sectors per cluster
+     */
+    public void setSectorsPerCluster(int v) {
+        if (v == getSectorsPerCluster()) return;
+        if (!isPowerOfTwo(v)) throw new IllegalArgumentException(
+                "value must be a power of two");
+        
+        set8(SECTORS_PER_CLUSTER_OFFSET, v);
+    }
+    
+    /**
+     * Gets the number of reserved (for bootrecord) sectors
+     * 
+     * @return int
+     */
+    public int getNrReservedSectors() {
+        return get16(RESERVED_SECTORS_OFFSET);
+    }
+
+    /**
+     * Sets the number of reserved (for bootrecord) sectors
+     * 
+     * @param v the new number of reserved sectors
+     */
+    public void setNrReservedSectors(int v) {
+        if (v == getNrReservedSectors()) return;
+        if (v < 1) throw new IllegalArgumentException(
+                "there must be >= 1 reserved sectors");
+        set16(RESERVED_SECTORS_OFFSET, v);
+    }
+
+    /**
+     * Gets the number of fats
+     * 
+     * @return int
+     */
+    public final int getNrFats() {
+        return get8(FAT_COUNT_OFFSET);
+    }
+
+    /**
+     * Sets the number of fats
+     *
+     * @param v the new number of fats
+     */
+    public final void setNrFats(int v) {
+        if (v == getNrFats()) return;
+        
+        set8(FAT_COUNT_OFFSET, v);
+    }
+    
+    /**
+     * Gets the number of logical sectors
+     * 
+     * @return int
+     */
+    protected int getNrLogicalSectors() {
+        return get16(TOTAL_SECTORS_16_OFFSET);
+    }
+    
+    /**
+     * Sets the number of logical sectors
+     * 
+     * @param v the new number of logical sectors
+     */
+    protected void setNrLogicalSectors(int v) {
+        if (v == getNrLogicalSectors()) return;
+        
+        set16(TOTAL_SECTORS_16_OFFSET, v);
+    }
+    
+    protected void setNrTotalSectors(long v) {
+        set32(TOTAL_SECTORS_32_OFFSET, v);
+    }
+    
+    protected long getNrTotalSectors() {
+        return get32(TOTAL_SECTORS_32_OFFSET);
+    }
+    
+    /**
+     * Gets the medium descriptor byte
+     * 
+     * @return int
+     */
+    public int getMediumDescriptor() {
+        return get8(0x15);
+    }
+
+    /**
+     * Sets the medium descriptor byte
+     * 
+     * @param v the new medium descriptor
+     */
+    public void setMediumDescriptor(int v) {
+        set8(0x15, v);
+    }
+    
+    /**
+     * Gets the number of sectors/track
+     * 
+     * @return int
+     */
+    public int getSectorsPerTrack() {
+        return get16(0x18);
+    }
+
+    /**
+     * Sets the number of sectors/track
+     *
+     * @param v the new number of sectors per track
+     */
+    public void setSectorsPerTrack(int v) {
+        if (v == getSectorsPerTrack()) return;
+        
+        set16(0x18, v);
+    }
+
+    /**
+     * Gets the number of heads
+     * 
+     * @return int
+     */
+    public int getNrHeads() {
+        return get16(0x1a);
+    }
+
+    /**
+     * Sets the number of heads
+     * 
+     * @param v the new number of heads
+     */
+    public void setNrHeads(int v) {
+        if (v == getNrHeads()) return;
+        
+        set16(0x1a, v);
+    }
+
+    /**
+     * Gets the number of hidden sectors
+     * 
+     * @return int
+     */
+    public long getNrHiddenSectors() {
+        return get32(0x1c);
+    }
+
+    /**
+     * Sets the number of hidden sectors
+     *
+     * @param v the new number of hidden sectors
+     */
+    public void setNrHiddenSectors(long v) {
+        if (v == getNrHiddenSectors()) return;
+        
+        set32(0x1c, v);
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder res = new StringBuilder(1024);
+        res.append("Bootsector :\n");
+        res.append("oemName=");
+        res.append(getOemName());
+        res.append('\n');
+        res.append("medium descriptor = ");
+        res.append(getMediumDescriptor());
+        res.append('\n');
+        res.append("Nr heads = ");
+        res.append(getNrHeads());
+        res.append('\n');
+        res.append("Sectors per track = ");
+        res.append(getSectorsPerTrack());
+        res.append('\n');
+        res.append("Sector per cluster = ");
+        res.append(getSectorsPerCluster());
+        res.append('\n');
+        res.append("byte per sector = ");
+        res.append(getBytesPerSector());
+        res.append('\n');
+        res.append("Nr fats = ");
+        res.append(getNrFats());
+        res.append('\n');
+        res.append("Nr hidden sectors = ");
+        res.append(getNrHiddenSectors());
+        res.append('\n');
+        res.append("Nr logical sectors = ");
+        res.append(getNrLogicalSectors());
+        res.append('\n');
+        res.append("Nr reserved sector = ");
+        res.append(getNrReservedSectors());
+        res.append('\n');
+        
+        return res.toString();
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/ClusterChain.java b/src/main/java/de/waldheinz/fs/fat/ClusterChain.java
new file mode 100644
index 0000000..e296092
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/ClusterChain.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.AbstractFsObject;
+import de.waldheinz.fs.BlockDevice;
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * A chain of clusters as stored in a {@link Fat}.
+ *
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+final class ClusterChain extends AbstractFsObject {
+    protected final Fat fat;
+    private final BlockDevice device;
+    private final int clusterSize;
+    protected final long dataOffset;
+    
+    private long startCluster;
+    
+    /**
+     * Creates a new {@code ClusterChain} that contains no clusters.
+     *
+     * @param fat the {@code Fat} that holds the new chain
+     * @param readOnly if the chain should be created read-only
+     */
+    public ClusterChain(Fat fat, boolean readOnly) {
+        this(fat, 0, readOnly);
+    }
+    
+    public ClusterChain(Fat fat, long startCluster, boolean readOnly) {
+        super(readOnly);
+        
+        this.fat = fat;
+        
+        if (startCluster != 0) {
+            this.fat.testCluster(startCluster);
+            
+            if (this.fat.isFreeCluster(startCluster))
+                throw new IllegalArgumentException(
+                    "cluster " + startCluster + " is free");
+        }
+        
+        this.device = fat.getDevice();
+        this.dataOffset = FatUtils.getFilesOffset(fat.getBootSector());
+        this.startCluster = startCluster;
+        this.clusterSize = fat.getBootSector().getBytesPerCluster();
+    }
+
+    public int getClusterSize() {
+        return clusterSize;
+    }
+    
+    public Fat getFat() {
+        return fat;
+    }
+
+    public BlockDevice getDevice() {
+        return device;
+    }
+
+    /**
+     * Returns the first cluster of this chain.
+     *
+     * @return the chain's first cluster, which may be 0 if this chain does
+     *      not contain any clusters
+     */
+    public long getStartCluster() {
+        return startCluster;
+    }
+    
+    /**
+     * Calculates the device offset (0-based) for the given cluster and offset
+     * within the cluster.
+     * 
+     * @param cluster
+     * @param clusterOffset
+     * @return long
+     * @throws FileSystemException
+     */
+    private long getDevOffset(long cluster, int clusterOffset) {
+        return dataOffset + clusterOffset +
+                ((cluster - Fat.FIRST_CLUSTER) * clusterSize);
+    }
+
+    /**
+     * Returns the size this {@code ClusterChain} occupies on the device.
+     *
+     * @return the size this chain occupies on the device in bytes
+     */
+    public long getLengthOnDisk() {
+        if (getStartCluster() == 0) return 0;
+        
+        return getChainLength() * clusterSize;
+    }
+    
+    /**
+     * Sets the length of this {@code ClusterChain} in bytes. Because a
+     * {@code ClusterChain} can only contain full clusters, the new size
+     * will always be a multiple of the cluster size.
+     *
+     * @param size the desired number of bytes the can be stored in
+     *      this {@code ClusterChain}
+     * @return the true number of bytes this {@code ClusterChain} can contain
+     * @throws IOException on error setting the new size
+     * @see #setChainLength(int) 
+     */
+    public long setSize(long size) throws IOException {
+        final long nrClusters = ((size + clusterSize - 1) / clusterSize);
+        if (nrClusters > Integer.MAX_VALUE)
+            throw new IOException("too many clusters");
+
+        setChainLength((int) nrClusters);
+        
+        return clusterSize * nrClusters;
+    }
+
+    /**
+     * Determines the length of this {@code ClusterChain} in clusters.
+     *
+     * @return the length of this chain
+     */
+    public int getChainLength() {
+        if (getStartCluster() == 0) return 0;
+        
+        final long[] chain = getFat().getChain(getStartCluster());
+        return chain.length;
+    }
+
+    /**
+     * Sets the length of this cluster chain in clusters.
+     *
+     * @param nrClusters the new number of clusters this chain should contain,
+     *      must be {@code >= 0}
+     * @throws IOException on error updating the chain length
+     * @see #setSize(long) 
+     */
+    public void setChainLength(int nrClusters) throws IOException {
+        if (nrClusters < 0) throw new IllegalArgumentException(
+                "negative cluster count"); //NOI18N
+                
+        if ((this.startCluster == 0) && (nrClusters == 0)) {
+            /* nothing to do */
+        } else if ((this.startCluster == 0) && (nrClusters > 0)) {
+            final long[] chain = fat.allocNew(nrClusters);
+            this.startCluster = chain[0];
+        } else {
+            final long[] chain = fat.getChain(startCluster);
+            
+            if (nrClusters != chain.length) {
+                if (nrClusters > chain.length) {
+                    /* grow the chain */
+                    int count = nrClusters - chain.length;
+                    
+                    while (count > 0) {
+                        fat.allocAppend(getStartCluster());
+                        count--;
+                    }
+                } else {
+                    /* shrink the chain */
+                    if (nrClusters > 0) {
+                        fat.setEof(chain[nrClusters - 1]);
+                        for (int i = nrClusters; i < chain.length; i++) {
+                            fat.setFree(chain[i]);
+                        }
+                    } else {
+                        for (int i=0; i < chain.length; i++) {
+                            fat.setFree(chain[i]);
+                        }
+                        
+                        this.startCluster = 0;
+                    }
+                }
+            }
+        }
+    }
+    
+    public void readData(long offset, ByteBuffer dest)
+            throws IOException {
+
+        int len = dest.remaining();
+
+        if ((startCluster == 0 && len > 0)) throw new EOFException();
+        
+        final long[] chain = getFat().getChain(startCluster);
+        final BlockDevice dev = getDevice();
+
+        int chainIdx = (int) (offset / clusterSize);
+        if (offset % clusterSize != 0) {
+            int clusOfs = (int) (offset % clusterSize);
+            int size = Math.min(len,
+                    (int) (clusterSize - (offset % clusterSize) - 1));
+            dest.limit(dest.position() + size);
+
+            dev.read(getDevOffset(chain[chainIdx], clusOfs), dest);
+            
+            offset += size;
+            len -= size;
+            chainIdx++;
+        }
+
+        while (len > 0) {
+            int size = Math.min(clusterSize, len);
+            dest.limit(dest.position() + size);
+
+            dev.read(getDevOffset(chain[chainIdx], 0), dest);
+
+            len -= size;
+            chainIdx++;
+        }
+    }
+    
+    /**
+     * Writes data to this cluster chain, possibly growing the chain so it
+     * can store the additional data. When this method returns without throwing
+     * an exception, the buffer's {@link ByteBuffer#position() position} will
+     * equal it's {@link ByteBuffer#limit() limit}, and the limit will not
+     * have changed. This is not guaranteed if writing fails.
+     *
+     * @param offset the offset where to write the first byte from the buffer
+     * @param srcBuf the buffer to write to this {@code ClusterChain}
+     * @throws IOException on write error
+     */
+    public void writeData(long offset, ByteBuffer srcBuf) throws IOException {
+        
+        int len = srcBuf.remaining();
+
+        if (len == 0) return;
+
+        final long minSize = offset + len;
+        if (getLengthOnDisk() < minSize) {
+            setSize(minSize);
+        }
+        
+        final long[] chain = fat.getChain(getStartCluster());
+
+        int chainIdx = (int) (offset / clusterSize);
+        if (offset % clusterSize != 0) {
+            int clusOfs = (int) (offset % clusterSize);
+            int size = Math.min(len,
+                    (int) (clusterSize - (offset % clusterSize)));
+            srcBuf.limit(srcBuf.position() + size);
+            
+            device.write(getDevOffset(chain[chainIdx], clusOfs), srcBuf);
+            
+            offset += size;
+            len -= size;
+            chainIdx++;
+        }
+        
+        while (len > 0) {
+            int size = Math.min(clusterSize, len);
+            srcBuf.limit(srcBuf.position() + size);
+
+            device.write(getDevOffset(chain[chainIdx], 0), srcBuf);
+
+            len -= size;
+            chainIdx++;
+        }
+        
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) return false;
+        if (!(obj instanceof ClusterChain)) return false;
+        
+        final ClusterChain other = (ClusterChain) obj;
+        
+        if (this.fat != other.fat &&
+                (this.fat == null || !this.fat.equals(other.fat))) {
+
+            return false;
+        }
+        
+        if (this.startCluster != other.startCluster) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 79 * hash +
+                (this.fat != null ? this.fat.hashCode() : 0);
+        hash = 79 * hash +
+                (int) (this.startCluster ^ (this.startCluster >>> 32));
+        return hash;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/ClusterChainDirectory.java b/src/main/java/de/waldheinz/fs/fat/ClusterChainDirectory.java
new file mode 100644
index 0000000..fa3e9df
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/ClusterChainDirectory.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * A directory that is stored in a cluster chain.
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+class ClusterChainDirectory extends AbstractDirectory {
+
+    /**
+     * According to the FAT specification, this is the maximum size a FAT
+     * directory may occupy on disk. The {@code ClusterChainDirectory} takes
+     * care not to grow beyond this limit.
+     *
+     * @see #changeSize(int) 
+     */
+    public final static int MAX_SIZE = 65536 * 32;
+
+    /**
+     * The {@code ClusterChain} that stores this directory. Package-visible
+     * for testing.
+     */
+    final ClusterChain chain;
+    
+    protected ClusterChainDirectory(ClusterChain chain, boolean isRoot) {
+        
+        super((int)(chain.getLengthOnDisk() / FatDirectoryEntry.SIZE),
+                chain.isReadOnly(), isRoot);
+        
+        this.chain = chain;   
+    }
+    
+    public static ClusterChainDirectory readRoot(
+            ClusterChain chain) throws IOException {
+        
+        final ClusterChainDirectory result =
+                new ClusterChainDirectory(chain, true);
+        
+        result.read();
+        return result;
+    }
+    
+    public static ClusterChainDirectory createRoot(Fat fat) throws IOException {
+
+        if (fat.getFatType() != FatType.FAT32) {
+            throw new IllegalArgumentException(
+                    "only FAT32 stores root directory in a cluster chain");
+        }
+
+        final Fat32BootSector bs = (Fat32BootSector) fat.getBootSector();
+        final ClusterChain cc = new ClusterChain(fat, false);
+        cc.setChainLength(1);
+        
+        bs.setRootDirFirstCluster(cc.getStartCluster());
+        
+        final ClusterChainDirectory result =
+                new ClusterChainDirectory(cc, true);
+        
+        result.flush();
+        return result;
+    }
+    
+    @Override
+    protected final void read(ByteBuffer data) throws IOException {
+        this.chain.readData(0, data);
+    }
+
+    @Override
+    protected final void write(ByteBuffer data) throws IOException {
+        final int toWrite = data.remaining();
+        chain.writeData(0, data);
+        final long trueSize = chain.getLengthOnDisk();
+        
+        /* TODO: check if the code below is really needed */
+        if (trueSize > toWrite) {
+            final int rest = (int) (trueSize - toWrite);
+            final ByteBuffer fill = ByteBuffer.allocate(rest);
+            chain.writeData(toWrite, fill);
+        }
+    }
+
+    /**
+     * Returns the first cluster of the chain that stores this directory for
+     * non-root instances or 0 if this is the root directory.
+     *
+     * @return the first storage cluster of this directory
+     * @see #isRoot() 
+     */
+    @Override
+    protected final long getStorageCluster() {
+        return isRoot() ? 0 : chain.getStartCluster();
+    }
+    
+    public final void delete() throws IOException {
+        chain.setChainLength(0);
+    }
+    
+    @Override
+    protected final void changeSize(int entryCount)
+            throws IOException, IllegalArgumentException {
+
+        assert (entryCount >= 0);
+
+        final int size = entryCount * FatDirectoryEntry.SIZE;
+
+        if (size > MAX_SIZE) throw new DirectoryFullException(
+                "directory would grow beyond " + MAX_SIZE + " bytes",
+                getCapacity(), entryCount);
+        
+        sizeChanged(chain.setSize(Math.max(size, chain.getClusterSize())));
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/DirectoryFullException.java b/src/main/java/de/waldheinz/fs/fat/DirectoryFullException.java
new file mode 100644
index 0000000..5f9770c
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/DirectoryFullException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import java.io.IOException;
+
+/**
+ * Gets thrown when either
+ * <ul>
+ * <li>a {@link Fat16RootDirectory} becomes full or</li>
+ * <li>a {@link ClusterChainDirectory} grows beyond it's
+ *      {@link ClusterChainDirectory#MAX_SIZE maximum size}
+ * </ul>
+ * 
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public final class DirectoryFullException extends IOException {
+    private final static long serialVersionUID = 2;
+    private final int currentCapacity;
+    private final int requestedCapacity;
+    
+    DirectoryFullException(int currentCapacity, int requestedCapacity) {
+        this("directory is full", currentCapacity, requestedCapacity);
+    }
+    
+    DirectoryFullException(String message,
+            int currentCapacity, int requestedCapacity) {
+
+        super(message);
+
+        this.currentCapacity = currentCapacity;
+        this.requestedCapacity = requestedCapacity;
+    }
+    
+    /**
+     * Returns the current capacity of the directory.
+     *
+     * @return the current capacity
+     */
+    public int getCurrentCapacity() {
+        return currentCapacity;
+    }
+
+    /**
+     * Returns the capacity the directory tried to grow, which did not succeed.
+     *
+     * @return the requested capacity
+     */
+    public int getRequestedCapacity() {
+        return requestedCapacity;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/DosUtils.java b/src/main/java/de/waldheinz/fs/fat/DosUtils.java
new file mode 100644
index 0000000..09e1ebb
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/DosUtils.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import java.util.Calendar;
+
+/**
+ * This class contains some methods for date and time conversions between Java
+ * and the format known from DOS filesystems (e.g. fat)
+ * 
+ * @author Ewout Prangsma &lt; epr at jnode.org&gt;
+ */
+final class DosUtils {
+
+    private DosUtils() { /* no instances */ }
+
+    /**
+     * Decode a 16-bit encoded DOS date/time into a java date/time.
+     * 
+     * @param dosDate
+     * @param dosTime
+     * @return long
+     */
+    public static long decodeDateTime(int dosDate, int dosTime) {
+        final Calendar cal = Calendar.getInstance();
+        
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.set(Calendar.SECOND, (dosTime & 0x1f) * 2);
+        cal.set(Calendar.MINUTE, (dosTime >> 5) & 0x3f);
+        cal.set(Calendar.HOUR_OF_DAY, dosTime >> 11);
+
+        cal.set(Calendar.DATE, dosDate & 0x1f);
+        cal.set(Calendar.MONTH, ((dosDate >> 5) & 0x0f) - 1);
+        cal.set(Calendar.YEAR, 1980 + (dosDate >> 9));
+        
+        return cal.getTimeInMillis();
+    }
+
+    /**
+     * Encode a java date/time into a 16-bit encoded DOS time
+     * 
+     * @param javaDateTime
+     * @return long
+     */
+    public static int encodeTime(long javaDateTime) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTimeInMillis(javaDateTime);
+        return 2048 * cal.get(Calendar.HOUR_OF_DAY) + 32 * cal.get(Calendar.MINUTE) +
+                cal.get(Calendar.SECOND) / 2;
+    }
+
+    /**
+     * Encode a java date/time into a 16-bit encoded DOS date
+     * 
+     * @param javaDateTime
+     * @return long
+     */
+    public static int encodeDate(long javaDateTime) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTimeInMillis(javaDateTime);
+        return 512 * (cal.get(Calendar.YEAR) - 1980) + 32 * (cal.get(Calendar.MONTH) + 1) +
+                cal.get(Calendar.DATE);
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java b/src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java
new file mode 100644
index 0000000..d9848cc
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import java.security.SecureRandom;
+
+/**
+ * Generates dummy 8.3 buffers that are associated with the long names.
+ * 
+ * @author Daniel Galpin &lt;dgalpin@google.com&gt; based upon the work of
+ *         Andrew Tridgell &lt;tridge@samba.org&gt;
+ */
+final class Dummy83BufferGenerator {
+    final SecureRandom mRandom;
+
+    /**
+     * Creates a new instance of {@code Dummy83BufferGenerator} that uses
+     * randomness only to avoid short name collisions.
+     */
+    public Dummy83BufferGenerator() {
+        mRandom = new SecureRandom();
+    }
+
+    /*
+     * Its in the DOS manual!(DOS 5: page 72) Valid: A..Z 0..9 _ ^ $ ~ ! # % & - {} () @ ' `
+     *
+     * Invalid: spaces/periods,
+     */
+    public static boolean validChar(char toTest) {
+        if (toTest >= 'A' && toTest <= 'Z') return true;
+        if (toTest >= 'a' && toTest <= 'z') return true;
+        if (toTest >= '0' && toTest <= '9') return true;
+        if (toTest == '_' || toTest == '^' || toTest == '$' || toTest == '~' ||
+                toTest == '!' || toTest == '#' || toTest == '%' || toTest == '&' ||
+                toTest == '-' || toTest == '{' || toTest == '}' || toTest == '(' ||
+                toTest == ')' || toTest == '@' || toTest == '\'' || toTest == '`')
+            return true;
+
+        return false;
+    }
+    
+    public static boolean isSkipChar(char c) {
+        return (c == '.') || (c == ' ');
+    }
+
+    public static String tidyString(String dirty) {
+        final StringBuilder result = new StringBuilder();
+
+        /* epurate it from alien characters */
+        for (int src=0; src < dirty.length(); src++) {
+            final char toTest = Character.toUpperCase(dirty.charAt(src));
+            if (isSkipChar(toTest)) continue;
+
+            if (validChar(toTest)) {
+                result.append(toTest);
+            } else {
+                result.append('_');
+            }
+        }
+
+        return result.toString();
+    }
+
+    public static boolean cleanString(String s) {
+        for (int i=0; i < s.length(); i++) {
+            if (isSkipChar(s.charAt(i))) return false;
+            if (!validChar(s.charAt(i))) return false;
+        }
+
+        return true;
+    }
+
+    public static String stripLeadingPeriods(String str) {
+        final StringBuilder sb = new StringBuilder(str.length());
+
+        for (int i=0; i < str.length(); i++) {
+            if (str.charAt(i) != '.') { //NOI18N
+                sb.append(str.substring(i));
+                break;
+            }
+        }
+        
+        return sb.toString();
+    }    /*
+     * These characters are all invalid in 8.3 names, plus have been shown to be
+     * harmless on all tested devices
+     */
+    static final private char[] invalidchar = {
+            (char) 0x01, (char) 0x02, (char) 0x03, (char) 0x04, (char) 0x05, (char) 0x06,
+            (char) 0x0B,
+            (char) 0x0C, (char) 0x0E, (char) 0x0F, (char) 0x10, (char) 0x11, (char) 0x12,
+            (char) 0x13,
+            (char) 0x14, (char) 0x15, (char) 0x16, (char) 0x17, (char) 0x18, (char) 0x19,
+            (char) 0x1A,
+            (char) 0x1B, (char) 0x1C, (char) 0x1D, (char) 0x1E, (char) 0x1F, (char) 0x22,
+            (char) 0x2a,
+            (char) 0x3a, (char) 0x3c, (char) 0x3e, (char) 0x3f, (char) 0x5b, (char) 0x5d,
+            (char) 0x7c
+    };
+
+    /**
+     * See original C Linux patch by Andrew Tridgell &lt;tridge@samba.org&gt;
+     * build a 11 byte 8.3 buffer which is not a short filename. We want 11
+     * bytes which: - will be seen as a constant string to all APIs on Linux and
+     * Windows - cannot be matched with wildcard patterns - cannot be used to
+     * access the file - has a low probability of collision within a directory -
+     * has an invalid 3 byte extension - contains at least one non-space and
+     * non-nul byte
+     * 
+     * @param longFullName the long file name to generate the buffer for
+     * @return the generated 8.3 buffer
+     */
+    public ShortName generate83BufferNew(String longFullName)
+            throws IllegalStateException {
+
+        char[] retBuffer = new char[11];
+
+        boolean hasRealShortName = false;// getRealShortNameInstead(longFullName,
+                                         // retBuffer);
+        if (!hasRealShortName) {
+            int i, tilde_pos, slash_pos;
+            int randomNumber = Math.abs(mRandom.nextInt());
+
+            /*
+             * the '/' makes sure that even unpatched Linux systems can't get at
+             * files by the 8.3 entry.
+             */
+
+            slash_pos = randomNumber % 8;
+            randomNumber >>= 3;
+
+            /*
+             * fill in the first 8 bytes with invalid characters. Note that we
+             * need to be careful not to run out of randomness. We use the same
+             * extension for all buffers.
+             */
+            for (i = 0; i < 8; i++) {
+            	if (i == slash_pos)
+                    retBuffer[i] = '/';
+                else {
+                    retBuffer[i] =
+                            invalidchar[randomNumber % invalidchar.length];
+                    randomNumber /= invalidchar.length;
+                    if (randomNumber < invalidchar.length)
+                        randomNumber = Math.abs(mRandom.nextInt());
+                }
+            }
+            
+            for ( i = 0; i < 8; i ++ ) {
+                if (retBuffer[i] == 0xe5) {
+                    throw new RuntimeException();
+                }
+            }
+
+            retBuffer[8] = 'i';
+            retBuffer[9] = 'f';
+            retBuffer[10] = 'l';
+        }
+        ShortName retName = new ShortName(retBuffer);
+        retName.setHasShortNameOnly(hasRealShortName);
+        return retName;
+    }
+
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/Fat.java b/src/main/java/de/waldheinz/fs/fat/Fat.java
new file mode 100644
index 0000000..3f3ab43
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/Fat.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * 
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public final class Fat {
+
+    /**
+     * The first cluster that really holds user data in a FAT.
+     */
+    public final static int FIRST_CLUSTER = 2;
+    
+    private final long[] entries;
+    private final FatType fatType;
+    private final int sectorCount;
+    private final int sectorSize;
+    private final BlockDevice device;
+    private final BootSector bs;
+    private final long offset;
+    private final int lastClusterIndex;
+    
+    private int lastAllocatedCluster;
+
+    /**
+     * Reads a {@code Fat} as specified by a {@code BootSector}.
+     *
+     * @param bs the boot sector specifying the {@code Fat} layout
+     * @param fatNr the number of the {@code Fat} to read
+     * @return the {@code Fat} that was read
+     * @throws IOException on read error
+     * @throws IllegalArgumentException if {@code fatNr} is greater than
+     *      {@link BootSector#getNrFats()}
+     */
+    public static Fat read(BootSector bs, int fatNr)
+            throws IOException, IllegalArgumentException {
+        
+        if (fatNr > bs.getNrFats()) {
+            throw new IllegalArgumentException(
+                    "boot sector says there are only " + bs.getNrFats() +
+                    " FATs when reading FAT #" + fatNr);
+        }
+        
+        final long fatOffset = FatUtils.getFatOffset(bs, fatNr);
+        final Fat result = new Fat(bs, fatOffset);
+        result.read();
+        return result;
+    }
+    
+    /**
+     * Creates a new {@code Fat} as specified by a {@code BootSector}.
+     *
+     * @param bs the boot sector specifying the {@code Fat} layout
+     * @param fatNr the number of the {@code Fat} to create
+     * @return the {@code Fat} that was created
+     * @throws IOException on write error
+     * @throws IllegalArgumentException if {@code fatNr} is greater than
+     *      {@link BootSector#getNrFats()}
+     */
+    public static Fat create(BootSector bs, int fatNr)
+            throws IOException, IllegalArgumentException {
+        
+        if (fatNr > bs.getNrFats()) {
+            throw new IllegalArgumentException(
+                    "boot sector says there are only " + bs.getNrFats() +
+                    " FATs when creating FAT #" + fatNr);
+        }
+        
+        final long fatOffset = FatUtils.getFatOffset(bs, fatNr);
+        final Fat result = new Fat(bs, fatOffset);
+
+        if (bs.getDataClusterCount() > result.entries.length)
+            throw new IOException("FAT too small for device");
+            
+        result.init(bs.getMediumDescriptor());
+        result.write();
+        return result;
+    }
+    
+    private Fat(BootSector bs, long offset) throws IOException {
+        this.bs = bs;
+        this.fatType = bs.getFatType();
+        if (bs.getSectorsPerFat() > Integer.MAX_VALUE)
+            throw new IllegalArgumentException("FAT too large");
+
+        if (bs.getSectorsPerFat() <= 0) throw new IOException(
+                "boot sector says there are " + bs.getSectorsPerFat() +
+                " sectors per FAT");
+
+        if (bs.getBytesPerSector() <= 0) throw new IOException(
+                "boot sector says there are " + bs.getBytesPerSector() +
+                " bytes per sector");
+
+        this.sectorCount = (int) bs.getSectorsPerFat();
+        this.sectorSize = bs.getBytesPerSector();
+        this.device = bs.getDevice();
+        this.offset = offset;
+        this.lastAllocatedCluster = FIRST_CLUSTER;
+        
+        if (bs.getDataClusterCount() > Integer.MAX_VALUE) throw
+                new IOException("too many data clusters");
+        
+        if (bs.getDataClusterCount() == 0) throw
+                new IOException("no data clusters");
+        
+        this.lastClusterIndex = (int) bs.getDataClusterCount() + FIRST_CLUSTER;
+
+        entries = new long[(int) ((sectorCount * sectorSize) /
+                fatType.getEntrySize())];
+                
+        if (lastClusterIndex > entries.length) throw new IOException(
+            "file system has " + lastClusterIndex +
+            "clusters but only " + entries.length + " FAT entries");
+    }
+    
+    public FatType getFatType() {
+        return fatType;
+    }
+    
+    /**
+     * Returns the {@code BootSector} that specifies this {@code Fat}.
+     *
+     * @return this {@code Fat}'s {@code BootSector}
+     */
+    public BootSector getBootSector() {
+        return this.bs;
+    }
+
+    /**
+     * Returns the {@code BlockDevice} where this {@code Fat} is stored.
+     *
+     * @return the device holding this FAT
+     */
+    public BlockDevice getDevice() {
+        return device;
+    }
+    
+    private void init(int mediumDescriptor) {
+        entries[0] = 
+                (mediumDescriptor & 0xFF) |
+                (0xFFFFF00L & fatType.getBitMask());
+        entries[1] = fatType.getEofMarker();
+    }
+    
+    /**
+     * Read the contents of this FAT from the given device at the given offset.
+     * 
+     * @param offset the byte offset where to read the FAT from the device
+     * @throws IOException on read error
+     */
+    private void read() throws IOException {
+        final byte[] data = new byte[sectorCount * sectorSize];
+        device.read(offset, ByteBuffer.wrap(data));
+
+        for (int i = 0; i < entries.length; i++)
+            entries[i] = fatType.readEntry(data, i);
+    }
+    
+    public void write() throws IOException {
+        this.writeCopy(offset);
+    }
+    
+    /**
+     * Write the contents of this FAT to the given device at the given offset.
+     * 
+     * @param offset the device offset where to write the FAT copy
+     * @throws IOException on write error
+     */
+    public void writeCopy(long offset) throws IOException {
+        final byte[] data = new byte[sectorCount * sectorSize];
+        
+        for (int index = 0; index < entries.length; index++) {
+            fatType.writeEntry(data, index, entries[index]);
+        }
+        
+        device.write(offset, ByteBuffer.wrap(data));
+    }
+    
+    /**
+     * Gets the medium descriptor byte
+     * 
+     * @return int
+     */
+    public int getMediumDescriptor() {
+        return (int) (entries[0] & 0xFF);
+    }
+    
+    /**
+     * Gets the entry at a given offset
+     * 
+     * @param index
+     * @return long
+     */
+    public long getEntry(int index) {
+        return entries[index];
+    }
+
+    /**
+     * Returns the last free cluster that was accessed in this FAT.
+     *
+     * @return the last seen free cluster
+     */
+    public int getLastFreeCluster() {
+        return this.lastAllocatedCluster;
+    }
+    
+    public long[] getChain(long startCluster) {
+        testCluster(startCluster);
+        // Count the chain first
+        int count = 1;
+        long cluster = startCluster;
+        while (!isEofCluster(entries[(int) cluster])) {
+            count++;
+            cluster = entries[(int) cluster];
+        }
+        // Now create the chain
+        long[] chain = new long[count];
+        chain[0] = startCluster;
+        cluster = startCluster;
+        int i = 0;
+        while (!isEofCluster(entries[(int) cluster])) {
+            cluster = entries[(int) cluster];
+            chain[++i] = cluster;
+        }
+        return chain;
+    }
+
+    /**
+     * Gets the cluster after the given cluster
+     * 
+     * @param cluster
+     * @return long The next cluster number or -1 which means eof.
+     */
+    public long getNextCluster(long cluster) {
+        testCluster(cluster);
+        long entry = entries[(int) cluster];
+        if (isEofCluster(entry)) {
+            return -1;
+        } else {
+            return entry;
+        }
+    }
+
+    /**
+     * Allocate a cluster for a new file
+     * 
+     * @return long the number of the newly allocated cluster
+     * @throws IOException if there are no free clusters
+     */
+    public long allocNew() throws IOException {
+
+        int i;
+        int entryIndex = -1;
+
+        for (i = lastAllocatedCluster; i < lastClusterIndex; i++) {
+            if (isFreeCluster(i)) {
+                entryIndex = i;
+                break;
+            }
+        }
+        
+        if (entryIndex < 0) {
+            for (i = FIRST_CLUSTER; i < lastAllocatedCluster; i++) {
+                if (isFreeCluster(i)) {
+                    entryIndex = i;
+                    break;
+                }
+            }
+        }
+        
+        if (entryIndex < 0) {
+            throw new IOException(
+                    "FAT Full (" + (lastClusterIndex - FIRST_CLUSTER)
+                    + ", " + i + ")"); //NOI18N
+        }
+        
+        entries[entryIndex] = fatType.getEofMarker();
+        lastAllocatedCluster = entryIndex % lastClusterIndex;
+        if (lastAllocatedCluster < FIRST_CLUSTER)
+            lastAllocatedCluster = FIRST_CLUSTER;
+        
+        return entryIndex;
+    }
+    
+    /**
+     * Returns the number of clusters that are currently not in use by this FAT.
+     * This estimate does only account for clusters that are really available in
+     * the data portion of the file system, not for clusters that might only
+     * theoretically be stored in the {@code Fat}.
+     *
+     * @return the free cluster count
+     * @see FsInfoSector#setFreeClusterCount(long)
+     * @see FsInfoSector#getFreeClusterCount()
+     * @see BootSector#getDataClusterCount() 
+     */
+    public int getFreeClusterCount() {
+        int result = 0;
+
+        for (int i=FIRST_CLUSTER; i < lastClusterIndex; i++) {
+            if (isFreeCluster(i)) result++;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the cluster number that was last allocated in this fat.
+     *
+     * @return
+     */
+    public int getLastAllocatedCluster() {
+        return this.lastAllocatedCluster;
+    }
+    
+    /**
+     * Allocate a series of clusters for a new file.
+     * 
+     * @param nrClusters when number of clusters to allocate
+     * @return long
+     * @throws IOException if there are no free clusters
+     */
+    public long[] allocNew(int nrClusters) throws IOException {
+        final long rc[] = new long[nrClusters];
+        
+        rc[0] = allocNew();
+        for (int i = 1; i < nrClusters; i++) {
+            rc[i] = allocAppend(rc[i - 1]);
+        }
+        
+        return rc;
+    }
+    
+    /**
+     * Allocate a cluster to append to a new file
+     * 
+     * @param cluster a cluster from a chain where the new cluster should be
+     *      appended
+     * @return long the newly allocated and appended cluster number
+     * @throws IOException if there are no free clusters
+     */
+    public long allocAppend(long cluster)
+            throws IOException {
+        
+        testCluster(cluster);
+        
+        while (!isEofCluster(entries[(int) cluster])) {
+            cluster = entries[(int) cluster];
+        }
+        
+        long newCluster = allocNew();
+        entries[(int) cluster] = newCluster;
+
+        return newCluster;
+    }
+
+    public void setEof(long cluster) {
+        testCluster(cluster);
+        entries[(int) cluster] = fatType.getEofMarker();
+    }
+
+    public void setFree(long cluster) {
+        testCluster(cluster);
+        entries[(int) cluster] = 0;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Fat)) return false;
+        
+        final Fat other = (Fat) obj;
+        if (this.fatType != other.fatType) return false;
+        if (this.sectorCount != other.sectorCount) return false;
+        if (this.sectorSize != other.sectorSize) return false;
+        if (this.lastClusterIndex != other.lastClusterIndex) return false;
+        if (!Arrays.equals(this.entries, other.entries)) return false;
+        if (this.getMediumDescriptor() != other.getMediumDescriptor())
+            return false;
+
+        return true;
+    }
+    
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 23 * hash + Arrays.hashCode(this.entries);
+        hash = 23 * hash + this.fatType.hashCode();
+        hash = 23 * hash + this.sectorCount;
+        hash = 23 * hash + this.sectorSize;
+        hash = 23 * hash + this.lastClusterIndex;
+        return hash;
+    }
+    
+    /**
+     * Is the given entry a free cluster?
+     *
+     * @param entry
+     * @return boolean
+     */
+    protected boolean isFreeCluster(long entry) {
+        if (entry > Integer.MAX_VALUE) throw new IllegalArgumentException();
+        return (entries[(int) entry] == 0);
+    }
+    
+    /**
+     * Is the given entry a reserved cluster?
+     *
+     * @param entry
+     * @return boolean
+     */
+    protected boolean isReservedCluster(long entry) {
+        return fatType.isReservedCluster(entry);
+    }
+
+    /**
+     * Is the given entry an EOF marker
+     *
+     * @param entry
+     * @return boolean
+     */
+    protected boolean isEofCluster(long entry) {
+        return fatType.isEofCluster(entry);
+    }
+    
+    protected void testCluster(long cluster) throws IllegalArgumentException {
+        if ((cluster < FIRST_CLUSTER) || (cluster >= entries.length)) {
+            throw new IllegalArgumentException(
+                    "invalid cluster value " + cluster);
+        }
+    }
+    
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append(this.getClass().getSimpleName());
+        sb.append("[type=");
+        sb.append(fatType);
+        sb.append(", mediumDescriptor=0x");
+        sb.append(Integer.toHexString(getMediumDescriptor()));
+        sb.append(", sectorCount=");
+        sb.append(sectorCount);
+        sb.append(", sectorSize=");
+        sb.append(sectorSize);
+        sb.append(", freeClusters=");
+        sb.append(getFreeClusterCount());
+        sb.append("]");
+        
+        return sb.toString();
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/Fat16BootSector.java b/src/main/java/de/waldheinz/fs/fat/Fat16BootSector.java
new file mode 100644
index 0000000..38bdc2e
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/Fat16BootSector.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+
+/**
+ * The boot sector layout as used by the FAT12 / FAT16 variants.
+ *
+ * @author Matthias Treydte &lt;matthias.treydte at meetwise.com&gt;
+ */
+final class Fat16BootSector extends BootSector {
+
+    /**
+     * The default number of entries for the root directory.
+     * 
+     * @see #getRootDirEntryCount()
+     * @see #setRootDirEntryCount(int) 
+     */
+    public static final int DEFAULT_ROOT_DIR_ENTRY_COUNT = 512;
+
+    /**
+     * The default volume label.
+     */
+    public static final String DEFAULT_VOLUME_LABEL = "NO NAME"; //NOI18N
+    
+    /**
+     * The maximum number of clusters for a FAT12 file system. This is actually
+     * the number of clusters where mkdosfs stop complaining about a FAT16
+     * partition having not enough sectors, so it would be misinterpreted
+     * as FAT12 without special handling.
+     *
+     * @see #getNrLogicalSectors()
+     */
+    public static final int MAX_FAT12_CLUSTERS = 4084;
+
+    public static final int MAX_FAT16_CLUSTERS = 65524;
+
+    /**
+     * The offset to the sectors per FAT value.
+     */
+    public static final int SECTORS_PER_FAT_OFFSET = 0x16;
+
+    /**
+     * The offset to the root directory entry count value.
+     *
+     * @see #getRootDirEntryCount()
+     * @see #setRootDirEntryCount(int) 
+     */
+    public static final int ROOT_DIR_ENTRIES_OFFSET = 0x11;
+
+    /**
+     * The offset to the first byte of the volume label.
+     */
+    public static final int VOLUME_LABEL_OFFSET = 0x2b;
+    
+    /**
+     * Offset to the FAT file system type string.
+     *
+     * @see #getFileSystemType() 
+     */
+    public static final int FILE_SYSTEM_TYPE_OFFSET = 0x36;
+    
+    /**
+     * The maximum length of the volume label.
+     */
+    public static final int MAX_VOLUME_LABEL_LENGTH = 11;
+    
+    public static final int EXTENDED_BOOT_SIGNATURE_OFFSET = 0x26;
+
+    /**
+     * Creates a new {@code Fat16BootSector} for the specified device.
+     *
+     * @param device the {@code BlockDevice} holding the boot sector
+     */
+    public Fat16BootSector(BlockDevice device) {
+        super(device);
+    }
+    
+    /**
+     * Returns the volume label that is stored in this boot sector.
+     *
+     * @return the volume label
+     */
+    public String getVolumeLabel() {
+        final StringBuilder sb = new StringBuilder();
+
+        for (int i=0; i < MAX_VOLUME_LABEL_LENGTH; i++) {
+            final char c = (char) get8(VOLUME_LABEL_OFFSET + i);
+
+            if (c != 0) {
+                sb.append(c);
+            } else {
+                break;
+            }
+        }
+        
+        return sb.toString();
+    }
+
+    /**
+     * Sets the volume label that is stored in this boot sector.
+     *
+     * @param label the new volume label
+     * @throws IllegalArgumentException if the specified label is longer
+     *      than {@link #MAX_VOLUME_LABEL_LENGTH}
+     */
+    public void setVolumeLabel(String label) throws IllegalArgumentException {
+        if (label.length() > MAX_VOLUME_LABEL_LENGTH)
+            throw new IllegalArgumentException("volume label too long");
+
+        for (int i = 0; i < MAX_VOLUME_LABEL_LENGTH; i++) {
+            set8(VOLUME_LABEL_OFFSET + i,
+                    i < label.length() ? label.charAt(i) : 0);
+        }
+    }
+    
+    /**
+     * Gets the number of sectors/fat for FAT 12/16.
+     *
+     * @return int
+     */
+    @Override
+    public long getSectorsPerFat() {
+        return get16(SECTORS_PER_FAT_OFFSET);
+    }
+
+    /**
+     * Sets the number of sectors/fat
+     *
+     * @param v  the new number of sectors per fat
+     */
+    @Override
+    public void setSectorsPerFat(long v) {
+        if (v == getSectorsPerFat()) return;
+        if (v > 0x7FFF) throw new IllegalArgumentException(
+                "too many sectors for a FAT12/16");
+        
+        set16(SECTORS_PER_FAT_OFFSET, (int)v);
+    }
+
+    @Override
+    public FatType getFatType() {
+        final long rootDirSectors = ((getRootDirEntryCount() * 32) +
+                (getBytesPerSector() - 1)) / getBytesPerSector();
+        final long dataSectors = getSectorCount() -
+                (getNrReservedSectors() + (getNrFats() * getSectorsPerFat()) +
+                rootDirSectors);
+        final long clusterCount = dataSectors / getSectorsPerCluster();
+        
+        if (clusterCount > MAX_FAT16_CLUSTERS) throw new IllegalStateException(
+                "too many clusters for FAT12/16: " + clusterCount);
+        
+        return clusterCount > MAX_FAT12_CLUSTERS ?
+            FatType.FAT16 : FatType.FAT12;
+    }
+    
+    @Override
+    public void setSectorCount(long count) {
+        if (count > 65535) {
+            setNrLogicalSectors(0);
+            setNrTotalSectors(count);
+        } else {
+            setNrLogicalSectors((int) count);
+            setNrTotalSectors(count);
+        }
+    }
+    
+    @Override
+    public long getSectorCount() {
+        if (getNrLogicalSectors() == 0) return getNrTotalSectors();
+        else return getNrLogicalSectors();
+    }
+    
+    /**
+     * Gets the number of entries in the root directory.
+     *
+     * @return int the root directory entry count
+     */
+    @Override
+    public int getRootDirEntryCount() {
+        return get16(ROOT_DIR_ENTRIES_OFFSET);
+    }
+    
+    /**
+     * Sets the number of entries in the root directory
+     *
+     * @param v the new number of entries in the root directory
+     * @throws IllegalArgumentException for negative values
+     */
+    public void setRootDirEntryCount(int v) throws IllegalArgumentException {
+        if (v < 0) throw new IllegalArgumentException();
+        if (v == getRootDirEntryCount()) return;
+        
+        set16(ROOT_DIR_ENTRIES_OFFSET, v);
+    }
+    
+    @Override
+    public void init() throws IOException {
+        super.init();
+        
+        setRootDirEntryCount(DEFAULT_ROOT_DIR_ENTRY_COUNT);
+        setVolumeLabel(DEFAULT_VOLUME_LABEL);
+    }
+
+    @Override
+    public int getFileSystemTypeLabelOffset() {
+        return FILE_SYSTEM_TYPE_OFFSET;
+    }
+
+    @Override
+    public int getExtendedBootSignatureOffset() {
+        return EXTENDED_BOOT_SIGNATURE_OFFSET;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/Fat16RootDirectory.java b/src/main/java/de/waldheinz/fs/fat/Fat16RootDirectory.java
new file mode 100644
index 0000000..958e8a0
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/Fat16RootDirectory.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * The root directory of a FAT12/16 partition.
+ *
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+final class Fat16RootDirectory extends AbstractDirectory {
+    private final BlockDevice device;
+    private final long deviceOffset;
+
+    private Fat16RootDirectory(Fat16BootSector bs, boolean readOnly) {
+        super(bs.getRootDirEntryCount(), readOnly, true);
+
+        if (bs.getRootDirEntryCount() <= 0) throw new IllegalArgumentException(
+                "root directory size is " + bs.getRootDirEntryCount());
+        
+        this.deviceOffset = FatUtils.getRootDirOffset(bs);
+        this.device = bs.getDevice();
+    }
+    
+    /**
+     * Reads a {@code Fat16RootDirectory} as indicated by the specified
+     * {@code Fat16BootSector}.
+     *
+     * @param bs the boot sector that describes the root directory to read
+     * @param readOnly if the directory shold be created read-only
+     * @return the directory that was read
+     * @throws IOException on read error
+     */
+    public static Fat16RootDirectory read(
+            Fat16BootSector bs, boolean readOnly) throws IOException {
+        
+        final Fat16RootDirectory result = new Fat16RootDirectory(bs, readOnly);
+        result.read();
+        return result;
+    }
+
+    /**
+     * Creates a new {@code Fat16RootDirectory} as indicated by the specified
+     * {@code Fat16BootSector}. The directory will always be created in
+     * read-write mode.
+     *
+     * @param bs the boot sector that describes the root directory to create
+     * @return the directory that was created
+     * @throws IOException on write error
+     */
+    public static Fat16RootDirectory create(
+            Fat16BootSector bs) throws IOException {
+        
+        final Fat16RootDirectory result = new Fat16RootDirectory(bs, false);
+        result.flush();
+        return result;
+    }
+    
+    @Override
+    protected void read(ByteBuffer data) throws IOException {
+        this.device.read(deviceOffset, data);
+    }
+
+    @Override
+    protected void write(ByteBuffer data) throws IOException {
+        this.device.write(deviceOffset, data);
+    }
+
+    /**
+     * By convention always returns 0, as the FAT12/16 root directory is not
+     * stored in a cluster chain.
+     *
+     * @return always 0
+     */
+    @Override
+    protected long getStorageCluster() {
+        return 0;
+    }
+
+    /**
+     * As a FAT12/16 root directory can not change it's size, this method
+     * throws a {@code DirectoryFullException} if the requested size is
+     * larger than {@link #getCapacity()} and does nothing else.
+     *
+     * @param entryCount {@inheritDoc}
+     */
+    @Override
+    protected void changeSize(int entryCount) throws DirectoryFullException {
+        if (getCapacity() < entryCount) {
+            throw new DirectoryFullException(getCapacity(), entryCount);
+        }
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java b/src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java
new file mode 100644
index 0000000..eded7ee
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/Fat32BootSector.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+
+/**
+ * Contains the FAT32 specific parts of the boot sector.
+ *
+ * @author Matthias Treydte &lt;matthias.treydte at meetwise.com&gt;
+ */
+final class Fat32BootSector extends BootSector {
+
+    /**
+     * The offset to the entry specifying the first cluster of the FAT32
+     * root directory.
+     */
+    public final static int ROOT_DIR_FIRST_CLUSTER_OFFSET = 0x2c;
+
+    /**
+     * The offset to the 4 bytes specifying the sectors per FAT value.
+     */
+    public static final int SECTORS_PER_FAT_OFFSET = 0x24;
+
+    /**
+     * Offset to the file system type label.
+     */
+    public static final int FILE_SYSTEM_TYPE_OFFSET = 0x52;
+    
+    public static final int VERSION_OFFSET = 0x2a;
+    public static final int VERSION = 0;
+
+    public static final int FS_INFO_SECTOR_OFFSET = 0x30;
+    public static final int BOOT_SECTOR_COPY_OFFSET = 0x32;
+    public static final int EXTENDED_BOOT_SIGNATURE_OFFSET = 0x42;
+    
+    /*
+     * TODO: make this constructor private
+     */
+    public Fat32BootSector(BlockDevice device) throws IOException {
+        super(device);
+    }
+    
+    @Override
+    public void init() throws IOException {
+        super.init();
+
+        set16(VERSION_OFFSET, VERSION);
+
+        setBootSectorCopySector(6); /* as suggested by M$ */
+    }
+
+    /**
+     * Returns the first cluster in the FAT that contains the root directory.
+     *
+     * @return the root directory's first cluster
+     */
+    public long getRootDirFirstCluster() {
+        return get32(ROOT_DIR_FIRST_CLUSTER_OFFSET);
+    }
+
+    /**
+     * Sets the first cluster of the root directory.
+     *
+     * @param value the root directory's first cluster
+     */
+    public void setRootDirFirstCluster(long value) {
+        if (getRootDirFirstCluster() == value) return;
+        
+        set32(ROOT_DIR_FIRST_CLUSTER_OFFSET, value);
+    }
+
+    /**
+     * Sets the sectur number that contains a copy of the boot sector.
+     *
+     * @param sectNr the sector that contains a boot sector copy
+     */
+    public void setBootSectorCopySector(int sectNr) {
+        if (getBootSectorCopySector() == sectNr) return;
+        if (sectNr < 0) throw new IllegalArgumentException(
+                "boot sector copy sector must be >= 0");
+        
+        set16(BOOT_SECTOR_COPY_OFFSET, sectNr);
+    }
+    
+    /**
+     * Returns the sector that contains a copy of the boot sector, or 0 if
+     * there is no copy.
+     *
+     * @return the sector number of the boot sector copy
+     */
+    public int getBootSectorCopySector() {
+        return get16(BOOT_SECTOR_COPY_OFFSET);
+    }
+
+    /**
+     * Sets the 11-byte volume label stored at offset 0x47.
+     *
+     * @param label the new volume label, may be {@code null}
+     */
+    public void setVolumeLabel(String label) {
+        for (int i=0; i < 11; i++) {
+            final byte c =
+                    (label == null) ? 0 :
+                    (label.length() > i) ? (byte) label.charAt(i) : 0x20;
+
+            set8(0x47 + i, c);
+        }
+    }
+
+    public int getFsInfoSectorNr() {
+        return get16(FS_INFO_SECTOR_OFFSET);
+    }
+
+    public void setFsInfoSectorNr(int offset) {
+        if (getFsInfoSectorNr() == offset) return;
+
+        set16(FS_INFO_SECTOR_OFFSET, offset);
+    }
+    
+    @Override
+    public void setSectorsPerFat(long v) {
+        if (getSectorsPerFat() == v) return;
+        
+        set32(SECTORS_PER_FAT_OFFSET, v);
+    }
+    
+    @Override
+    public long getSectorsPerFat() {
+        return get32(SECTORS_PER_FAT_OFFSET);
+    }
+
+    @Override
+    public FatType getFatType() {
+        return FatType.FAT32;
+    }
+
+    @Override
+    public void setSectorCount(long count) {
+        super.setNrTotalSectors(count);
+    }
+
+    @Override
+    public long getSectorCount() {
+        return super.getNrTotalSectors();
+    }
+
+    /**
+     * This is always 0 for FAT32.
+     *
+     * @return always 0
+     */
+    @Override
+    public int getRootDirEntryCount() {
+        return 0;
+    }
+    
+    public void setFileSystemId(int id) {
+        super.set32(0x43, id);
+    }
+
+    public int getFileSystemId() {
+        return (int) super.get32(0x43);
+    }
+
+    /**
+     * Writes a copy of this boot sector to the specified device, if a copy
+     * is requested.
+     *
+     * @param device the device to write the boot sector copy to
+     * @throws IOException on write error
+     * @see #getBootSectorCopySector() 
+     */
+    public void writeCopy(BlockDevice device) throws IOException {
+        if (getBootSectorCopySector() > 0) {
+            final long offset = getBootSectorCopySector() * SIZE;
+            buffer.rewind();
+            buffer.limit(buffer.capacity());
+            device.write(offset, buffer);
+        }
+    }
+
+    @Override
+    public int getFileSystemTypeLabelOffset() {
+        return FILE_SYSTEM_TYPE_OFFSET;
+    }
+
+    @Override
+    public int getExtendedBootSignatureOffset() {
+        return EXTENDED_BOOT_SIGNATURE_OFFSET;
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FatDirectoryEntry.java b/src/main/java/de/waldheinz/fs/fat/FatDirectoryEntry.java
new file mode 100644
index 0000000..b7a3611
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FatDirectoryEntry.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.AbstractFsObject;
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+final class FatDirectoryEntry extends AbstractFsObject {
+    
+    /**
+     * The size in bytes of an FAT directory entry.
+     */
+    public final static int SIZE = 32;
+    
+    /**
+     * The offset to the attributes byte.
+     */
+    private static final int OFFSET_ATTRIBUTES = 0x0b;
+    
+    /**
+     * The offset to the file size dword.
+     */
+    private static final int OFFSET_FILE_SIZE = 0x1c;
+    
+    private static final int F_READONLY = 0x01;
+    private static final int F_HIDDEN = 0x02;
+    private static final int F_SYSTEM = 0x04;
+    private static final int F_VOLUME_ID = 0x08;
+    private static final int F_DIRECTORY = 0x10;
+    private static final int F_ARCHIVE = 0x20;
+
+    private static final int MAX_CLUSTER = 0xFFFF;
+    
+    /**
+     * The magic byte denoting that this entry was deleted and is free
+     * for reuse.
+     *
+     * @see #isDeleted() 
+     */
+    public static final int ENTRY_DELETED_MAGIC = 0xe5;
+    
+    private final byte[] data;
+    private boolean dirty;
+    boolean hasShortNameOnly;
+    
+    FatDirectoryEntry(byte[] data, boolean readOnly) {
+        super(readOnly);
+        
+        this.data = data;
+    }
+    
+    private FatDirectoryEntry() {
+        this(new byte[SIZE], false);
+        
+    }
+    
+    /**
+     * Reads a {@code FatDirectoryEntry} from the specified {@code ByteBuffer}.
+     * The buffer must have at least {@link #SIZE} bytes remaining. The entry
+     * is read from the buffer's current position, and if this method returns
+     * non-null the position will have advanced by {@link #SIZE} bytes,
+     * otherwise the position will remain unchanged.
+     *
+     * @param buff the buffer to read the entry from
+     * @param readOnly if the resulting {@code FatDirecoryEntry} should be
+     *      read-only
+     * @return the directory entry that was read from the buffer or {@code null}
+     *      if there was no entry to read from the specified position (first
+     *      byte was 0)
+     */
+    public static FatDirectoryEntry read(ByteBuffer buff, boolean readOnly) {
+        assert (buff.remaining() >= SIZE);
+
+        /* peek into the buffer to see if we're done with reading */
+        
+        if (buff.get(buff.position()) == 0) return null;
+
+        /* read the directory entry */
+
+        final byte[] data = new byte[SIZE];
+        buff.get(data);
+        return new FatDirectoryEntry(data, readOnly);
+    }
+
+    public static void writeNullEntry(ByteBuffer buff) {
+        for (int i=0; i < SIZE; i++) {
+            buff.put((byte) 0);
+        }
+    }
+    
+    /**
+     * Decides if this entry is a "volume label" entry according to the FAT
+     * specification.
+     *
+     * @return if this is a volume label entry
+     */
+    public boolean isVolumeLabel() {
+        if (isLfnEntry()) return false;
+        else return ((getFlags() & (F_DIRECTORY | F_VOLUME_ID)) == F_VOLUME_ID);
+    }
+
+    private void setFlag(int mask, boolean set) {
+        final int oldFlags = getFlags();
+
+        if (((oldFlags & mask) != 0) == set) return;
+        
+        if (set) {
+            setFlags(oldFlags | mask);
+        } else {
+            setFlags(oldFlags & ~mask);
+        }
+
+        this.dirty = true;
+    }
+
+    public boolean isSystemFlag() {
+        return ((getFlags() & F_SYSTEM) != 0);
+    }
+
+    public void setSystemFlag(boolean isSystem) {
+        setFlag(F_SYSTEM, isSystem);
+    }
+
+    public boolean isArchiveFlag() {
+        return ((getFlags() & F_ARCHIVE) != 0);
+    }
+
+    public void setArchiveFlag(boolean isArchive) {
+        setFlag(F_ARCHIVE, isArchive);
+    }
+    
+    public boolean isHiddenFlag() {
+        return ((getFlags() & F_HIDDEN) != 0);
+    }
+
+    public void setHiddenFlag(boolean isHidden) {
+        setFlag(F_HIDDEN, isHidden);
+    }
+    
+    public boolean isVolumeIdFlag() {
+        return ((getFlags() & F_VOLUME_ID) != 0);
+    }
+    
+    public boolean isLfnEntry() {
+        return isReadonlyFlag() && isSystemFlag() &&
+                isHiddenFlag() && isVolumeIdFlag();
+    }
+    
+    public boolean isDirty() {
+        return dirty;
+    }
+    
+    private int getFlags() {
+        return LittleEndian.getUInt8(data, OFFSET_ATTRIBUTES);
+    }
+    
+    private void setFlags(int flags) {
+        LittleEndian.setInt8(data, OFFSET_ATTRIBUTES, flags);
+    }
+    
+    public boolean isDirectory() {
+        return ((getFlags() & (F_DIRECTORY | F_VOLUME_ID)) == F_DIRECTORY);
+    }
+    
+    public static FatDirectoryEntry create(boolean directory) {
+        final FatDirectoryEntry result = new FatDirectoryEntry();
+
+        if (directory) {
+            result.setFlags(F_DIRECTORY);
+        }
+        
+        /* initialize date and time fields */
+
+        final long now = System.currentTimeMillis();
+        result.setCreated(now);
+        result.setLastAccessed(now);
+        result.setLastModified(now);
+        
+        return result;
+    }
+    
+    public static FatDirectoryEntry createVolumeLabel(String volumeLabel) {
+        assert(volumeLabel != null);
+        
+        final byte[] data = new byte[SIZE];
+        
+        System.arraycopy(
+                    volumeLabel.getBytes(), 0,
+                    data, 0,
+                    volumeLabel.length());
+
+        final FatDirectoryEntry result = new FatDirectoryEntry(data, false);
+        result.setFlags(FatDirectoryEntry.F_VOLUME_ID);
+        return result;
+    }
+    
+    public String getVolumeLabel() {
+        if (!isVolumeLabel())
+            throw new UnsupportedOperationException("not a volume label");
+            
+        final StringBuilder sb = new StringBuilder();
+        
+        for (int i=0; i < AbstractDirectory.MAX_LABEL_LENGTH; i++) {
+            final byte b = this.data[i];
+            
+            if (b != 0) {
+                sb.append((char) b);
+            } else {
+                break;
+            }
+        }
+        
+        return sb.toString();
+    }
+
+    public long getCreated() {
+        return DosUtils.decodeDateTime(
+                LittleEndian.getUInt16(data, 0x10),
+                LittleEndian.getUInt16(data, 0x0e));
+    }
+    
+    public void setCreated(long created) {
+        LittleEndian.setInt16(data, 0x0e,
+                DosUtils.encodeTime(created));
+        LittleEndian.setInt16(data, 0x10,
+                DosUtils.encodeDate(created));
+
+        this.dirty = true;
+    }
+
+    public long getLastModified() {
+        return DosUtils.decodeDateTime(
+                LittleEndian.getUInt16(data, 0x18),
+                LittleEndian.getUInt16(data, 0x16));
+    }
+
+    public void setLastModified(long lastModified) {
+        LittleEndian.setInt16(data, 0x16,
+                DosUtils.encodeTime(lastModified));
+        LittleEndian.setInt16(data, 0x18,
+                DosUtils.encodeDate(lastModified));
+
+        this.dirty = true;
+    }
+
+    public long getLastAccessed() {
+        return DosUtils.decodeDateTime(
+                LittleEndian.getUInt16(data, 0x12),
+                0); /* time is not recorded */
+    }
+    
+    public void setLastAccessed(long lastAccessed) {
+        LittleEndian.setInt16(data, 0x12,
+                DosUtils.encodeDate(lastAccessed));
+
+        this.dirty = true;
+    }
+    
+    /**
+     * Returns if this entry has been marked as deleted. A deleted entry has
+     * its first byte set to the magic {@link #ENTRY_DELETED_MAGIC} value.
+     * 
+     * @return if this entry is marked as deleted
+     */
+    public boolean isDeleted() {
+        return  (LittleEndian.getUInt8(data, 0) == ENTRY_DELETED_MAGIC);
+    }
+    
+    /**
+     * Returns the size of this entry as stored at {@link #OFFSET_FILE_SIZE}.
+     * 
+     * @return the size of the file represented by this entry
+     */
+    public long getLength() {
+        return LittleEndian.getUInt32(data, OFFSET_FILE_SIZE);
+    }
+
+    /**
+     * Sets the size of this entry stored at {@link #OFFSET_FILE_SIZE}.
+     * 
+     * @param length the new size of the file represented by this entry
+     * @throws IllegalArgumentException if {@code length} is out of range
+     */
+    public void setLength(long length) throws IllegalArgumentException {
+        LittleEndian.setInt32(data, OFFSET_FILE_SIZE, length);
+    }
+    
+    /**
+     * Returns the {@code ShortName} that is stored in this directory entry or
+     * {@code null} if this entry has not been initialized.
+     * 
+     * @return the {@code ShortName} stored in this entry or {@code null}
+     */
+    public ShortName getShortName() {
+        if (this.data[0] == 0) {
+            return null;
+        } else {
+            return ShortName.parse(this.data);
+        }
+    }
+    
+    /**
+     * Does this entry refer to a file?
+     *
+     * @return
+     * @see org.jnode.fs.FSDirectoryEntry#isFile()
+     */
+    public boolean isFile() {
+        return ((getFlags() & (F_DIRECTORY | F_VOLUME_ID)) == 0);
+    }
+    
+    public void setShortName(ShortName sn) {
+        if (sn.equals(this.getShortName())) return;
+        
+        sn.write(this.data);
+        this.hasShortNameOnly = sn.hasShortNameOnly();
+        this.dirty = true;
+    }
+
+    /**
+     * Returns the startCluster.
+     * 
+     * @return int
+     */
+    public long getStartCluster() {
+    	int lowBytes = LittleEndian.getUInt16(data, 0x1a);
+        long highBytes = LittleEndian.getUInt16(data, 0x14);
+        return ( highBytes << 16 | lowBytes );
+    }
+    
+    /**
+     * Sets the startCluster.
+     *
+     * @param startCluster The startCluster to set
+     */
+    void setStartCluster(long startCluster) {
+        if ( startCluster > Integer.MAX_VALUE ) throw new AssertionError();
+
+        LittleEndian.setInt16(data, 0x1a, (int) startCluster);
+        LittleEndian.setInt16(data, 0x14, (int)(startCluster >>> 16));
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() +
+                " [name=" + getShortName() + "]"; //NOI18N
+    }
+
+    /**
+     * Writes this directory entry into the specified buffer.
+     *
+     * @param buff the buffer to write this entry to
+     */
+    void write(ByteBuffer buff) {
+        buff.put(data);
+        this.dirty = false;
+    }
+
+    /**
+     * Returns if the read-only flag is set for this entry. Do not confuse
+     * this with {@link #isReadOnly()}.
+     *
+     * @return if the read only file system flag is set on this entry
+     * @see #F_READONLY
+     * @see #setReadonlyFlag(boolean) 
+     */
+    public boolean isReadonlyFlag() {
+        return ((getFlags() & F_READONLY) != 0);
+    }
+
+    /**
+     * Updates the read-only file system flag for this entry.
+     *
+     * @param isReadonly the new value for the read-only flag
+     * @see #F_READONLY
+     * @see #isReadonlyFlag() 
+     */
+    public void setReadonlyFlag(boolean isReadonly) {
+        setFlag(F_READONLY, isReadonly);
+    }
+    
+    String getLfnPart() {
+        final char[] unicodechar = new char[13];
+
+        unicodechar[0] = (char) LittleEndian.getUInt16(data, 1);
+        unicodechar[1] = (char) LittleEndian.getUInt16(data, 3);
+        unicodechar[2] = (char) LittleEndian.getUInt16(data, 5);
+        unicodechar[3] = (char) LittleEndian.getUInt16(data, 7);
+        unicodechar[4] = (char) LittleEndian.getUInt16(data, 9);
+        unicodechar[5] = (char) LittleEndian.getUInt16(data, 14);
+        unicodechar[6] = (char) LittleEndian.getUInt16(data, 16);
+        unicodechar[7] = (char) LittleEndian.getUInt16(data, 18);
+        unicodechar[8] = (char) LittleEndian.getUInt16(data, 20);
+        unicodechar[9] = (char) LittleEndian.getUInt16(data, 22);
+        unicodechar[10] = (char) LittleEndian.getUInt16(data, 24);
+        unicodechar[11] = (char) LittleEndian.getUInt16(data, 28);
+        unicodechar[12] = (char) LittleEndian.getUInt16(data, 30);
+
+        int end = 0;
+
+        while ((end < 13) && (unicodechar[end] != '\0')) {
+            end++;
+        }
+        
+        return new String(unicodechar).substring(0, end);
+    }
+
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FatFile.java b/src/main/java/de/waldheinz/fs/fat/FatFile.java
new file mode 100644
index 0000000..95942e0
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FatFile.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.AbstractFsObject;
+import java.io.IOException;
+import de.waldheinz.fs.FsFile;
+import de.waldheinz.fs.ReadOnlyException;
+import java.io.EOFException;
+import java.nio.ByteBuffer;
+
+/**
+ * The in-memory representation of a single file (chain of clusters) on a
+ * FAT file system.
+ * 
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ * @since 0.6
+ */
+public final class FatFile extends AbstractFsObject implements FsFile {
+    private final FatDirectoryEntry entry;
+    private final ClusterChain chain;
+    
+    private FatFile(FatDirectoryEntry myEntry, ClusterChain chain) {
+        super(myEntry.isReadOnly());
+        
+        this.entry = myEntry;
+        this.chain = chain;
+    }
+    
+    static FatFile get(Fat fat, FatDirectoryEntry entry)
+            throws IOException {
+        
+        if (entry.isDirectory())
+            throw new IllegalArgumentException(entry + " is a directory");
+            
+        final ClusterChain cc = new ClusterChain(
+                fat, entry.getStartCluster(), entry.isReadonlyFlag());
+                
+        if (entry.getLength() > cc.getLengthOnDisk()) throw new IOException(
+                "entry is larger than associated cluster chain");
+                
+        return new FatFile(entry, cc);
+    }
+    
+    /**
+     * Returns the length of this file in bytes. This is the length that
+     * is stored in the directory entry that is associated with this file.
+     * 
+     * @return long the length that is recorded for this file
+     */
+    @Override
+    public long getLength() {
+        checkValid();
+        
+        return entry.getLength();
+    }
+    
+    /**
+     * Sets the size (in bytes) of this file. Because
+     * {@link #write(long, java.nio.ByteBuffer) writing} to the file will grow
+     * it automatically if needed, this method is mainly usefull for truncating
+     * a file. 
+     *
+     * @param length the new length of the file in bytes
+     * @throws ReadOnlyException if this file is read-only
+     * @throws IOException on error updating the file size
+     */
+    @Override
+    public void setLength(long length) throws ReadOnlyException, IOException {
+        checkWritable();
+        
+        if (getLength() == length) return;
+        
+        updateTimeStamps(true);
+        chain.setSize(length);
+        
+        this.entry.setStartCluster(chain.getStartCluster());
+        this.entry.setLength(length);
+    }
+    
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * Unless this file is {@link #isReadOnly() read-ony}, this method also
+     * updates the "last accessed" field in the directory entry that is
+     * associated with this file.
+     * </p>
+     * 
+     * @param offset {@inheritDoc}
+     * @param dest {@inheritDoc}
+     * @see FatDirectoryEntry#setLastAccessed(long)
+     */
+    @Override
+    public void read(long offset, ByteBuffer dest) throws IOException {
+        checkValid();
+        
+        final int len = dest.remaining();
+        
+        if (len == 0) return;
+        
+        if (offset + len > getLength()) {
+            throw new EOFException();
+        }
+        
+        if (!isReadOnly()) {
+            updateTimeStamps(false);
+        }
+        
+        chain.readData(offset, dest);
+    }
+
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * If the data to be written extends beyond the current
+     * {@link #getLength() length} of this file, an attempt is made to
+     * {@link #setLength(long) grow} the file so that the data will fit.
+     * Additionally, this method updates the "last accessed" and "last modified"
+     * fields on the directory entry that is associated with this file.
+     * </p>
+     *
+     * @param offset {@inheritDoc}
+     * @param srcBuf {@inheritDoc}
+     */
+    @Override
+    public void write(long offset, ByteBuffer srcBuf)
+            throws ReadOnlyException, IOException {
+
+        checkWritable();
+
+        updateTimeStamps(true);
+        
+        final long lastByte = offset + srcBuf.remaining();
+
+        if (lastByte > getLength()) {
+            setLength(lastByte);
+        }
+        
+        chain.writeData(offset, srcBuf);
+    }
+    
+    private void updateTimeStamps(boolean write) {
+        final long now = System.currentTimeMillis();
+        entry.setLastAccessed(now);
+        
+        if (write) {
+            entry.setLastModified(now);
+        }
+    }
+
+    /**
+     * Has no effect besides possibly throwing an {@code ReadOnlyException}. To
+     * make sure that all data is written out to disk use the
+     * {@link FatFileSystem#flush()} method.
+     *
+     * @throws ReadOnlyException if this {@code FatFile} is read-only
+     */
+    @Override
+    public void flush() throws ReadOnlyException {
+        checkWritable();
+        
+        /* nothing else to do */
+    }
+    
+    /**
+     * Returns the {@code ClusterChain} that holds the contents of
+     * this {@code FatFile}.
+     *
+     * @return the file's {@code ClusterChain}
+     */
+    ClusterChain getChain() {
+        checkValid();
+        
+        return chain;
+    }
+    
+    /**
+     * Returns a human-readable string representation of this {@code FatFile},
+     * mainly for debugging purposes.
+     *
+     * @return a string describing this {@code FatFile}
+     */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + " [length=" + getLength() +
+                ", first cluster=" + chain.getStartCluster() + "]";
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FatFileSystem.java b/src/main/java/de/waldheinz/fs/fat/FatFileSystem.java
new file mode 100644
index 0000000..db4d3e2
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FatFileSystem.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.AbstractFileSystem;
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+import de.waldheinz.fs.ReadOnlyException;
+
+/**
+ * <p>
+ * Implements the {@code FileSystem} interface for the FAT family of file
+ * systems. This class always uses the "long file name" specification when
+ * writing directory entries.
+ * </p><p>
+ * For creating (aka "formatting") FAT file systems please refer to the
+ * {@link SuperFloppyFormatter} class.
+ * </p>
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public final class FatFileSystem extends AbstractFileSystem {
+    
+    private final Fat fat;
+    private final FsInfoSector fsiSector;
+    private final BootSector bs;
+    private final FatLfnDirectory rootDir;
+    private final AbstractDirectory rootDirStore;
+    private final FatType fatType;
+    private final long filesOffset;
+
+    FatFileSystem(BlockDevice api, boolean readOnly) throws IOException {
+
+        this(api, readOnly, false);
+    }
+    
+    /**
+     * Constructor for FatFileSystem in specified readOnly mode
+     * 
+     * @param device the {@code BlockDevice} holding the file system
+     * @param readOnly if this FS should be read-lonly
+     * @param ignoreFatDifferences
+     * @throws IOException on read error
+     */
+    private FatFileSystem(BlockDevice device, boolean readOnly,
+            boolean ignoreFatDifferences)
+            throws IOException {
+        
+        super(readOnly);
+        
+        this.bs = BootSector.read(device);
+        
+        if (bs.getNrFats() <= 0) throw new IOException(
+                "boot sector says there are no FATs");
+        
+        this.filesOffset = FatUtils.getFilesOffset(bs);
+        this.fatType = bs.getFatType();
+        this.fat = Fat.read(bs, 0);
+
+        if (!ignoreFatDifferences) {
+            for (int i=1; i < bs.getNrFats(); i++) {
+                final Fat tmpFat = Fat.read(bs, i);
+                if (!fat.equals(tmpFat)) {
+                    throw new IOException("FAT " + i + " differs from FAT 0");
+                }
+            }
+        }
+        
+        if (fatType == FatType.FAT32) {
+            final Fat32BootSector f32bs = (Fat32BootSector) bs;
+            ClusterChain rootDirFile = new ClusterChain(fat,
+                    f32bs.getRootDirFirstCluster(), isReadOnly());
+            this.rootDirStore = ClusterChainDirectory.readRoot(rootDirFile);
+            this.fsiSector = FsInfoSector.read(f32bs);
+            
+            if (fsiSector.getFreeClusterCount() != fat.getFreeClusterCount()) {
+                throw new IOException("free cluster count mismatch - fat: " +
+                        fat.getFreeClusterCount() + " - fsinfo: " +
+                        fsiSector.getFreeClusterCount());
+            }
+        } else {
+            this.rootDirStore =
+                    Fat16RootDirectory.read((Fat16BootSector) bs,readOnly);
+            this.fsiSector = null;
+        }
+
+        this.rootDir = new FatLfnDirectory(rootDirStore, fat, isReadOnly());
+            
+    }
+
+    /**
+     * Reads the file system structure from the specified {@code BlockDevice}
+     * and returns a fresh {@code FatFileSystem} instance to read or modify
+     * it.
+     *
+     * @param device the {@code BlockDevice} holding the file system
+     * @param readOnly if the {@code FatFileSystem} should be in read-only mode
+     * @return the {@code FatFileSystem} instance for the device
+     * @throws IOException on read error or if the file system structure could
+     *      not be parsed
+     */
+    public static FatFileSystem read(BlockDevice device, boolean readOnly)
+            throws IOException {
+        
+        return new FatFileSystem(device, readOnly);
+    }
+
+    long getFilesOffset() {
+        checkClosed();
+        
+        return filesOffset;
+    }
+
+    /**
+     * Returns the size of the FAT entries of this {@code FatFileSystem}.
+     *
+     * @return the exact type of the FAT used by this file system
+     */
+    public FatType getFatType() {
+        checkClosed();
+
+        return this.fatType;
+    }
+
+    /**
+     * Returns the volume label of this file system.
+     *
+     * @return the volume label
+     */
+    public String getVolumeLabel() {
+        checkClosed();
+        
+        final String fromDir = rootDirStore.getLabel();
+        
+        if (fromDir == null && fatType != FatType.FAT32) {
+            return ((Fat16BootSector)bs).getVolumeLabel();
+        } else {
+            return fromDir;
+        }
+    }
+    
+    /**
+     * Sets the volume label for this file system.
+     *
+     * @param label the new volume label, may be {@code null}
+     * @throws ReadOnlyException if the file system is read-only
+     * @throws IOException on write error
+     */
+    public void setVolumeLabel(String label)
+            throws ReadOnlyException, IOException {
+        
+        checkClosed();
+        checkReadOnly();
+
+        rootDirStore.setLabel(label);
+        
+        if (fatType != FatType.FAT32) {
+            ((Fat16BootSector)bs).setVolumeLabel(label);
+        }
+    }
+
+    AbstractDirectory getRootDirStore() {
+        checkClosed();
+        
+        return rootDirStore;
+    }
+    
+    /**
+     * Flush all changed structures to the device.
+     * 
+     * @throws IOException on write error
+     */
+    @Override
+    public void flush() throws IOException {
+        checkClosed();
+        
+        if (bs.isDirty()) {
+            bs.write();
+        }
+        
+        for (int i = 0; i < bs.getNrFats(); i++) {
+            fat.writeCopy(FatUtils.getFatOffset(bs, i));
+        }
+        
+        rootDir.flush();
+        
+        if (fsiSector != null) {
+            fsiSector.setFreeClusterCount(fat.getFreeClusterCount());
+            fsiSector.setLastAllocatedCluster(fat.getLastAllocatedCluster());
+            fsiSector.write();
+        }
+    }
+    
+    @Override
+    public FatLfnDirectory getRoot() {
+        checkClosed();
+        
+        return rootDir;
+    }
+    
+    /**
+     * Returns the fat.
+     * 
+     * @return Fat
+     */
+    public Fat getFat() {
+        return fat;
+    }
+
+    /**
+     * Returns the bootsector.
+     * 
+     * @return BootSector
+     */
+    public BootSector getBootSector() {
+        checkClosed();
+        
+        return bs;
+    }
+
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * This method shows the free space in terms of available clusters.
+     * </p>
+     * 
+     * @return always -1
+     */
+    @Override
+    public long getFreeSpace() {
+    	return this.fat.getFreeClusterCount() * this.bs.getBytesPerCluster();
+    }
+
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * This method is currently not implemented for {@code FatFileSystem} and
+     * always returns -1.
+     * </p>
+     *
+     * @return always -1
+     */
+    @Override
+    public long getTotalSpace() {
+    	return this.bs.getDataClusterCount() * this.bs.getBytesPerCluster();    	
+    }
+
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * This method is currently not implemented for {@code FatFileSystem} and
+     * always returns -1.
+     * </p>
+     *
+     * @return always -1
+     */
+    @Override
+    public long getUsableSpace() {
+        // TODO implement me
+        return -1;
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FatLfnDirectory.java b/src/main/java/de/waldheinz/fs/fat/FatLfnDirectory.java
new file mode 100644
index 0000000..9f4aa9b
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FatLfnDirectory.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.AbstractFsObject;
+import de.waldheinz.fs.FsDirectory;
+import de.waldheinz.fs.FsDirectoryEntry;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The {@link FsDirectory} implementation for FAT file systems. This
+ * implementation aims to fully comply to the FAT specification, including
+ * the quite complex naming system regarding the long file names (LFNs) and
+ * their corresponding 8+3 short file names. This also means that an
+ * {@code FatLfnDirectory} is case-preserving but <em>not</em> case-sensitive.
+ * 
+ * @author gbin
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ * @since 0.6
+ */
+public final class FatLfnDirectory
+        extends AbstractFsObject
+        implements FsDirectory {
+    
+    /**
+     * This set is used to check if a file name is already in use in this
+     * directory. The FAT specification says that file names must be unique
+     * ignoring the case, so this set contains all names converted to
+     * lower-case, and all checks must be performed using lower-case strings.
+     */
+    private final Set<String> usedNames;
+    private final Fat fat;
+    private final Map<ShortName, FatLfnDirectoryEntry> shortNameIndex;
+    private final Map<String, FatLfnDirectoryEntry> longNameIndex;
+    private final Map<FatDirectoryEntry, FatFile> entryToFile;
+    private final Map<FatDirectoryEntry, FatLfnDirectory> entryToDirectory;
+    private Dummy83BufferGenerator dbg;
+    
+    final AbstractDirectory dir;
+    
+    FatLfnDirectory(AbstractDirectory dir, Fat fat, boolean readOnly)
+            throws IOException {
+        
+        super(readOnly);
+        
+        if ((dir == null) || (fat == null)) throw new NullPointerException();
+        
+        this.fat = fat;
+        this.dir = dir;
+        
+        this.shortNameIndex =
+                new LinkedHashMap<ShortName, FatLfnDirectoryEntry>();
+                
+        this.longNameIndex =
+                new LinkedHashMap<String, FatLfnDirectoryEntry>();
+                
+        this.entryToFile =
+                new LinkedHashMap<FatDirectoryEntry, FatFile>();
+                
+        this.entryToDirectory =
+                new LinkedHashMap<FatDirectoryEntry, FatLfnDirectory>();
+                
+        this.usedNames = new HashSet<String>();
+        this.dbg = new Dummy83BufferGenerator();
+        
+        parseLfn();
+    }
+    
+    FatFile getFile(FatDirectoryEntry entry) throws IOException {
+        FatFile file = entryToFile.get(entry);
+
+        if (file == null) {
+            file = FatFile.get(fat, entry);
+            entryToFile.put(entry, file);
+        }
+        
+        return file;
+    }
+    
+    FatLfnDirectory getDirectory(FatDirectoryEntry entry) throws IOException {
+        FatLfnDirectory result = entryToDirectory.get(entry);
+
+        if (result == null) {
+            final ClusterChainDirectory storage = read(entry, fat);
+            result = new FatLfnDirectory(storage, fat, isReadOnly());
+            entryToDirectory.put(entry, result);
+        }
+        
+        return result;
+    }
+    
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * According to the FAT file system specification, leading and trailing
+     * spaces in the {@code name} are ignored by this method.
+     * </p>
+     * 
+     * @param name {@inheritDoc}
+     * @return {@inheritDoc}
+     * @throws IOException {@inheritDoc}
+     */
+    @Override
+    public FatLfnDirectoryEntry addFile(String name) throws IOException {
+        checkWritable();
+        checkUniqueName(name);
+        
+        name = name.trim();
+        final ShortName sn = makeShortName(name, false);
+        
+        final FatLfnDirectoryEntry entry =
+                new FatLfnDirectoryEntry(name, sn, this, false);
+
+        dir.addEntries(entry.compactForm());
+        
+        shortNameIndex.put(sn, entry);
+        longNameIndex.put(name.toLowerCase(), entry);
+
+        getFile(entry.realEntry);
+        
+        dir.setDirty();
+        return entry;
+    }
+    
+    boolean isFreeName(String name) {
+        return true;
+    }
+    
+    private void checkUniqueName(String name) throws IOException {
+    }
+    
+    private void freeUniqueName(String name) {
+    }
+    
+    private ShortName makeShortName(String name, boolean isDirectory) throws IOException {
+        final ShortName result;
+
+        try {
+            result = dbg.generate83BufferNew(name);
+        } catch (IllegalArgumentException ex) {
+            throw new IOException(
+                    "could not generate short name for \"" + name + "\"", ex);
+        }        
+        return result;
+    }
+    
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * According to the FAT file system specification, leading and trailing
+     * spaces in the {@code name} are ignored by this method.
+     * </p>
+     *
+     * @param name {@inheritDoc}
+     * @return {@inheritDoc}
+     * @throws IOException {@inheritDoc}
+     */
+    @Override
+    public FatLfnDirectoryEntry addDirectory(String name) throws IOException {
+        checkWritable();
+        checkUniqueName(name);
+        
+        name = name.trim();
+        final ShortName sn = makeShortName(name, true);
+        final FatDirectoryEntry real = dir.createSub(fat);
+        real.setShortName(sn);
+        final FatLfnDirectoryEntry e =
+                new FatLfnDirectoryEntry(this, real, name);
+        
+        try {
+            dir.addEntries(e.compactForm());
+        } catch (IOException ex) {
+            final ClusterChain cc =
+                    new ClusterChain(fat, real.getStartCluster(), false);
+            cc.setChainLength(0);
+            dir.removeEntry(real);
+            throw ex;
+        }
+        
+        shortNameIndex.put(sn, e);
+        longNameIndex.put(name.toLowerCase(), e);
+
+        getDirectory(real);
+        
+        flush();
+        return e;
+    }
+    
+    /**
+     * <p>
+     * {@inheritDoc}
+     * </p><p>
+     * According to the FAT file system specification, leading and trailing
+     * spaces in the {@code name} are ignored by this method.
+     * </p>
+     *
+     * @param name {@inheritDoc}
+     * @return {@inheritDoc}
+     */
+    @Override
+    public FatLfnDirectoryEntry getEntry(String name) {
+        name = name.trim().toLowerCase();
+        
+        final FatLfnDirectoryEntry entry = longNameIndex.get(name);
+        
+        if (entry == null) {
+            if (!ShortName.canConvert(name)) return null;
+            return shortNameIndex.get(ShortName.get(name));
+        } else {
+            return entry;
+        }
+    }
+    
+    private void parseLfn() throws IOException {
+        int i = 0;
+        final int size = dir.getEntryCount();
+        
+        while (i < size) {
+            // jump over empty entries
+            while (i < size && dir.getEntry(i) == null) {
+                i++;
+            }
+
+            if (i >= size) {
+                break;
+            }
+
+            int offset = i; // beginning of the entry
+            // check when we reach a real entry
+            while (dir.getEntry(i).isLfnEntry()) {
+                i++;
+                if (i >= size) {
+                    // This is a cutted entry, forgive it
+                    break;
+                }
+            }
+            
+            if (i >= size) {
+                // This is a cutted entry, forgive it
+                break;
+            }
+            
+            final FatLfnDirectoryEntry current =
+                    FatLfnDirectoryEntry.extract(this, offset, ++i - offset);
+            
+            if (!current.realEntry.isDeleted() && current.isValid()) {
+                checkUniqueName(current.getName());
+                
+                shortNameIndex.put(current.realEntry.getShortName(), current);
+                longNameIndex.put(current.getName().toLowerCase(), current);
+            }
+        }
+    }
+    
+    private void updateLFN() throws IOException {
+        ArrayList<FatDirectoryEntry> dest =
+                new ArrayList<FatDirectoryEntry>();
+
+        for (FatLfnDirectoryEntry currentEntry : shortNameIndex.values()) {
+            FatDirectoryEntry[] encoded = currentEntry.compactForm();
+            dest.addAll(Arrays.asList(encoded));
+        }
+        
+        final int size = dest.size();
+
+        dir.changeSize(size);
+        dir.setEntries(dest);
+    }
+
+    @Override
+    public void flush() throws IOException {
+        checkWritable();
+        
+        for (FatFile f : entryToFile.values()) {
+            f.flush();
+        }
+        
+        for (FatLfnDirectory d : entryToDirectory.values()) {
+            d.flush();
+        }
+        
+        updateLFN();
+        dir.flush();
+    }
+
+    @Override
+    public Iterator<FsDirectoryEntry> iterator() {
+        return new Iterator<FsDirectoryEntry>() {
+
+            final Iterator<FatLfnDirectoryEntry> it =
+                    shortNameIndex.values().iterator();
+
+            @Override
+            public boolean hasNext() {
+                return it.hasNext();
+            }
+
+            @Override
+            public FsDirectoryEntry next() {
+                return it.next();
+            }
+
+            /**
+             * @see java.util.Iterator#remove()
+             */
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    /**
+     * Remove the entry with the given name from this directory.
+     * 
+     * @param name the name of the entry to remove
+     * @throws IOException on error removing the entry
+     * @throws IllegalArgumentException on an attempt to remove the dot entries
+     */
+    @Override
+    public void remove(String name)
+            throws IOException, IllegalArgumentException {
+        
+        checkWritable();
+        
+        final FatLfnDirectoryEntry entry = getEntry(name);
+        if (entry == null) return;
+        
+        unlinkEntry(entry);
+        
+        final ClusterChain cc = new ClusterChain(
+                fat, entry.realEntry.getStartCluster(), false);
+
+        cc.setChainLength(0);
+        
+        freeUniqueName(name);
+        updateLFN();
+    }
+    
+    /**
+     * Unlinks the specified entry from this directory without actually
+     * deleting it.
+     *
+     * @param e the entry to be unlinked
+     * @see #linkEntry(de.waldheinz.fs.fat.FatLfnDirectoryEntry) 
+     */
+    void unlinkEntry(FatLfnDirectoryEntry entry) {
+        final ShortName sn = entry.realEntry.getShortName();
+        
+        if (sn.equals(ShortName.DOT) || sn.equals(ShortName.DOT_DOT)) throw
+                new IllegalArgumentException(
+                    "the dot entries can not be removed");
+
+        final String lowerName = entry.getName().toLowerCase();
+
+        assert (this.longNameIndex.containsKey(lowerName));
+        this.longNameIndex.remove(lowerName);
+        
+        assert (this.shortNameIndex.containsKey(sn));
+        this.shortNameIndex.remove(sn);
+        
+        if (entry.isFile()) {
+            this.entryToFile.remove(entry.realEntry);
+        } else {
+            this.entryToDirectory.remove(entry.realEntry);
+        }
+    }
+    
+    /**
+     * Links the specified entry to this directory, updating the entrie's
+     * short name.
+     *
+     * @param entry the entry to be linked (added) to this directory
+     * @see #unlinkEntry(de.waldheinz.fs.fat.FatLfnDirectoryEntry) 
+     */
+    void linkEntry(FatLfnDirectoryEntry entry) throws IOException {
+        checkUniqueName(entry.getName());
+        ShortName name;
+        name = this.dbg.generate83BufferNew(entry.getName());
+        entry.realEntry.setShortName(name);
+        
+        this.longNameIndex.put(entry.getName().toLowerCase(), entry);
+        this.shortNameIndex.put(entry.realEntry.getShortName(), entry);
+        
+        updateLFN();
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() +
+                " [size=" + shortNameIndex.size() + //NOI18N
+                ", dir=" + dir + "]"; //NOI18N
+    }
+    
+    private static ClusterChainDirectory read(FatDirectoryEntry entry, Fat fat)
+            throws IOException {
+
+        if (!entry.isDirectory()) throw
+                new IllegalArgumentException(entry + " is no directory");
+
+        final ClusterChain chain = new ClusterChain(
+                fat, entry.getStartCluster(),
+                entry.isReadonlyFlag());
+
+        final ClusterChainDirectory result =
+                new ClusterChainDirectory(chain, false);
+
+        result.read();
+        return result;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FatLfnDirectoryEntry.java b/src/main/java/de/waldheinz/fs/fat/FatLfnDirectoryEntry.java
new file mode 100644
index 0000000..0882516
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FatLfnDirectoryEntry.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.AbstractFsObject;
+import de.waldheinz.fs.FsDirectoryEntry;
+import de.waldheinz.fs.ReadOnlyException;
+import java.io.IOException;
+
+/**
+ * Represents an entry in a {@link FatLfnDirectory}. Besides implementing the
+ * {@link FsDirectoryEntry} interface for FAT file systems, it allows access
+ * to the {@link #setArchiveFlag(boolean) archive},
+ * {@link #setHiddenFlag(boolean) hidden},
+ * {@link #setReadOnlyFlag(boolean) read-only} and
+ * {@link #setSystemFlag(boolean) system} flags specifed for the FAT file
+ * system.
+ *
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ * @since 0.6
+ */
+public final class FatLfnDirectoryEntry
+        extends AbstractFsObject
+        implements FsDirectoryEntry {
+    
+    final FatDirectoryEntry realEntry;
+    
+    private FatLfnDirectory parent;
+    private String fileName;
+    
+    FatLfnDirectoryEntry(String name, ShortName sn,
+            FatLfnDirectory parent, boolean directory) {
+        
+        super(false);
+        
+        this.parent = parent;
+        this.fileName = name;
+        
+        final long now = System.currentTimeMillis();
+        this.realEntry = FatDirectoryEntry.create(directory);
+        this.realEntry.setShortName(sn);
+        this.realEntry.setCreated(now);
+        this.realEntry.setLastAccessed(now);
+    }
+    
+    FatLfnDirectoryEntry(FatLfnDirectory parent,
+            FatDirectoryEntry realEntry, String fileName) {
+        
+        super(parent.isReadOnly());
+        
+        this.parent = parent;
+        this.realEntry = realEntry;
+        this.fileName = fileName;
+    }
+    
+    static FatLfnDirectoryEntry extract(
+            FatLfnDirectory dir, int offset, int len) {
+            
+        final FatDirectoryEntry realEntry = dir.dir.getEntry(offset + len - 1);
+        final String fileName;
+        
+        if (len == 1) {
+            /* this is just an old plain 8.3 entry */
+            fileName = realEntry.getShortName().asSimpleString();
+        } else {
+            /* stored in reverse order */
+            final StringBuilder name = new StringBuilder(13 * (len - 1));
+            
+            for (int i = len - 2; i >= 0; i--) {
+                FatDirectoryEntry entry = dir.dir.getEntry(i + offset);
+                name.append(entry.getLfnPart());
+            }
+            
+            fileName = name.toString().trim();
+        }
+        
+         return new FatLfnDirectoryEntry(dir, realEntry, fileName);
+    }
+    
+    /**
+     * Returns if this directory entry has the FAT "hidden" flag set.
+     *
+     * @return if this is a hidden directory entry
+     * @see #setHiddenFlag(boolean)
+     */
+    public boolean isHiddenFlag() {
+        return this.realEntry.isHiddenFlag();
+    }
+    
+    /**
+     * Sets the "hidden" flag on this {@code FatLfnDirectoryEntry} to the
+     * specified value.
+     *
+     * @param hidden if this entry should have the hidden flag set
+     * @throws ReadOnlyException if this entry is read-only
+     * @see #isHiddenFlag()
+     */
+    public void setHiddenFlag(boolean hidden) throws ReadOnlyException {
+        checkWritable();
+        
+        this.realEntry.setHiddenFlag(hidden);
+    }
+    
+    /**
+     * Returns if this directory entry has the FAT "system" flag set.
+     *
+     * @return if this is a "system" directory entry
+     * @see #setSystemFlag(boolean)
+     */
+    public boolean isSystemFlag() {
+        return this.realEntry.isSystemFlag();
+    }
+    
+    /**
+     * Sets the "system" flag on this {@code FatLfnDirectoryEntry} to the
+     * specified value.
+     *
+     * @param systemEntry if this entry should have the system flag set
+     * @throws ReadOnlyException if this entry is read-only
+     * @see #isSystemFlag()
+     */
+    public void setSystemFlag(boolean systemEntry) throws ReadOnlyException {
+        checkWritable();
+        
+        this.realEntry.setSystemFlag(systemEntry);
+    }
+
+    /**
+     * Returns if this directory entry has the FAT "read-only" flag set. This
+     * entry may still modified if {@link #isReadOnly()} returns {@code true}.
+     *
+     * @return if this entry has the read-only flag set
+     * @see #setReadOnlyFlag(boolean) 
+     */
+    public boolean isReadOnlyFlag() {
+        return this.realEntry.isReadonlyFlag();
+    }
+
+    /**
+     * Sets the "read only" flag on this {@code FatLfnDirectoryEntry} to the
+     * specified value. This method only modifies the read-only flag as
+     * specified by the FAT file system, which is essentially ignored by the
+     * fat32-lib. The true indicator if it is possible to alter this 
+     *
+     * @param readOnly if this entry should be flagged as read only
+     * @throws ReadOnlyException if this entry is read-only as given by
+     *      {@link #isReadOnly()} method
+     * @see #isReadOnlyFlag() 
+     */
+    public void setReadOnlyFlag(boolean readOnly) throws ReadOnlyException {
+        checkWritable();
+        
+        this.realEntry.setReadonlyFlag(readOnly);
+    }
+
+    /**
+     * Returns if this directory entry has the FAT "archive" flag set.
+     * 
+     * @return if this entry has the archive flag set
+     */
+    public boolean isArchiveFlag() {
+        return this.realEntry.isArchiveFlag();
+    }
+
+    /**
+     * Sets the "archive" flag on this {@code FatLfnDirectoryEntry} to the
+     * specified value.
+     *
+     * @param archive if this entry should have the archive flag set
+     * @throws ReadOnlyException if this entry is
+     *      {@link #isReadOnly() read-only}
+     */
+    public void setArchiveFlag(boolean archive) throws ReadOnlyException {
+        checkWritable();
+
+        this.realEntry.setArchiveFlag(archive);
+    }
+    
+    private int totalEntrySize() {
+        int result = (fileName.length() / 13) + 1;
+
+        if ((fileName.length() % 13) != 0) {
+            result++;
+        }
+        
+        return result;
+    }
+
+    FatDirectoryEntry[] compactForm() {
+        if (this.realEntry.getShortName().equals(ShortName.DOT) ||
+                this.realEntry.getShortName().equals(ShortName.DOT_DOT) ||
+                this.realEntry.hasShortNameOnly) {
+            /* the dot entries must not have a LFN */
+            return new FatDirectoryEntry[]{this.realEntry};
+        }
+    
+        final int totalEntrySize = totalEntrySize();
+
+        final FatDirectoryEntry[] entries =
+                new FatDirectoryEntry[totalEntrySize];
+
+        final byte checkSum = this.realEntry.getShortName().checkSum();
+        int j = 0;
+        
+        for (int i = totalEntrySize - 2; i > 0; i--) {
+            entries[i] = createPart(fileName.substring(j * 13, j * 13 + 13),
+                    j + 1, checkSum, false);
+            j++;
+        }
+
+        entries[0] = createPart(fileName.substring(j * 13),
+                j + 1, checkSum, true);
+        
+        entries[totalEntrySize - 1] = this.realEntry;
+        
+        return entries;
+    }
+
+    @Override
+    public String getName() {
+        checkValid();
+        
+        return fileName;
+    }
+    
+    @Override
+    public void setName(String newName) throws IOException {
+        checkWritable();
+        
+        if (!this.parent.isFreeName(newName)) {
+            throw new IOException(
+                    "the name \"" + newName + "\" is already in use");
+        }
+        
+        this.parent.unlinkEntry(this);
+        this.fileName = newName;
+        this.parent.linkEntry(this);
+    }
+    
+    /**
+     * Moves this entry to a new directory under the specified name.
+     *
+     * @param target the direcrory where this entry should be moved to
+     * @param newName the new name under which this entry will be accessible
+     *      in the target directory
+     * @throws IOException on error moving this entry
+     * @throws ReadOnlyException if this directory is read-only
+     */
+    public void moveTo(FatLfnDirectory target, String newName)
+            throws IOException, ReadOnlyException {
+
+        checkWritable();
+
+        if (!target.isFreeName(newName)) {
+            throw new IOException(
+                    "the name \"" + newName + "\" is already in use");
+        }
+        
+        this.parent.unlinkEntry(this);
+        this.parent = target;
+        this.fileName = newName;
+        this.parent.linkEntry(this);
+    }
+    
+    @Override
+    public void setLastModified(long lastModified) {
+        checkWritable();
+        realEntry.setLastModified(lastModified);
+    }
+    
+    @Override
+    public FatFile getFile() throws IOException {
+        return parent.getFile(realEntry);
+    }
+    
+    @Override
+    public FatLfnDirectory getDirectory() throws IOException {
+        return parent.getDirectory(realEntry);
+    }
+    
+    @Override
+    public String toString() {
+        return "LFN = " + fileName + " / SFN = " + realEntry.getShortName();
+    }
+    
+    private static FatDirectoryEntry createPart(String subName,
+            int ordinal, byte checkSum, boolean isLast) {
+            
+        final char[] unicodechar = new char[13];
+        subName.getChars(0, subName.length(), unicodechar, 0);
+
+        for (int i=subName.length(); i < 13; i++) {
+            if (i==subName.length()) {
+                unicodechar[i] = 0x0000;
+            } else {
+                unicodechar[i] = 0xffff;
+            }
+        }
+
+        final byte[] rawData = new byte[FatDirectoryEntry.SIZE];
+        
+        if (isLast) {
+            LittleEndian.setInt8(rawData, 0, ordinal + (1 << 6));
+        } else {
+            LittleEndian.setInt8(rawData, 0, ordinal);
+        }
+        
+        LittleEndian.setInt16(rawData, 1, unicodechar[0]);
+        LittleEndian.setInt16(rawData, 3, unicodechar[1]);
+        LittleEndian.setInt16(rawData, 5, unicodechar[2]);
+        LittleEndian.setInt16(rawData, 7, unicodechar[3]);
+        LittleEndian.setInt16(rawData, 9, unicodechar[4]);
+        LittleEndian.setInt8(rawData, 11, 0x0f); // this is the hidden
+                                                    // attribute tag for
+        // lfn
+        LittleEndian.setInt8(rawData, 12, 0); // reserved
+        LittleEndian.setInt8(rawData, 13, checkSum); // checksum
+        LittleEndian.setInt16(rawData, 14, unicodechar[5]);
+        LittleEndian.setInt16(rawData, 16, unicodechar[6]);
+        LittleEndian.setInt16(rawData, 18, unicodechar[7]);
+        LittleEndian.setInt16(rawData, 20, unicodechar[8]);
+        LittleEndian.setInt16(rawData, 22, unicodechar[9]);
+        LittleEndian.setInt16(rawData, 24, unicodechar[10]);
+        LittleEndian.setInt16(rawData, 26, 0); // sector... unused
+        LittleEndian.setInt16(rawData, 28, unicodechar[11]);
+        LittleEndian.setInt16(rawData, 30, unicodechar[12]);
+        
+        return new FatDirectoryEntry(rawData, false);
+    }
+
+    @Override
+    public long getLastModified() throws IOException {
+        return realEntry.getLastModified();
+    }
+
+    @Override
+    public long getCreated() throws IOException {
+        return realEntry.getCreated();
+    }
+
+    @Override
+    public long getLastAccessed() throws IOException {
+        return realEntry.getLastAccessed();
+    }
+
+    @Override
+    public boolean isFile() {
+        return realEntry.isFile();
+    }
+
+    @Override
+    public boolean isDirectory() {
+        return realEntry.isDirectory();
+    }
+
+    @Override
+    public boolean isDirty() {
+        return realEntry.isDirty();
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FatType.java b/src/main/java/de/waldheinz/fs/fat/FatType.java
new file mode 100644
index 0000000..1978264
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FatType.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+/**
+ * Enumerates the different entry sizes of 12, 16 and 32 bits for the different
+ * FAT flavours.
+ *
+ * @author Ewout Prangsma &lt;epr at jnode.org&gt;
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public enum FatType {
+
+    /**
+     * Represents a 12-bit file allocation table.
+     */
+    FAT12((1 << 12) - 16, 0xFFFL, 1.5f, "FAT12   ") { //NOI18N
+
+        @Override
+        long readEntry(byte[] data, int index) {
+            final int idx = (int) (index * 1.5);
+            final int b1 = data[idx] & 0xFF;
+            final int b2 = data[idx + 1] & 0xFF;
+            final int v = (b2 << 8) | b1;
+            
+            if ((index % 2) == 0) {
+                return v & 0xFFF;
+            } else {
+                return v >> 4;
+            }
+        }
+
+        @Override
+        void writeEntry(byte[] data, int index, long entry) {
+            final int idx = (int) (index * 1.5);
+            
+            if ((index % 2) == 0) {
+                data[idx] = (byte) (entry & 0xFF);
+                data[idx + 1] = (byte) ((entry >> 8) & 0x0F);
+            } else {
+                data[idx] |= (byte) ((entry & 0x0F) << 4);
+                data[idx + 1] = (byte) ((entry >> 4) & 0xFF);
+            }
+        }
+    },
+
+    /**
+     * Represents a 16-bit file allocation table.
+     */
+    FAT16((1 << 16) - 16, 0xFFFFL, 2.0f, "FAT16   ") { //NOI18N
+        
+        @Override
+        long readEntry(byte[] data, int index) {
+            final int idx = index << 1;
+            final int b1 = data[idx] & 0xFF;
+            final int b2 = data[idx + 1] & 0xFF;
+            return (b2 << 8) | b1;
+        }
+
+        @Override
+        void writeEntry(byte[] data, int index, long entry) {
+            final int idx = index << 1;
+            data[idx] = (byte) (entry & 0xFF);
+            data[idx + 1] = (byte) ((entry >> 8) & 0xFF);
+        }
+    },
+    
+    /**
+     * Represents a 32-bit file allocation table.
+     */
+    FAT32((1 << 28) - 16, 0xFFFFFFFFL, 4.0f, "FAT32   ") { //NOI18N
+
+        @Override
+        long readEntry(byte[] data, int index) {
+            final int idx = index * 4;
+            final long l1 = data[idx] & 0xFF;
+            final long l2 = data[idx + 1] & 0xFF;
+            final long l3 = data[idx + 2] & 0xFF;
+            final long l4 = data[idx + 3] & 0xFF;
+            return (l4 << 24) | (l3 << 16) | (l2 << 8) | l1;
+        }
+
+        @Override
+        void writeEntry(byte[] data, int index, long entry) {
+            final int idx = index << 2;
+            data[idx] = (byte) (entry & 0xFF);
+            data[idx + 1] = (byte) ((entry >> 8) & 0xFF);
+            data[idx + 2] = (byte) ((entry >> 16) & 0xFF);
+            data[idx + 3] = (byte) ((entry >> 24) & 0xFF);
+        }
+    };
+
+    private final long minReservedEntry;
+    private final long maxReservedEntry;
+    private final long eofCluster;
+    private final long eofMarker;
+    private final long bitMask;
+    private final int maxClusters;
+    private final String label;
+    private final float entrySize;
+
+    private FatType(int maxClusters,
+            long bitMask, float entrySize, String label) {
+        
+        this.minReservedEntry = (0xFFFFFF0L & bitMask);
+        this.maxReservedEntry = (0xFFFFFF6L & bitMask);
+        this.eofCluster = (0xFFFFFF8L & bitMask);
+        this.eofMarker = (0xFFFFFFFL & bitMask);
+        this.entrySize = entrySize;
+        this.label = label;
+        this.maxClusters = maxClusters;
+        this.bitMask = bitMask;
+    }
+
+    abstract long readEntry(byte[] data, int index);
+
+    abstract void writeEntry(byte[] data, int index, long entry);
+
+    /**
+     * Returns the maximum number of clusters this file system can address.
+     *
+     * @return the maximum cluster count supported
+     */
+    long maxClusters() {
+        return this.maxClusters;
+    }
+    
+    /**
+     * Returns the human-readable FAT name string as written to the
+     * {@link com.meetwise.fs.BootSector}.
+     *
+     * @return the boot sector label for this FAT type
+     */
+    String getLabel() {
+        return this.label;
+    }
+
+    boolean isReservedCluster(long entry) {
+        return ((entry >= minReservedEntry) && (entry <= maxReservedEntry));
+    }
+
+    boolean isEofCluster(long entry) {
+        return (entry >= eofCluster);
+    }
+
+    long getEofMarker() {
+        return eofMarker;
+    }
+
+    float getEntrySize() {
+        return entrySize;
+    }
+    
+    long getBitMask() {
+        return bitMask;
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FatUtils.java b/src/main/java/de/waldheinz/fs/fat/FatUtils.java
new file mode 100644
index 0000000..b653f7c
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FatUtils.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+package de.waldheinz.fs.fat;
+
+import java.io.IOException;
+
+/**
+ * <description>
+ * 
+ * @author Ewout Prangsma &lt; epr at jnode.org&gt;
+ * @author Fabien DUMINY
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public class FatUtils {
+    
+    /**
+     * Gets the offset (in bytes) of the fat with the given index
+     * 
+     * @param bs
+     * @param fatNr (0..)
+     * @return long
+     * @throws IOException 
+     */
+    public static long getFatOffset(BootSector bs, int fatNr) {
+        long sectSize = bs.getBytesPerSector();
+        long sectsPerFat = bs.getSectorsPerFat();
+        long resSects = bs.getNrReservedSectors();
+
+        long offset = resSects * sectSize;
+        long fatSize = sectsPerFat * sectSize;
+
+        offset += fatNr * fatSize;
+
+        return offset;
+    }
+
+    /**
+     * Gets the offset (in bytes) of the root directory with the given index
+     * 
+     * @param bs
+     * @return long
+     * @throws IOException 
+     */
+    public static long getRootDirOffset(BootSector bs) {
+        long sectSize = bs.getBytesPerSector();
+        long sectsPerFat = bs.getSectorsPerFat();
+        int fats = bs.getNrFats();
+
+        long offset = getFatOffset(bs, 0);
+        
+        offset += fats * sectsPerFat * sectSize;
+
+        return offset;
+    }
+
+    /**
+     * Gets the offset of the data (file) area
+     * 
+     * @param bs
+     * @return long
+     * @throws IOException 
+     */
+    public static long getFilesOffset(BootSector bs) {
+        long offset = getRootDirOffset(bs);
+        
+        offset += bs.getRootDirEntryCount() * 32;
+
+        return offset;
+    }
+    
+    private FatUtils() { /* no instances */ }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/FsInfoSector.java b/src/main/java/de/waldheinz/fs/fat/FsInfoSector.java
new file mode 100644
index 0000000..0399a9f
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/FsInfoSector.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+
+/**
+ * The FAT32 File System Information Sector.
+ *
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ * @see http://en.wikipedia.org/wiki/File_Allocation_Table#FS_Information_Sector
+ */
+final class FsInfoSector extends Sector {
+
+    /**
+     * The offset to the free cluster count value in the FS info sector.
+     */
+    public static final int FREE_CLUSTERS_OFFSET = 0x1e8;
+
+    /**
+     * The offset to the "last allocated cluster" value in this sector.
+     */
+    public static final int LAST_ALLOCATED_OFFSET = 0x1ec;
+
+    /**
+     * The offset to the signature of this sector.
+     */
+    public static final int SIGNATURE_OFFSET = 0x1fe;
+
+    private FsInfoSector(BlockDevice device, long offset) {
+        super(device, offset, BootSector.SIZE);
+    }
+
+    /**
+     * Reads a {@code FsInfoSector} as specified by the given
+     * {@code Fat32BootSector}.
+     *
+     * @param bs the boot sector that specifies where the FS info sector is
+     *      stored
+     * @return the FS info sector that was read
+     * @throws IOException on read error
+     * @see Fat32BootSector#getFsInfoSectorNr() 
+     */
+    public static FsInfoSector read(Fat32BootSector bs) throws IOException {
+        final FsInfoSector result =
+                new FsInfoSector(bs.getDevice(), offset(bs));
+        
+        result.read();
+        result.verify();
+        return result;
+    }
+
+    /**
+     * Creates an new {@code FsInfoSector} where the specified
+     * {@code Fat32BootSector} indicates it should be.
+     *
+     * @param bs the boot sector specifying the FS info sector storage
+     * @return the FS info sector instance that was created
+     * @throws IOException on write error
+     * @see Fat32BootSector#getFsInfoSectorNr() 
+     */
+    public static FsInfoSector create(Fat32BootSector bs) throws IOException {
+        final int offset = offset(bs);
+
+        if (offset == 0) throw new IOException(
+                "creating a FS info sector at offset 0 is strange");
+        
+        final FsInfoSector result =
+                new FsInfoSector(bs.getDevice(), offset(bs));
+        
+        result.init();
+        result.write();
+        return result;
+    }
+
+    private static int offset(Fat32BootSector bs) {
+        return bs.getFsInfoSectorNr() * bs.getBytesPerSector();
+    }
+
+    /**
+     * Sets the number of free clusters on the file system stored at
+     * {@link #FREE_CLUSTERS_OFFSET}.
+     *
+     * @param value the new free cluster count
+     * @see Fat#getFreeClusterCount()
+     */
+    public void setFreeClusterCount(long value) {
+        if (getFreeClusterCount() == value) return;
+        
+        set32(FREE_CLUSTERS_OFFSET, value);
+    }
+    
+    /**
+     * Returns the number of free clusters on the file system as sepcified by
+     * the 32-bit value at {@link #FREE_CLUSTERS_OFFSET}.
+     *
+     * @return the number of free clusters
+     * @see Fat#getFreeClusterCount() 
+     */
+    public long getFreeClusterCount() {
+        return get32(FREE_CLUSTERS_OFFSET);
+    }
+
+    /**
+     * Sets the last allocated cluster that was used in the {@link Fat}.
+     *
+     * @param value the FAT's last allocated cluster number
+     * @see Fat#getLastAllocatedCluster() 
+     */
+    public void setLastAllocatedCluster(long value) {
+        if (getLastAllocatedCluster() == value) return;
+        
+        super.set32(LAST_ALLOCATED_OFFSET, value);
+    }
+
+    /**
+     * Returns the last allocated cluster number of the {@link Fat} of the
+     * file system this FS info sector is part of.
+     *
+     * @return the last allocated cluster number
+     * @see Fat#getLastAllocatedCluster() 
+     */
+    public long getLastAllocatedCluster() {
+        return super.get32(LAST_ALLOCATED_OFFSET);
+    }
+
+    private void init() {
+        buffer.position(0x00);
+        buffer.put((byte) 0x52);
+        buffer.put((byte) 0x52);
+        buffer.put((byte) 0x61);
+        buffer.put((byte) 0x41);
+        
+        /* 480 reserved bytes */
+
+        buffer.position(0x1e4);
+        buffer.put((byte) 0x72);
+        buffer.put((byte) 0x72);
+        buffer.put((byte) 0x41);
+        buffer.put((byte) 0x61);
+        
+        setFreeClusterCount(-1);
+        setLastAllocatedCluster(Fat.FIRST_CLUSTER);
+
+        buffer.position(SIGNATURE_OFFSET);
+        buffer.put((byte) 0x55);
+        buffer.put((byte) 0xaa);
+        
+        markDirty();
+    }
+
+    private void verify() throws IOException {
+        if (!(get8(SIGNATURE_OFFSET) == 0x55) ||
+                !(get8(SIGNATURE_OFFSET + 1) == 0xaa)) {
+
+            throw new IOException("invalid FS info sector signature");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return FsInfoSector.class.getSimpleName() +
+                " [freeClusterCount=" + getFreeClusterCount() + //NOI18N
+                ", lastAllocatedCluster=" + getLastAllocatedCluster() + //NOI18N
+                ", offset=" + getOffset() + //NOI18N
+                ", dirty=" + isDirty() + //NOI18N
+                "]"; //NOI18N
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/LittleEndian.java b/src/main/java/de/waldheinz/fs/fat/LittleEndian.java
new file mode 100644
index 0000000..a89f7ae
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/LittleEndian.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2003-2009 JNode.org
+ *               2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+
+/**
+ * Little endian (LSB first) conversion methods.
+ *
+ * @author Ewout Prangsma &lt;epr at users.sourceforge.net&gt;
+ */
+final class LittleEndian {
+
+    private LittleEndian() { /* no instances */ }
+    
+    /**
+     * Gets an 8-bit unsigned integer from the given byte array at
+     * the given offset.
+     *
+     * @param src the byte offset where to read the value from
+     * @param offset the byte array to extract the value from
+     * @return the integer that was read
+     */
+    public static int getUInt8(byte[] src, int offset) {
+        return src[offset] & 0xFF;
+    }
+
+    /**
+     * Gets a 16-bit unsigned integer from the given byte array at the given offset.
+     *
+     * @param src
+     * @param offset
+     */
+    public static int getUInt16(byte[] src, int offset) {
+        final int v0 = src[offset + 0] & 0xFF;
+        final int v1 = src[offset + 1] & 0xFF;
+        return ((v1 << 8) | v0);
+    }
+
+    /**
+     * Gets a 32-bit unsigned integer from the given byte array at the given offset.
+     *
+     * @param src
+     * @param offset
+     */
+    public static long getUInt32(byte[] src, int offset) {
+        final long v0 = src[offset + 0] & 0xFF;
+        final long v1 = src[offset + 1] & 0xFF;
+        final long v2 = src[offset + 2] & 0xFF;
+        final long v3 = src[offset + 3] & 0xFF;
+        return ((v3 << 24) | (v2 << 16) | (v1 << 8) | v0);
+    }
+
+    /**
+     * Sets an 8-bit integer in the given byte array at the given offset.
+     */
+    public static void setInt8(byte[] dst, int offset, int value) {
+        dst[offset] = (byte) value;
+    }
+
+    /**
+     * Sets a 16-bit integer in the given byte array at the given offset.
+     */
+    public static void setInt16(byte[] dst, int offset, int value) {
+        dst[offset + 0] = (byte) (value & 0xFF);
+        dst[offset + 1] = (byte) ((value >>> 8) & 0xFF);
+    }
+
+    /**
+     * Sets a 32-bit integer in the given byte array at the given offset.
+     */
+    public static void setInt32(byte[] dst, int offset, long value)
+            throws IllegalArgumentException {
+        
+        if (value > Integer.MAX_VALUE) {
+            throw new IllegalArgumentException(
+                    value + " can not be represented in a 32bit dword");
+        }
+        
+        dst[offset + 0] = (byte) (value & 0xFF);
+        dst[offset + 1] = (byte) ((value >>> 8) & 0xFF);
+        dst[offset + 2] = (byte) ((value >>> 16) & 0xFF);
+        dst[offset + 3] = (byte) ((value >>> 24) & 0xFF);
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/Sector.java b/src/main/java/de/waldheinz/fs/fat/Sector.java
new file mode 100644
index 0000000..670f149
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/Sector.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * 
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+class Sector {
+    private final BlockDevice device;
+    private final long offset;
+
+    /**
+     * The buffer holding the contents of this {@code Sector}.
+     */
+    protected final ByteBuffer buffer;
+
+    private boolean dirty;
+    
+    protected Sector(BlockDevice device, long offset, int size) {
+        this.offset = offset;
+        this.device = device;
+        this.buffer = ByteBuffer.allocate(size);
+        this.buffer.order(ByteOrder.LITTLE_ENDIAN);
+        this.dirty = true;
+    }
+    
+    /**
+     * Reads the contents of this {@code Sector} from the device into the
+     * internal buffer and resets the "dirty" state.
+     *
+     * @throws IOException on read error
+     * @see #isDirty() 
+     */
+    protected void read() throws IOException {
+        buffer.rewind();
+        buffer.limit(buffer.capacity());
+        device.read(offset, buffer);
+        this.dirty = false;
+    }
+    
+    public final boolean isDirty() {
+        return this.dirty;
+    }
+    
+    protected final void markDirty() {
+        this.dirty = true;
+    }
+
+    /**
+     * Returns the {@code BlockDevice} where this {@code Sector} is stored.
+     *
+     * @return this {@code Sector}'s device
+     */
+    public BlockDevice getDevice() {
+        return this.device;
+    }
+
+    public final void write() throws IOException {
+        if (!isDirty()) return;
+        
+        buffer.position(0);
+        buffer.limit(buffer.capacity());
+        device.write(offset, buffer);
+        this.dirty = false;
+    }
+
+    protected int get16(int offset) {
+        return buffer.getShort(offset) & 0xffff;
+    }
+
+    protected long get32(int offset) {
+        return buffer.getInt(offset) & 0xffffffff;
+    }
+    
+    protected int get8(int offset) {
+        return buffer.get(offset) & 0xff;
+    }
+    
+    protected void set16(int offset, int value) {
+        buffer.putShort(offset, (short) (value & 0xffff));
+        dirty = true;
+    }
+
+    protected void set32(int offset, long value) {
+        buffer.putInt(offset, (int) (value & 0xffffffff));
+        dirty = true;
+    }
+
+    protected void set8(int offset, int value) {
+        if ((value & 0xff) != value) {
+            throw new IllegalArgumentException(
+                    value + " too big to be stored in a single octet");
+        }
+        
+        buffer.put(offset, (byte) (value & 0xff));
+        dirty = true;
+    }
+    
+    /**
+     * Returns the device offset to this {@code Sector}.
+     *
+     * @return the {@code Sector}'s device offset
+     */
+    protected long getOffset() {
+        return this.offset;
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/ShortName.java b/src/main/java/de/waldheinz/fs/fat/ShortName.java
new file mode 100644
index 0000000..0fb382a
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/ShortName.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+
+/**
+ * Represents a "short" (8.3) file name as used by DOS.
+ * 
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+final class ShortName {
+
+    /**
+     * These are taken from the FAT specification.
+     */
+    private final static byte[] ILLEGAL_CHARS = {
+            0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B,
+            0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C
+    };
+
+    /**
+     * The name of the "current directory" (".") entry of a FAT directory.
+     */
+    public final static ShortName DOT = new ShortName(".", ""); // NOI18N
+
+    /**
+     * The name of the "parent directory" ("..") entry of a FAT directory.
+     */
+    public final static ShortName DOT_DOT = new ShortName("..", ""); // NOI18N
+
+    private final char[] name;
+    private boolean mShortNameOnly;
+
+    private ShortName(String nameExt) {
+        if (nameExt.length() > 12)
+            throw new IllegalArgumentException("name too long");
+
+        final int i = nameExt.indexOf('.');
+        final String nameString, extString;
+
+        if (i < 0) {
+            nameString = nameExt.toUpperCase();
+            extString = "";
+        } else {
+            nameString = nameExt.substring(0, i).toUpperCase();
+            extString = nameExt.substring(i + 1).toUpperCase();
+        }
+
+        this.name = toCharArray(nameString, extString);
+        checkValidChars(this.name);
+    }
+
+    ShortName(String name, String ext) {
+        this.name = toCharArray(name, ext);
+    }
+
+    ShortName(char[] name) {
+        this.name = name;
+    }
+
+    public ShortName(char[] nameArr, char[] extArr) {
+        char[] result = new char[11];
+        System.arraycopy(nameArr, 0, result, 0, nameArr.length);
+        System.arraycopy(extArr, 0, result, 8, extArr.length);
+        this.name = result;
+    }
+
+    private static char[] toCharArray(String name, String ext) {
+        checkValidName(name);
+        checkValidExt(ext);
+
+        final char[] result = new char[11];
+        Arrays.fill(result, ' ');
+        System.arraycopy(name.toCharArray(), 0, result, 0, name.length());
+        System.arraycopy(ext.toCharArray(), 0, result, 8, ext.length());
+
+        return result;
+    }
+
+    /**
+     * Calculates the checksum that is used to test a long file name for it's
+     * validity.
+     * 
+     * @return the {@code ShortName}'s checksum
+     */
+    public byte checkSum() {
+        final byte[] dest = new byte[11];
+        for (int i = 0; i < 11; i++)
+            dest[i] = (byte) name[i];
+
+        int sum = dest[0];
+        for (int i = 1; i < 11; i++) {
+            sum = dest[i] + (((sum & 1) << 7) + ((sum & 0xfe) >> 1));
+        }
+
+        return (byte) (sum & 0xff);
+    }
+
+    /**
+     * Parses the specified string into a {@code ShortName}.
+     * 
+     * @param name the name+extension of the {@code ShortName} to get
+     * @return the {@code ShortName} representing the specified name
+     * @throws IllegalArgumentException if the specified name can not be parsed
+     *             into a {@code ShortName}
+     * @see #canConvert(java.lang.String)
+     */
+    public static ShortName get(String name) throws IllegalArgumentException {
+        if (name.equals("."))
+            return DOT;
+        else if (name.equals(".."))
+            return DOT_DOT;
+        else
+            return new ShortName(name);
+    }
+
+    /**
+     * Tests if the specified string can be converted to a {@code ShortName}.
+     * 
+     * @param nameExt the string to test
+     * @return if the string can be converted
+     * @see #get(java.lang.String)
+     */
+    public static boolean canConvert(String nameExt) {
+        /* TODO: do this without exceptions */
+        try {
+            ShortName.get(nameExt);
+            return true;
+        } catch (IllegalArgumentException ex) {
+            return false;
+        }
+    }
+
+    public static ShortName parse(byte[] data) {
+        final char[] nameArr = new char[8];
+
+        for (int i = 0; i < nameArr.length; i++) {
+            nameArr[i] = (char) LittleEndian.getUInt8(data, i);
+        }
+
+        final char[] extArr = new char[3];
+        for (int i = 0; i < extArr.length; i++) {
+            extArr[i] = (char) LittleEndian.getUInt8(data, 0x08 + i);
+        }
+
+        return new ShortName(nameArr, extArr);
+    }
+
+    public void write(byte[] dest) {
+        for (int i = 0; i < 11; i++) {
+            dest[i] = (byte) name[i];
+        }
+    }
+
+    public String asSimpleString() {
+        return new String(this.name).trim();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < this.name.length; i++) {
+            sb.append(Integer.toHexString(name[i]));
+            sb.append(' ');
+        }
+        return getClass().getSimpleName() +
+                " [" +
+                asSimpleString() + " -- " +
+                sb.toString() + "]"; // NOI18N
+    }
+
+    private static void checkValidName(String name) {
+        checkString(name, "name", 1, 8);
+    }
+
+    private static void checkValidExt(String ext) {
+        checkString(ext, "extension", 0, 3);
+    }
+
+    private static void checkString(String str, String strType,
+            int minLength, int maxLength) {
+
+        if (str == null)
+            throw new IllegalArgumentException(strType +
+                    " is null");
+        if (str.length() < minLength)
+            throw new IllegalArgumentException(strType +
+                    " must have at least " + minLength +
+                    " characters: " + str);
+        if (str.length() > maxLength)
+            throw new IllegalArgumentException(strType +
+                    " has more than " + maxLength +
+                    " characters: " + str);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ShortName)) {
+            return false;
+        }
+
+        final ShortName other = (ShortName) obj;
+        return Arrays.equals(name, other.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(this.name);
+    }
+
+    public void setHasShortNameOnly(boolean hasShortNameOnly) {
+        mShortNameOnly = hasShortNameOnly;
+    }
+
+    public boolean hasShortNameOnly() {
+        return mShortNameOnly;
+    }
+
+    /**
+     * Checks if the specified char array consists only of "valid" byte values
+     * according to the FAT specification.
+     * 
+     * @param chars the char array to test
+     * @throws IllegalArgumentException if invalid chars are contained
+     */
+    public static void checkValidChars(char[] chars)
+            throws IllegalArgumentException {
+
+        if (chars[0] == 0x20)
+            throw new IllegalArgumentException(
+                    "0x20 can not be the first character");
+
+        for (int i = 0; i < chars.length; i++) {
+            if ((chars[i] & 0xff) != chars[i])
+                throw new IllegalArgumentException("multi-byte character at " + i);
+
+            final byte toTest = (byte) (chars[i] & 0xff);
+
+            if (toTest < 0x20 && toTest != 0x05)
+                throw new IllegalArgumentException("character < 0x20 at" + i);
+
+            for (int j = 0; j < ILLEGAL_CHARS.length; j++) {
+                if (toTest == ILLEGAL_CHARS[j])
+                    throw new IllegalArgumentException("illegal character " +
+                            ILLEGAL_CHARS[j] + " at " + i);
+            }
+        }
+    }
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/SuperFloppyFormatter.java b/src/main/java/de/waldheinz/fs/fat/SuperFloppyFormatter.java
new file mode 100644
index 0000000..5a64639
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/SuperFloppyFormatter.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.fat;
+
+import de.waldheinz.fs.BlockDevice;
+import java.io.IOException;
+import java.util.Random;
+
+/**
+ * <p>
+ * Allows to create FAT file systems on {@link BlockDevice}s which follow the
+ * "super floppy" standard. This means that the device will be formatted so
+ * that it does not contain a partition table. Instead, the entire device holds
+ * a single FAT file system.
+ * </p><p>
+ * This class follows the "builder" pattern, which means it's methods always
+ * returns the {@code SuperFloppyFormatter} instance they're called on. This
+ * allows to chain the method calls like this:
+ * <pre>
+ *  BlockDevice dev = new RamDisk(16700000);
+ *  FatFileSystem fs = SuperFloppyFormatter.get(dev).
+ *          setFatType(FatType.FAT12).format();
+ * </pre>
+ * 
+ * </p>
+ *
+ * @author Matthias Treydte &lt;matthias.treydte at meetwise.com&gt;
+ */
+public final class SuperFloppyFormatter {
+
+    /**
+     * The media descriptor used (hard disk).
+     */
+    public final static int MEDIUM_DESCRIPTOR_HD = 0xf8;
+
+    /**
+     * The default number of FATs.
+     */
+    public final static int DEFAULT_FAT_COUNT = 2;
+
+    /**
+     * The default number of sectors per track.
+     */
+    public final static int DEFAULT_SECTORS_PER_TRACK = 32;
+
+    /**
+     * The default number of heads.
+     * 
+     * @since 0.6
+     */
+    public final static int DEFAULT_HEADS = 64;
+
+    /**
+     * The default number of heads.
+     * 
+     * @deprecated the name of this constant was mistyped
+     * @see #DEFAULT_HEADS
+     */
+    @Deprecated
+    public final static int DEFULT_HEADS = DEFAULT_HEADS;
+
+    /**
+     * The default OEM name for file systems created by this class.
+     */
+    public final static String DEFAULT_OEM_NAME = "fat32lib"; //NOI18N
+    
+    private static final int MAX_DIRECTORY = 512;
+    
+    private final BlockDevice device;
+    
+    private String label;
+    private String oemName;
+    private FatType fatType;
+    private int sectorsPerCluster;
+    private int reservedSectors;
+    private int fatCount;
+
+    /**
+     * Creates a new {@code SuperFloppyFormatter} for the specified
+     * {@code BlockDevice}.
+     *
+     * @param device
+     * @throws IOException on error accessing the specified {@code device}
+     */
+    private SuperFloppyFormatter(BlockDevice device) throws IOException {
+        this.device = device;
+        this.oemName = DEFAULT_OEM_NAME;
+        this.fatCount = DEFAULT_FAT_COUNT;
+        setFatType(fatTypeFromDevice());
+    }
+    
+    /**
+     * Retruns a {@code SuperFloppyFormatter} instance suitable for formatting
+     * the specified device.
+     *
+     * @param dev the device that should be formatted
+     * @return the formatter for the device
+     * @throws IOException on error creating the formatter
+     */
+    public static SuperFloppyFormatter get(BlockDevice dev) throws IOException {
+        return new SuperFloppyFormatter(dev);
+    }
+    
+    /**
+     * Returns the OEM name that will be written to the {@link BootSector}.
+     *
+     * @return the OEM name of the new file system
+     */
+    public String getOemName() {
+        return oemName;
+    }
+    
+    /**
+     * Sets the OEM name of the boot sector.
+     *
+     * TODO: throw an exception early if name is invalid (too long, ...)
+     *
+     * @param oemName the new OEM name
+     * @return this {@code SuperFloppyFormatter}
+     * @see BootSector#setOemName(java.lang.String)
+     */
+    public SuperFloppyFormatter setOemName(String oemName) {
+        this.oemName = oemName;
+        return this;
+    }
+    
+    /**
+     * Sets the volume label of the file system to create.
+     * 
+     * TODO: throw an exception early if label is invalid (too long, ...)
+     * 
+     * @param label the new file system label, may be {@code null}
+     * @return this {@code SuperFloppyFormatter}
+     * @see FatFileSystem#setVolumeLabel(java.lang.String)
+     */
+    public SuperFloppyFormatter setVolumeLabel(String label) {
+        this.label = label;
+        return this;
+    }
+
+    /**
+     * Returns the volume label that will be given to the new file system.
+     *
+     * @return the file system label, may be {@code null}
+     * @see FatFileSystem#getVolumeLabel() 
+     */
+    public String getVolumeLabel() {
+        return label;
+    }
+
+    private void initBootSector(BootSector bs)
+            throws IOException {
+        
+        bs.init();
+        bs.setFileSystemTypeLabel(fatType.getLabel());
+        bs.setNrReservedSectors(reservedSectors);
+        bs.setNrFats(fatCount);
+        bs.setSectorsPerCluster(sectorsPerCluster);
+        bs.setMediumDescriptor(MEDIUM_DESCRIPTOR_HD);
+        bs.setSectorsPerTrack(DEFAULT_SECTORS_PER_TRACK);
+        bs.setNrHeads(DEFAULT_HEADS);
+        bs.setOemName(oemName);
+    }
+
+    /**
+     * Initializes the boot sector and file system for the device. The file
+     * system created by this method will always be in read-write mode.
+     *
+     * @return the file system that was created
+     * @throws IOException on write error
+     */
+    public FatFileSystem format() throws IOException {
+        final int sectorSize = device.getSectorSize();
+        final int totalSectors = (int)(device.getSize() / sectorSize);
+        
+        final FsInfoSector fsi;
+        final BootSector bs;
+        if (sectorsPerCluster == 0) throw new AssertionError();
+        
+        if (fatType == FatType.FAT32) {
+            bs = new Fat32BootSector(device);
+            initBootSector(bs);
+            
+            final Fat32BootSector f32bs = (Fat32BootSector) bs;
+            
+            f32bs.setFsInfoSectorNr(1);
+            
+            f32bs.setSectorsPerFat(sectorsPerFat(0, totalSectors));
+            final Random rnd = new Random(System.currentTimeMillis());
+            f32bs.setFileSystemId(rnd.nextInt());
+            
+            f32bs.setVolumeLabel(label);
+            
+            /* create FS info sector */
+            fsi = FsInfoSector.create(f32bs);
+        } else {
+            bs = new Fat16BootSector(device);
+            initBootSector(bs);
+            
+            final Fat16BootSector f16bs = (Fat16BootSector) bs;
+            
+            final int rootDirEntries = rootDirectorySize(
+                    device.getSectorSize(), totalSectors);
+                    
+            f16bs.setRootDirEntryCount(rootDirEntries);
+            f16bs.setSectorsPerFat(sectorsPerFat(rootDirEntries, totalSectors));
+            if (label != null) f16bs.setVolumeLabel(label);
+            fsi = null;
+        }
+
+        
+//        bs.write();
+        
+        if (fatType == FatType.FAT32) {
+            Fat32BootSector f32bs = (Fat32BootSector) bs;
+            /* possibly writes the boot sector copy */
+            f32bs.writeCopy(device);
+        }
+        
+        final Fat fat = Fat.create(bs, 0);
+        
+        final AbstractDirectory rootDirStore;
+        if (fatType == FatType.FAT32) {
+            rootDirStore = ClusterChainDirectory.createRoot(fat);
+            fsi.setFreeClusterCount(fat.getFreeClusterCount());
+            fsi.setLastAllocatedCluster(fat.getLastAllocatedCluster());
+            fsi.write();
+        } else {
+            rootDirStore = Fat16RootDirectory.create((Fat16BootSector) bs);
+        }
+        
+        final FatLfnDirectory rootDir =
+                new FatLfnDirectory(rootDirStore, fat, false);
+        
+        rootDir.flush();
+        
+        for (int i = 0; i < bs.getNrFats(); i++) {
+            fat.writeCopy(FatUtils.getFatOffset(bs, i));
+        }
+        
+        bs.write();
+
+        FatFileSystem fs = FatFileSystem.read(device, false);
+
+        if (label != null) {
+            fs.setVolumeLabel(label);
+        }
+
+        fs.flush();
+        return fs;
+    }
+
+    private int sectorsPerFat(int rootDirEntries, int totalSectors)
+            throws IOException {
+        
+        final int bps = device.getSectorSize();
+        final int rootDirSectors =
+                ((rootDirEntries * 32) + (bps - 1)) / bps;
+        final long tmp1 =
+                totalSectors - (this.reservedSectors + rootDirSectors);
+        int tmp2 = (256 * this.sectorsPerCluster) + this.fatCount;
+
+        if (fatType == FatType.FAT32)
+            tmp2 /= 2;
+
+        final int result = (int) ((tmp1 + (tmp2 - 1)) / tmp2);
+        
+        return result;
+    }
+    
+    /**
+     * Determines a usable FAT type from the {@link #device} by looking at the
+     * {@link BlockDevice#getSize() device size} only.
+     *
+     * @return the suggested FAT type
+     * @throws IOException on error determining the device's size
+     */
+    private FatType fatTypeFromDevice() throws IOException {
+    	return fatTypeFromSize(device.getSize());
+    }
+    
+    /**
+     * Determines a usable FAT type from the {@link #device} by looking at the
+     * {@link BlockDevice#getSize() device size} only.
+     *
+     * @return the suggested FAT type
+     * @throws IOException on error determining the device's size
+     */
+    public static FatType fatTypeFromSize(long sizeInBytes) {
+        final long sizeInMb = sizeInBytes / (1024 * 1024);
+        if (sizeInMb < 4) return FatType.FAT12;
+        else if (sizeInMb < 512) return FatType.FAT16;
+        else return FatType.FAT32;    	
+    }
+    
+    public static int clusterSizeFromSize(long sizeInBytes, int sectorSize){
+    	switch(fatTypeFromSize(sizeInBytes)) {
+        case FAT12:
+            return sectorsPerCluster12(sizeInBytes, sectorSize);
+        case FAT16:
+            return sectorsPerCluster16FromSize(sizeInBytes, sectorSize);
+        case FAT32:
+            return sectorsPerCluster32FromSize(sizeInBytes, sectorSize);
+            
+        default:
+            throw new AssertionError();
+    	}
+    }
+    
+    /**
+     * Returns the exact type of FAT the will be created by this formatter.
+     *
+     * @return the FAT type
+     */
+    public FatType getFatType() {
+        return this.fatType;
+    }
+
+    /**
+     * Sets the type of FAT that will be created by this
+     * {@code SuperFloppyFormatter}.
+     *
+     * @param fatType the desired {@code FatType}
+     * @return this {@code SuperFloppyFormatter}
+     * @throws IOException on error setting the {@code fatType}
+     * @throws IllegalArgumentException if {@code fatType} does not support the
+     *      size of the device
+     */
+    public SuperFloppyFormatter setFatType(FatType fatType)
+            throws IOException, IllegalArgumentException {
+        
+        if (fatType == null) throw new NullPointerException();
+
+        switch (fatType) {
+            case FAT12: case FAT16:
+                this.reservedSectors = 1;
+                break;
+                
+            case FAT32:
+                this.reservedSectors = 32;
+        }
+        
+        this.sectorsPerCluster = defaultSectorsPerCluster(fatType);
+        this.fatType = fatType;
+        
+        return this;
+    }
+    
+    private static int rootDirectorySize(int bps, int nbTotalSectors) {
+        final int totalSize = bps * nbTotalSectors;
+        if (totalSize >= MAX_DIRECTORY * 5 * 32) {
+            return MAX_DIRECTORY;
+        } else {
+            return totalSize / (5 * 32);
+        }
+    }
+    
+    static private int MAX_FAT32_CLUSTERS = 0x0FFFFFF5;
+    
+    static private int sectorsPerCluster32FromSize(long size, int sectorSize) {
+        final long sectors = size / sectorSize;
+        
+        if (sectors <= 66600) throw new IllegalArgumentException(
+                "disk too small for FAT32");
+
+        return
+                sectors > 67108864 ? 64 :
+                sectors > 33554432 ? 32 :
+                sectors > 16777216 ? 16 :
+                sectors >   532480 ?  8 : 1;
+    }
+    
+    private int sectorsPerCluster32() throws IOException {
+        if (this.reservedSectors != 32) throw new IllegalStateException(
+                "number of reserved sectors must be 32");
+        
+        if (this.fatCount != 2) throw new IllegalStateException(
+                "number of FATs must be 2");
+
+        final long sectors = device.getSize() / device.getSectorSize();
+
+        if (sectors <= 66600) throw new IllegalArgumentException(
+                "disk too small for FAT32");
+
+        return sectorsPerCluster32FromSize(device.getSize(), device.getSectorSize());
+    }
+
+    static private int MAX_FAT16_CLUSTERS = 65524;
+    
+    static private int sectorsPerCluster16FromSize(long size, int sectorSize) {
+        final long sectors = size / sectorSize;
+        
+        if (sectors <= 8400) throw new IllegalArgumentException(
+                "disk too small for FAT16");
+
+        if (sectors > 4194304) throw new IllegalArgumentException(
+                "disk too large for FAT16");
+
+          return
+          sectors > 2097152 ? 64 :
+          sectors > 1048576 ? 32 :
+          sectors >  524288 ? 16 :
+          sectors >  262144 ?  8 :
+          sectors >   32680 ?  4 : 2;
+    }
+    
+    private int sectorsPerCluster16() throws IOException {
+        if (this.reservedSectors != 1) throw new IllegalStateException(
+                "number of reserved sectors must be 1");
+
+        if (this.fatCount != 2) throw new IllegalStateException(
+                "number of FATs must be 2");
+        
+    	long size = device.getSize();
+        int sectorSize = device.getSectorSize();
+        return sectorsPerCluster16FromSize(size, sectorSize);        
+    }
+    
+    private int defaultSectorsPerCluster(FatType fatType) throws IOException {
+    	long size = device.getSize();
+        int sectorSize = device.getSectorSize();
+    	
+        switch (fatType) {
+            case FAT12:
+                return sectorsPerCluster12(size, sectorSize);
+
+            case FAT16:
+                return sectorsPerCluster16();
+
+            case FAT32:
+                return sectorsPerCluster32();
+                
+            default:
+                throw new AssertionError();
+        }
+    }
+
+    static private int sectorsPerCluster12(long size, int sectorSize) {
+        int result = 1;
+        
+        final long sectors = size / sectorSize;
+
+        while (sectors / result > Fat16BootSector.MAX_FAT12_CLUSTERS) {
+            result *= 2;
+            if (result * size > 4096) throw new
+                    IllegalArgumentException("disk too large for FAT12");
+        }
+        
+        return result;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/fat/package-info.java b/src/main/java/de/waldheinz/fs/fat/package-info.java
new file mode 100644
index 0000000..4baf68f
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/fat/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * Contains the classes implementing the FAT(12/16/32) file system.
+ */
+package de.waldheinz.fs.fat;
diff --git a/src/main/java/de/waldheinz/fs/package-info.java b/src/main/java/de/waldheinz/fs/package-info.java
new file mode 100644
index 0000000..eb534b4
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+ 
+/**
+ * Contains the file-system independent classes and interfaces, as well as
+ * the {@link de.waldheinz.fs.FileSystemFactory} for creating
+ * {@link de.waldheinz.fs.FileSystem} instances.
+ */
+package de.waldheinz.fs;
diff --git a/src/main/java/de/waldheinz/fs/util/FileDisk.java b/src/main/java/de/waldheinz/fs/util/FileDisk.java
new file mode 100644
index 0000000..0f3f0bb
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/util/FileDisk.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.util;
+
+import de.waldheinz.fs.BlockDevice;
+import de.waldheinz.fs.ReadOnlyException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/**
+ * This is a {@code BlockDevice} that uses a {@link File} as it's backing store.
+ *
+ * @author Matthias Treydte &lt;matthias.treydte at meetwise.com&gt;
+ */
+public final class FileDisk implements BlockDevice {
+
+    /**
+     * The number of bytes per sector for all {@code FileDisk} instances.
+     */
+    public final static int BYTES_PER_SECTOR = 512;
+
+    private final RandomAccessFile raf;
+    private final FileChannel fc;
+    private final boolean readOnly;
+    private boolean closed;
+
+    /**
+     * Creates a new instance of {@code FileDisk} for the specified
+     * {@code File}.
+     *
+     * @param file the file that holds the disk contents
+     * @param readOnly if the file should be opened in read-only mode, which
+     *      will result in a read-only {@code FileDisk} instance
+     * @throws FileNotFoundException if the specified file does not exist
+     * @see #isReadOnly() 
+     */
+    public FileDisk(File file, boolean readOnly) throws FileNotFoundException {
+        if (!file.exists()) throw new FileNotFoundException();
+
+        this.readOnly = readOnly;
+        this.closed = false;
+        final String modeString = readOnly ? "r" : "rw"; //NOI18N
+        this.raf = new RandomAccessFile(file, modeString);
+        this.fc = raf.getChannel();
+    }
+
+    public FileDisk(RandomAccessFile raf, FileChannel fc, boolean readOnly) {
+        this.closed = false;
+        this.raf = raf;
+        this.fc = fc;
+        this.readOnly = readOnly;
+    }    
+    
+    private FileDisk(RandomAccessFile raf, boolean readOnly) {
+        this.closed = false;
+        this.raf = raf;
+        this.fc = raf.getChannel();
+        this.readOnly = readOnly;
+    }
+
+    /**
+     * Creates a new {@code FileDisk} of the specified size. The
+     * {@code FileDisk} returned by this method will be writable.
+     *
+     * @param file the file to hold the {@code FileDisk} contents
+     * @param size the size of the new {@code FileDisk}
+     * @return the created {@code FileDisk} instance
+     * @throws IOException on error creating the {@code FileDisk}
+     */
+    public static FileDisk create(File file, long size) throws IOException {
+        try {
+            final RandomAccessFile raf =
+                    new RandomAccessFile(file, "rw"); //NOI18N
+            raf.setLength(size);
+            
+            return new FileDisk(raf, false);
+        } catch (FileNotFoundException ex) {
+            throw new IOException(ex);
+        }
+    }
+    
+    @Override
+    public long getSize() throws IOException {
+        checkClosed();
+        
+        return raf.length();
+    }
+
+    @Override
+    public void read(long devOffset, ByteBuffer dest) throws IOException {
+        checkClosed();
+
+        int toRead = dest.remaining();
+        if ((devOffset + toRead) > getSize()) throw new IOException(
+                "reading past end of device");
+
+        while (toRead > 0) {
+            final int read = fc.read(dest, devOffset);
+            if (read < 0) throw new IOException();
+            toRead -= read;
+            devOffset += read;
+        }
+    }
+
+    @Override
+    public void write(long devOffset, ByteBuffer src) throws IOException {
+        checkClosed();
+
+        if (this.readOnly) throw new ReadOnlyException();
+        
+        int toWrite = src.remaining();
+
+        if ((devOffset + toWrite) > getSize()) throw new IOException(
+                "writing past end of file");
+
+        while (toWrite > 0) {
+            final int written = fc.write(src, devOffset);
+            if (written < 0) throw new IOException();
+            toWrite -= written;
+            devOffset += written;
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        checkClosed();
+    }
+
+    @Override
+    public int getSectorSize() {
+        checkClosed();
+        
+        return BYTES_PER_SECTOR;
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (isClosed()) return;
+
+        this.closed = true;
+        this.fc.close();
+        this.raf.close();
+    }
+    
+    @Override
+    public boolean isClosed() {
+        return this.closed;
+    }
+
+    private void checkClosed() {
+        if (closed) throw new IllegalStateException("device already closed");
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        checkClosed();
+        
+        return this.readOnly;
+    }
+
+}
diff --git a/src/main/java/de/waldheinz/fs/util/RamDisk.java b/src/main/java/de/waldheinz/fs/util/RamDisk.java
new file mode 100644
index 0000000..51a1be1
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/util/RamDisk.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package de.waldheinz.fs.util;
+
+import de.waldheinz.fs.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * A {@link BlockDevice} that lives entirely in heap memory. This is basically
+ * a RAM disk. A {@code RamDisk} is always writable.
+ *
+ * @author Matthias Treydte &lt;waldheinz at gmail.com&gt;
+ */
+public final class RamDisk implements BlockDevice {
+    
+    /**
+     * The default sector size for {@code RamDisk}s.
+     */
+    public final static int DEFAULT_SECTOR_SIZE = 512;
+    
+    private final int sectorSize;
+    private final ByteBuffer data;
+    private final int size;
+    private boolean closed;
+
+    /**
+     * Reads a GZIP compressed disk image from the specified input stream and
+     * returns a {@code RamDisk} holding the decompressed image.
+     *
+     * @param in the stream to read the disk image from
+     * @return the decompressed {@code RamDisk}
+     * @throws IOException on read or decompression error
+     */
+    public static RamDisk readGzipped(InputStream in) throws IOException {
+        final GZIPInputStream zis = new GZIPInputStream(in);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        
+        final byte[] buffer = new byte[4096];
+        
+        int read = zis.read(buffer);
+        int total = 0;
+        
+        while (read >= 0) {
+            total += read;
+            bos.write(buffer, 0, read);
+            read = zis.read(buffer);
+        }
+
+        if (total < DEFAULT_SECTOR_SIZE) throw new IOException(
+                "read only " + total + " bytes"); //NOI18N
+                
+        final ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray(), 0, total);
+        return new RamDisk(bb, DEFAULT_SECTOR_SIZE);
+    }
+    
+    private RamDisk(ByteBuffer buffer, int sectorSize) {
+        this.size = buffer.limit();
+        this.sectorSize = sectorSize;
+        this.data = buffer;
+        this.closed = false;
+    }
+
+    /**
+     * Creates a new instance of {@code RamDisk} of this specified
+     * size and using the {@link #DEFAULT_SECTOR_SIZE}.
+     *
+     * @param size the size of the new block device
+     */
+    public RamDisk(int size) {
+        this(size, DEFAULT_SECTOR_SIZE);
+    }
+
+    /**
+     * Creates a new instance of {@code RamDisk} of this specified
+     * size and sector size
+     *
+     * @param size the size of the new block device
+     * @param sectorSize the sector size of the new block device
+     */
+    public RamDisk(int size, int sectorSize) {
+        if (sectorSize < 1) throw new IllegalArgumentException(
+                "invalid sector size"); //NOI18N
+        
+        this.sectorSize = sectorSize;
+        this.size = size;
+        this.data = ByteBuffer.allocate(size);
+    }
+    
+    @Override
+    public long getSize() {
+        checkClosed();
+        return this.size;
+    }
+
+    @Override
+    public void read(long devOffset, ByteBuffer dest) throws IOException {
+        checkClosed();
+        
+        if (devOffset > getSize()){
+            final StringBuilder sb = new StringBuilder();
+            sb.append("read at ").append(devOffset);
+            sb.append(" is off size (").append(getSize()).append(")");
+            
+            throw new IllegalArgumentException(sb.toString());
+        }
+        
+        data.limit((int) (devOffset + dest.remaining()));
+        data.position((int) devOffset);
+        
+        dest.put(data);
+    }
+
+    @Override
+    public void write(long devOffset, ByteBuffer src) throws IOException {
+        checkClosed();
+        
+        if (devOffset + src.remaining() > getSize()) throw new
+                IllegalArgumentException(
+                "offset=" + devOffset +
+                ", length=" + src.remaining() +
+                ", size=" + getSize());
+                
+        data.limit((int) (devOffset + src.remaining()));
+        data.position((int) devOffset);
+        
+        
+        data.put(src);
+    }
+    
+    /**
+     * Returns a slice of the {@code ByteBuffer} that is used by this
+     * {@code RamDisk} as it's backing store. The returned buffer will be
+     * live (reflecting any changes made through the
+     * {@link #write(long, java.nio.ByteBuffer) method}, but read-only.
+     *
+     * @return a buffer holding the contents of this {@code RamDisk}
+     */
+    public ByteBuffer getBuffer() {
+        return this.data.asReadOnlyBuffer();
+    }
+    
+    @Override
+    public void flush() throws IOException {
+        checkClosed();
+    }
+    
+    @Override
+    public int getSectorSize() {
+        checkClosed();
+        return this.sectorSize;
+    }
+
+    @Override
+    public void close() throws IOException {
+        this.closed = true;
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.closed;
+    }
+
+    private void checkClosed() {
+        if (closed) throw new IllegalStateException("device already closed");
+    }
+
+    /**
+     * Returns always {@code false}, as a {@code RamDisk} is always writable.
+     *
+     * @return always {@code false}
+     */
+    @Override
+    public boolean isReadOnly() {
+        checkClosed();
+        
+        return false;
+    }
+    
+}
diff --git a/src/main/java/de/waldheinz/fs/util/package-info.java b/src/main/java/de/waldheinz/fs/util/package-info.java
new file mode 100644
index 0000000..afde34e
--- /dev/null
+++ b/src/main/java/de/waldheinz/fs/util/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009,2010 Matthias Treydte <mt@waldheinz.de>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * Contains some utility classes that are useful independent of the file system
+ * type.
+ */
+package de.waldheinz.fs.util;
+
