Merge @Flag and @Option annotations into a single @Parameter annotation. (FELIX-2363)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@948930 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/gogo/command/src/main/java/org/apache/felix/gogo/command/Basic.java b/gogo/command/src/main/java/org/apache/felix/gogo/command/Basic.java
index 618e3cb..16d2659 100644
--- a/gogo/command/src/main/java/org/apache/felix/gogo/command/Basic.java
+++ b/gogo/command/src/main/java/org/apache/felix/gogo/command/Basic.java
@@ -45,8 +45,7 @@
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.command.Descriptor;
-import org.osgi.service.command.Flag;
-import org.osgi.service.command.Option;
+import org.osgi.service.command.Parameter;
 import org.osgi.service.log.LogEntry;
 import org.osgi.service.log.LogReaderService;
 import org.osgi.service.log.LogService;
@@ -62,9 +61,9 @@
         m_bc = bc;
     }
 
-    @Descriptor(description="query bundle start level")
+    @Descriptor("query bundle start level")
     public void bundlelevel(
-        @Descriptor(description="bundle to query") Bundle bundle)
+        @Descriptor("bundle to query") Bundle bundle)
     {
         // Keep track of service references.
         List<ServiceReference> refs = new ArrayList();
@@ -87,12 +86,14 @@
         Util.ungetServices(m_bc, refs);
     }
 
-    @Descriptor(description="set bundle start level or initial bundle start level")
+    @Descriptor("set bundle start level or initial bundle start level")
     public void bundlelevel(
-        @Flag(name="-s", description="set the specified bundle's start level") boolean set,
-        @Flag(name="-i", description="set the initial bundle start level") boolean initial,
-        @Descriptor(description="target level") int level,
-        @Descriptor(description="target identifiers") Bundle[] bundles)
+        @Parameter(name="-s", description="set the specified bundle's start level",
+            presentValue="true", absentValue="false") boolean set,
+        @Parameter(name="-i", description="set the initial bundle start level",
+            presentValue="true", absentValue="false") boolean initial,
+        @Descriptor("target level") int level,
+        @Descriptor("target identifiers") Bundle[] bundles)
     {
         // Keep track of service references.
         List<ServiceReference> refs = new ArrayList();
@@ -147,7 +148,7 @@
         Util.ungetServices(m_bc, refs);
     }
 
-    @Descriptor(description="query framework active start level")
+    @Descriptor("query framework active start level")
     public void frameworklevel()
     {
         // Keep track of service references.
@@ -163,9 +164,9 @@
         Util.ungetServices(m_bc, refs);
     }
 
-    @Descriptor(description="set framework active start level")
+    @Descriptor("set framework active start level")
     public void frameworklevel(
-        @Descriptor(description="target start level") int level)
+        @Descriptor("target start level") int level)
     {
         // Keep track of service references.
         List<ServiceReference> refs = new ArrayList();
@@ -180,9 +181,9 @@
         Util.ungetServices(m_bc, refs);
     }
 
-    @Descriptor(description="display bundle headers")
+    @Descriptor("display bundle headers")
     public void headers(
-        @Descriptor(description="target bundles") Bundle[] bundles)
+        @Descriptor("target bundles") Bundle[] bundles)
     {
         bundles = ((bundles == null) || (bundles.length == 0))
             ? m_bc.getBundles() : bundles;
@@ -202,7 +203,7 @@
         }
     }
 
-    @Descriptor(description="displays available commands")
+    @Descriptor("displays available commands")
     public void help()
     {
         Map<String, List<Method>> commands = getCommands();
@@ -212,9 +213,9 @@
         }
     }
 
-    @Descriptor(description="displays information about a specific command")
+    @Descriptor("displays information about a specific command")
     public void help(
-        @Descriptor(description="target command") String name)
+        @Descriptor("target command") String name)
     {
         Map<String, List<Method>> commands = getCommands();
 
@@ -253,15 +254,15 @@
                 }
                 else
                 {
-                    System.out.println("\n" + m.getName() + " - " + d.description());
+                    System.out.println("\n" + m.getName() + " - " + d.value());
                 }
 
                 System.out.println("   scope: " + name.substring(0, name.indexOf(':')));
 
                 // Get flags and options.
                 Class[] paramTypes = m.getParameterTypes();
-                Map<String, Flag> flags = new TreeMap();
-                Map<String, Option> options = new TreeMap();
+                Map<String, Parameter> flags = new TreeMap();
+                Map<String, Parameter> options = new TreeMap();
                 List<String> params = new ArrayList();
                 Annotation[][] anns = m.getParameterAnnotations();
                 for (int paramIdx = 0; paramIdx < anns.length; paramIdx++)
@@ -270,20 +271,23 @@
                     for (int annIdx = 0; !found && (annIdx < anns[paramIdx].length); annIdx++)
                     {
                         Annotation ann = anns[paramIdx][annIdx];
-                        if (ann instanceof Flag)
+                        if (ann instanceof Parameter)
                         {
-                            flags.put(((Flag) ann).name(), (Flag) ann);
-                            found = true;
-                        }
-                        else if (ann instanceof Option)
-                        {
-                            options.put(((Option) ann).name(), (Option) ann);
+                            Parameter p = (Parameter) ann;
+                            if (p.presentValue().equals(Parameter.UNSPECIFIED))
+                            {
+                                options.put(p.name(), p);
+                            }
+                            else
+                            {
+                                flags.put(p.name(), p);
+                            }
                             found = true;
                         }
                         else if (ann instanceof Descriptor)
                         {
                             params.add(paramTypes[paramIdx].getSimpleName());
-                            params.add(((Descriptor) ann).description());
+                            params.add(((Descriptor) ann).value());
                             found = true;
                         }
                     }
@@ -298,7 +302,7 @@
                 if (flags.size() > 0)
                 {
                     System.out.println("   flags:");
-                    for (Entry<String, Flag> entry : flags.entrySet())
+                    for (Entry<String, Parameter> entry : flags.entrySet())
                     {
                         System.out.println("      "
                             + entry.getValue().name()
@@ -309,13 +313,13 @@
                 if (options.size() > 0)
                 {
                     System.out.println("   options:");
-                    for (Entry<String, Option> entry : options.entrySet())
+                    for (Entry<String, Parameter> entry : options.entrySet())
                     {
                         System.out.println("      "
                             + entry.getValue().name()
                             + "   "
                             + entry.getValue().description()
-                            + ((entry.getValue().dflt() == null) ? "" : " [optional]"));
+                            + ((entry.getValue().absentValue() == null) ? "" : " [optional]"));
                     }
                 }
                 if (params.size() > 0)
@@ -385,18 +389,18 @@
         return commands;
     }
 
-    @Descriptor(description="inspects bundle dependency information")
+    @Descriptor("inspects bundle dependency information")
     public void inspect(
-        @Descriptor(description="(package | bundle | fragment | service)") String type,
-        @Descriptor(description="(capability | requirement)") String direction,
-        @Descriptor(description="target bundles") Bundle[] bundles)
+        @Descriptor("(package | bundle | fragment | service)") String type,
+        @Descriptor("(capability | requirement)") String direction,
+        @Descriptor("target bundles") Bundle[] bundles)
     {
         Inspect.inspect(m_bc, type, direction, bundles);
     }
 
-    @Descriptor(description="install bundle using URLs")
+    @Descriptor("install bundle using URLs")
     public void install(
-        @Descriptor(description="target URLs") String[] urls)
+        @Descriptor("target URLs") String[] urls)
     {
         StringBuffer sb = new StringBuffer();
 
@@ -446,21 +450,27 @@
         }
     }
 
-    @Descriptor(description="list all installed bundles")
+    @Descriptor("list all installed bundles")
     public void lb(
-        @Flag(name="-l", description="show location") boolean showLoc,
-        @Flag(name="-s", description="show symbolic name") boolean showSymbolic,
-        @Flag(name="-u", description="show update location") boolean showUpdate)
+        @Parameter(name="-l", description="show location",
+            presentValue="true", absentValue="false") boolean showLoc,
+        @Parameter(name="-s", description="show symbolic name",
+            presentValue="true", absentValue="false") boolean showSymbolic,
+        @Parameter(name="-u", description="show update location",
+            presentValue="true", absentValue="false") boolean showUpdate)
     {
         lb(showLoc, showSymbolic, showUpdate, null);
     }
 
-    @Descriptor(description="list installed bundles matching a substring")
+    @Descriptor("list installed bundles matching a substring")
     public void lb(
-        @Flag(name="-l", description="show location") boolean showLoc,
-        @Flag(name="-s", description="show symbolic name") boolean showSymbolic,
-        @Flag(name="-u", description="show update location") boolean showUpdate,
-        @Descriptor(description="subtring matched against name or symbolic name") String pattern)
+        @Parameter(name="-l", description="show location",
+            presentValue="true", absentValue="false") boolean showLoc,
+        @Parameter(name="-s", description="show symbolic name",
+            presentValue="true", absentValue="false") boolean showSymbolic,
+        @Parameter(name="-u", description="show update location",
+            presentValue="true", absentValue="false") boolean showUpdate,
+        @Descriptor("subtring matched against name or symbolic name") String pattern)
     {
         // Keep track of service references.
         List<ServiceReference> refs = new ArrayList();
@@ -513,18 +523,18 @@
         return (name != null) && name.toLowerCase().contains(pattern.toLowerCase());
     }
 
-    @Descriptor(description="display all matching log entries")
+    @Descriptor("display all matching log entries")
     public void log(
-        @Descriptor(description="minimum log level [ debug | info | warn | error ]")
+        @Descriptor("minimum log level [ debug | info | warn | error ]")
             String logLevel)
     {
         log(-1, logLevel);
     }
 
-    @Descriptor(description="display some matching log entries")
+    @Descriptor("display some matching log entries")
     public void log(
-        @Descriptor(description="maximum number of entries") int maxEntries,
-        @Descriptor(description="minimum log level [ debug | info | warn | error ]")
+        @Descriptor("maximum number of entries") int maxEntries,
+        @Descriptor("minimum log level [ debug | info | warn | error ]")
             String logLevel)
     {
         // Keep track of service references.
@@ -616,9 +626,9 @@
         }
     }
 
-    @Descriptor(description="refresh bundles")
+    @Descriptor("refresh bundles")
     public void refresh(
-        @Descriptor(description="target bundles (can be null or empty)") Bundle[] bundles)
+        @Descriptor("target bundles (can be null or empty)") Bundle[] bundles)
     {
         if ((bundles != null) && (bundles.length == 0))
         {
@@ -640,9 +650,9 @@
         Util.ungetServices(m_bc, refs);
     }
 
-    @Descriptor(description="resolve bundles")
+    @Descriptor("resolve bundles")
     public void resolve(
-        @Descriptor(description="target bundles (can be null or empty)") Bundle[] bundles)
+        @Descriptor("target bundles (can be null or empty)") Bundle[] bundles)
     {
         if ((bundles != null) && (bundles.length == 0))
         {
@@ -664,11 +674,13 @@
         Util.ungetServices(m_bc, refs);
     }
 
-    @Descriptor(description="start bundles")
+    @Descriptor("start bundles")
     public void start(
-        @Flag(name="-t", description="transient") boolean trans,
-        @Flag(name="-p", description="use declared activation policy") boolean policy,
-        @Descriptor(description="target bundle identifiers or URLs") String[] ss)
+        @Parameter(name="-t", description="transient",
+            presentValue="true", absentValue="false") boolean trans,
+        @Parameter(name="-p", description="use declared activation policy",
+            presentValue="true", absentValue="false") boolean policy,
+        @Descriptor("target bundle identifiers or URLs") String[] ss)
     {
         int options = 0;
 
@@ -743,10 +755,11 @@
         }
     }
 
-    @Descriptor(description="stop bundles")
+    @Descriptor("stop bundles")
     public void stop(
-        @Flag(name="-t", description="transient") boolean trans,
-        @Descriptor(description="target bundles") Bundle[] bundles)
+        @Parameter(name="-t", description="transient",
+            presentValue="true", absentValue="false") boolean trans,
+        @Descriptor("target bundles") Bundle[] bundles)
     {
         if ((bundles == null) || (bundles.length == 0))
         {
@@ -785,9 +798,9 @@
         }
     }
 
-    @Descriptor(description="uninstall bundles")
+    @Descriptor("uninstall bundles")
     public void uninstall(
-        @Descriptor(description="target bundles") Bundle[] bundles)
+        @Descriptor("target bundles") Bundle[] bundles)
     {
         if ((bundles == null) || (bundles.length == 0))
         {
@@ -821,9 +834,9 @@
         }
     }
 
-    @Descriptor(description="update bundle")
+    @Descriptor("update bundle")
     public void update(
-        @Descriptor(description="target bundle") Bundle bundle)
+        @Descriptor("target bundle") Bundle bundle)
     {
         try
         {
@@ -850,10 +863,10 @@
         }
     }
 
-    @Descriptor(description="update bundle from URL")
+    @Descriptor("update bundle from URL")
     public void update(
-        @Descriptor(description="target bundle") Bundle bundle,
-        @Descriptor(description="URL from where to retrieve bundle") String location)
+        @Descriptor("target bundle") Bundle bundle,
+        @Descriptor("URL from where to retrieve bundle") String location)
     {
         if (location != null)
         {
@@ -900,10 +913,10 @@
         }
     }
 
-    @Descriptor(description="determines from where a bundle loads a class")
+    @Descriptor("determines from where a bundle loads a class")
     public void which(
-        @Descriptor(description="target bundle") Bundle bundle,
-        @Descriptor(description="target class name") String className)
+        @Descriptor("target bundle") Bundle bundle,
+        @Descriptor("target class name") String className)
     {
         if (bundle == null)
         {
diff --git a/gogo/command/src/main/java/org/apache/felix/gogo/command/Files.java b/gogo/command/src/main/java/org/apache/felix/gogo/command/Files.java
index 95b155e..ac445e5 100644
--- a/gogo/command/src/main/java/org/apache/felix/gogo/command/Files.java
+++ b/gogo/command/src/main/java/org/apache/felix/gogo/command/Files.java
@@ -38,9 +38,9 @@
         m_bc = bc;
     }
 
-    @Descriptor(description="get current directory")
+    @Descriptor("get current directory")
     public File cd(
-        @Descriptor(description="automatically supplied shell session") CommandSession session)
+        @Descriptor("automatically supplied shell session") CommandSession session)
     {
         try
         {
@@ -52,10 +52,10 @@
         }
     }
 
-    @Descriptor(description="change current directory")
+    @Descriptor("change current directory")
     public File cd(
-        @Descriptor(description="automatically supplied shell session") CommandSession session,
-        @Descriptor(description="target directory") String dir)
+        @Descriptor("automatically supplied shell session") CommandSession session,
+        @Descriptor("target directory") String dir)
         throws IOException
     {
         File cwd = (File) session.get(CWD);
@@ -81,18 +81,18 @@
         return cwd;
     }
 
-    @Descriptor(description="get current directory contents")
+    @Descriptor("get current directory contents")
     public File[] ls(
-        @Descriptor(description="automatically supplied shell session") CommandSession session)
+        @Descriptor("automatically supplied shell session") CommandSession session)
         throws IOException
     {
         return ls(session, null);
     }
 
-    @Descriptor(description="get specified path contents")
+    @Descriptor("get specified path contents")
     public File[] ls(
-        @Descriptor(description="automatically supplied shell session") CommandSession session,
-        @Descriptor(description="path with optionally wildcarded file name") String pattern)
+        @Descriptor("automatically supplied shell session") CommandSession session,
+        @Descriptor("path with optionally wildcarded file name") String pattern)
         throws IOException
     {
         pattern = ((pattern == null) || (pattern.length() == 0)) ? "." : pattern;
@@ -290,4 +290,4 @@
 
         return result;
     }
-}
+}
\ No newline at end of file
diff --git a/gogo/command/src/main/java/org/apache/felix/gogo/command/OBR.java b/gogo/command/src/main/java/org/apache/felix/gogo/command/OBR.java
index 8075661..8fc52db 100644
--- a/gogo/command/src/main/java/org/apache/felix/gogo/command/OBR.java
+++ b/gogo/command/src/main/java/org/apache/felix/gogo/command/OBR.java
@@ -31,7 +31,7 @@
 import org.apache.felix.bundlerepository.Resource;
 import org.osgi.framework.*;
 import org.osgi.service.command.Descriptor;
-import org.osgi.service.command.Flag;
+import org.osgi.service.command.Parameter;
 import org.osgi.util.tracker.ServiceTracker;
 
 public class OBR
@@ -70,10 +70,10 @@
         return (RepositoryAdmin) svcObj;
     }
 
-    @Descriptor(description="manage repositories")
+    @Descriptor("manage repositories")
     public void repos(
-        @Descriptor(description="( add | list | refresh | remove )") String action,
-        @Descriptor(description="space-delimited list of repository URLs") String[] args)
+        @Descriptor("( add | list | refresh | remove )") String action,
+        @Descriptor("space-delimited list of repository URLs") String[] args)
         throws IOException
     {
         Object svcObj = getRepositoryAdmin();
@@ -131,10 +131,11 @@
         }
     }
 
-    @Descriptor(description="list repository resources")
+    @Descriptor("list repository resources")
     public void list(
-        @Flag(name="-v", description="verbose") boolean verbose,
-        @Descriptor(description="optional strings used for name matching") String[] args)
+        @Parameter(name="-v", description="verbose",
+            presentValue="true", absentValue="false") boolean verbose,
+        @Descriptor("optional strings used for name matching") String[] args)
         throws IOException, InvalidSyntaxException
     {
         Object svcObj = getRepositoryAdmin();
@@ -245,9 +246,9 @@
         }
     }
 
-    @Descriptor(description="retrieve resource description from repository")
+    @Descriptor("retrieve resource description from repository")
     public void info(
-        @Descriptor(description="( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
+        @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
             String[] args)
         throws IOException, InvalidSyntaxException
     {
@@ -288,10 +289,11 @@
         }
     }
 
-    @Descriptor(description="deploy resource from repository")
+    @Descriptor("deploy resource from repository")
     public void deploy(
-        @Flag(name="-s", description="start deployed bundles") boolean start,
-        @Descriptor(description="( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
+        @Parameter(name="-s", description="start deployed bundles",
+            presentValue="true", absentValue="false") boolean start,
+        @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
             String[] args)
         throws IOException, InvalidSyntaxException
     {
@@ -394,11 +396,12 @@
         }
     }
 
-    @Descriptor(description="retrieve resource source code from repository")
+    @Descriptor("retrieve resource source code from repository")
     public void source(
-        @Flag(name="-x", description="extract") boolean extract,
-        @Descriptor(description="local target directory") File localDir,
-        @Descriptor(description="( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
+        @Parameter(name="-x", description="extract",
+            presentValue="true", absentValue="false") boolean extract,
+        @Descriptor("local target directory") File localDir,
+        @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
             String[] args)
         throws IOException, InvalidSyntaxException
     {
@@ -443,11 +446,12 @@
         }
     }
 
-    @Descriptor(description="retrieve resource JavaDoc from repository")
+    @Descriptor("retrieve resource JavaDoc from repository")
     public void javadoc(
-        @Flag(name="-x", description="extract") boolean extract,
-        @Descriptor(description="local target directory") File localDir,
-        @Descriptor(description="( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
+        @Parameter(name="-x", description="extract",
+            presentValue="true", absentValue="false") boolean extract,
+        @Descriptor("local target directory") File localDir,
+        @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...")
             String[] args)
         throws IOException, InvalidSyntaxException
     {
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Reflective.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Reflective.java
index 14b3711..61d9575 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Reflective.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/Reflective.java
@@ -30,8 +30,7 @@
 import java.util.Set;
 
 import org.osgi.service.command.CommandSession;
-import org.osgi.service.command.Flag;
-import org.osgi.service.command.Option;
+import org.osgi.service.command.Parameter;
 
 public final class Reflective
 {
@@ -213,15 +212,10 @@
             Annotation as[] = pas[argIndex];
             for (int a = 0; a < as.length; a++)
             {
-                if (as[a] instanceof Option)
+                if (as[a] instanceof Parameter)
                 {
-                    Option o = (Option) as[a];
-                    out[argIndex] = coerce(session, target, types[argIndex], o.dflt());
-                    start = argIndex + 1;
-                }
-                else if (as[a] instanceof Flag)
-                {
-                    out[argIndex] = coerce(session, target, types[argIndex], false);
+                    Parameter o = (Parameter) as[a];
+                    out[argIndex] = coerce(session, target, types[argIndex], o.absentValue());
                     start = argIndex + 1;
                 }
             }
@@ -241,10 +235,10 @@
                         Annotation as[] = pas[argIndex];
                         for (int a = 0; a < as.length; a++)
                         {
-                            if (as[a] instanceof Option)
+                            if (as[a] instanceof Parameter)
                             {
-                                Option o = (Option) as[a];
-                                if (o.name().equals(option))
+                                Parameter o = (Parameter) as[a];
+                                if (o.name().equals(option) && o.presentValue() == null)
                                 {
                                     itArgs.remove();
                                     assert itArgs.hasNext();
@@ -253,15 +247,11 @@
                                     out[argIndex] = coerce(session, target,
                                         types[argIndex], value);
                                 }
-                            }
-                            else if (as[a] instanceof Flag)
-                            {
-                                Flag o = (Flag) as[a];
-                                if (o.name().equals(option))
+                                else if (o.name().equals(option) && o.presentValue() != null)
                                 {
                                     itArgs.remove();
                                     out[argIndex] = coerce(session, target,
-                                        types[argIndex], true);
+                                        types[argIndex], o.presentValue());
                                 }
                             }
                         }
diff --git a/gogo/runtime/src/main/java/org/osgi/service/command/Descriptor.java b/gogo/runtime/src/main/java/org/osgi/service/command/Descriptor.java
index a2ad8f5..d38e878 100644
--- a/gogo/runtime/src/main/java/org/osgi/service/command/Descriptor.java
+++ b/gogo/runtime/src/main/java/org/osgi/service/command/Descriptor.java
@@ -27,5 +27,5 @@
 @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
 public @interface Descriptor
 {
-    String description();
+    String value();
 }
\ No newline at end of file
diff --git a/gogo/runtime/src/main/java/org/osgi/service/command/Flag.java b/gogo/runtime/src/main/java/org/osgi/service/command/Flag.java
deleted file mode 100644
index e08b69f..0000000
--- a/gogo/runtime/src/main/java/org/osgi/service/command/Flag.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.osgi.service.command;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.PARAMETER})
-public @interface Flag
-{
-    String name();
-    String description() default "";
-}
\ No newline at end of file
diff --git a/gogo/runtime/src/main/java/org/osgi/service/command/Option.java b/gogo/runtime/src/main/java/org/osgi/service/command/Option.java
deleted file mode 100644
index 5ae44b7..0000000
--- a/gogo/runtime/src/main/java/org/osgi/service/command/Option.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.osgi.service.command;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.PARAMETER})
-public @interface Option
-{
-    String name();
-    String description() default "";
-    String dflt();
-}
\ No newline at end of file
diff --git a/gogo/runtime/src/main/java/org/osgi/service/command/Parameter.java b/gogo/runtime/src/main/java/org/osgi/service/command/Parameter.java
new file mode 100644
index 0000000..13239c0
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/osgi/service/command/Parameter.java
@@ -0,0 +1,63 @@
+/*
+ * 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.osgi.service.command;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Parameter
+{
+    static final String UNSPECIFIED = "org.osgi.service.command.unspecified.parameter";
+
+    /**
+     * Parameter name, which must start with the hyphen character.
+     * @return parameter name.
+    **/
+    String name();
+
+    /**
+     * Optional parameter description.
+     * @return parameter description.
+    **/
+    String description() default "";
+
+    /**
+     * The default value of the parameter if its name is present on the
+     * command line. If this value is specified, then the command parsing
+     * will not expect a value on the command line for this parameter.
+     * If this value is UNSPECIFIED, then an argument must be specified on the
+     * command line for the parameter.
+     * @return default value of the parameter if its name is present on the
+     *         command line.
+    **/
+    String presentValue() default UNSPECIFIED;
+
+    /**
+     * The default value of the parameter if its name is not present on the
+     * command line. This value is effectively the default value for the
+     * parameter.
+     * @return default value of the parameter if its name is not present
+     *         on the command line.
+    **/
+    String absentValue();
+}
\ No newline at end of file