diff --git a/src/main/src/main/java/org/apache/karaf/main/Main.java b/src/main/src/main/java/org/apache/karaf/main/Main.java
index 630b71e..69ced57 100644
--- a/src/main/src/main/java/org/apache/karaf/main/Main.java
+++ b/src/main/src/main/java/org/apache/karaf/main/Main.java
@@ -18,7 +18,16 @@
  */
 package org.apache.karaf.main;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
 import java.lang.management.ManagementFactory;
 import java.lang.management.RuntimeMXBean;
 import java.net.InetAddress;
@@ -130,6 +139,10 @@ public class Main {
      * The system property for holding the Karaf version.
      */
     public static final String PROP_KARAF_VERSION = "karaf.version";
+    /**
+     * The system property for holding the Karaf command line arguments parsing feature.
+     */
+    public static final String PROP_KARAF_ARGS_PARSE = "karaf.args.parse";
 
     /**
      * Config property which identifies directories which contain bundles to be loaded by SMX
@@ -199,6 +212,7 @@ public class Main {
     private int shutdownTimeout = 5 * 60 * 1000;
     private boolean exiting = false;
     private ShutdownCallback shutdownCallback;
+    private boolean argsParse = true;
 
     public Main(String[] args) {
         this.args = args;
@@ -222,7 +236,7 @@ public class Main {
         System.setProperty(PROP_KARAF_BASE, karafBase.getPath());
         System.setProperty(PROP_KARAF_DATA, karafData.getPath());
         System.setProperty(PROP_KARAF_INSTANCES, karafInstances.getPath());
-
+        
         // Load system properties.
         loadSystemProperties(karafBase);
 
@@ -255,6 +269,49 @@ public class Main {
         lockDelay = Integer.parseInt(configProps.getProperty(PROPERTY_LOCK_DELAY, Integer.toString(lockDelay)));
         configProps.setProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, Integer.toString(lockStartLevel));
         shutdownTimeout = Integer.parseInt(configProps.getProperty(KARAF_SHUTDOWN_TIMEOUT, Integer.toString(shutdownTimeout)));
+        argsParse = Boolean.parseBoolean(configProps.getProperty(PROP_KARAF_ARGS_PARSE, "true"));
+
+        // Parse command line arguments... if not disabled
+        if (argsParse) {
+	        boolean executeCommands = false;
+	        boolean batchMode = false;
+	    	StringBuilder commands = new StringBuilder();
+	    	for (int i = 0; i < args.length; i++) {
+	    		String arg = args[i];
+	    		if (!arg.startsWith("-"))
+	    			break;
+	    		if (arg.equals("-c")) {
+	    			i++;
+	    			commands.append(args[i] + "\n");
+	    			executeCommands = true;
+	    		}
+	    		if (arg.startsWith("--command=")) {
+	    			commands.append(arg.substring(10) + "\n");
+	    			executeCommands = true;
+	    		}
+	    		if (arg.equals("-b") || arg.equals("--batch")) {
+	    			batchMode = true;
+	    			executeCommands = true;
+	    		}
+	    	}
+	    	if (batchMode) {
+	    		// Read commands from stdin
+	    		BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in));
+	    		String line = inReader.readLine();
+	    		while (line != null) {
+	    			commands.append(line + "\n");
+	    			line = inReader.readLine();
+	    		}
+	    	}
+	        if (executeCommands) {
+	        	System.setProperty("karaf.commands", commands.toString());
+	        	System.setProperty("karaf.executeCommands", "true");
+	            // Disable console and SSH if in exec or batch mode
+		        System.setProperty("karaf.startLocalConsole", "false");
+		        System.setProperty("karaf.startRemoteShell", "false");
+	        }
+        }
+
         // Start up the OSGI framework
 
         String factoryClass = configProps.getProperty(KARAF_FRAMEWORK_FACTORY);
@@ -277,6 +334,9 @@ public class Main {
                 lock(configProps);
             }
         }.start();
+        
+        
+        
     }
 
     public void awaitShutdown() throws Exception {
diff --git a/src/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java b/src/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
index 573b0e7..1e86d6b 100644
--- a/src/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
+++ b/src/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
@@ -23,24 +23,53 @@ import java.io.OutputStream;
 import java.io.PrintStream;
 import java.lang.reflect.Method;
 import java.security.PrivilegedExceptionAction;
+import java.util.Hashtable;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 import javax.security.auth.Subject;
 
 import jline.Terminal;
+
 import org.apache.felix.service.command.CommandProcessor;
 import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Converter;
 import org.apache.felix.service.command.Function;
 import org.apache.karaf.jaas.modules.UserPrincipal;
 import org.fusesource.jansi.AnsiConsole;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.blueprint.container.BlueprintEvent;
+import org.osgi.service.blueprint.container.BlueprintListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class ConsoleFactory {
+public class ConsoleFactory implements BundleListener, ServiceListener, BlueprintListener {
 
+	private transient Logger log = LoggerFactory.getLogger(ConsoleFactory.class);
     private BundleContext bundleContext;
     private CommandProcessor commandProcessor;
     private TerminalFactory terminalFactory;
     private Console console;
     private boolean start;
+    private RuntimeStatus runtimeStatus = new RuntimeStatus();
+    private AtomicBoolean executorInvoked = new AtomicBoolean(false);
+    private ServiceRegistration blueprintListenerReg;
+    
+	class RuntimeStatus {
+		public int events;
+		public int activeServices;
+		public int unstableBundles;
+		public int unstableBlueprints;
+    }
 
     public void setBundleContext(BundleContext bundleContext) {
         this.bundleContext = bundleContext;
@@ -49,6 +78,8 @@ public class ConsoleFactory {
     public synchronized void registerCommandProcessor(CommandProcessor commandProcessor) throws Exception {
         this.commandProcessor = commandProcessor;
         start();
+        if (Boolean.getBoolean("karaf.executeCommands"))
+        	prepareExecuteCommands();
     }
 
     public synchronized void unregisterCommandProcessor(CommandProcessor commandProcessor) throws Exception {
@@ -138,4 +169,166 @@ public class ConsoleFactory {
             return stream;
         }
     }
+
+    /**
+     * Sets up listeners to monitor the runtime state, waits until the runtime
+     * is "stable" (all services and bundles are active, etc.) then invokes the commands executor.
+     */
+    private void prepareExecuteCommands() {
+    	Bundle[] bundles = bundleContext.getBundles();
+    	synchronized (runtimeStatus) {
+    		// Temporarily add self as listeners
+        	bundleContext.addBundleListener(this);
+        	bundleContext.addServiceListener(this);
+        	// Get current number of unstable bundles
+	    	for (Bundle bundle : bundles) {
+	    		if (bundle.getState() == Bundle.STARTING || bundle.getState() == Bundle.STOPPING) {
+	    			runtimeStatus.unstableBundles++;
+	    		}
+	    	}
+	    	// Get current number of active services
+			try {
+				ServiceReference[] services = bundleContext.getAllServiceReferences(null, null);
+				runtimeStatus.activeServices = services.length;
+			} catch (InvalidSyntaxException e) {
+			}
+    	}
+    	// Register Blueprint listener, must be last to avoid deadlock on runtimeStatus
+    	blueprintListenerReg = bundleContext.registerService(BlueprintListener.class.getName(), this, new Hashtable<String, String>());
+	}
+
+	public void bundleChanged(BundleEvent event) {
+		synchronized (runtimeStatus) {
+			runtimeStatus.events++;
+			if (event.getType() == BundleEvent.STARTED || event.getType() == BundleEvent.STOPPED) {
+				runtimeStatus.unstableBundles--;
+			} else if (event.getType() == BundleEvent.STARTING || event.getType() == BundleEvent.STOPPING) {
+				runtimeStatus.unstableBundles++;
+			}
+			runtimeStatus.notifyAll();
+		}
+		invokeExecutorIfStable();
+	}
+
+	public void serviceChanged(ServiceEvent event) {
+		synchronized (runtimeStatus) {
+			runtimeStatus.events++;
+			if (event.getType() == ServiceEvent.REGISTERED) {
+				runtimeStatus.activeServices++;
+//				System.out.print(sth.activeServices + " ");
+			} else if (event.getType() == ServiceEvent.UNREGISTERING) {
+				runtimeStatus.activeServices--;
+//				System.out.print(sth.activeServices + " ");
+			}
+			runtimeStatus.notifyAll();
+		}
+		invokeExecutorIfStable();
+	}
+
+	public void blueprintEvent(BlueprintEvent event) {
+		synchronized (runtimeStatus) {
+			runtimeStatus.events++;
+			if (event.getType() == BlueprintEvent.CREATING || event.getType() == BlueprintEvent.WAITING || event.getType() == BlueprintEvent.DESTROYING) {
+				runtimeStatus.unstableBlueprints++;
+			} else if (event.getType() == BlueprintEvent.CREATED || event.getType() == BlueprintEvent.FAILURE || event.getType() == BlueprintEvent.DESTROYED) {
+				if (runtimeStatus.unstableBlueprints > 0)
+					runtimeStatus.unstableBlueprints--;
+			}
+			runtimeStatus.notifyAll();
+		}
+		invokeExecutorIfStable();
+	}
+	
+    /**
+     * Creates a non-terminal session, executes commands in <tt>karaf.commands</tt>
+     * then immediately shuts down the OSGi runtime.
+     */
+    private void executeCommands() {
+		String commands = System.getProperty("karaf.commands", "");
+		log.info("Executing: {}", commands);
+//		System.out.println("Executing: "+ commands);
+
+        InputStream in = unwrap(System.in);
+        PrintStream out = unwrap(System.out);
+        PrintStream err = unwrap(System.err);
+		CommandSession session = commandProcessor.createSession(in, out, err);
+		try {
+	        session.put("SCOPE", "shell:osgi:*");
+	        session.put("APPLICATION", System.getProperty("karaf.name", "root"));
+	        try {
+				Object result = session.execute(commands);
+//				System.out.println("Result is " + result);
+				if (result != null) {
+					session.getConsole().println(
+					  session.format(result, Converter.INSPECT));
+				}
+			} catch (Exception e) {
+				err.println("Error executing command: " + e);
+				e.printStackTrace(err);
+			}
+		} finally {
+			session.close();
+		}
+
+		// Shutdown OSGi Runtime
+        Bundle bundle = bundleContext.getBundle(0);
+        try {
+			bundle.stop();
+		} catch (BundleException e) {
+			log.error("Error when shutting down", e);
+		}
+    }
+    
+    /**
+     * Waits for OSGi runtime to stabilize for the last time, then executes commands in "karaf.commands"
+     * by calling {@link ConsoleFactory#executeCommands()}.
+     */
+    private void invokeExecutor() {
+    	log.info("Waiting for OSGi runtime to stabilize");
+    	new Thread("Wait for stable") {
+    		@Override
+    		public void run() {
+				while (true) {
+					try {
+    					int lastEvents; 
+		    			synchronized (runtimeStatus) {
+	    					lastEvents = runtimeStatus.events; 
+							runtimeStatus.wait(100);
+//							System.out.print("*" + sth.activeServices + " ");
+							if (lastEvents == runtimeStatus.events && runtimeStatus.unstableBundles <= 0 && runtimeStatus.unstableBlueprints <= 0) {
+								log.info("Time to launch command! {} services found", runtimeStatus.activeServices);
+//								System.out.println(String.format("Time to launch command! %d services found", sth.activeServices));
+								
+								// Unregister listeners
+								if (blueprintListenerReg != null) {
+									blueprintListenerReg.unregister();
+									blueprintListenerReg = null;
+								}
+								bundleContext.removeServiceListener(ConsoleFactory.this);
+								bundleContext.removeBundleListener(ConsoleFactory.this);
+								
+								executeCommands();
+								break;
+							}
+		    			}
+					} catch (InterruptedException e) {
+						log.info("Interrupted", e);
+						break;
+					}
+    			}
+    		}
+    	}.start();
+	}
+
+    /**
+     * Checks if the OSGi runtime is "stable" and calls {@link ConsoleFactory#invokeExecutor()}.
+     */
+    private void invokeExecutorIfStable() {
+		boolean prevState = executorInvoked.getAndSet(executorInvoked.get() ||
+				(runtimeStatus.unstableBundles <= 0 && runtimeStatus.unstableBlueprints <= 0));
+		if (prevState == false && executorInvoked.get()) {
+			invokeExecutor();
+		}
+    }
+    
 }
