Index: ./subversion/svnadmin/main.c
===================================================================
--- ./subversion/svnadmin/main.c
+++ ./subversion/svnadmin/main.c	Thu Feb 28 20:06:27 2002
@@ -275,7 +275,7 @@
       {
         svn_revnum_t youngest_rev;
         svn_fs_root_t *rev_root;
-        apr_array_header_t *revs;
+        apr_array_header_t *revs, *paths;
         int i;
 
         if (argc != 4)
@@ -284,11 +284,14 @@
             /* NOTREACHED */
           }
 
+        paths = apr_array_make (pool, 1, sizeof (const char *));
+        (*(const char **)apr_array_push(paths)) = argv[3];
+
         INT_ERR (svn_repos_open (&repos, path, pool));
         fs = svn_repos_fs (repos);
         svn_fs_youngest_rev (&youngest_rev, fs, pool);
         INT_ERR (svn_fs_revision_root (&rev_root, fs, youngest_rev, pool));
-        INT_ERR (svn_fs_revisions_changed (&revs, rev_root, argv[3], pool));
+        INT_ERR (svn_fs_revisions_changed (&revs, rev_root, paths, pool));
         for (i = 0; i < revs->nelts; i++)
           {
             svn_revnum_t this_rev = ((svn_revnum_t *)revs->elts)[i];
Index: ./subversion/include/svn_fs.h
===================================================================
--- ./subversion/include/svn_fs.h
+++ ./subversion/include/svn_fs.h	Thu Feb 28 23:51:32 2002
@@ -666,7 +666,9 @@
 
 
 /* Allocate and return an array *REVS of svn_revnum_t revisions in
-   which PATH under ROOT was modified.  Use POOL for all allocations.
+   which PATHS under ROOT were modified.  Use POOL for all allocations.
+   The array of *REVS are sorted in descending order. All duplicates
+   will also be removed. PATHS is an array of `const char *' entries.
 
    NOTE: This function uses node-id ancestry alone to determine
    modifiedness, and therefore does NOT claim that in any of the
@@ -674,7 +676,7 @@
    directory entries lists changed, etc.  */
 svn_error_t *svn_fs_revisions_changed (apr_array_header_t **revs,
                                        svn_fs_root_t *root,
-                                       const char *path,
+                                       const apr_array_header_t *paths,
                                        apr_pool_t *pool);
 
 
Index: ./subversion/include/svn_sorts.h
===================================================================
--- ./subversion/include/svn_sorts.h
+++ ./subversion/include/svn_sorts.h	Thu Feb 28 20:04:08 2002
@@ -70,6 +70,18 @@
 int svn_sort_compare_items_as_paths (const svn_item_t *a, const svn_item_t *b);
 
 
+/* Compare two svn_revnum_t's, returning an integer greater than, equal
+ * to, or less than 0, according as B is greater than, equal to, or less
+ * than A. Note that this sorts newest revsion to oldest (IOW, descending
+ * order).
+ *
+ * This is useful for converting an array of revisions into a sorted
+ * apr_array_header_t. You are responsible for detecting, preventing or
+ * removing duplicates.
+ */
+int svn_sort_compare_revisions (const void *a, const void *b);
+
+
 #ifndef apr_hash_sorted_keys
 /* Sort HT according to its keys, return an apr_array_header_t
    containing svn_item_t structures holding those keys and values
Index: ./subversion/libsvn_fs/tree.c
===================================================================
--- ./subversion/libsvn_fs/tree.c
+++ ./subversion/libsvn_fs/tree.c	Thu Feb 28 23:59:32 2002
@@ -36,6 +36,8 @@
 #include "svn_pools.h"
 #include "svn_error.h"
 #include "svn_fs.h"
+#include "svn_hash.h"
+#include "svn_sorts.h"
 #include "skel.h"
 #include "id.h"
 #include "fs.h"
@@ -2752,7 +2754,7 @@
 {
   apr_array_header_t **revs;
   svn_fs_t *fs;
-  svn_fs_id_t *id;
+  apr_array_header_t *ids;
   apr_pool_t *pool;
 };
 
@@ -2761,38 +2763,61 @@
 {
   struct revisions_changed_args *args = baton;
   apr_array_header_t *array;
-  dag_node_t *node;
-  svn_fs_id_t *tmp_id;
-  svn_revnum_t revision;
+  int i;
+  apr_pool_t *subpool = svn_pool_create(args->pool);
+  svn_revnum_t prev_rev;
 
   /* Allocate an array for holding revision numbers. */
-  array = apr_array_make (args->pool, 4, sizeof (svn_revnum_t));
+  array = apr_array_make (subpool, 4, sizeof (svn_revnum_t));
 
-  /* Loop, from ID, through its predecessors, until it ceases to
-     exist. */
-  tmp_id = svn_fs_copy_id (args->id, args->pool);
-  do
+  /* Check the ID for each path */
+  for (i = 0; i < args->ids->nelts; i++)
     {
-      int len = svn_fs_id_length (tmp_id);
+      svn_fs_id_t *tmp_id = APR_ARRAY_IDX(args->ids, i, svn_fs_id_t *);
 
-      /* Get the dag node for this id. */
-      SVN_ERR (svn_fs__dag_get_node (&node, args->fs, tmp_id, trail));
+      /* Loop, from ID, through its predecessors, until it ceases to
+         exist.  */
+      do
+        {
+          svn_revnum_t revision;
+          dag_node_t *node;
+          int len = svn_fs_id_length (tmp_id);
 
-      /* Now get the revision from the dag. */
-      SVN_ERR (svn_fs__dag_get_revision (&revision, node, trail));
+          /* Get the dag node for this id. */
+          SVN_ERR (svn_fs__dag_get_node (&node, args->fs, tmp_id, trail));
 
-      /* And put the revision into our array. */
-      (*((svn_revnum_t *) apr_array_push (array))) = revision;
+          /* Now get the revision from the dag. */
+          SVN_ERR (svn_fs__dag_get_revision (&revision, node, trail));
 
-      /* Hack up TMP_ID so that it represents its own predecessor. */
-      tmp_id[len - 1]--;
-      if (tmp_id[len - 1] == 0)
-        tmp_id[len - 2] = -1;
+          (*((svn_revnum_t *) apr_array_push (array))) = revision;
+
+          /* Hack up TMP_ID so that it represents its own predecessor.
+           * Node IDs come in pairs, terminated by a trailing -1. So we
+           * process a pair until the ID gets down to zero, then mock up
+           * the -1 so we'll process the previous one.  */
+        tmp_id[len - 1]--;
+        if (tmp_id[len - 1] == 0)
+          tmp_id[len - 2] = -1;
+        }
+      while (tmp_id[0] != -1);
     }
-  while (tmp_id[0] != -1);
 
-  /* Now make the array "go live". */
-  *(args->revs) = array;
+  /* Now sort the array */
+  qsort(array->elts, array->nelts, array->elt_size,
+        svn_sort_compare_revisions);
+
+  /* Now build the return array, removing duplicates along the way. */
+  *(args->revs) = apr_array_make (args->pool, 4, sizeof (svn_revnum_t));
+  prev_rev = SVN_INVALID_REVNUM;
+  for (i = 0; i < array->nelts; i++)
+    {
+      if (APR_ARRAY_IDX(array, i, svn_revnum_t) != prev_rev)
+        (*((svn_revnum_t *) apr_array_push (*(args->revs)))) =
+            APR_ARRAY_IDX(array, i, svn_revnum_t);
+      prev_rev = APR_ARRAY_IDX(array, i, svn_revnum_t);
+    }
+
+  svn_pool_destroy(subpool);
 
   return SVN_NO_ERROR;
 }
@@ -2800,22 +2825,35 @@
 svn_error_t *
 svn_fs_revisions_changed (apr_array_header_t **revs,
                           svn_fs_root_t *root,
-                          const char *path,
+                          const apr_array_header_t *paths,
                           apr_pool_t *pool)
 {
   struct revisions_changed_args args;
   svn_fs_t *fs = svn_fs_root_fs (root);
+  int i;
+  svn_fs_id_t *tmp_id;
+  const char *this_path;
+  apr_pool_t *subpool = svn_pool_create(pool);
 
   /* Populate the baton. */
   args.revs = revs;
   args.fs = fs;
   args.pool = pool;
+  args.ids = apr_array_make (subpool, 1, sizeof (svn_fs_id_t *));
 
-  /* Get the node-id for PATH under ROOT. */
-  SVN_ERR (svn_fs_node_id (&(args.id), root, path, pool));
+  /* Get the node-id for each PATH under ROOT. */
+  for (i = 0; i < paths->nelts; i++)
+    {
+      this_path = APR_ARRAY_IDX(paths, i, const char *);
+      SVN_ERR (svn_fs_node_id (&tmp_id, root, this_path, subpool));
+      *((svn_fs_id_t **) apr_array_push (args.ids)) = svn_fs_copy_id(tmp_id, subpool);
+    }
 
   /* Call the real function under the umbrella of a trail. */
-  SVN_ERR (svn_fs__retry_txn (fs, txn_body_revisions_changed, &args, pool));
+  SVN_ERR (svn_fs__retry_txn (fs, txn_body_revisions_changed, &args, subpool));
+
+  /* Destroy all memory used, except the revisions array */
+  svn_pool_destroy(subpool);
 
   /* Return the array. */
   return SVN_NO_ERROR;
Index: ./subversion/libsvn_subr/sorts.c
===================================================================
--- ./subversion/libsvn_subr/sorts.c
+++ ./subversion/libsvn_subr/sorts.c	Thu Feb 28 20:04:08 2002
@@ -83,6 +83,18 @@
   return svn_path_compare_paths (str_a, str_b);
 }
 
+int
+svn_sort_compare_revisions (const void *a, const void *b)
+{
+  svn_revnum_t a_rev = *(svn_revnum_t *)a;
+  svn_revnum_t b_rev = *(svn_revnum_t *)b;
+
+  if (a_rev == b_rev)
+    return 0;
+
+  return a_rev < b_rev ? 1 : -1;
+}
+
 
 #ifndef apr_hash_sort_keys
 
Index: ./subversion/libsvn_client/log.c
===================================================================
--- ./subversion/libsvn_client/log.c
+++ ./subversion/libsvn_client/log.c	Fri Mar  1 00:25:41 2002
@@ -58,8 +58,8 @@
   svn_ra_plugin_t *ra_lib;  
   void *ra_baton, *session;
   svn_stringbuf_t *URL;
-  svn_wc_entry_t *entry;
-  svn_stringbuf_t *basename;
+  svn_stringbuf_t *basename = NULL;
+  svn_string_t path_str;
   apr_array_header_t *condensed_targets;
   svn_revnum_t start_revnum, end_revnum;
 
@@ -71,36 +71,101 @@
          "svn_client_log: caller failed to supply revision");
     }
 
-  SVN_ERR (svn_path_condense_targets (&basename, &condensed_targets,
-                                      targets, pool));
+  start_revnum = end_revnum = SVN_INVALID_REVNUM;
 
-  /* Get full URL from the common path, carefully. */
-  SVN_ERR (svn_wc_entry (&entry, basename, pool));
-  if (! entry)
-    return svn_error_createf
-      (SVN_ERR_UNVERSIONED_RESOURCE, 0, NULL, pool,
-       "svn_client_log: %s is not under revision control", basename->data);
-  if (! entry->url)
-    return svn_error_createf
-      (SVN_ERR_ENTRY_MISSING_URL, 0, NULL, pool,
-       "svn_client_log: entry '%s' has no URL", basename->data);
-  URL = svn_stringbuf_dup (entry->url, pool);
+  path_str.data = (APR_ARRAY_IDX(targets, 0, svn_stringbuf_t *))->data;
+  path_str.len = strlen(path_str.data);
+
+  /* Use the passed URL, if there is one.  */
+  if (svn_path_is_url (&path_str))
+    {
+      /* Set the URL from our first target */
+      URL = svn_path_uri_encode(&path_str, pool);
+
+      /* Initialize this array, since we'll be building it below */
+      condensed_targets = apr_array_make (pool, 1, sizeof(svn_stringbuf_t *));
+
+      /* The logic here is this: If we get passed one argument, we assume
+         it is the full URL to a file/dir we want log info for. If we get
+         a URL plus some paths, then we assume that the URL is the base,
+         and that the paths passed are relative to it.  */
+      if (targets->nelts > 1)
+        {
+          int i;
+
+          /* We have some paths, let's use them. Start after the URL.  */
+          for (i = 1; i < targets->nelts; i++)
+            (*((svn_stringbuf_t **)apr_array_push (condensed_targets))) =
+                APR_ARRAY_IDX(targets, i, svn_stringbuf_t *);
+        }
+      else
+        {
+          /* Currently, this doesn't work as expected. We need to know if
+           * the single URL passed is pointing to a directory or a file.
+           * For example, passing:
+           *
+           *         http://repo.com/repo/project/Makefile
+           *
+           * is fairly simple to handle. You Simply Split the last
+           * component off (Makefile) and push it into condensed_targets,
+           * and then make the URL the base dir (minus Makefile). Problem
+           * is, this wont work for:
+           *
+           *         http://repo.com/repo
+           *
+           * where stripping off a component will break the call. We need
+           * a way to find out from the server if this URL points to a
+           * directory or a file. If it points to a directory, we have
+           * can pass it straight through. A file can be split as
+           * explained above.  */
+          return svn_error_create
+            (SVN_ERR_UNSUPPORTED_FEATURE, 0, NULL, pool,
+             "currently you must provide paths with a URL");
+        }
+    }
+  else
+    {
+      svn_wc_entry_t *entry;
+
+      /* Use local working copy.  */
+
+      SVN_ERR (svn_path_condense_targets (&basename, &condensed_targets,
+                                          targets, pool));
+
+      SVN_ERR (svn_wc_entry (&entry, basename, pool));
+      if (! entry)
+        return svn_error_createf
+          (SVN_ERR_UNVERSIONED_RESOURCE, 0, NULL, pool,
+          "svn_client_log: %s is not under revision control", basename->data);
+      if (! entry->url)
+        return svn_error_createf
+          (SVN_ERR_ENTRY_MISSING_URL, 0, NULL, pool,
+          "svn_client_log: entry '%s' has no URL", basename->data);
+      URL = svn_stringbuf_dup (entry->url, pool);
+    }
 
   /* Get the RA library that handles URL. */
   SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
   SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, URL->data, pool));
 
-  /* Open a repository session to the URL. */
-  SVN_ERR (svn_client__open_ra_session (&session, ra_lib, URL, basename,
-                                        TRUE, TRUE, auth_baton, pool));
+  /* Open a repository session to the URL. If we got here from a full URL
+     passed to the command line, then we don't pass basename or
+     do_auth/use_admin to open the ra_session.  */
+  if (NULL != basename)
+    SVN_ERR (svn_client__open_ra_session (&session, ra_lib, URL, basename,
+                                          TRUE, TRUE, auth_baton, pool));
+  else
+    SVN_ERR (svn_client__open_ra_session (&session, ra_lib, URL, NULL, FALSE,
+                                          FALSE, auth_baton, pool));
 
+  /* Get the revisions based on the users "hints".  */
   SVN_ERR (svn_client__get_revision_number
-           (&start_revnum, ra_lib, session, start, basename->data, pool));
+           (&start_revnum, ra_lib, session, start, basename ? basename->data : NULL, pool));
   SVN_ERR (svn_client__get_revision_number
-           (&end_revnum, ra_lib, session, end, basename->data, pool));
+           (&end_revnum, ra_lib, session, end, basename ? basename->data : NULL, pool));
 
   SVN_ERR (ra_lib->get_log (session,
-                            condensed_targets,  /* ### todo: or `targets'? */
+                            condensed_targets,
                             start_revnum,
                             end_revnum,
                             discover_changed_paths,
Index: ./subversion/clients/cmdline/man/svn.1
===================================================================
--- ./subversion/clients/cmdline/man/svn.1
+++ ./subversion/clients/cmdline/man/svn.1	Thu Feb 28 20:04:08 2002
@@ -215,11 +215,38 @@
 \fBimport\fP \fIRepository-URL\fP [\fIPath\fP] [\fINew-Repository-Entry\fP]
 Import a file or tree into the repository.
 .TP
-\fBlog\fP [\fIfile|dir\fP]
+\fBlog\fP [\fIurl\fP] [\fIfile|dir\fP]
 Show log messages (and affected entities) for commits in which any of the
 entities in question changed.  If none were specified, then recursive
-inclusion is the default.  The set of messages can be further restricted by a
-date or revision range specification (using -d or -r).
+inclusion is the default.  The set of messages can be further restricted
+by a date or revision range specification (using -d or -r). A URL can also
+be specific to retrieve logs from a remote repository. If the URL is
+passed alone, then only that entry will be searched. If paths are also
+supplied with the URL, then only those paths are searched, based at the
+given URL.
+
+\fBexample:\fP svn log
+
+Recursively retrieve logs for all revision under "."
+
+\fBexample:\fP svn log README
+
+Retrieve logs for only those revisions where README was affected.
+
+\fBexample:\fP svn log http://rep.com/repo/README
+
+Retrieve logs for the file without the need for a local checkout of the
+repository.
+
+\fBexample:\fP svn log README LICENSE
+
+Retrive logs for all revisions where both files were affected.
+
+\fBexample:\fP svn log http://rep.com/repo README LICENSE
+
+Retrieve logs for both files in the remote repository without the need for
+a local checkout of the repository.
+
 .TP
 \fBmkdir\fP [\fIdirectory...\fP]
 Create the directory(ies), if they do not already exist. The directories can
Index: ./subversion/clients/cmdline/main.c
===================================================================
--- ./subversion/clients/cmdline/main.c
+++ ./subversion/clients/cmdline/main.c	Thu Feb 28 20:04:08 2002
@@ -189,8 +189,20 @@
   
   { "log", svn_cl__log, {0},
     "Show the log messages for a set of revision(s) and/or file(s).\n"
-    "usage: svn log [PATH1 [PATH2] ...] \n",
-    {'r', 'v', svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
+    "usage: svn log [URL] [PATH1 [PATH2] ...] \n"
+    "    Either get the log messages for local PATHs or PATHs at the\n"
+    "    URL. If URL is given by itself, then log messages are output for\n"
+    "    that specific path. The -v option will include a list of affected\n"
+    "    files for each log message. Examples are:\n"
+    "\n"
+    "    svn log\n"
+    "\n"
+    "    svn log foo.c\n"
+    "\n"
+    "    svn log http://www.example.com/repo/project/foo.c\n"
+    "\n"
+    "    svn log http://www.example.com/repo/project foo.c bar.c\n",
+    {'r', 'D', 'v', svn_cl__auth_username_opt, svn_cl__auth_password_opt} },
   
   { "merge", svn_cl__merge, {0},
     "Merge changes in the working copy.  IMPLEMENTATION INCOMPLETE.\n"
Index: ./subversion/tests/libsvn_fs/fs-test.c
===================================================================
--- ./subversion/tests/libsvn_fs/fs-test.c
+++ ./subversion/tests/libsvn_fs/fs-test.c	Thu Feb 28 21:41:26 2002
@@ -5754,8 +5754,12 @@
         int i;
         const char *path = greek_paths[j];
         const svn_revnum_t num_revs = chrevs[j][0];
+        apr_array_header_t *paths;
+
+        paths = apr_array_make (spool, 1, sizeof (const char *));
+        (*(const char **)apr_array_push(paths)) = path;
         
-        SVN_ERR (svn_fs_revisions_changed (&revs, rev_root, path, spool));
+        SVN_ERR (svn_fs_revisions_changed (&revs, rev_root, paths, spool));
 
         /* Are we at least looking at the right number of returned
            revisions? */
Index: ./subversion/libsvn_repos/log.c
===================================================================
--- ./subversion/libsvn_repos/log.c
+++ ./subversion/libsvn_repos/log.c	Thu Feb 28 22:19:42 2002
@@ -104,6 +104,7 @@
   apr_pool_t *subpool = svn_pool_create (pool);
   apr_hash_t *changed_paths = NULL;
   svn_fs_t *fs = repos->fs;
+  apr_array_header_t *revs = NULL;
 
   if (start == SVN_INVALID_REVNUM)
     SVN_ERR (svn_fs_youngest_rev (&start, fs, pool));
@@ -111,12 +112,49 @@
   if (end == SVN_INVALID_REVNUM)
     SVN_ERR (svn_fs_youngest_rev (&end, fs, pool));
 
+  if (paths && paths->nelts)
+    {
+      int i;
+      svn_fs_root_t *rev_root;
+      apr_array_header_t *cpaths =
+          apr_array_make(subpool, paths->nelts, sizeof(const char *));
+
+      /* Build an array of const char's from our stringbuf stuff.  */
+      for (i = 0; i < paths->nelts; i++)
+        (*(const char **)apr_array_push(cpaths)) =
+                (APR_ARRAY_IDX(paths, i, svn_stringbuf_t *))->data;
+
+      /* Set the revision root to the newer of the revisions we are
+       * searching for.  */
+      SVN_ERR (svn_fs_revision_root (&rev_root, fs, (start > end) ? start : end, subpool));
+
+      /* And the search is on... */
+      SVN_ERR (svn_fs_revisions_changed (&revs, rev_root, cpaths, subpool));
+
+      /* If no revisions were found for these entries, we have nothing to
+       * show. Just return now before we break a sweat.  */
+      if (!revs || !revs->nelts)
+        return SVN_NO_ERROR;
+    }
+
   for (this_rev = start;
        ((start >= end) ? (this_rev >= end) : (this_rev <= end));
        ((start >= end) ? this_rev-- : this_rev++))
     {
       svn_string_t *author, *date, *message;
 
+      /* If we have a list of revs for use, check to make sure this is one
+       * of them.  */
+      if (revs)
+        {
+          int i, matched = 0;
+          for (i = 0; i < revs->nelts && !matched; i++)
+            if (this_rev == ((svn_revnum_t *)(revs->elts))[i])
+              matched = 1;
+          if (! matched)
+            continue;
+	}
+
       SVN_ERR (svn_fs_revision_prop
                (&author, fs, this_rev, SVN_PROP_REVISION_AUTHOR, subpool));
       SVN_ERR (svn_fs_revision_prop
@@ -126,20 +164,7 @@
 
       /* ### Below, we discover changed paths if the user requested
          them (i.e., "svn log -v" means `discover_changed_paths' will
-         be non-zero here), OR if we're filtering on paths, in which
-         case we use changed_paths to determine whether or not to even
-         invoke the log receiver on this log item.
-
-         Note that there is another, more efficient way to filter by
-         path.  Instead of looking at every revision, and eliminating
-         those that didn't change any of the paths in question, you
-         start at `start', and grab the fs node for every path in
-         paths.  Check the created rev field; if any of them equal
-         `start', include this log item.  Then jump immediately to the
-         next highest/lowest created-rev field of any path in paths,
-         and do the same thing, until you jump to a rev that's beyond
-         `end'.  Premature optimization right now, however.
-      */
+         be non-zero here).  */
 
 #ifndef SVN_REPOS_ALLOW_LOG_WITH_PATHS
       discover_changed_paths = FALSE;
@@ -153,8 +178,8 @@
 
           changed_paths = apr_hash_make (subpool);
           
-          SVN_ERR (svn_fs_revision_root (&base_root, fs, this_rev - 1, pool));
-          SVN_ERR (svn_fs_revision_root (&this_root, fs, this_rev, pool));
+          SVN_ERR (svn_fs_revision_root (&base_root, fs, this_rev - 1, subpool));
+          SVN_ERR (svn_fs_revision_root (&this_root, fs, this_rev, subpool));
 
           /* ### todo: not sure this needs an editor and dir_deltas.
              Might be easier to just walk the one revision tree,
@@ -188,32 +213,6 @@
              for repository style. */
         }
 
-      /* Check if any of the filter paths changed in this revision. */
-      if (paths && paths->nelts > 0)
-        {
-          int i;
-          void *val;
-
-          for (i = 0; i < paths->nelts; i++)
-            {
-              svn_stringbuf_t *this_path;
-              this_path = (((svn_stringbuf_t **)(paths)->elts)[i]);
-              val = apr_hash_get (changed_paths,
-                                  this_path->data, this_path->len); 
-              
-              if (val)   /* Stop looking -- we've found a match. */
-                break;
-            }
-
-          /* The check below happens outside the `for' loop
-             immediately above, so that the `continue' will apply to
-             the outermost `for' loop.  The logic is: if we are doing
-             path filtering, and this revision *doesn't* affect one of
-             the filter paths, then we skip the invocation of the log
-             receiver and `continue' on to the next revision. */
-          if (! val)
-            continue;
-        }
 #endif /* SVN_REPOS_ALLOW_LOG_WITH_PATHS */
 
       SVN_ERR ((*receiver) (receiver_baton,


