diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 2d0363d188efab6b2d12a9e2a948cfa173bba1ca..e41c75846b33071156b036a3389ed374926856c0 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -41,6 +41,7 @@ set(llcommon_SOURCE_FILES
     llerror.cpp
     llerrorthread.cpp
     llevent.cpp
+    lleventapi.cpp
     lleventcoro.cpp
     lleventdispatcher.cpp
     lleventfilter.cpp
@@ -140,6 +141,7 @@ set(llcommon_HEADER_FILES
     llerrorlegacy.h
     llerrorthread.h
     llevent.h
+    lleventapi.h
     lleventcoro.h
     lleventdispatcher.h
     lleventfilter.h
diff --git a/indra/llcommon/lleventapi.cpp b/indra/llcommon/lleventapi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1dd104da8f631ce4702f2446cc5910d8fd828fbb
--- /dev/null
+++ b/indra/llcommon/lleventapi.cpp
@@ -0,0 +1,30 @@
+/**
+ * @file   lleventapi.cpp
+ * @author Nat Goodspeed
+ * @date   2009-11-10
+ * @brief  Implementation for lleventapi.
+ * 
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "lleventapi.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+
+LLEventAPI::LLEventAPI(const std::string& name, const std::string& desc, const std::string& field):
+    lbase(name, field),
+    ibase(name),
+    mDesc(desc)
+{
+}
+
+LLEventAPI::~LLEventAPI()
+{
+}
diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h
new file mode 100644
index 0000000000000000000000000000000000000000..fef12988cb41870d17c8efb52a5ccdfb5bd5ed8f
--- /dev/null
+++ b/indra/llcommon/lleventapi.h
@@ -0,0 +1,53 @@
+/**
+ * @file   lleventapi.h
+ * @author Nat Goodspeed
+ * @date   2009-10-28
+ * @brief  LLEventAPI is the base class for every class that wraps a C++ API
+ *         in an event API
+ * (see https://wiki.lindenlab.com/wiki/Incremental_Viewer_Automation/Event_API).
+ * 
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLEVENTAPI_H)
+#define LL_LLEVENTAPI_H
+
+#include "lleventdispatcher.h"
+#include "llinstancetracker.h"
+#include <string>
+
+/**
+ * LLEventAPI not only provides operation dispatch functionality, inherited
+ * from LLDispatchListener -- it also gives us event API introspection.
+ * Deriving from LLInstanceTracker lets us enumerate instances.
+ */
+class LLEventAPI: public LLDispatchListener,
+                  public LLInstanceTracker<LLEventAPI, std::string>
+{
+    typedef LLDispatchListener lbase;
+    typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
+
+public:
+    /**
+     * @param name LLEventPump name on which this LLEventAPI will listen. This
+     * also serves as the LLInstanceTracker instance key.
+     * @param desc Documentation string shown to a client trying to discover
+     * available event APIs.
+     * @param field LLSD::Map key used by LLDispatchListener to look up the
+     * subclass method to invoke [default "op"].
+     */
+    LLEventAPI(const std::string& name, const std::string& desc, const std::string& field="op");
+    virtual ~LLEventAPI();
+
+    /// Get the string name of this LLEventAPI
+    std::string getName() const { return ibase::getKey(); }
+    /// Get the documentation string
+    std::string getDesc() const { return mDesc; }
+
+private:
+    std::string mDesc;
+};
+
+#endif /* ! defined(LL_LLEVENTAPI_H) */
diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp
index 6b1413d05494851ca76373a91ed5f3569e93df1b..017bf3a52194ae8d1b5878738918aaeffc7d7614 100644
--- a/indra/llcommon/lleventdispatcher.cpp
+++ b/indra/llcommon/lleventdispatcher.cpp
@@ -36,9 +36,11 @@ LLEventDispatcher::~LLEventDispatcher()
 }
 
 /// Register a callable by name
-void LLEventDispatcher::add(const std::string& name, const Callable& callable, const LLSD& required)
+void LLEventDispatcher::add(const std::string& name, const std::string& desc,
+                            const Callable& callable, const LLSD& required)
 {
-    mDispatch[name] = DispatchMap::mapped_type(callable, required);
+    mDispatch.insert(DispatchMap::value_type(name,
+                                             DispatchMap::mapped_type(callable, desc, required)));
 }
 
 void LLEventDispatcher::addFail(const std::string& name, const std::string& classname) const
@@ -98,14 +100,14 @@ bool LLEventDispatcher::attemptCall(const std::string& name, const LLSD& event)
     }
     // Found the name, so it's plausible to even attempt the call. But first,
     // validate the syntax of the event itself.
-    std::string mismatch(llsd_matches(found->second.second, event));
+    std::string mismatch(llsd_matches(found->second.mRequired, event));
     if (! mismatch.empty())
     {
         LL_ERRS("LLEventDispatcher") << "LLEventDispatcher(" << mDesc << ") calling '" << name
                                      << "': bad request: " << mismatch << LL_ENDL;
     }
     // Event syntax looks good, go for it!
-    (found->second.first)(event);
+    (found->second.mFunc)(event);
     return true;                    // tell caller we were able to call
 }
 
@@ -116,7 +118,7 @@ LLEventDispatcher::Callable LLEventDispatcher::get(const std::string& name) cons
     {
         return Callable();
     }
-    return found->second.first;
+    return found->second.mFunc;
 }
 
 LLDispatchListener::LLDispatchListener(const std::string& pumpname, const std::string& key):
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index 5a86b90bff1924a5357b843f3dab622df4262a39..eba7b607f18eb25b1694aee4db0c2a1ba6677087 100644
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
@@ -44,7 +44,10 @@ class LL_COMMON_API LLEventDispatcher
      * is used to validate the structure of each incoming event (see
      * llsd_matches()).
      */
-    void add(const std::string& name, const Callable& callable, const LLSD& required=LLSD());
+    void add(const std::string& name,
+             const std::string& desc,
+             const Callable& callable,
+             const LLSD& required=LLSD());
 
     /**
      * Special case: a subclass of this class can pass an unbound member
@@ -52,18 +55,22 @@ class LL_COMMON_API LLEventDispatcher
      * <tt>boost::bind()</tt> expression.
      */
     template <class CLASS>
-    void add(const std::string& name, void (CLASS::*method)(const LLSD&),
+    void add(const std::string& name,
+             const std::string& desc,
+             void (CLASS::*method)(const LLSD&),
              const LLSD& required=LLSD())
     {
-        addMethod<CLASS>(name, method, required);
+        addMethod<CLASS>(name, desc, method, required);
     }
 
     /// Overload for both const and non-const methods
     template <class CLASS>
-    void add(const std::string& name, void (CLASS::*method)(const LLSD&) const,
+    void add(const std::string& name,
+             const std::string& desc,
+             void (CLASS::*method)(const LLSD&) const,
              const LLSD& required=LLSD())
     {
-        addMethod<CLASS>(name, method, required);
+        addMethod<CLASS>(name, desc, method, required);
     }
 
     /// Unregister a callable
@@ -86,7 +93,8 @@ class LL_COMMON_API LLEventDispatcher
 
 private:
     template <class CLASS, typename METHOD>
-    void addMethod(const std::string& name, const METHOD& method, const LLSD& required)
+    void addMethod(const std::string& name, const std::string& desc,
+                   const METHOD& method, const LLSD& required)
     {
         CLASS* downcast = dynamic_cast<CLASS*>(this);
         if (! downcast)
@@ -95,7 +103,7 @@ class LL_COMMON_API LLEventDispatcher
         }
         else
         {
-            add(name, boost::bind(method, downcast, _1), required);
+            add(name, desc, boost::bind(method, downcast, _1), required);
         }
     }
     void addFail(const std::string& name, const std::string& classname) const;
@@ -103,7 +111,18 @@ class LL_COMMON_API LLEventDispatcher
     bool attemptCall(const std::string& name, const LLSD& event) const;
 
     std::string mDesc, mKey;
-    typedef std::map<std::string, std::pair<Callable, LLSD> > DispatchMap;
+    struct DispatchEntry
+    {
+        DispatchEntry(const Callable& func, const std::string& desc, const LLSD& required):
+            mFunc(func),
+            mDesc(desc),
+            mRequired(required)
+        {}
+        Callable mFunc;
+        std::string mDesc;
+        LLSD mRequired;
+    };
+    typedef std::map<std::string, DispatchEntry> DispatchMap;
     DispatchMap mDispatch;
 };
 
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index acbf51d75ca26be890928c262ffd5e39f4f5918d..104629c157d2ba7cbd34f1de4cb27d85853bb005 100644
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -106,7 +106,7 @@ void LLAres::QueryResponder::queryError(int code)
 LLAres::LLAres() :
     chan_(NULL),
     mInitSuccess(false),
-    mListener(new LLAresListener("LLAres", this))
+    mListener(new LLAresListener(this))
 {
 	if (ares_init(&chan_) != ARES_SUCCESS)
 	{
diff --git a/indra/llmessage/llareslistener.cpp b/indra/llmessage/llareslistener.cpp
index a8beb8cbde350d7a414eccd7d8855903b69387bc..7db3675b77420c80c883526b41b42fd3d3a01969 100644
--- a/indra/llmessage/llareslistener.cpp
+++ b/indra/llmessage/llareslistener.cpp
@@ -22,13 +22,18 @@
 #include "llevents.h"
 #include "llsdutil.h"
 
-LLAresListener::LLAresListener(const std::string& pumpname, LLAres* llares):
-    LLDispatchListener(pumpname, "op"),
+LLAresListener::LLAresListener(LLAres* llares):
+    LLEventAPI("LLAres",
+               "LLAres listener to request DNS operations"),
     mAres(llares)
 {
     // add() every method we want to be able to invoke via this event API.
-    // Optional third parameter validates expected LLSD request structure.
-    add("rewriteURI", &LLAresListener::rewriteURI,
+    // Optional last parameter validates expected LLSD request structure.
+    add("rewriteURI",
+        "Given [\"uri\"], return on [\"reply\"] an array of alternative URIs.\n"
+        "On failure, returns an array containing only the original URI, so\n"
+        "failure case can be processed like success case.",
+        &LLAresListener::rewriteURI,
         LLSD().insert("uri", LLSD()).insert("reply", LLSD()));
 }
 
diff --git a/indra/llmessage/llareslistener.h b/indra/llmessage/llareslistener.h
index bf093b3d3d79bfb17dadf5e98cf2ff62c695bb51..33cef79c093f934232509384eeb89650e2a25de7 100644
--- a/indra/llmessage/llareslistener.h
+++ b/indra/llmessage/llareslistener.h
@@ -14,18 +14,17 @@
 #if ! defined(LL_LLARESLISTENER_H)
 #define LL_LLARESLISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 
 class LLAres;
 class LLSD;
 
 /// Listen on an LLEventPump with specified name for LLAres request events.
-class LLAresListener: public LLDispatchListener
+class LLAresListener: public LLEventAPI
 {
 public:
-    /// Specify the pump name on which to listen, and bind the LLAres instance
-    /// to use (e.g. gAres)
-    LLAresListener(const std::string& pumpname, LLAres* llares);
+    /// Bind the LLAres instance to use (e.g. gAres)
+    LLAresListener(LLAres* llares);
 
 private:
     /// command["op"] == "rewriteURI" 
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 03925f922c1182024deb2a1826f03579a5f8d6e9..eb67e3a56143b6fe1c6a5f5647cd224f2314a2a7 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -46,7 +46,7 @@ LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;
 LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;
 std::map<std::string,std::string> LLFloaterReg::sGroupMap;
 
-static LLFloaterRegListener sFloaterRegListener("LLFloaterReg");
+static LLFloaterRegListener sFloaterRegListener;
 
 //*******************************************************
 
diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp
index 57d148b5af474025a2fd9bbbc94f816c7850da2a..029d3b681035246cad07545abfe2350ebbfc4826 100644
--- a/indra/llui/llfloaterreglistener.cpp
+++ b/indra/llui/llfloaterreglistener.cpp
@@ -21,19 +21,35 @@
 #include "llfloater.h"
 #include "llbutton.h"
 
-LLFloaterRegListener::LLFloaterRegListener(const std::string& pumpName):
-    LLDispatchListener(pumpName, "op")
+LLFloaterRegListener::LLFloaterRegListener():
+    LLEventAPI("LLFloaterReg",
+               "LLFloaterReg listener to (e.g.) show/hide LLFloater instances")
 {
-    add("getBuildMap",  &LLFloaterRegListener::getBuildMap,  LLSD().insert("reply", LLSD()));
+    add("getBuildMap",
+        "Return on [\"reply\"] data about all registered LLFloaterReg floater names",
+        &LLFloaterRegListener::getBuildMap,
+        LLSD().insert("reply", LLSD()));
     LLSD requiredName;
     requiredName["name"] = LLSD();
-    add("showInstance", &LLFloaterRegListener::showInstance, requiredName);
-    add("hideInstance", &LLFloaterRegListener::hideInstance, requiredName);
-    add("toggleInstance", &LLFloaterRegListener::toggleInstance, requiredName);
+    add("showInstance",
+        "Ask to display the floater specified in [\"name\"]",
+        &LLFloaterRegListener::showInstance,
+        requiredName);
+    add("hideInstance",
+        "Ask to hide the floater specified in [\"name\"]",
+        &LLFloaterRegListener::hideInstance,
+        requiredName);
+    add("toggleInstance",
+        "Ask to toggle the state of the floater specified in [\"name\"]",
+        &LLFloaterRegListener::toggleInstance,
+        requiredName);
     LLSD requiredNameButton;
     requiredNameButton["name"] = LLSD();
     requiredNameButton["button"] = LLSD();
-    add("clickButton", &LLFloaterRegListener::clickButton, requiredNameButton);
+    add("clickButton",
+        "Simulate clicking the named [\"button\"] in the visible floater named in [\"name\"]",
+        &LLFloaterRegListener::clickButton,
+        requiredNameButton);
 }
 
 void LLFloaterRegListener::getBuildMap(const LLSD& event) const
diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h
index 304ecd10904aebd567289db04c69c7da45136318..a38117f6b073f1a945106e8b8ae4f84d74cc4696 100644
--- a/indra/llui/llfloaterreglistener.h
+++ b/indra/llui/llfloaterreglistener.h
@@ -12,18 +12,18 @@
 #if ! defined(LL_LLFLOATERREGLISTENER_H)
 #define LL_LLFLOATERREGLISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 #include <string>
 
 class LLSD;
 
 /// Event API wrapper for LLFloaterReg
-class LLFloaterRegListener: public LLDispatchListener
+class LLFloaterRegListener: public LLEventAPI
 {
 public:
     /// As all public LLFloaterReg methods are static, there's no point in
     /// binding an LLFloaterReg instance.
-    LLFloaterRegListener(const std::string& pumpName);
+    LLFloaterRegListener();
 
 private:
     void getBuildMap(const LLSD& event) const;
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index 75f4d6177dc3958e5b1fc0b9f54dc6133e8a7ccb..fe4fbe75105eeb2064d5b9a6d188cd0b3ef387ae 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -16,10 +16,14 @@
 #include "llnotifications.h"
 
 LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
-    LLDispatchListener("LLNotifications", "op"),
+    LLEventAPI("LLNotifications",
+               "LLNotifications listener to (e.g.) pop up a notification"),
     mNotifications(notifications)
 {
-    add("requestAdd", &LLNotificationsListener::requestAdd);
+    add("requestAdd",
+        "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
+        "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
+        &LLNotificationsListener::requestAdd);
 }
 
 void LLNotificationsListener::requestAdd(const LLSD& event_data) const
diff --git a/indra/llui/llnotificationslistener.h b/indra/llui/llnotificationslistener.h
index 6f71a7c7817dc6490592e9c570c4f386d8977788..9b405d7b4b0c72c00b2c0299da81c0638f39ed86 100644
--- a/indra/llui/llnotificationslistener.h
+++ b/indra/llui/llnotificationslistener.h
@@ -12,12 +12,12 @@
 #ifndef LL_LLNOTIFICATIONSLISTENER_H
 #define LL_LLNOTIFICATIONSLISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 
 class LLNotifications;
 class LLSD;
 
-class LLNotificationsListener : public LLDispatchListener
+class LLNotificationsListener : public LLEventAPI
 {
 public:
     LLNotificationsListener(LLNotifications & notifications);
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp
index 0f00078b33ca0eef6e58e501774e1030fbfd6d13..3da6a4e3f4e6bdf793e03fd41eafdd9d244aa602 100644
--- a/indra/newview/llagentlistener.cpp
+++ b/indra/newview/llagentlistener.cpp
@@ -22,12 +22,20 @@
 #include "llviewerregion.h"
 
 LLAgentListener::LLAgentListener(LLAgent &agent)
-  : LLDispatchListener("LLAgent", "op"),
+  : LLEventAPI("LLAgent",
+               "LLAgent listener to (e.g.) teleport, sit, stand, etc."),
     mAgent(agent)
 {
-	add("requestTeleport", &LLAgentListener::requestTeleport);
-	add("requestSit", &LLAgentListener::requestSit);
-	add("requestStand", &LLAgentListener::requestStand);
+	add("requestTeleport",
+        "Teleport: [\"regionname\"], [\"x\"], [\"y\"], [\"z\"]\n"
+        "If [\"skip_confirmation\"] is true, use LLURLDispatcher rather than LLCommandDispatcher.",
+        &LLAgentListener::requestTeleport);
+	add("requestSit",
+        "Ask to sit on the object specified in [\"obj_uuid\"]",
+        &LLAgentListener::requestSit);
+	add("requestStand",
+        "Ask to stand up",
+        &LLAgentListener::requestStand);
 }
 
 void LLAgentListener::requestTeleport(LLSD const & event_data) const
diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h
index 6f0b5a54c5f0efd54b8bd116437b00779ae63879..eed6922b3e2e6b1a3b283c047ac4a7e8b94b9d17 100644
--- a/indra/newview/llagentlistener.h
+++ b/indra/newview/llagentlistener.h
@@ -13,12 +13,12 @@
 #ifndef LL_LLAGENTLISTENER_H
 #define LL_LLAGENTLISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 
 class LLAgent;
 class LLSD;
 
-class LLAgentListener : public LLDispatchListener
+class LLAgentListener : public LLEventAPI
 {
 public:
 	LLAgentListener(LLAgent &agent);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ddb6589b496997d21b7f39f63c9a386976b7d80d..845a264327d8d6f9b1f443808b55e37a7b3b4e31 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -207,7 +207,7 @@
 #pragma warning (disable:4702)
 #endif
 
-static LLAppViewerListener sAppViewerListener("LLAppViewer", LLAppViewer::instance);
+static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
 
 ////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
 //
diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp
index 3259309eee76872a69e8aa2b8cd16563c77dd10a..adb5f43c1a8a701f093cfe9214b89280531e987c 100644
--- a/indra/newview/llappviewerlistener.cpp
+++ b/indra/newview/llappviewerlistener.cpp
@@ -19,14 +19,18 @@
 // other Linden headers
 #include "llappviewer.h"
 
-LLAppViewerListener::LLAppViewerListener(const std::string& pumpname,
-                                         const LLAppViewerGetter& getter):
-    LLDispatchListener(pumpname, "op"),
+LLAppViewerListener::LLAppViewerListener(const LLAppViewerGetter& getter):
+    LLEventAPI("LLAppViewer",
+               "LLAppViewer listener to (e.g.) request shutdown"),
     mAppViewerGetter(getter)
 {
     // add() every method we want to be able to invoke via this event API.
-    add("requestQuit", &LLAppViewerListener::requestQuit);
-    add("forceQuit", &LLAppViewerListener::forceQuit);
+    add("requestQuit",
+        "Ask to quit nicely",
+        &LLAppViewerListener::requestQuit);
+    add("forceQuit",
+        "Quit abruptly",
+        &LLAppViewerListener::forceQuit);
 }
 
 void LLAppViewerListener::requestQuit(const LLSD& event)
diff --git a/indra/newview/llappviewerlistener.h b/indra/newview/llappviewerlistener.h
index 73227cb95a771e2a74092f3cf74197ae230a2c52..deedcbc17976db460bcbfbb88d4771104ceef697 100644
--- a/indra/newview/llappviewerlistener.h
+++ b/indra/newview/llappviewerlistener.h
@@ -12,20 +12,19 @@
 #if ! defined(LL_LLAPPVIEWERLISTENER_H)
 #define LL_LLAPPVIEWERLISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 #include <boost/function.hpp>
 
 class LLAppViewer;
 class LLSD;
 
 /// Listen on an LLEventPump with specified name for LLAppViewer request events.
-class LLAppViewerListener: public LLDispatchListener
+class LLAppViewerListener: public LLEventAPI
 {
 public:
     typedef boost::function<LLAppViewer*(void)> LLAppViewerGetter;
-    /// Specify the pump name on which to listen, and bind the LLAppViewer
-    /// instance to use (e.g. LLAppViewer::instance()).
-    LLAppViewerListener(const std::string& pumpname, const LLAppViewerGetter& getter);
+    /// Bind the LLAppViewer instance to use (e.g. LLAppViewer::instance()).
+    LLAppViewerListener(const LLAppViewerGetter& getter);
 
 private:
     void requestQuit(const LLSD& event);
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index b01293d17c73ada9fc880c0e8f3f2c5c7cfd8796..80b0a430e0248fc76f95594a80df1bd14b167288 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -64,7 +64,7 @@
 #include "llwindow.h"
 #include "stringize.h"
 #include "llsdutil_math.h"
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 
 #if LL_WINDOWS
 #include "lldxhardware.h"
@@ -302,13 +302,17 @@ static std::string get_viewer_release_notes_url()
 	return LLWeb::escapeURL(url.str());
 }
 
-class LLFloaterAboutListener: public LLDispatchListener
+class LLFloaterAboutListener: public LLEventAPI
 {
 public:
 	LLFloaterAboutListener():
-		LLDispatchListener("LLFloaterAbout", "op")
+		LLEventAPI("LLFloaterAbout",
+                   "LLFloaterAbout listener to retrieve About box info")
 	{
-		add("getInfo", &LLFloaterAboutListener::getInfo, LLSD().insert("reply", LLSD()));
+		add("getInfo",
+            "Request an LLSD::Map containing information used to populate About box",
+            &LLFloaterAboutListener::getInfo,
+            LLSD().insert("reply", LLSD()));
 	}
 
 private:
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index e5f347ddc404696933b6ccc7e78840d67268670d..945294f3f2734980302da7bf106e29b45927641c 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -73,9 +73,9 @@ LLLoginInstance::LLLoginInstance() :
 {
 	mLoginModule->getEventPump().listen("lllogininstance", 
 		boost::bind(&LLLoginInstance::handleLoginEvent, this, _1));
-	mDispatcher.add("fail.login", boost::bind(&LLLoginInstance::handleLoginFailure, this, _1));
-	mDispatcher.add("connect",    boost::bind(&LLLoginInstance::handleLoginSuccess, this, _1));
-	mDispatcher.add("disconnect", boost::bind(&LLLoginInstance::handleDisconnect, this, _1));
+	mDispatcher.add("fail.login", "", boost::bind(&LLLoginInstance::handleLoginFailure, this, _1));
+	mDispatcher.add("connect",    "", boost::bind(&LLLoginInstance::handleLoginSuccess, this, _1));
+	mDispatcher.add("disconnect", "", boost::bind(&LLLoginInstance::handleDisconnect, this, _1));
 }
 
 LLLoginInstance::~LLLoginInstance()
diff --git a/indra/newview/lluilistener.cpp b/indra/newview/lluilistener.cpp
index 9c643e78dec9ee2fcd8f0833a7697ec3308a75f6..8b4cfa72481582dcafabaef2e0cb4f9b0316bf70 100644
--- a/indra/newview/lluilistener.cpp
+++ b/indra/newview/lluilistener.cpp
@@ -20,10 +20,16 @@
 #include "lluictrl.h"
 #include "llerror.h"
 
-LLUIListener::LLUIListener(const std::string& name):
-    LLDispatchListener(name, "op")
+LLUIListener::LLUIListener():
+    LLEventAPI("UI",
+               "LLUICtrl::CommitCallbackRegistry listener.\n"
+               "Capable of invoking any function (with parameter) you can specify in XUI.")
 {
-    add("call", &LLUIListener::call, LLSD().insert("function", LLSD()));
+    add("call",
+        "Invoke the operation named by [\"function\"], passing [\"parameter\"],\n"
+        "as if from a user gesture on a menu -- or a button click.",
+        &LLUIListener::call,
+        LLSD().insert("function", LLSD()));
 }
 
 void LLUIListener::call(const LLSD& event) const
diff --git a/indra/newview/lluilistener.h b/indra/newview/lluilistener.h
index ea904a99ff86b82bae69b85d79a920ad5d84cc9f..8605d60bd33ecae10252b81965be9d873314fe09 100644
--- a/indra/newview/lluilistener.h
+++ b/indra/newview/lluilistener.h
@@ -12,15 +12,15 @@
 #if ! defined(LL_LLUILISTENER_H)
 #define LL_LLUILISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 #include <string>
 
 class LLSD;
 
-class LLUIListener: public LLDispatchListener
+class LLUIListener: public LLEventAPI
 {
 public:
-    LLUIListener(const std::string& name);
+    LLUIListener();
 
 private:
     void call(const LLSD& event) const;
diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp
index ecba1b8eb0a3ea26dc4aa33eb24d1856f96ecf6b..0b9db1b906d33052bafe98da18c01378843dc605 100644
--- a/indra/newview/llviewercontrollistener.cpp
+++ b/indra/newview/llviewercontrollistener.cpp
@@ -18,12 +18,22 @@
 LLViewerControlListener gSavedSettingsListener;
 
 LLViewerControlListener::LLViewerControlListener()
-	: LLDispatchListener("LLViewerControl",  "group")
+	: LLEventAPI("LLViewerControl",
+                 "LLViewerControl listener: set, toggle or set default for various controls",
+                 "group")
 {
-	add("Global", boost::bind(&LLViewerControlListener::set, &gSavedSettings, _1));
-	add("PerAccount", boost::bind(&LLViewerControlListener::set, &gSavedPerAccountSettings, _1));
-	add("Warning", boost::bind(&LLViewerControlListener::set, &gWarningSettings, _1));
-	add("Crash", boost::bind(&LLViewerControlListener::set, &gCrashSettings, _1));
+	add("Global",
+        "Set gSavedSettings control [\"key\"] to value [\"value\"]",
+        boost::bind(&LLViewerControlListener::set, &gSavedSettings, _1));
+	add("PerAccount",
+        "Set gSavedPerAccountSettings control [\"key\"] to value [\"value\"]",
+        boost::bind(&LLViewerControlListener::set, &gSavedPerAccountSettings, _1));
+	add("Warning",
+        "Set gWarningSettings control [\"key\"] to value [\"value\"]",
+        boost::bind(&LLViewerControlListener::set, &gWarningSettings, _1));
+	add("Crash",
+        "Set gCrashSettings control [\"key\"] to value [\"value\"]",
+        boost::bind(&LLViewerControlListener::set, &gCrashSettings, _1));
 
 #if 0
 	add(/*"toggleControl",*/ "Global", boost::bind(&LLViewerControlListener::toggleControl, &gSavedSettings, _1));
diff --git a/indra/newview/llviewercontrollistener.h b/indra/newview/llviewercontrollistener.h
index cacf97e908e8f6784339e155b20267b718acfbdf..88afbb871dc025ca6a84bd9b5c9a82a90af7dfdf 100644
--- a/indra/newview/llviewercontrollistener.h
+++ b/indra/newview/llviewercontrollistener.h
@@ -12,12 +12,12 @@
 #ifndef LL_LLVIEWERCONTROLLISTENER_H
 #define LL_LLVIEWERCONTROLLISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 
 class LLControlGroup;
 class LLSD;
 
-class  LLViewerControlListener : public LLDispatchListener
+class  LLViewerControlListener : public LLEventAPI
 {
 public:
 	LLViewerControlListener();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 820f709ba5f722393f3088aeb216e1c6302b1560..976d89a5b7f2f3f6d9fb5a4a8c75dc9c498764fd 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -415,7 +415,7 @@ class LLMenuParcelObserver : public LLParcelObserver
 
 static LLMenuParcelObserver* gMenuParcelObserver = NULL;
 
-static LLUIListener sUIListener("UI");
+static LLUIListener sUIListener;
 
 LLMenuParcelObserver::LLMenuParcelObserver()
 {
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6b0f8814b9aeed93466be297d9f3f919f98ca845..d69cc5999cbf91374cad9b33e0cad67fd9de249f 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1212,7 +1212,7 @@ LLViewerWindow::LLViewerWindow(
 	mStatesDirty(false),
 	mIsFullscreenChecked(false),
 	mCurrResolutionIndex(0),
-    mViewerWindowListener(new LLViewerWindowListener("LLViewerWindow", this))
+    mViewerWindowListener(new LLViewerWindowListener(this))
 {
 	LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
 	LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp
index a890b042ae0f3d348af93abc0dc45a31f9dc86d6..de5778827112fa732d9ba75e61b562ddc6ac0291 100644
--- a/indra/newview/llviewerwindowlistener.cpp
+++ b/indra/newview/llviewerwindowlistener.cpp
@@ -20,8 +20,9 @@
 // other Linden headers
 #include "llviewerwindow.h"
 
-LLViewerWindowListener::LLViewerWindowListener(const std::string& pumpname, LLViewerWindow* llviewerwindow):
-    LLDispatchListener(pumpname, "op"),
+LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow):
+    LLEventAPI("LLViewerWindow",
+               "LLViewerWindow listener to (e.g.) save a screenshot"),
     mViewerWindow(llviewerwindow)
 {
     // add() every method we want to be able to invoke via this event API.
@@ -34,8 +35,15 @@ LLViewerWindowListener::LLViewerWindowListener(const std::string& pumpname, LLVi
 //  saveSnapshotArgs["showui"] = LLSD::Boolean();
 //  saveSnapshotArgs["rebuild"] = LLSD::Boolean();
 //  saveSnapshotArgs["type"] = LLSD::String();
-    add("saveSnapshot", &LLViewerWindowListener::saveSnapshot, saveSnapshotArgs);
-    add("requestReshape", &LLViewerWindowListener::requestReshape);
+    add("saveSnapshot",
+        "Save screenshot: [\"filename\"], [\"width\"], [\"height\"], [\"showui\"], [\"rebuild\"], [\"type\"]\n"
+        "type: \"COLOR\", \"DEPTH\", \"OBJECT_ID\"\n"
+        "Post on [\"reply\"] an event containing [\"ok\"]",
+        &LLViewerWindowListener::saveSnapshot,
+        saveSnapshotArgs);
+    add("requestReshape",
+        "Resize the window: [\"w\"], [\"h\"]",
+        &LLViewerWindowListener::requestReshape);
 }
 
 void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
diff --git a/indra/newview/llviewerwindowlistener.h b/indra/newview/llviewerwindowlistener.h
index 59c636ecec85b5b683019d3d7475b45dbe7673d4..699f7907af2ef682a88ba5e4c6eff3d58733b06b 100644
--- a/indra/newview/llviewerwindowlistener.h
+++ b/indra/newview/llviewerwindowlistener.h
@@ -12,18 +12,17 @@
 #if ! defined(LL_LLVIEWERWINDOWLISTENER_H)
 #define LL_LLVIEWERWINDOWLISTENER_H
 
-#include "lleventdispatcher.h"
+#include "lleventapi.h"
 
 class LLViewerWindow;
 class LLSD;
 
 /// Listen on an LLEventPump with specified name for LLViewerWindow request events.
-class LLViewerWindowListener: public LLDispatchListener
+class LLViewerWindowListener: public LLEventAPI
 {
 public:
-    /// Specify the pump name on which to listen, and bind the LLViewerWindow
-    /// instance to use (e.g. gViewerWindow).
-    LLViewerWindowListener(const std::string& pumpname, LLViewerWindow* llviewerwindow);
+    /// Bind the LLViewerWindow instance to use (e.g. gViewerWindow).
+    LLViewerWindowListener(LLViewerWindow* llviewerwindow);
 
 private:
     void saveSnapshot(const LLSD& event) const;