diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..91b28c7
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>9</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.settings</artifactId>
+    <packaging>bundle</packaging>
+    <version>0.1.0-SNAPSHOT</version>
+
+    <name>Apache Sling Settings</name>
+    <description>
+        Settings support including run modes
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/settings
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/settings
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/settings
+        </url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.apache.sling.settings
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.sling.settings.impl
+                        </Private-Package>
+                        <Bundle-Activator>
+                            org.apache.sling.settings.impl.Activator
+                        </Bundle-Activator>
+                        <Import-Package>
+                            javax.servlet.*;
+                            org.apache.felix.shell;
+                            org.apache.felix.webconsole;
+                            resolution:=optional, *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.shell</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.webconsole</artifactId>
+            <version>1.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/settings/SlingSettingsService.java b/src/main/java/org/apache/sling/settings/SlingSettingsService.java
new file mode 100644
index 0000000..97c8fcc
--- /dev/null
+++ b/src/main/java/org/apache/sling/settings/SlingSettingsService.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import java.net.URL;
+
+/**
+ * The <code>SlingSettingsService</code> provides basic Sling settings.
+ *
+ */
+public interface SlingSettingsService {
+
+    /**
+     * The name of the framework property defining the Sling home directory
+     * (value is "sling.home"). This is a Platform file system directory below
+     * which all runtime data, such as the Felix bundle archives, logfiles, the
+     * repository, etc., is located.
+     * <p>
+     * This property is available calling the
+     * <code>BundleContext.getProperty(String)</code> method.
+     *
+     * @see #SLING_HOME_URL
+     */
+    String SLING_HOME = "sling.home";
+
+    /**
+     * The name of the framework property defining the Sling home directory as
+     * an URL (value is "sling.home.url").
+     * <p>
+     * The value of this property is assigned the value of
+     * <code>new File(${sling.home}).toURI().toString()</code> before
+     * resolving the property variables.
+     * <p>
+     * This property is available calling the
+     * <code>BundleContext.getProperty(String)</code> method.
+     *
+     * @see #SLING_HOME
+     */
+    String SLING_HOME_URL = "sling.home.url";
+
+    /**
+     * The identifier of the running Sling instance.
+     */
+    String getSlingId();
+
+    /**
+     * Returns the value of the {@link #SLING_HOME}
+     * property.
+     */
+    String getSlingHomePath();
+
+    /**
+     * Returns the value of the {@link #SLING_HOME_URL}
+     * property.
+     */
+    URL getSlingHome();
+}
diff --git a/src/main/java/org/apache/sling/settings/impl/Activator.java b/src/main/java/org/apache/sling/settings/impl/Activator.java
new file mode 100644
index 0000000..cb3b522
--- /dev/null
+++ b/src/main/java/org/apache/sling/settings/impl/Activator.java
@@ -0,0 +1,64 @@
+/*
+ * 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.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.sling.settings.SlingSettingsService;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * This is the bundle activator.
+ * It registers the SlingSettingsService.
+ *
+ */
+public class Activator implements BundleActivator {
+
+    /** The service registration */
+    private ServiceRegistration serviceRegistration;
+
+    /**
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext context) throws Exception {
+        final Object service = new SlingSettingsServiceImpl(context);
+        final Dictionary<String, String> props = new Hashtable<String, String>();
+        props.put(Constants.SERVICE_PID, service.getClass().getName());
+        props.put(Constants.SERVICE_DESCRIPTION,
+            "Apache Sling Settings Service");
+        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+        serviceRegistration = context.registerService(new String[] {
+                                               SlingSettingsService.class.getName()},
+                                           service, props);
+    }
+
+    /**
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) throws Exception {
+        if ( serviceRegistration != null ) {
+            serviceRegistration.unregister();
+            serviceRegistration = null;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
new file mode 100644
index 0000000..b8fdf7f
--- /dev/null
+++ b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
@@ -0,0 +1,184 @@
+/*
+ * 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.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.UUID;
+
+import org.apache.sling.settings.SlingSettingsService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the basic implementation of the sling settings service.
+ */
+public class SlingSettingsServiceImpl
+    implements SlingSettingsService {
+
+    /** The logger */
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /** The sling instance id. */
+    private String slingId;
+
+    /** The sling home */
+    private final String slingHome;
+
+    /** The sling home url */
+    private URL slingHomeUrl;
+
+    private static final String DATA_FILE = "sling.id.file";
+
+    /**
+     * Create the service and search the Sling home urls and
+     * get/create a sling id.
+     * @param context The bundle context
+     */
+    public SlingSettingsServiceImpl(final BundleContext context) {
+        // get sling home and sling home url
+        this.slingHome = context.getProperty(SLING_HOME);
+        final String url = context.getProperty(SLING_HOME_URL);
+        if ( url != null ) {
+            try {
+                this.slingHomeUrl = new URL(url);
+            } catch (MalformedURLException e) {
+                logger.error("Sling home url is not a url: {}", url);
+            }
+        }
+
+        // try to read the id from the id file first
+        final File idFile = context.getDataFile(DATA_FILE);
+        if ( idFile == null ) {
+            // 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);
+
+        // if we don't have an id yet, we look for the engine bundle for compatibility reasons
+        if ( this.slingId == null ) {
+            final Bundle engineBundle = this.searchEngineBundle(context);
+            if ( engineBundle != null ) {
+                final File engineIdFile = engineBundle.getBundleContext().getDataFile(DATA_FILE);
+                this.slingId = this.readSlingId(engineIdFile);
+                if ( this.slingId != null ) {
+                    // delete the old file
+                    engineIdFile.delete();
+                    this.writeSlingId(idFile, this.slingId);
+                }
+            }
+        }
+
+        // no sling id yet or failure to read file: create an id and store
+        if (slingId == null) {
+            slingId = UUID.randomUUID().toString();
+            this.writeSlingId(idFile, this.slingId);
+        }
+    }
+
+    /** Read the id from a file. */
+    private String readSlingId(final File idFile) {
+        if (idFile.exists() && idFile.length() >= 36) {
+            FileInputStream fin = 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");
+
+                    // 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;
+                }
+            } catch (Throwable t) {
+                logger.error("Failed reading UUID from id file " + idFile
+                        + ", creating new id", t);
+            } finally {
+                if (fin != null) {
+                    try {
+                        fin.close();
+                    } catch (IOException ignore) {
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /** Write the sling id file. */
+    private void writeSlingId(final File idFile, final String id) {
+        idFile.delete();
+        idFile.getParentFile().mkdirs();
+        FileOutputStream fout = null;
+        try {
+            fout = new FileOutputStream(idFile);
+            fout.write(slingId.getBytes("ISO-8859-1"));
+            fout.flush();
+        } catch (Throwable t) {
+            logger.error("Failed writing UUID to id file " + idFile, t);
+        } finally {
+            if (fout != null) {
+                try {
+                    fout.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    }
+
+    /** Search the engine bundle. */
+    private Bundle searchEngineBundle(final BundleContext bc) {
+        final Bundle[] bundles = bc.getBundles();
+        for(final Bundle b : bundles) {
+            if ( "org.apache.sling.engine".equals(b.getSymbolicName()) ) {
+                return b;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see org.apache.sling.settings.SlingSettingsService#getSlingId()
+     */
+    public String getSlingId() {
+        return this.slingId;
+    }
+
+    /**
+     * @see org.apache.sling.settings.SlingSettingsService#getSlingHome()
+     */
+    public URL getSlingHome() {
+        return this.slingHomeUrl;
+    }
+
+    /**
+     * @see org.apache.sling.settings.SlingSettingsService#getSlingHomePath()
+     */
+    public String getSlingHomePath() {
+        return this.slingHome;
+    }
+}
