diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Reflective.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Reflective.java
index 901e45e..e7e8ddd 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Reflective.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Reflective.java
@@ -18,369 +18,349 @@
  */
 package org.apache.felix.gogo.runtime.shell;
 
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
 
-import org.osgi.service.command.CommandSession;
+import org.osgi.service.command.*;
 
-public class Reflective
-{
-    public final static Object NO_MATCH = new Object();
-    public final static Set<String> KEYWORDS = new HashSet<String>(
-        Arrays.asList(new String[] { "abstract", "continue", "for", "new", "switch",
-                "assert", "default", "goto", "package", "synchronized", "boolean", "do",
-                "if", "private", "this", "break", "double", "implements", "protected",
-                "throw", "byte", "else", "import", "public", "throws", "case", "enum",
-                "instanceof", "return", "transient", "catch", "extends", "int", "short",
-                "try", "char", "final", "interface", "static", "void", "class",
-                "finally", "long", "strictfp", "volatile", "const", "float", "native",
-                "super", "while" }));
-    public final static String MAIN = "_main";
+public class Reflective {
+	public final static Object NO_MATCH = new Object();
+	public final static Set<String> KEYWORDS = new HashSet<String>(Arrays
+			.asList(new String[] { "abstract", "continue", "for", "new",
+					"switch", "assert", "default", "goto", "package",
+					"synchronized", "boolean", "do", "if", "private", "this",
+					"break", "double", "implements", "protected", "throw",
+					"byte", "else", "import", "public", "throws", "case",
+					"enum", "instanceof", "return", "transient", "catch",
+					"extends", "int", "short", "try", "char", "final",
+					"interface", "static", "void", "class", "finally", "long",
+					"strictfp", "volatile", "const", "float", "native",
+					"super", "while" }));
+	public final static String MAIN = "_main";
 
-    public Object method(CommandSession session, Object target, String name,
-        List<Object> args) throws IllegalArgumentException, IllegalAccessException,
-        InvocationTargetException, Exception
-    {
-        Method[] methods = target.getClass().getMethods();
-        name = name.toLowerCase();
+	public Object method(CommandSession session, Object target, String name,
+			List<Object> args) throws IllegalArgumentException,
+			IllegalAccessException, InvocationTargetException, Exception {
+		Method[] methods = target.getClass().getMethods();
+		name = name.toLowerCase();
 
-        String get = "get" + name;
-        String is = "is" + name;
-        String set = "set" + name;
+		String get = "get" + name;
+		String is = "is" + name;
+		String set = "set" + name;
 
-        if (KEYWORDS.contains(name))
-        {
-            name = "_" + name;
-        }
+		if (KEYWORDS.contains(name)) {
+			name = "_" + name;
+		}
 
-        if (target instanceof Class)
-        {
-            Method[] staticMethods = ((Class<?>) target).getMethods();
-            for (Method m : staticMethods)
-            {
-                String mname = m.getName().toLowerCase();
-                if (mname.equals(name) || mname.equals(get) || mname.equals(set)
-                    || mname.equals(is) || mname.equals(MAIN))
-                {
-                    methods = staticMethods;
-                    break;
-                }
-            }
-        }
+		if (target instanceof Class) {
+			Method[] staticMethods = ((Class<?>) target).getMethods();
+			for (Method m : staticMethods) {
+				String mname = m.getName().toLowerCase();
+				if (mname.equals(name) || mname.equals(get)
+						|| mname.equals(set) || mname.equals(is)
+						|| mname.equals(MAIN)) {
+					methods = staticMethods;
+					break;
+				}
+			}
+		}
 
-        Method bestMethod = null;
-        Object[] bestArgs = null;
-        int match = -1;
-        ArrayList<Class<?>[]> possibleTypes = new ArrayList<Class<?>[]>();
+		Method bestMethod = null;
+		Object[] bestArgs = null;
+		int match = -1;
+		ArrayList<Class<?>[]> possibleTypes = new ArrayList<Class<?>[]>();
 
-        for (Method m : methods)
-        {
-            String mname = m.getName().toLowerCase();
-            if (mname.equals(name) || mname.equals(get) || mname.equals(set)
-                || mname.equals(is) || mname.equals(MAIN))
-            {
-                Class<?>[] types = m.getParameterTypes();
-                ArrayList<Object> xargs = new ArrayList<Object>(args);
+		for (Method m : methods) {
+			String mname = m.getName().toLowerCase();
+			if (mname.equals(name) || mname.equals(get) || mname.equals(set)
+					|| mname.equals(is) || mname.equals(MAIN)) {
+				Class<?>[] types = m.getParameterTypes();
+				ArrayList<Object> xargs = new ArrayList<Object>(args);
 
-                // pass command name as argv[0] to main, so it can handle multiple commands
-                if (mname.equals(MAIN))
-                {
-                    xargs.add(0, name);
-                }
+				// pass command name as argv[0] to main, so it can handle
+				// multiple commands
+				if (mname.equals(MAIN)) {
+					xargs.add(0, name);
+				}
 
-                // Check if the command takes a session
-                if (types.length > 0 && CommandSession.class.isAssignableFrom(types[0]))
-                {
-                    xargs.add(0, session);
-                }
+				// Check if the command takes a session
+				if (types.length > 0
+						&& CommandSession.class.isAssignableFrom(types[0])) {
+					xargs.add(0, session);
+				}
 
-                Object[] parms = new Object[types.length];
-                // if (types.length >= args.size() ) {
-                int local = coerce(session, target, types, parms, xargs);
-                if ((local >= xargs.size()) && (local >= types.length))
-                { // derek - stop no-args
-                    boolean exact = (local == xargs.size() && local == types.length);
-                    if (exact || local > match)
-                    {
-                        bestMethod = m;
-                        bestArgs = parms;
-                        match = local;
-                    }
-                    if (exact)
-                    {
-                        break;
-                    }
-                }
-                else
-                {
-                    possibleTypes.add(types);
-                }
-                // }
-                // if (match == -1 && types.length == 1
-                // && types[0] == Object[].class) {
-                // bestMethod = m;
-                // Object value = args.toArray();
-                // bestArgs = new Object[] { value };
-                // }
-            }
-        }
+				Object[] parms = new Object[types.length];
+				// if (types.length >= args.size() ) {
+				int local = coerce(session, target, m, types, parms, xargs);
+				if ((local >= xargs.size()) && (local >= types.length)) { // derek
+																			// -
+																			// stop
+																			// no-args
+					boolean exact = (local == xargs.size() && local == types.length);
+					if (exact || local > match) {
+						bestMethod = m;
+						bestArgs = parms;
+						match = local;
+					}
+					if (exact) {
+						break;
+					}
+				} else {
+					possibleTypes.add(types);
+				}
+				// }
+				// if (match == -1 && types.length == 1
+				// && types[0] == Object[].class) {
+				// bestMethod = m;
+				// Object value = args.toArray();
+				// bestArgs = new Object[] { value };
+				// }
+			}
+		}
 
-        if (bestMethod != null)
-        {
-            bestMethod.setAccessible(true);
-            // derek: BUGFIX catch InvocationTargetException
-            // return bestMethod.invoke(target, bestArgs);
-            try
-            {
-                return bestMethod.invoke(target, bestArgs);
-            }
-            catch (InvocationTargetException e)
-            {
-                Throwable cause = e.getCause();
-                if (cause instanceof Exception)
-                {
-                    throw (Exception) cause;
-                }
-                throw e;
-            }
-        }
-        else
-        {
-            //throw new IllegalArgumentException("Cannot find command:" + name + " with args:" + args);
-            // { derek
-            ArrayList<String> list = new ArrayList<String>();
-            for (Class<?>[] types : possibleTypes)
-            {
-                StringBuilder buf = new StringBuilder();
-                buf.append('(');
-                for (Class<?> type : types)
-                {
-                    if (buf.length() > 1)
-                    {
-                        buf.append(", ");
-                    }
-                    buf.append(type.getSimpleName());
-                }
-                buf.append(')');
-                list.add(buf.toString());
-            }
+		if (bestMethod != null) {
+			bestMethod.setAccessible(true);
+			// derek: BUGFIX catch InvocationTargetException
+			// return bestMethod.invoke(target, bestArgs);
+			try {
+				return bestMethod.invoke(target, bestArgs);
+			} catch (InvocationTargetException e) {
+				Throwable cause = e.getCause();
+				if (cause instanceof Exception) {
+					throw (Exception) cause;
+				}
+				throw e;
+			}
+		} else {
+			// throw new IllegalArgumentException("Cannot find command:" + name
+			// + " with args:" + args);
+			// { derek
+			ArrayList<String> list = new ArrayList<String>();
+			for (Class<?>[] types : possibleTypes) {
+				StringBuilder buf = new StringBuilder();
+				buf.append('(');
+				for (Class<?> type : types) {
+					if (buf.length() > 1) {
+						buf.append(", ");
+					}
+					buf.append(type.getSimpleName());
+				}
+				buf.append(')');
+				list.add(buf.toString());
+			}
 
-            throw new IllegalArgumentException(String.format(
-                "Cannot coerce %s%s to any of %s", name, args, list));
-            // } derek
-        }
-    }
+			throw new IllegalArgumentException(String.format(
+					"Cannot coerce %s%s to any of %s", name, args, list));
+			// } derek
+		}
+	}
 
-    /**
-     * Complex routein to convert the arguments given from the command line to
-     * the arguments of the method call. First, an attempt is made to convert
-     * each argument. If this fails, a check is made to see if varargs can be
-     * applied. This happens when the last method argument is an array.
-     *
-     * @param session
-     * @param target
-     * @param types
-     * @param out
-     * @param in
-     * @return
-     * @throws Exception
-     */
-    @SuppressWarnings("unchecked")
-    private int coerce(CommandSession session, Object target, Class<?> types[],
-        Object out[], List<Object> in) throws Exception
-    {
-        int i = 0;
-        while (i < out.length)
-        {
-            out[i] = null;
-            try
-            {
-                // Try to convert one argument
-                // derek: add empty array as extra argument
-                //out[i] = coerce(session, target, types[i], in.get(i));
-                if (i == in.size())
-                {
-                    out[i] = NO_MATCH;
-                }
-                else
-                {
-                    out[i] = coerce(session, target, types[i], in.get(i));
-                }
+	/**
+	 * Complex routein to convert the arguments given from the command line to
+	 * the arguments of the method call. First, an attempt is made to convert
+	 * each argument. If this fails, a check is made to see if varargs can be
+	 * applied. This happens when the last method argument is an array.
+	 * 
+	 * @param session
+	 * @param target
+	 * @param m
+	 * @param types
+	 * @param out
+	 * @param in
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	private int coerce(CommandSession session, Object target, Method m,
+			Class<?> types[], Object out[], List<Object> in) throws Exception {
+		Annotation[][] pas = m.getParameterAnnotations();
 
-                if (out[i] == NO_MATCH)
-                {
-                    // Failed
-                    // No match, check for varargs
-                    if (types[i].isArray() && i == types.length - 1)
-                    {
-                        // Try to parse the remaining arguments in an array
-                        Class<?> component = types[i].getComponentType();
-                        Object components = Array.newInstance(component, in.size() - i);
-                        int n = i;
-                        while (i < in.size())
-                        {
-                            Object t = coerce(session, target, component, in.get(i));
-                            if (t == NO_MATCH)
-                            {
-                                return -1;
-                            }
-                            Array.set(components, i - n, t);
-                            i++;
-                        }
-                        out[n] = components;
-                        // Is last element, so we will quite hereafter
-                        // return n;
-                        if (i == in.size())
-                        {
-                            ++i;
-                        }
-                        return i; // derek - return number of args converted
-                    }
-                    return -1;
-                }
-                i++;
-            }
-            catch (Exception e)
-            {
-                System.err.println("Reflective:" + e);
-                e.printStackTrace();
+		for (int argIndex = 0; argIndex < pas.length; argIndex++) {
+			Annotation as[] = pas[argIndex];
+			for (int a = 0; a < as.length; a++) {
+				if (as[a].getClass() == Option.class) {
+					Option o = (Option) as[a];
+					out[argIndex] = coerce(session, target, types[argIndex], o
+							.dflt());
+				} else if (as[a].getClass() == Flag.class) {
+					Flag o = (Flag) as[a];
+					out[argIndex] = coerce(session, target, types[argIndex],
+							false);
+				}
+			}
+		}
 
-                // should get rid of those exceptions, but requires
-                // reg ex matching to see if it throws an exception.
-                // dont know what is better
-                return -1;
-            }
-        }
-        return i;
-    }
+		
+		in = new ArrayList(in);
+		for (Iterator<Object> i = in.iterator(); i.hasNext();) {
+			Object item = i.next();
+			if (item instanceof String) {
+				String option = (String) item;
+				if (option.startsWith("-")) {
+					for (int argIndex = 0; argIndex < pas.length; argIndex++) {
+						Annotation as[] = pas[argIndex];
+						for (int a = 0; a < as.length; a++) {
+							if (as[a].getClass() == Option.class) {
+								Option o = (Option) as[a];
+								if (o.name().equals(option)) {
+									i.remove();
+									assert i.hasNext();
+									Object value = i.next();
+									i.remove();
+									out[argIndex] = coerce(session, target,
+											types[argIndex], value);
+								}
+							} else if (as[a].getClass() == Flag.class) {
+								Flag o = (Flag) as[a];
+								if (o.name().equals(option)) {
+									i.remove();
+									out[argIndex] = coerce(session, target,
+											types[argIndex], true);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		int start = 0;
+		while (start < out.length) {
+			out[start] = null;
+			try {
+				// Try to convert one argument
+				// derek: add empty array as extra argument
+				// out[i] = coerce(session, target, types[i], in.get(i));
+				if (start == in.size()) {
+					out[start] = NO_MATCH;
+				} else {
+					out[start] = coerce(session, target, types[start], in.get(start));
+				}
 
-    Object coerce(CommandSession session, Object target, Class<?> type, Object arg)
-        throws Exception
-    {
-        if (arg == null)
-        {
-            return null;
-        }
+				if (out[start] == NO_MATCH) {
+					// Failed
+					// No match, check for varargs
+					if (types[start].isArray() && start == types.length - 1) {
+						// Try to parse the remaining arguments in an array
+						Class<?> component = types[start].getComponentType();
+						Object components = Array.newInstance(component, in
+								.size()
+								- start);
+						int n = start;
+						while (start < in.size()) {
+							Object t = coerce(session, target, component, in
+									.get(start));
+							if (t == NO_MATCH) {
+								return -1;
+							}
+							Array.set(components, start - n, t);
+							start++;
+						}
+						out[n] = components;
+						// Is last element, so we will quite hereafter
+						// return n;
+						if (start == in.size()) {
+							++start;
+						}
+						return start; // derek - return number of args converted
+					}
+					return -1;
+				}
+				start++;
+			} catch (Exception e) {
+				System.err.println("Reflective:" + e);
+				e.printStackTrace();
 
-        if (type.isAssignableFrom(arg.getClass()))
-        {
-            return arg;
-        }
+				// should get rid of those exceptions, but requires
+				// reg ex matching to see if it throws an exception.
+				// dont know what is better
+				return -1;
+			}
+		}
+		return start;
+	}
 
-        Object converted = session.convert(type, arg);
-        if (converted != null)
-        {
-            return converted;
-        }
+	Object coerce(CommandSession session, Object target, Class<?> type,
+			Object arg) throws Exception {
+		if (arg == null) {
+			return null;
+		}
 
-        String string = arg.toString();
-        if (type.isAssignableFrom(String.class))
-        {
-            return string;
-        }
+		if (type.isAssignableFrom(arg.getClass())) {
+			return arg;
+		}
 
-        if (type.isArray())
-        {
-            // Must handle array types
-            return NO_MATCH;
-        }
-        else
-        {
-            if (!type.isPrimitive())
-            {
-                try
-                {
-                    return type.getConstructor(String.class).newInstance(string);
-                }
-                catch (Exception e)
-                {
-                    return NO_MATCH;
-                }
-            }
-        }
+		Object converted = session.convert(type, arg);
+		if (converted != null) {
+			return converted;
+		}
 
-        try
-        {
-            if (type == boolean.class)
-            {
-                return new Boolean(string);
-            }
-            else
-            {
-                if (type == byte.class)
-                {
-                    return new Byte(string);
-                }
-                else
-                {
-                    if (type == char.class)
-                    {
-                        if (string.length() == 1)
-                        {
-                            return string.charAt(0);
-                        }
-                    }
-                    else
-                    {
-                        if (type == short.class)
-                        {
-                            return new Short(string);
-                        }
-                        else
-                        {
-                            if (type == int.class)
-                            {
-                                return new Integer(string);
-                            }
-                            else
-                            {
-                                if (type == float.class)
-                                {
-                                    return new Float(string);
-                                }
-                                else
-                                {
-                                    if (type == double.class)
-                                    {
-                                        return new Double(string);
-                                    }
-                                    else
-                                    {
-                                        if (type == long.class)
-                                        {
-                                            return new Long(string);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        catch (NumberFormatException e)
-        {
-        }
+		String string = arg.toString();
+		if (type.isAssignableFrom(String.class)) {
+			return string;
+		}
 
-        return NO_MATCH;
-    }
+		if (type.isArray()) {
+			// Must handle array types
+			return NO_MATCH;
+		} else {
+			if (!type.isPrimitive()) {
+				try {
+					return type.getConstructor(String.class)
+							.newInstance(string);
+				} catch (Exception e) {
+					return NO_MATCH;
+				}
+			}
+		}
 
-    public static boolean hasCommand(Object target, String function)
-    {
-        Method[] methods = target.getClass().getMethods();
-        for (Method m : methods)
-        {
-            if (m.getName().equals(function))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
+		try {
+			if (type == boolean.class) {
+				return new Boolean(string);
+			} else {
+				if (type == byte.class) {
+					return new Byte(string);
+				} else {
+					if (type == char.class) {
+						if (string.length() == 1) {
+							return string.charAt(0);
+						}
+					} else {
+						if (type == short.class) {
+							return new Short(string);
+						} else {
+							if (type == int.class) {
+								return new Integer(string);
+							} else {
+								if (type == float.class) {
+									return new Float(string);
+								} else {
+									if (type == double.class) {
+										return new Double(string);
+									} else {
+										if (type == long.class) {
+											return new Long(string);
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		} catch (NumberFormatException e) {
+		}
+
+		return NO_MATCH;
+	}
+
+	public static boolean hasCommand(Object target, String function) {
+		Method[] methods = target.getClass().getMethods();
+		for (Method m : methods) {
+			if (m.getName().equals(function)) {
+				return true;
+			}
+		}
+		return false;
+	}
 }
