Merge "Document how plugins can get access to a data directory"
diff --git a/Documentation/cmd-index.txt b/Documentation/cmd-index.txt
index c4f222b..fd49ae5 100644
--- a/Documentation/cmd-index.txt
+++ b/Documentation/cmd-index.txt
@@ -126,6 +126,24 @@
 link:cmd-show-queue.html[gerrit show-queue]::
 	Display the background work queues, including replication.
 
+link:cmd-plugin-install.html[gerrit plugin add]::
+    Alias for 'gerrit plugin install'.
+
+link:cmd-plugin-install.html[gerrit plugin install]::
+    Install/Add a plugin.
+
+link:cmd-plugin-ls.html[gerrit plugin ls]::
+    List the installed plugins.
+
+link:cmd-plugin-reload.html[gerrit plugin reload]::
+    Reload/Restart plugins.
+
+link:cmd-plugin-remove.html[gerrit plugin remove]::
+    Disable plugins.
+
+link:cmd-plugin-remove.html[gerrit plugin rm]::
+    Alias for 'gerrit plugin remove'.
+
 link:cmd-kill.html[kill]::
 	Kills a scheduled or running task.
 
diff --git a/Documentation/cmd-plugin-install.txt b/Documentation/cmd-plugin-install.txt
new file mode 100644
index 0000000..79d1f4a
--- /dev/null
+++ b/Documentation/cmd-plugin-install.txt
@@ -0,0 +1,71 @@
+plugin install
+==============
+
+NAME
+----
+plugin install - Install/Add a plugin.
+
+plugin add - Install/Add a plugin.
+
+SYNOPSIS
+--------
+[verse]
+'ssh' -p <port> <host> 'gerrit plugin install | add'
+  [--name <NAME> | -n <NAME>]
+  - | <URL> | <PATH>
+
+DESCRIPTION
+-----------
+Install/Add a plugin. The plugin will be copied into the site path's
+`plugins` directory.
+
+ACCESS
+------
+Caller must be a member of the privileged 'Administrators' group.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+OPTIONS
+-------
+-::
+	Plugin jar as piped input.
+
+<URL>::
+	URL from where the plugin should be downloaded. This can be an
+	HTTP or FTP site.
+
+<PATH>::
+	Absolute file path to the plugin jar.
+
+--name::
+-n::
+	The name under which the plugin should be installed.
+
+EXAMPLES
+--------
+Install a plugin from an absolute file path on the server's host:
+
+====
+	ssh -p 29418 localhost gerrit plugin install -n name \
+	  $(pwd)/my-plugin.jar
+====
+
+Install a plugin from an HTTP site:
+
+====
+	ssh -p 29418 localhost gerrit plugin install -n name \
+	  http://build-server/output/our-plugin.jar
+====
+
+Install a plugin from piped input:
+
+====
+	ssh -p 29418 localhost gerrit plugin install -n name \
+	  - <target/name-0.1.jar
+====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/cmd-plugin-ls.txt b/Documentation/cmd-plugin-ls.txt
new file mode 100644
index 0000000..6cce83c
--- /dev/null
+++ b/Documentation/cmd-plugin-ls.txt
@@ -0,0 +1,44 @@
+plugin ls
+=========
+
+NAME
+----
+plugin ls - List the installed plugins.
+
+SYNOPSIS
+--------
+[verse]
+'ssh' -p <port> <host> 'gerrit plugin ls'
+  [--all | -a]
+  [--format {text | json | json_compact}]
+
+DESCRIPTION
+-----------
+List the installed plugins and show their version and status.
+
+ACCESS
+------
+Caller must be a member of the privileged 'Administrators' group.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+OPTIONS
+-------
+--all::
+-a::
+	List all plugins, including disabled plugins.
+
+--format::
+	What output format to display the results in.
++
+--
+`text`:: Simple text based format.
+`json`:: Map of JSON objects describing each project.
+`json_compact`:: Minimized JSON output.
+--
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/cmd-plugin-reload.txt b/Documentation/cmd-plugin-reload.txt
new file mode 100644
index 0000000..8c22afd
--- /dev/null
+++ b/Documentation/cmd-plugin-reload.txt
@@ -0,0 +1,43 @@
+plugin reload
+=============
+
+NAME
+----
+plugin reload - Reload/Restart plugins.
+
+SYNOPSIS
+--------
+[verse]
+'ssh' -p <port> <host> 'gerrit plugin reload'
+  <NAME> ...
+
+DESCRIPTION
+-----------
+Reload/Restart plugins. Whether a plugin is reloaded or restarted
+is defined by the plugin's link:dev-plugins.html#reload_method[reload method].
+
+ACCESS
+------
+Caller must be a member of the privileged 'Administrators' group.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+OPTIONS
+-------
+<NAME>::
+	Name of the plugin that should be reloaded.  Multiple names of
+	plugins that should be reloaded may be specified.
+
+EXAMPLES
+--------
+Reload a plugin:
+
+====
+	ssh -p 29418 localhost gerrit plugin reload my-plugin
+====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/cmd-plugin-remove.txt b/Documentation/cmd-plugin-remove.txt
new file mode 100644
index 0000000..ab8f95b
--- /dev/null
+++ b/Documentation/cmd-plugin-remove.txt
@@ -0,0 +1,45 @@
+plugin remove
+=============
+
+NAME
+----
+plugin remove - Disable plugins.
+
+plugin rm - Disable plugins.
+
+SYNOPSIS
+--------
+[verse]
+'ssh' -p <port> <host> 'gerrit plugin remove | rm'
+  <NAME> ...
+
+DESCRIPTION
+-----------
+Disable plugins. The plugins will be disabled by renaming the plugin
+jars in the site path's `plugins` directory to `<plugin-jar-name>.disabled`.
+
+ACCESS
+------
+Caller must be a member of the privileged 'Administrators' group.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+OPTIONS
+-------
+<NAME>::
+	Name of the plugin that should be disabled.  Multiple names of
+	plugins that should be disabled may be specified.
+
+EXAMPLES
+--------
+Disable a plugin:
+
+====
+	ssh -p 29418 localhost gerrit plugin remove my-plugin
+====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 8610dba..0f234f7 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -2255,7 +2255,7 @@
 Background color used for patch outdated messages.  The value must be
 a valid HTML hex color code, or standard color name.
 +
-By default a shade of red, `FF0000`.
+By default a shade of red, `F08080`.
 
 [[theme.tableOddRowColor]]theme.tableOddRowColor::
 +
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index b583db3..926904a 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -7,13 +7,13 @@
 Depending on how tightly the extension code is coupled with the Gerrit
 server code, there is a distinction between `plugins` and `extensions`.
 
-A plugin in Gerrit is tightly coupled code that runs in the same
+A `plugin` in Gerrit is tightly coupled code that runs in the same
 JVM as Gerrit. It has full access to all server internals. Plugins
 are tightly coupled to a specific major.minor server version and
 may require source code changes to compile against a different
 server version.
 
-An extension in Gerrit runs inside of the same JVM as Gerrit
+An `extension` in Gerrit runs inside of the same JVM as Gerrit
 in the same way as a plugin, but has limited visibility to the
 server's internals. The limited visibility reduces the extension's
 dependencies, enabling it to be compatible across a wider range
@@ -67,7 +67,7 @@
 
 Plugins using the tightly coupled `gerrit-plugin-api.jar` must
 declare this API dependency in the manifest to gain access to server
-internals. If no Gerrit-ApiType is specified the stable `extension`
+internals. If no `Gerrit-ApiType` is specified the stable `extension`
 API will be assumed. This may cause ClassNotFoundExceptions when
 loading a plugin that needs the plugin API.
 
@@ -80,9 +80,9 @@
 
 Plugins that use explicit Guice registration must name the Guice
 modules in the manifest. Up to three modules can be named in the
-manifest. Gerrit-Module supplies bindings to the core server;
-Gerrit-SshModule supplies SSH commands to the SSH server (if
-enabled); Gerrit-HttpModule supplies servlets and filters to the HTTP
+manifest. `Gerrit-Module` supplies bindings to the core server;
+`Gerrit-SshModule` supplies SSH commands to the SSH server (if
+enabled); `Gerrit-HttpModule` supplies servlets and filters to the HTTP
 server (if enabled). If no modules are named automatic registration
 will be performed by scanning all classes in the plugin JAR for
 `@Listen` and `@Export("")` annotations.
@@ -93,12 +93,13 @@
   Gerrit-HttpModule: tld.example.project.HttpModuleClassName
 ====
 
+[[reload_method]]
 Reload Method
 ~~~~~~~~~~~~~
 
 If a plugin holds an exclusive resource that must be released before
 loading the plugin again (for example listening on a network port or
-acquiring a file lock) the manifest must declare Gerrit-ReloadMode
+acquiring a file lock) the manifest must declare `Gerrit-ReloadMode`
 to be `restart`. Otherwise the preferred method of `reload` will
 be used, as it enables the server to hot-patch an updated plugin
 with no down time.
@@ -132,6 +133,9 @@
   may still route to the old plugin if the swap wasn't complete yet).
   The old plugin is stopped.
 
+To reload/restart a plugin the link:cmd-plugin-reload.html[plugin reload]
+command can be used.
+
 Classpath
 ---------
 
@@ -166,7 +170,7 @@
 ====
 
 If no Guice modules are declared in the manifest, SSH commands may
-use auto-registration by providing an @Export annotation:
+use auto-registration by providing an `@Export` annotation:
 
 ====
   import com.google.gerrit.extensions.annotations.Export;
@@ -346,32 +350,8 @@
 Deployment
 ----------
 
-Compiled plugins and extensions can be deployed to a
-running Gerrit server using the SSH interface by any user with
-link:access-control.html#capability_administrateServer[Administrate Server]
-capability. Binaries can be specified in three different formats:
-
-* Absolute file path on the server's host. The server will copy
-  the plugin from this location to its own site path.
-+
-----
-$ ssh -p 29418 localhost gerrit plugin install -n name $(pwd)/my-plugin.jar
-----
-
-* Valid URL, including any HTTP or FTP site reachable by the
-  server. The server will download the plugin and save a copy in
-  its own site path.
-+
-----
-$ ssh -p 29418 localhost gerrit plugin install -n name http://build-server/output/our-plugin.jar
-----
-
-* As piped input to the plugin install command. The server will
-  copy input until EOF, and save a copy under its own site path.
-+
-----
-$ ssh -p 29418 localhost gerrit plugin install -n name - <target/name-0.1.jar
-----
+Compiled plugins and extensions can be deployed to a running Gerrit
+server using the link:cmd-plugin-install.html[plugin install] command.
 
 Plugins can also be copied directly into the server's
 directory at `$site_path/plugins/$name.jar`.  The name of
@@ -380,6 +360,9 @@
 directory for updated plugins. The time can be adjusted by
 link:config-gerrit.html#plugins.checkFrequency[plugins.checkFrequency].
 
+For disabling plugins the link:cmd-plugin-remove.html[plugin remove]
+command can be used.
+
 GERRIT
 ------
 Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/rest-api.txt b/Documentation/rest-api.txt
index 1a359ac..ec87ee1 100644
--- a/Documentation/rest-api.txt
+++ b/Documentation/rest-api.txt
@@ -128,6 +128,113 @@
   }
 ----
 
+[[changes]]
+/changes/ (Query Changes)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Queries changes visible to the caller. The query string must be
+provided by the `q` parameter. The `n` parameter can be used to limit
+the returned results.
+
+Query for open changes of watched projects:
+----
+  GET /changes/?format=JSON&q=status:open+is:watched&n=2 HTTP/1.0
+
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json;charset=UTF-8
+
+  )]}'
+  {
+    "project": "demo",
+    "branch": "master",
+    "id": "Idaf5e098d70898b7119f6f4af5a6c13343d64b57",
+    "subject": "One change",
+    "status": "NEW",
+    "created": "2012-07-17 07:18:30.854000000",
+    "updated": "2012-07-17 07:19:27.766000000",
+    "reviewed": true,
+    "_sortkey": "001e7057000006dc",
+    "_number": 1756,
+    "owner": {
+      "name": "John Doe"
+    },
+    "labels": {
+      "Verified": {},
+      "Code-Review": {}
+    }
+  },
+  {
+    "project": "demo",
+    "branch": "master",
+    "id": "I09c8041b5867d5b33170316e2abc34b79bbb8501",
+    "subject": "Another change",
+    "status": "NEW",
+    "created": "2012-07-17 07:18:30.884000000",
+    "updated": "2012-07-17 07:18:30.885000000",
+    "_sortkey": "001e7056000006dd",
+    "_number": 1757,
+    "owner": {
+      "name": "John Doe"
+    },
+    "labels": {
+      "Verified": {},
+      "Code-Review": {}
+    },
+    "_more_changes": true
+  }
+----
+
+The change output is sorted by the last update time, most recently
+updated to oldest update.
+
+If the `n` query parameter is supplied and additional changes exist
+that match the query beyond the end, the last change object has a
+`_more_changes: true` JSON field set. Callers can resume a query with
+the `n` query parameter, supplying the last change's `_sortkey` field
+as the value. When going in the reverse direction with the `p` query
+parameter a `_more_changes: true` is put in the first change object if
+there are results *before* the first change returned.
+
+Clients are allowed to specify more than one query by setting the `q`
+parameter multiple times. In this case the result is an array of
+arrays, one per query in the same order the queries were given in.
+
+Query that retrieves changes for a user's dashboard:
+----
+  GET /changes/?format=JSON&q=is:open+owner:self&q=is:open+reviewer:self+-owner:self&q=is:closed+owner:self+limit:5 HTTP/1.0
+
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json;charset=UTF-8
+
+  )]}'
+  [
+    [
+      {
+        "project": "demo",
+        "branch": "master",
+        "id": "Idaf5e098d70898b7119f6f4af5a6c13343d64b57",
+        "subject": "One change",
+        "status": "NEW",
+        "created": "2012-07-17 07:18:30.854000000",
+        "updated": "2012-07-17 07:19:27.766000000",
+        "reviewed": true,
+        "_sortkey": "001e7057000006dc",
+        "_number": 1756,
+        "owner": {
+          "name": "John Doe"
+        },
+        "labels": {
+          "Verified": {},
+          "Code-Review": {}
+        }
+      }
+    ],
+    [],
+    []
+  ]
+----
+
 
 GERRIT
 ------
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index 446b71d..8bc365b 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -422,7 +422,7 @@
 }
 
 .changeTable .outdated {
-  background: changeTableOutdatedColor;
+  background: changeTableOutdatedColor !important;
 }
 
 .changeTable .iconCell {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/RestApiServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/RestApiServlet.java
index bb1ad69..be8ae32 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/RestApiServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/RestApiServlet.java
@@ -34,7 +34,9 @@
 import java.io.OutputStream;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
+import java.util.Collections;
 import java.util.Map;
+import java.util.Set;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -182,11 +184,16 @@
 
     public <T> boolean parse(T param, HttpServletRequest req,
         HttpServletResponse res) throws IOException {
+      return parse(param, req, res, Collections.<String>emptySet());
+    }
+
+    public <T> boolean parse(T param, HttpServletRequest req,
+        HttpServletResponse res, Set<String> argNames) throws IOException {
       CmdLineParser clp = parserFactory.create(param);
       try {
         @SuppressWarnings("unchecked")
         Map<String, String[]> parameterMap = req.getParameterMap();
-        clp.parseOptionMap(parameterMap);
+        clp.parseOptionMap(parameterMap, argNames);
       } catch (CmdLineException e) {
         if (!clp.wasHelpRequestedByOption()) {
           res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
index a2f4c99..9723674 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
@@ -43,7 +43,7 @@
     theme.trimColor = color(name, "trimColor", "#D4E9A9");
     theme.selectionColor = color(name, "selectionColor", "#FFFFCC");
     theme.topMenuColor = color(name, "topMenuColor", theme.trimColor);
-    theme.changeTableOutdatedColor = color(name, "changeTableOutdatedColor", "#FF0000");
+    theme.changeTableOutdatedColor = color(name, "changeTableOutdatedColor", "#F08080");
     theme.tableOddRowColor = color(name, "tableOddRowColor", "transparent");
     theme.tableEvenRowColor = color(name, "tableEvenRowColor", "transparent");
     return theme;
diff --git a/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java b/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java
index d4174cb..a9f5229 100644
--- a/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java
+++ b/gerrit-util-cli/src/main/java/com/google/gerrit/util/cli/CmdLineParser.java
@@ -54,9 +54,11 @@
 import java.io.Writer;
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.ResourceBundle;
+import java.util.Set;
 
 /**
  * Extended command line parser which handles --foo=value arguments.
@@ -209,6 +211,12 @@
 
   public void parseOptionMap(Map<String, String[]> parameters)
       throws CmdLineException {
+    parseOptionMap(parameters, Collections.<String>emptySet());
+  }
+
+  public void parseOptionMap(Map<String, String[]> parameters,
+      Set<String> argNames)
+      throws CmdLineException {
     ArrayList<String> tmp = new ArrayList<String>();
     for (Map.Entry<String, String[]> ent : parameters.entrySet()) {
       String name = ent.getKey();
@@ -230,7 +238,9 @@
         }
       } else {
         for (String value : ent.getValue()) {
-          tmp.add(name);
+          if (!argNames.contains(ent.getKey())) {
+            tmp.add(name);
+          }
           tmp.add(value);
         }
       }