diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/console/BlobStoreFixture.java oak-run/src/main/java/org/apache/jackrabbit/oak/console/BlobStoreFixture.java
new file mode 100644
index 0000000..18a30b1
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/console/BlobStoreFixture.java
@@ -0,0 +1,29 @@
+/*
+ * 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.jackrabbit.oak.console;
+
+import java.io.Closeable;
+
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+
+public interface BlobStoreFixture extends Closeable {
+
+    BlobStore getBlobStore();
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/console/Console.java oak-run/src/main/java/org/apache/jackrabbit/oak/console/Console.java
index 6a1ee3f..268468c 100644
--- oak-run/src/main/java/org/apache/jackrabbit/oak/console/Console.java
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/console/Console.java
@@ -31,6 +31,9 @@ import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
 import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
 import org.apache.jackrabbit.oak.plugins.document.rdb.RDBDataSourceFactory;
 import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
+import org.apache.jackrabbit.oak.run.cli.CommonOptions;
+import org.apache.jackrabbit.oak.run.cli.NodeStoreFixtureProvider;
+import org.apache.jackrabbit.oak.run.cli.Options;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.codehaus.groovy.tools.shell.IO;
@@ -49,91 +52,35 @@ public class Console {
 
     public static void main(String[] args) throws Exception {
         OptionParser parser = new OptionParser();
-        OptionSpec<Integer> clusterId = parser.accepts("clusterId", "MongoMK clusterId")
-                .withRequiredArg().ofType(Integer.class).defaultsTo(0);
+
         OptionSpec quiet = parser.accepts("quiet", "be less chatty");
         OptionSpec shell = parser.accepts("shell", "run the shell after executing files");
-        OptionSpec readWrite = parser.accepts("read-write", "connect to repository in read-write mode");
-        OptionSpec<String> fdsPathSpec = parser.accepts("fds-path", "Path to FDS store").withOptionalArg().defaultsTo("");
-        OptionSpec help = parser.acceptsAll(asList("h", "?", "help"), "show help").forHelp();
-
-        // RDB specific options
-        OptionSpec<String> rdbjdbcuser = parser.accepts("rdbjdbcuser", "RDB JDBC user").withOptionalArg().defaultsTo("");
-        OptionSpec<String> rdbjdbcpasswd = parser.accepts("rdbjdbcpasswd", "RDB JDBC password").withOptionalArg().defaultsTo("");
 
-        OptionSpec<String> nonOption = parser.nonOptions("console {<path-to-repository> | <mongodb-uri>}");
+        Options opts = new Options();
+        OptionSet options = opts.parseAndConfigure(parser, args);
 
-        OptionSet options = parser.parse(args);
-        List<String> nonOptions = nonOption.values(options);
-
-        if (options.has(help)) {
+        if (opts.getCommonOpts().isHelpRequested()) {
             parser.printHelpOn(System.out);
             System.exit(0);
         }
 
+        List<String> nonOptions = opts.getCommonOpts().getNonOptions();
         if (nonOptions.isEmpty()) {
             parser.printHelpOn(System.err);
             System.exit(1);
         }
 
-        BlobStore blobStore = null;
-        String fdsPath = fdsPathSpec.value(options);
-        if (!"".equals(fdsPath)) {
-            File fdsDir = new File(fdsPath);
-            if (fdsDir.exists()) {
-                FileDataStore fds = new FileDataStore();
-                fds.setPath(fdsDir.getAbsolutePath());
-                fds.init(null);
-
-                blobStore = new DataStoreBlobStore(fds);
-            }
-        }
-
-        boolean readOnly = !options.has(readWrite);
-
-        NodeStoreFixture fixture;
-        if (nonOptions.get(0).startsWith(MongoURI.MONGODB_PREFIX)) {
-            MongoClientURI uri = new MongoClientURI(nonOptions.get(0));
-            if (uri.getDatabase() == null) {
-                System.err.println("Database missing in MongoDB URI: " + uri.getURI());
-                System.exit(1);
-            }
-            MongoConnection mongo = new MongoConnection(uri.getURI());
-
-            DocumentMK.Builder builder = new DocumentMK.Builder()
-                    .setBlobStore(blobStore)
-                    .setMongoDB(mongo.getDB()).
-                    setClusterId(clusterId.value(options));
-            if (readOnly) {
-                builder.setReadOnlyMode();
-            }
-            DocumentNodeStore store = builder.getNodeStore();
-            fixture = new MongoFixture(store);
-        } else if (nonOptions.get(0).startsWith("jdbc")) {
-            DataSource ds = RDBDataSourceFactory.forJdbcUrl(nonOptions.get(0), rdbjdbcuser.value(options),
-                    rdbjdbcpasswd.value(options));
-            DocumentMK.Builder builder = new DocumentMK.Builder()
-                    .setBlobStore(blobStore)
-                    .setRDBConnection(ds).
-                    setClusterId(clusterId.value(options));
-            if (readOnly) {
-                builder.setReadOnlyMode();
-            }
-            DocumentNodeStore store = builder.getNodeStore();
-            fixture = new MongoFixture(store);
-        } else {
-            fixture = SegmentTarFixture.create(new File(nonOptions.get(0)), readOnly, blobStore);
-        }
+        NodeStoreFixture fixture = NodeStoreFixtureProvider.create(opts);
 
         List<String> scriptArgs = nonOptions.size() > 1 ?
-                nonOptions.subList(1, nonOptions.size()) : Collections.<String>emptyList();
+                opts.getCommonOpts().getNonOptions().subList(1, nonOptions.size()) : Collections.<String>emptyList();
         IO io = new IO();
 
         if(options.has(quiet)){
             io.setVerbosity(IO.Verbosity.QUIET);
         }
 
-        if (readOnly) {
+        if (!opts.getCommonOpts().isReadWrite()) {
             io.out.println("Repository connected in read-only mode. Use '--read-write' for write operations");
         }
 
@@ -151,22 +98,4 @@ public class Console {
 
         System.exit(code);
     }
-
-    private static class MongoFixture implements NodeStoreFixture {
-        private final DocumentNodeStore nodeStore;
-
-        private MongoFixture(DocumentNodeStore nodeStore) {
-            this.nodeStore = nodeStore;
-        }
-
-        @Override
-        public NodeStore getStore() {
-            return nodeStore;
-        }
-
-        @Override
-        public void close() throws IOException {
-            nodeStore.dispose();
-        }
-    }
 }
\ No newline at end of file
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/BlobStoreFixtureProvider.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/BlobStoreFixtureProvider.java
new file mode 100644
index 0000000..3ea9490
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/BlobStoreFixtureProvider.java
@@ -0,0 +1,136 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.annotation.CheckForNull;
+
+import com.google.common.collect.Maps;
+import com.google.common.io.Closer;
+import com.google.common.io.Files;
+import org.apache.commons.io.FileUtils;
+import org.apache.felix.cm.file.ConfigurationHandler;
+import org.apache.jackrabbit.core.data.DataStore;
+import org.apache.jackrabbit.core.data.DataStoreException;
+import org.apache.jackrabbit.oak.blob.cloud.aws.s3.SharedS3DataStore;
+import org.apache.jackrabbit.oak.blob.cloud.azure.blobstorage.AzureDataStore;
+import org.apache.jackrabbit.oak.console.BlobStoreFixture;
+import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore;
+import org.apache.jackrabbit.oak.plugins.blob.datastore.OakFileDataStore;
+import org.apache.jackrabbit.oak.run.cli.BlobStoreOptions.Type;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+
+import static org.apache.jackrabbit.oak.commons.PropertiesUtil.populate;
+
+public class BlobStoreFixtureProvider {
+
+    @CheckForNull
+    public static BlobStoreFixture create(Options options) throws Exception{
+        BlobStoreOptions bsopts = options.getOptionBean(BlobStoreOptions.class);
+
+        if (bsopts == null){
+            return null;
+        }
+
+        Type bsType = bsopts.getBlobStoreType();
+
+        if (bsType == Type.NONE){
+            return null;
+        }
+        Closer closer = Closer.create();
+        DataStore delegate;
+        if (bsType == Type.S3){
+            SharedS3DataStore s3ds = new SharedS3DataStore();
+            Properties props = loadAndTransformProps(bsopts.getS3ConfigPath());
+            s3ds.setProperties(props);
+            s3ds.init(null);
+            delegate = s3ds;
+        } else if(bsType == Type.AZURE){
+            AzureDataStore azureds = new AzureDataStore();
+            String cfgPath = bsopts.getAzureConfigPath();
+            Properties props = loadAndTransformProps(cfgPath);
+            azureds.setProperties(props);
+            File homeDir =  Files.createTempDir();
+            azureds.init(homeDir.getAbsolutePath());
+            closer.register(asCloseable(homeDir));
+            delegate = azureds;
+        } else {
+            delegate = new OakFileDataStore();
+            String cfgPath = bsopts.getFDSConfigPath();
+            Properties props = loadAndTransformProps(cfgPath);
+            populate(delegate, Maps.fromProperties(props), true);
+            delegate.init(null);
+        }
+        DataStoreBlobStore blobStore = new DataStoreBlobStore(delegate);
+        return new DataStoreFixture(blobStore, closer);
+    }
+
+    private static class DataStoreFixture implements BlobStoreFixture {
+        private final DataStoreBlobStore blobStore;
+        private final Closer closer;
+
+        private DataStoreFixture(DataStoreBlobStore blobStore, Closer closer) {
+            this.blobStore = blobStore;
+            this.closer = closer;
+        }
+
+        @Override
+        public BlobStore getBlobStore() {
+            return blobStore;
+        }
+
+        @Override
+        public void close() throws IOException {
+            closer.close();
+            try {
+                blobStore.close();
+            } catch (DataStoreException e) {
+                throw new IOException(e);
+            }
+        }
+    }
+
+    private static Properties loadAndTransformProps(String cfgPath) throws IOException {
+        Dictionary dict = ConfigurationHandler.read(new FileInputStream(cfgPath));
+        Properties props = new Properties();
+        Enumeration keys = dict.keys();
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            props.put(key, dict.get(key));
+        }
+        return props;
+    }
+
+    private static Closeable asCloseable(final File dir) {
+        return new Closeable() {
+            @Override
+            public void close() throws IOException {
+                FileUtils.deleteDirectory(dir);
+            }
+        };
+    }
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/BlobStoreOptions.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/BlobStoreOptions.java
new file mode 100644
index 0000000..488bd3d
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/BlobStoreOptions.java
@@ -0,0 +1,71 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+
+import static java.util.Arrays.asList;
+
+public class BlobStoreOptions implements OptionsBean {
+    public enum Type {FDS, S3, AZURE, NONE}
+    private final OptionSpec<String> fdsOption;
+    private final OptionSpec<String> s3Option;
+    private final OptionSpec<String> azureOption;
+    private OptionSet options;
+
+    public BlobStoreOptions(OptionParser parser){
+        fdsOption = parser.acceptsAll(asList("fds", "fds-path"), "FileDataStore config")
+                .withRequiredArg().ofType(String.class);
+        s3Option = parser.accepts("s3ds", "S3DataStore config")
+                .withRequiredArg().ofType(String.class);
+        azureOption = parser.accepts("azureblobds", "AzureBlobStorageDataStore config")
+                .withRequiredArg().ofType(String.class);
+    }
+
+    @Override
+    public void configure(OptionSet options) {
+        this.options = options;
+    }
+
+    public String getFDSConfigPath(){
+        return fdsOption.value(options);
+    }
+
+    public String getS3ConfigPath(){
+        return s3Option.value(options);
+    }
+
+    public String getAzureConfigPath(){
+        return azureOption.value(options);
+    }
+
+    public Type getBlobStoreType(){
+        if (options.has(fdsOption)){
+            return Type.FDS;
+        } else if (options.has(s3Option)){
+            return Type.S3;
+        } else if (options.has(azureOption)){
+            return Type.AZURE;
+        }
+        return Type.NONE;
+    }
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/CommonOptions.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/CommonOptions.java
new file mode 100644
index 0000000..230b460
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/CommonOptions.java
@@ -0,0 +1,75 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import java.util.List;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+
+import static java.util.Arrays.asList;
+
+public class CommonOptions implements OptionsBean {
+    private final OptionSpec<Void> help;
+    private final OptionSpec<Void> readWriteOption;
+    private final OptionSpec<String> nonOption;
+    private OptionSet options;
+
+    public CommonOptions(OptionParser parser){
+        help = parser.acceptsAll(asList("h", "?", "help"), "show help").forHelp();
+        readWriteOption = parser.accepts("read-write", "connect to repository in read-write mode");
+        nonOption = parser.nonOptions("{<path-to-repository> | <mongodb-uri>}");
+    }
+
+    @Override
+    public void configure(OptionSet options) {
+        this.options = options;
+    }
+
+    public boolean isHelpRequested(){
+        return options.has(help);
+    }
+
+    public boolean isReadWrite(){
+        return options.has(readWriteOption);
+    }
+
+    public List<String> getNonOptions(){
+        return nonOption.values(options);
+    }
+
+    public boolean isMongo(){
+        return getStoreArg().startsWith("mongodb://");
+    }
+
+    public boolean isRDB(){
+        return getStoreArg().startsWith("jdbc");
+    }
+
+    public boolean isSegment(){
+        return !isMongo() && !isRDB();
+    }
+
+    public String getStoreArg() {
+        List<String> nonOptions = nonOption.values(options);
+        return nonOptions.size() > 0 ? nonOptions.get(0) : "";
+    }
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/DocumentNodeStoreOptions.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/DocumentNodeStoreOptions.java
new file mode 100644
index 0000000..8b6ecbf
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/DocumentNodeStoreOptions.java
@@ -0,0 +1,58 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+
+public class DocumentNodeStoreOptions implements OptionsBean {
+    private final OptionSpec<Integer> clusterId;
+    private final OptionSpec<Void> disableBranchesSpec;
+    private final OptionSpec<Integer> cacheSizeSpec;
+    private OptionSet options;
+
+    public DocumentNodeStoreOptions(OptionParser parser){
+        clusterId = parser.accepts("clusterId", "MongoMK clusterId")
+                .withRequiredArg().ofType(Integer.class).defaultsTo(0);
+        disableBranchesSpec = parser.
+                accepts("disableBranches", "disable branches");
+        cacheSizeSpec = parser.
+                accepts("cacheSize", "cache size")
+                .withRequiredArg().ofType(Integer.class).defaultsTo(0);
+    }
+
+    @Override
+    public void configure(OptionSet options) {
+        this.options = options;
+    }
+
+    public int getClusterId(){
+        return clusterId.value(options);
+    }
+
+    public int getCacheSize() {
+        return cacheSizeSpec.value(options);
+    }
+
+    public boolean disableBranchesSpec() {
+        return options.has(disableBranchesSpec);
+    }
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/NodeStoreFixtureProvider.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/NodeStoreFixtureProvider.java
new file mode 100644
index 0000000..cbab8d3
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/NodeStoreFixtureProvider.java
@@ -0,0 +1,175 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.net.UnknownHostException;
+
+import javax.sql.DataSource;
+
+import com.google.common.io.Closer;
+import com.mongodb.MongoClientURI;
+import org.apache.jackrabbit.oak.console.BlobStoreFixture;
+import org.apache.jackrabbit.oak.console.NodeStoreFixture;
+import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
+import org.apache.jackrabbit.oak.plugins.document.rdb.RDBDataSourceFactory;
+import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
+import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
+import org.apache.jackrabbit.oak.segment.file.ReadOnlyFileStore;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+
+import static org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder;
+
+public class NodeStoreFixtureProvider {
+    private static final long MB = 1024 * 1024;
+
+    public static NodeStoreFixture create(Options options) throws Exception {
+        return create(options, !options.getOptionBean(CommonOptions.class).isReadWrite());
+    }
+
+    public static NodeStoreFixture create(Options options, boolean readOnly) throws Exception {
+        CommonOptions commonOpts = options.getOptionBean(CommonOptions.class);
+
+        Closer closer = Closer.create();
+        BlobStoreFixture blobFixture = BlobStoreFixtureProvider.create(options);
+        BlobStore blobStore = null;
+        if (blobFixture != null) {
+            blobStore = blobFixture.getBlobStore();
+            closer.register(blobFixture);
+        }
+
+        NodeStore store = null;
+        if (commonOpts.isMongo() || commonOpts.isRDB()) {
+            store = configureDocumentMk(options, blobStore, closer, readOnly);
+        } else {
+            store = configureSegment(options, blobStore, closer, readOnly);
+        }
+
+        return new SimpleNodeStoreFixture(store, closer);
+    }
+
+
+    private static NodeStore configureDocumentMk(Options options,
+                                                 BlobStore blobStore, Closer closer,
+                                                 boolean readOnly) throws UnknownHostException {
+        DocumentMK.Builder builder = new DocumentMK.Builder();
+
+        if (blobStore != null) {
+            builder.setBlobStore(blobStore);
+        }
+
+        DocumentNodeStoreOptions docStoreOpts = options.getOptionBean(DocumentNodeStoreOptions.class);
+
+        builder.setClusterId(docStoreOpts.getClusterId());
+
+        if (readOnly) {
+            builder.setReadOnlyMode();
+        }
+
+        int cacheSize = docStoreOpts.getCacheSize();
+        if (cacheSize != 0) {
+            builder.memoryCacheSize(cacheSize * MB);
+        }
+
+        if (docStoreOpts.disableBranchesSpec()) {
+            builder.disableBranches();
+        }
+
+        CommonOptions commonOpts = options.getOptionBean(CommonOptions.class);
+
+        if (commonOpts.isMongo()) {
+            MongoClientURI uri = new MongoClientURI(commonOpts.getStoreArg());
+            if (uri.getDatabase() == null) {
+                System.err.println("Database missing in MongoDB URI: "
+                        + uri.getURI());
+                System.exit(1);
+            }
+            MongoConnection mongo = new MongoConnection(uri.getURI());
+            closer.register(asCloseable(mongo));
+            builder.setMongoDB(mongo.getDB());
+        } else if (commonOpts.isRDB()) {
+            RDBStoreOptions rdbOpts = options.getOptionBean(RDBStoreOptions.class);
+            DataSource ds = RDBDataSourceFactory.forJdbcUrl(commonOpts.getStoreArg(),
+                    rdbOpts.getUser(), rdbOpts.getPassword());
+            builder.setRDBConnection(ds);
+        }
+
+        return builder.getNodeStore();
+    }
+
+    private static NodeStore configureSegment(Options options, BlobStore blobStore, Closer closer, boolean readOnly)
+            throws IOException, InvalidFileStoreVersionException {
+
+        String path = options.getOptionBean(CommonOptions.class).getStoreArg();
+        FileStoreBuilder builder = fileStoreBuilder(new File(path)).withMaxFileSize(256);
+
+        if (blobStore != null) {
+            builder.withBlobStore(blobStore);
+        }
+
+        NodeStore nodeStore;
+        if (readOnly) {
+            ReadOnlyFileStore fileStore = builder.buildReadOnly();
+            closer.register(fileStore);
+            nodeStore = SegmentNodeStoreBuilders.builder(fileStore).build();
+        } else {
+            FileStore fileStore = builder.build();
+            closer.register(fileStore);
+            nodeStore = SegmentNodeStoreBuilders.builder(fileStore).build();
+        }
+
+        return nodeStore;
+    }
+
+    private static Closeable asCloseable(final MongoConnection con) {
+        return new Closeable() {
+            @Override
+            public void close() throws IOException {
+                con.close();
+            }
+        };
+    }
+
+    private static class SimpleNodeStoreFixture implements NodeStoreFixture {
+        private final Closer closer;
+        private final NodeStore nodeStore;
+
+        private SimpleNodeStoreFixture(NodeStore nodeStore, Closer closer) {
+            this.closer = closer;
+            this.nodeStore = nodeStore;
+        }
+
+        @Override
+        public NodeStore getStore() {
+            return nodeStore;
+        }
+
+        @Override
+        public void close() throws IOException {
+            closer.close();
+        }
+    }
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionBeans.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionBeans.java
new file mode 100644
index 0000000..b745525
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionBeans.java
@@ -0,0 +1,50 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import joptsimple.OptionParser;
+
+public enum OptionBeans implements OptionsBeanFactory {
+
+    RDB_STORE {
+        @Override
+        public OptionsBean newInstance(OptionParser parser){
+            return new RDBStoreOptions(parser);
+        }
+    },
+    DOCUMENT_NODE_STORE {
+        @Override
+        public OptionsBean newInstance(OptionParser parser){
+            return new DocumentNodeStoreOptions(parser);
+        }
+    },
+    COMMON {
+        @Override
+        public OptionsBean newInstance(OptionParser parser){
+            return new CommonOptions(parser);
+        }
+    },
+    BLOB_STORE {
+        @Override
+        public OptionsBean newInstance(OptionParser parser){
+            return new BlobStoreOptions(parser);
+        }
+    }
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/Options.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/Options.java
new file mode 100644
index 0000000..d41cee0
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/Options.java
@@ -0,0 +1,83 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.MutableClassToInstanceMap;
+import com.google.common.collect.Sets;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Arrays.asList;
+
+public class Options {
+    private final Set<OptionsBeanFactory> beanFactories = Sets.newHashSet();
+    private final EnumSet<OptionBeans> oakRunOptions;
+    private final ClassToInstanceMap<OptionsBean> optionBeans = MutableClassToInstanceMap.create();
+    private OptionSet optionSet;
+
+    public Options(){
+        this.oakRunOptions = EnumSet.allOf(OptionBeans.class);
+    }
+
+    public Options(OptionBeans... options) {
+        this.oakRunOptions = Sets.newEnumSet(asList(options), OptionBeans.class);
+    }
+
+    public OptionSet parseAndConfigure(OptionParser parser, String[] args){
+        for (OptionsBeanFactory o : Iterables.concat(oakRunOptions, beanFactories)){
+            OptionsBean bean = o.newInstance(parser);
+            optionBeans.put(bean.getClass(), bean);
+        }
+        optionSet = parser.parse(args);
+        configure(optionSet);
+        return optionSet;
+    }
+
+    public OptionSet getOptionSet() {
+        return optionSet;
+    }
+
+    public <T extends OptionsBean> T getOptionBean(Class<T> clazz){
+        Object o = optionBeans.get(clazz);
+        checkNotNull(o, "No [%s] found in [%s]",
+                clazz.getSimpleName(), optionBeans);
+        return (T) o;
+    }
+
+    public void registerOptionsFactory(OptionsBeanFactory factory){
+        beanFactories.add(factory);
+    }
+
+    public CommonOptions getCommonOpts(){
+        return getOptionBean(CommonOptions.class);
+    }
+
+    private void configure(OptionSet optionSet){
+        for (OptionsBean bean : optionBeans.values()){
+            bean.configure(optionSet);
+        }
+    }
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionsBean.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionsBean.java
new file mode 100644
index 0000000..4ee7b83
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionsBean.java
@@ -0,0 +1,27 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import joptsimple.OptionSet;
+
+public interface OptionsBean {
+
+    void configure(OptionSet options);
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionsBeanFactory.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionsBeanFactory.java
new file mode 100644
index 0000000..e59196c
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/OptionsBeanFactory.java
@@ -0,0 +1,27 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import joptsimple.OptionParser;
+
+public interface OptionsBeanFactory {
+
+    OptionsBean newInstance(OptionParser parser);
+}
diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/RDBStoreOptions.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/RDBStoreOptions.java
new file mode 100644
index 0000000..239c6bd
--- /dev/null
+++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/cli/RDBStoreOptions.java
@@ -0,0 +1,48 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+
+public class RDBStoreOptions implements OptionsBean {
+    private final OptionSpec<String> rdbjdbcuser;
+    private final OptionSpec<String> rdbjdbcpasswd;
+    private OptionSet options;
+
+    public RDBStoreOptions(OptionParser parser){
+        rdbjdbcuser = parser.accepts("rdbjdbcuser", "RDB JDBC user").withOptionalArg().defaultsTo("");
+        rdbjdbcpasswd = parser.accepts("rdbjdbcpasswd", "RDB JDBC password").withOptionalArg().defaultsTo("");
+    }
+
+    @Override
+    public void configure(OptionSet options) {
+        this.options = options;
+    }
+
+    public String getUser(){
+        return rdbjdbcuser.value(options);
+    }
+
+    public String getPassword(){
+        return rdbjdbcpasswd.value(options);
+    }
+}
diff --git oak-run/src/test/java/org/apache/jackrabbit/oak/run/cli/OptionsTest.java oak-run/src/test/java/org/apache/jackrabbit/oak/run/cli/OptionsTest.java
new file mode 100644
index 0000000..3f88850
--- /dev/null
+++ oak-run/src/test/java/org/apache/jackrabbit/oak/run/cli/OptionsTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jackrabbit.oak.run.cli;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class OptionsTest {
+
+    @Test
+    public void noArgs() throws Exception{
+        OptionParser parser = new OptionParser();
+        Options opts = new Options();
+        opts.parseAndConfigure(parser, new String[]{});
+        assertNotNull(opts.getCommonOpts());
+    }
+
+    @Test
+    public void help() throws Exception{
+        OptionParser parser = new OptionParser();
+        Options opts = new Options();
+        opts.parseAndConfigure(parser, new String[]{"-h"});
+        assertTrue(opts.getCommonOpts().isHelpRequested());
+
+    }
+
+}
\ No newline at end of file
