diff --git a/pom.xml b/pom.xml
index 349146e..2a767db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -117,5 +117,17 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-simple</artifactId>
         </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.8.2</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
index 5fadb1e..1281495 100644
--- a/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
+++ b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
@@ -18,6 +18,8 @@
  */
 package org.apache.sling.settings.impl;
 
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -77,6 +79,9 @@
     /** The name of the data file holding install run mode options */
     private static final String OPTIONS_FILE = "sling.options.file";
 
+    /** The length in bytes of a sling identifier */
+    private static final int SLING_ID_LENGTH = 36;
+
     /** The properties for name, description. */
     private final Map<String, String> slingProps = new HashMap<String, String>();
 
@@ -124,7 +129,7 @@
             // the osgi framework does not support storing something in the file system
             throw new RuntimeException("Unable to read from bundle data file.");
         }
-        this.slingId = this.readSlingId(idFile);
+        this.slingId = this.readSlingId(idFile, SLING_ID_LENGTH);
 
         // no sling id yet or failure to read file: create an id and store
         if (slingId == null) {
@@ -147,7 +152,7 @@
         }
     }
 
-    private static final class Options implements Serializable {
+    static final class Options implements Serializable {
         private static final long serialVersionUID = 1L;
         String[] modes;
         String   selected;
@@ -263,7 +268,7 @@
         return optionsList;
     }
 
-    private void writeOptions(final BundleContext context, final List<Options> optionsList) {
+    void writeOptions(final BundleContext context, final List<Options> optionsList) {
         final File file = context.getDataFile(OPTIONS_FILE);
         FileOutputStream fos = null;
         ObjectOutputStream oos = null;
@@ -286,30 +291,28 @@
     /**
      * Read the id from a file.
      */
-    private String readSlingId(final File idFile) {
-        if (idFile.exists() && idFile.length() >= 36) {
-            FileInputStream fin = null;
+    String readSlingId(final File idFile, int maxLength) {
+        if (idFile.exists() && idFile.length() >= maxLength) {
+            DataInputStream dis = null;
             try {
-                fin = new FileInputStream(idFile);
-                final byte[] rawBytes = new byte[36];
-                if (fin.read(rawBytes) == 36) {
-                    final String rawString = new String(rawBytes, "ISO-8859-1");
+                final byte[] rawBytes = new byte[maxLength];
+                dis = new DataInputStream(new FileInputStream(idFile));
+                dis.readFully(rawBytes);
+                final String rawString = new String(rawBytes, "ISO-8859-1");
 
-                    // roundtrip to ensure correct format of UUID value
-                    final String id = UUID.fromString(rawString).toString();
-                    logger.debug("Got Sling ID {} from file {}", id, idFile);
+                // roundtrip to ensure correct format of UUID value
+                final String id = UUID.fromString(rawString).toString();
+                logger.debug("Got Sling ID {} from file {}", id, idFile);
 
-                    return id;
-                }
+                return id;
             } catch (final Throwable t) {
                 logger.error("Failed reading UUID from id file " + idFile
                         + ", creating new id", t);
             } finally {
-                if (fin != null) {
+                if (dis != null) {
                     try {
-                        fin.close();
-                    } catch (IOException ignore) {
-                    }
+                        dis.close();
+                    } catch (IOException ignore){}
                 }
             }
         }
@@ -319,22 +322,22 @@
     /**
      * Write the sling id file.
      */
-    private void writeSlingId(final File idFile, final String id) {
+    void writeSlingId(final File idFile, final String id) {
         idFile.delete();
         idFile.getParentFile().mkdirs();
-        FileOutputStream fout = null;
+        DataOutputStream dos = null;
         try {
-            fout = new FileOutputStream(idFile);
-            fout.write(slingId.getBytes("ISO-8859-1"));
-            fout.flush();
+            final byte[] rawBytes = id.getBytes("ISO-8859-1");
+            dos = new DataOutputStream(new FileOutputStream(idFile));
+            dos.write(rawBytes, 0, rawBytes.length);
+            dos.flush();
         } catch (final Throwable t) {
             logger.error("Failed writing UUID to id file " + idFile, t);
         } finally {
-            if (fout != null) {
+            if (dos != null) {
                 try {
-                    fout.close();
-                } catch (IOException ignore) {
-                }
+                    dos.close();
+                } catch (IOException ignore) {}
             }
         }
     }
diff --git a/src/test/java/org/apache/sling/settings/impl/SlingSettingsServiceImplTest.java b/src/test/java/org/apache/sling/settings/impl/SlingSettingsServiceImplTest.java
new file mode 100644
index 0000000..81e3dd1
--- /dev/null
+++ b/src/test/java/org/apache/sling/settings/impl/SlingSettingsServiceImplTest.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.settings.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.RandomStringUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.apache.sling.launchpad.api.StartupHandler;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+
+public class SlingSettingsServiceImplTest {
+
+    private static final String SLING_ID_FILE_NAME = "sling.id.file";
+
+    private static final String OPTIONS_FILE_NAME = "sling.options.file";
+
+    private static final String SLING_ID = "097bae9b-bf60-45a2-ad8c-ccdd374dd9b0";
+
+    private File slingIdFile = null;
+
+    private File optionsFile = null;
+
+    @Before
+    public void before() throws IOException {
+        slingIdFile = File.createTempFile(
+                SLING_ID_FILE_NAME, "");
+        optionsFile = File.createTempFile(
+                OPTIONS_FILE_NAME, "");
+    }
+
+    @After
+    public void after() throws IOException {
+        if (slingIdFile != null ) {
+            slingIdFile.delete();
+            slingIdFile = null;
+        }
+        if (optionsFile != null) {
+            optionsFile.delete();
+            optionsFile = null;
+        }
+    }
+
+    @Test
+    public void testGenerateSlingId()
+            throws IOException {
+        String slingId =  readSlingId(slingIdFile, optionsFile, SLING_ID.length());
+        Assert.assertNotNull(slingId);
+    }
+
+    @Test
+    public void testGetSlingId()
+            throws IOException {
+        writeSlingId(slingIdFile, optionsFile, SLING_ID);
+        String generated =  readSlingId(slingIdFile, optionsFile, SLING_ID.length());
+        Assert.assertNotNull(generated);
+        Assert.assertEquals(SLING_ID, generated);
+        String slingId = readSlingId(slingIdFile, optionsFile, SLING_ID.length());
+        Assert.assertNotNull(slingId);
+        Assert.assertEquals(generated, slingId);
+    }
+
+    @Test
+    public void testGetLongSlingIdFromTooLargeData()
+            throws IOException {
+        String data = SLING_ID + RandomStringUtils.randomAscii(1024 * 1024); // 1MB long random String
+        writeSlingId(slingIdFile, optionsFile, data);
+        String slingId =  readSlingId(slingIdFile, optionsFile, SLING_ID.length());
+        Assert.assertNotNull(slingId);
+        Assert.assertEquals(SLING_ID, slingId);
+    }
+
+    @Test
+    public void testGetSlingIdFromTooShortData()
+            throws IOException {
+        String data = RandomStringUtils.randomAscii(8); // 8 byte long string
+        writeSlingId(slingIdFile, optionsFile, data);
+        String slingId =  readSlingId(slingIdFile, optionsFile, SLING_ID.length());
+        Assert.assertNotNull(slingId);
+        Assert.assertNotEquals(SLING_ID, slingId);
+    }
+
+    private String readSlingId(File slingIdFile, File optionsFile, int maxLength)
+            throws IOException {
+        SlingSettingsServiceImpl settings = getSlingSettings(slingIdFile, optionsFile);
+        return settings.readSlingId(slingIdFile, maxLength);
+    }
+
+    private void writeSlingId(File slingIdFile, File optionsFile, String slingId)
+            throws IOException {
+        SlingSettingsServiceImpl settings = getSlingSettings(slingIdFile, optionsFile);
+        settings.writeSlingId(slingIdFile, slingId);
+    }
+
+    private SlingSettingsServiceImpl getSlingSettings(File slingIdFile, File optionsFile)
+            throws IOException {
+        BundleContext context = Mockito.mock(BundleContext.class);
+        Mockito.when(context.getDataFile(SLING_ID_FILE_NAME))
+                .thenReturn(slingIdFile);
+        Mockito.when(context.getDataFile(OPTIONS_FILE_NAME))
+                .thenReturn(optionsFile);
+        StartupHandler handler = Mockito.mock(StartupHandler.class);
+        // write options
+        List<SlingSettingsServiceImpl.Options> options = new ArrayList<SlingSettingsServiceImpl.Options>();
+        FileOutputStream fos = null;
+        ObjectOutputStream oos = null;
+        try {
+            fos = new FileOutputStream(optionsFile);
+            oos = new ObjectOutputStream(fos);
+            oos.writeObject(options);
+        } catch ( final IOException ioe ) {
+            throw new RuntimeException("Unable to write to options data file.", ioe);
+        } finally {
+            if ( oos != null ) {
+                try {
+                    oos.close();
+                } catch (IOException ignore) {
+                    // ...
+                }
+            }
+            if ( fos != null ) {
+                try {
+                    fos.close();
+                } catch (IOException ignore) {
+                    // ...
+                }
+            }
+        }
+        return new SlingSettingsServiceImpl(context, handler);
+    }
+}
