Index: notes/http-and-webdav/webdav-usage.html
===================================================================
--- notes/http-and-webdav/webdav-usage.html	(revision 1023844)
+++ notes/http-and-webdav/webdav-usage.html	(revision 1005387)
@@ -19,7 +19,7 @@
 
     <p>
       This document details how WebDAV is used within the
-      <a href="http://subversion.apache.org/">Subversion
+      <a href="http://subversion.tigris.org/">Subversion
       product</a>. Specifically, how the client side interfaces with
       <a href="http://www.webdav.org/neon/">Neon</a> to generate
       WebDAV requests over the wire, and what the
@@ -31,7 +31,7 @@
     </p>
     <p>
       This document heavily refers to the
-      <a href="http://svn.apache.org/repos/asf/subversion/trunk/notes/subversion-design.html">Subversion
+      <a href="http://subversion.tigris.org/files/documents/15/17/svn-design.html">Subversion
 	design document</a> and the
       <a href="http://www.webdav.org/deltav/">latest Delta-V protocol
 	draft</a>. Details of those documents will <em>not</em> be
Index: notes/wc-ng/copying
===================================================================
--- notes/wc-ng/copying	(revision 1023844)
+++ notes/wc-ng/copying	(revision 1005387)
@@ -27,10 +27,7 @@
                              A /X (from /S@N)   M /X/T
                                                 (with local mods)
 
-  /S@N    /S/T@M             A /X (from /S@N)
-                             (if server finds T@M is same thing as T@N)
-                             or
-                             A /X (from /S@N)   A /X/T (from /S/A@M)
+  /S@N    /S/T@M             A /X (from /S@N)   A /X/T (from /S/A@M)
                              or
                              A /X (from /S@N)   R /X/T (from /S/A@M)
                                                 (the FS layer converts
@@ -71,26 +68,13 @@
 child.  In both cases the commit must either add or replace the child
 and if the copy is from a source that is locally added or replaced the
 client can make the distinction and send a delete before adding the
-replacement.  For a mixed revision, as the client doesn't know whether
-the child existed in its parent's revision and so can't distinguish
+replacement.  For a mixed revision the client doesn't distinguish
 between add and replace, it always sends an add and the FS layer
 converts to a replace as required (for details see 2010-04-19 comments
 in issue 3314).  We will probably have to continue rely on this in
 WC-NG as there is not enough information in the source to determine
 whether or not the child also exists in the parent's revision.
 
-If the mixed-rev source has a "not-present" child (effectively the
-same as "updated to r0"), then the copy schedules this as "delete".
-The client doesn't know whether the child existed in its parent's
-revision, so it can't distinguish between delete and no-op, so it
-always sends a delete.
-
-  ### This current fails, in both 1.6 and trunk.
-
-  ### TODO: The server needs to silently elide a delete, or the client
-  needs to detect the error and recover from it and continue if that
-  is possible.
-
 Child nodes not-present in the source become not-present working nodes
 in the copy, this ensures that they get deleted by the commit.  We
 might want to use a new not-copied state instead, since these deletes
Index: notes/wc-ng/nodes
===================================================================
--- notes/wc-ng/nodes	(revision 1023844)
+++ notes/wc-ng/nodes	(revision 1005387)
@@ -155,23 +155,11 @@
   previous existing node, just like it does in WC-1.  A partial revert of
   this state is not a particularly helpful or frequent use case.
 
-  GJS: I believe that wc_db should enable the individual reverts. The
-  first revert will undo the add/copy, and the second revert will undo
-  the delete. The UI (or the next level up in libsvn_wc) can collapse
-  those into a single user action. This leaves us the future
-  possibility of finer-grained reverts.
-
 ### EHU: The statement above probably means that *all* nodes in the subtree
   need to be rewritten: they all have a deleted state with the affected
   op_depth, meaning they probably need a 'replaced/copied-to' state with
   the same op_depth...
 
-  GJS: not all nodes. The newly-arriving copy/move may have
-  new/disjoint nodes that were not part of the deleted set. We will
-  simply add new rows for these arriving nodes. Similarly, the
-  arriving subtree may NOT have a similar node, so the deleted node
-  remains untouched.
-
 
 Copies of mixed-revision subtrees become multiple layers
 --------------------------------------------------------
@@ -203,32 +191,6 @@
   we have to store the mixed-rev copy flat (single op_depth) and modify the
   commit rules to act on revision-number changes within this flat tree.
 
-  GJS: correct. Consider a root of the subtree at r10, and a
-  descendent is at r12. We cannot create one layer at r10, and another
-  at r12 because we do not have the descendent@r10 to place into the
-  first layer. Thus, we need to use a single op_depth layer for this
-  operation. At commit time, one copy will be me for the subtree from
-  r10, a deletion will be made for the descendent, and then another
-  copy performed for the r12 descendent.
-
-### GJS: in the above scenario, we do not know if the descendent
-  existed in r10, so the deletion may not be necessary (and could even
-  throw an error!). I do not recall if our copy's destination is
-  allowed to exist (ie. we have implied overwrite semantics in the
-  repository).
-
-  PM: Yes, we have overwrite sematics.  The FS layer on the server has
-  magic that converts the copy of the r12 descendant into a replace if
-  the descendant exists in r10.  The client does not send a delete.
-
-  This magic applies to copies, not deletes, so there is a problem
-  when the descendant is deleted in the mixed-revision copy in the
-  working copy.  When faced with a copy of the subtree at r10 and a
-  delete of a descendant at r12 the commit doesn't work at present.
-  Deleting the descendant is wrong if it does not exist in r10, but
-  not deleting it is wrong if it does exist.  I suppose the client
-  could ask the server, or perhaps use multiple layers of BASE to
-  track mixed-revisions (argh!).
 
 In a deleted subtree, all nodes get marked deleted explicitly
 -------------------------------------------------------------
@@ -274,18 +236,8 @@
 
 TODO:
 
-       GJS: yup. tho it will complicate a revert of a copy/move-here
-       since we will need to perform a query to see whether we should
-       convert the copy/move into a deleted node, or whether to simply
-       remove the node entirely.
-
-       GJS: and yes, if wc_db performed a double-operation revert,
-       then we wouldn't have to do this. arguably, we could push the
-       2-op revert to a future release when we also choose to alter
-       the higher layers to bring in the finer-grained control. (or
-       maybe we have to look at prior nodes regardless, so checking
-       for "replace with a deleted node" comes for no additional
-       cost).
+ * Explain the role of the 'deleted-below' columns
+   ### JAF: No, that idea has already been rejected.
 
  * Document states of the table and their meaning (including values
     of the relevant columns)
Index: subversion/libsvn_diff/diff_file.c
===================================================================
--- subversion/libsvn_diff/diff_file.c	(revision 1023844)
+++ subversion/libsvn_diff/diff_file.c	(revision 1005387)
@@ -67,26 +67,21 @@
 typedef struct svn_diff__file_baton_t
 {
   const svn_diff_file_options_t *options;
-
-  struct file_info {
-    const char *path;  /* path to this file, absolute or relative to CWD */
+  const char *path[4];
 
-    /* All the following fields are active while this datasource is open */
-    apr_file_t *file;  /* handle of this file */
-    apr_off_t size;    /* total raw size in bytes of this file */
+  apr_file_t *file[4];
+  apr_off_t size[4];
 
-    /* The current chunk: CHUNK_SIZE bytes except for the last chunk. */
-    int chunk;     /* the current chunk number, zero-based */
-    char *buffer;  /* a buffer containing the current chunk */
-    char *curp;    /* current position in the current chunk */
-    char *endp;    /* next memory address after the current chunk */
-
-    svn_diff__normalize_state_t normalize_state;
-  } files[4];
+  int chunk[4];
+  char *buffer[4];
+  char *curp[4];
+  char *endp[4];
 
   /* List of free tokens that may be reused. */
   svn_diff__file_token_t *tokens;
 
+  svn_diff__normalize_state_t normalize_state[4];
+
   apr_pool_t *pool;
 } svn_diff__file_baton_t;
 
@@ -203,30 +198,26 @@
 }
 
 
-/* Let FILE stand for the file_info struct element of BATON->files that is
- * indexed by DATASOURCE.  BATON's type is (svn_diff__file_baton_t *).
- *
- * Open the file at FILE.path; initialize FILE.file, FILE.size, FILE.buffer,
- * FILE.curp and FILE.endp; allocate a buffer and read the first chunk.
- *
- * Implements svn_diff_fns_t::datasource_open. */
+/* Implements svn_diff_fns_t::datasource_open */
 static svn_error_t *
 datasource_open(void *baton, svn_diff_datasource_e datasource)
 {
   svn_diff__file_baton_t *file_baton = baton;
-  struct file_info *file = &file_baton->files[datasource_to_index(datasource)];
+  int idx;
   apr_finfo_t finfo;
   apr_off_t length;
   char *curp;
   char *endp;
 
-  SVN_ERR(svn_io_file_open(&file->file, file->path,
+  idx = datasource_to_index(datasource);
+
+  SVN_ERR(svn_io_file_open(&file_baton->file[idx], file_baton->path[idx],
                            APR_READ, APR_OS_DEFAULT, file_baton->pool));
 
   SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE,
-                               file->file, file_baton->pool));
+                               file_baton->file[idx], file_baton->pool));
 
-  file->size = finfo.size;
+  file_baton->size[idx] = finfo.size;
   length = finfo.size > CHUNK_SIZE ? CHUNK_SIZE : finfo.size;
 
   if (length == 0)
@@ -235,10 +226,10 @@
   endp = curp = apr_palloc(file_baton->pool, (apr_size_t) length);
   endp += length;
 
-  file->buffer = file->curp = curp;
-  file->endp = endp;
+  file_baton->buffer[idx] = file_baton->curp[idx] = curp;
+  file_baton->endp[idx] = endp;
 
-  return read_chunk(file->file, file->path,
+  return read_chunk(file_baton->file[idx], file_baton->path[idx],
                     curp, length, 0, file_baton->pool);
 }
 
@@ -261,7 +252,7 @@
 {
   svn_diff__file_baton_t *file_baton = baton;
   svn_diff__file_token_t *file_token;
-  struct file_info *file = &file_baton->files[datasource_to_index(datasource)];
+  int idx;
   char *endp;
   char *curp;
   char *eol;
@@ -273,13 +264,15 @@
 
   *token = NULL;
 
-  curp = file->curp;
-  endp = file->endp;
+  idx = datasource_to_index(datasource);
 
-  last_chunk = offset_to_chunk(file->size);
+  curp = file_baton->curp[idx];
+  endp = file_baton->endp[idx];
+
+  last_chunk = offset_to_chunk(file_baton->size[idx]);
 
   if (curp == endp
-      && last_chunk == file->chunk)
+      && last_chunk == file_baton->chunk[idx])
     {
       return SVN_NO_ERROR;
     }
@@ -296,8 +289,8 @@
     }
 
   file_token->datasource = datasource;
-  file_token->offset = chunk_to_offset(file->chunk)
-                       + (curp - file->buffer);
+  file_token->offset = chunk_to_offset(file_baton->chunk[idx])
+                       + (curp - file_baton->buffer[idx]);
   file_token->raw_length = 0;
   file_token->length = 0;
 
@@ -318,7 +311,7 @@
             }
         }
 
-      if (file->chunk == last_chunk)
+      if (file_baton->chunk[idx] == last_chunk)
         {
           eol = endp;
           break;
@@ -327,21 +320,21 @@
       length = endp - curp;
       file_token->raw_length += length;
       svn_diff__normalize_buffer(&curp, &length,
-                                 &file->normalize_state,
+                                 &file_baton->normalize_state[idx],
                                  curp, file_baton->options);
       file_token->length += length;
       h = svn_diff__adler32(h, curp, length);
 
-      curp = endp = file->buffer;
-      file->chunk++;
-      length = file->chunk == last_chunk ?
-        offset_in_chunk(file->size) : CHUNK_SIZE;
+      curp = endp = file_baton->buffer[idx];
+      file_baton->chunk[idx]++;
+      length = file_baton->chunk[idx] == last_chunk ?
+        offset_in_chunk(file_baton->size[idx]) : CHUNK_SIZE;
       endp += length;
-      file->endp = endp;
+      file_baton->endp[idx] = endp;
 
-      SVN_ERR(read_chunk(file->file, file->path,
+      SVN_ERR(read_chunk(file_baton->file[idx], file_baton->path[idx],
                          curp, length,
-                         chunk_to_offset(file->chunk),
+                         chunk_to_offset(file_baton->chunk[idx]),
                          file_baton->pool));
 
       /* If the last chunk ended in a CR, we're done. */
@@ -356,7 +349,7 @@
 
   length = eol - curp;
   file_token->raw_length += length;
-  file->curp = eol;
+  file_baton->curp[idx] = eol;
 
   /* If the file length is exactly a multiple of CHUNK_SIZE, we will end up
    * with a spurious empty token.  Avoid returning it.
@@ -367,7 +360,7 @@
     {
       char *c = curp;
       svn_diff__normalize_buffer(&c, &length,
-                                 &file->normalize_state,
+                                 &file_baton->normalize_state[idx],
                                  curp, file_baton->options);
 
       file_token->norm_offset = file_token->offset;
@@ -395,12 +388,13 @@
   char buffer[2][COMPARE_CHUNK_SIZE];
   char *bufp[2];
   apr_off_t offset[2];
-  struct file_info *file[2];
+  int idx[2];
   apr_off_t length[2];
   apr_off_t total_length;
   /* How much is left to read of each token from the file. */
   apr_off_t raw_length[2];
   int i;
+  int chunk[2];
   svn_diff__normalize_state_t state[2];
 
   file_token[0] = token1;
@@ -426,18 +420,17 @@
 
   for (i = 0; i < 2; ++i)
     {
-      int idx = datasource_to_index(file_token[i]->datasource);
-
-      file[i] = &file_baton->files[idx];
+      idx[i] = datasource_to_index(file_token[i]->datasource);
       offset[i] = file_token[i]->norm_offset;
+      chunk[i] = file_baton->chunk[idx[i]];
       state[i] = svn_diff__normalize_state_normal;
 
-      if (offset_to_chunk(offset[i]) == file[i]->chunk)
+      if (offset_to_chunk(offset[i]) == chunk[i])
         {
           /* If the start of the token is in memory, the entire token is
            * in memory.
            */
-          bufp[i] = file[i]->buffer;
+          bufp[i] = file_baton->buffer[idx[i]];
           bufp[i] += offset_in_chunk(offset[i]);
 
           length[i] = total_length;
@@ -465,15 +458,15 @@
                                          NULL,
                                          _("The file '%s' changed unexpectedly"
                                            " during diff"),
-                                         file[i]->path);
+                                         file_baton->path[idx[i]]);
 
               /* Read a chunk from disk into a buffer */
               bufp[i] = buffer[i];
               length[i] = raw_length[i] > COMPARE_CHUNK_SIZE ?
                 COMPARE_CHUNK_SIZE : raw_length[i];
 
-              SVN_ERR(read_chunk(file[i]->file,
-                                 file[i]->path,
+              SVN_ERR(read_chunk(file_baton->file[idx[i]],
+                                 file_baton->path[idx[i]],
                                  bufp[i], length[i], offset[i],
                                  file_baton->pool));
               offset[i] += length[i];
@@ -630,8 +623,8 @@
 
   memset(&baton, 0, sizeof(baton));
   baton.options = options;
-  baton.files[0].path = original;
-  baton.files[1].path = modified;
+  baton.path[0] = original;
+  baton.path[1] = modified;
   baton.pool = svn_pool_create(pool);
 
   SVN_ERR(svn_diff_diff(diff, &baton, &svn_diff__file_vtable, pool));
@@ -652,9 +645,9 @@
 
   memset(&baton, 0, sizeof(baton));
   baton.options = options;
-  baton.files[0].path = original;
-  baton.files[1].path = modified;
-  baton.files[2].path = latest;
+  baton.path[0] = original;
+  baton.path[1] = modified;
+  baton.path[2] = latest;
   baton.pool = svn_pool_create(pool);
 
   SVN_ERR(svn_diff_diff3(diff, &baton, &svn_diff__file_vtable, pool));
@@ -676,10 +669,10 @@
 
   memset(&baton, 0, sizeof(baton));
   baton.options = options;
-  baton.files[0].path = original;
-  baton.files[1].path = modified;
-  baton.files[2].path = latest;
-  baton.files[3].path = ancestor;
+  baton.path[0] = original;
+  baton.path[1] = modified;
+  baton.path[2] = latest;
+  baton.path[3] = ancestor;
   baton.pool = svn_pool_create(pool);
 
   SVN_ERR(svn_diff_diff4(diff, &baton, &svn_diff__file_vtable, pool));
Index: subversion/libsvn_subr/io.c
===================================================================
--- subversion/libsvn_subr/io.c	(revision 1023844)
+++ subversion/libsvn_subr/io.c	(revision 1005387)
@@ -334,10 +334,6 @@
   unsigned int i;
   struct temp_file_cleanup_s *baton = NULL;
 
-  /* At the beginning, we don't know whether unique_path will need 
-     UTF8 conversion */
-  svn_boolean_t needs_utf8_conversion = TRUE;
-
   SVN_ERR_ASSERT(file || unique_path);
 
   if (dirpath == NULL)
@@ -378,11 +374,6 @@
       if (delete_when == svn_io_file_del_on_close)
         flag |= APR_DELONCLOSE;
 
-      /* Increase the chance that rand() will return something truely
-         independent from what others get or do. */
-      if (i == 2)
-        srand(apr_time_now());
-
       /* Special case the first attempt -- if we can avoid having a
          generated numeric portion at all, that's best.  So first we
          try with just the suffix; then future tries add a number
@@ -393,35 +384,17 @@
          This is good, since "1" would misleadingly imply that
          the second attempt was actually the first... and if someone's
          got conflicts on their conflicts, we probably don't want to
-         add to their confusion :-). 
-
-         Also, the randomization used to minimize the number of re-try 
-         cycles will interfere with certain tests that compare working
-         copies etc.
-       */
+         add to their confusion :-). */
       if (i == 1)
         unique_name = apr_psprintf(scratch_pool, "%s%s", path, suffix);
       else
-        unique_name = apr_psprintf(scratch_pool, "%s.%u_%x%s", path, i, rand(), suffix);
+        unique_name = apr_psprintf(scratch_pool, "%s.%u%s", path, i, suffix);
 
       /* Hmmm.  Ideally, we would append to a native-encoding buf
          before starting iteration, then convert back to UTF-8 for
          return. But I suppose that would make the appending code
          sensitive to i18n in a way it shouldn't be... Oh well. */
-      if (needs_utf8_conversion)
-        {
-          SVN_ERR(cstring_from_utf8(&unique_name_apr, unique_name, scratch_pool));
-          if (i == 1)
-            {
-              /* The variable parts of unique_name will not require UTF8
-                 conversion. Therefore, if UTF8 conversion had no effect
-                 on it in the first iteration, it won't require conversion
-                 in any future interation. */
-              needs_utf8_conversion = strcmp(unique_name_apr, unique_name);
-            }
-        }
-      else
-        unique_name_apr = unique_name;
+      SVN_ERR(cstring_from_utf8(&unique_name_apr, unique_name, scratch_pool));
 
       apr_err = file_open(&try_file, unique_name_apr, flag,
                           APR_OS_DEFAULT, FALSE, result_pool);
Index: subversion/libsvn_subr/svn_string.c
===================================================================
--- subversion/libsvn_subr/svn_string.c	(revision 1023844)
+++ subversion/libsvn_subr/svn_string.c	(revision 1005387)
@@ -406,7 +406,7 @@
    * to just write the new byte at the end of the used section
    * and terminate the string properly.
    */
-  if (str->blocksize > old_len + 1)
+  if (str->blocksize < old_len + 1)
     {
       /* The following read does not depend this write, so we
        * can issue the write first to minimize register pressure:
Index: subversion/tests/libsvn_diff/parse-diff-test.c
===================================================================
--- subversion/tests/libsvn_diff/parse-diff-test.c	(revision 1023844)
+++ subversion/tests/libsvn_diff/parse-diff-test.c	(revision 1005387)
@@ -301,7 +301,10 @@
     SVN_TEST_ASSERT(exp_eof == hunk_eof);
     if (exp_eof)
       break;
-    SVN_TEST_STRING_ASSERT(exp_buf->data, hunk_buf->data);
+    if (strcmp(exp_buf->data, hunk_buf->data))
+      return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                               "Expected '%s' but was '%s'", exp_buf->data,
+                               hunk_buf->data);
   }
 
   SVN_TEST_ASSERT(hunk_buf->len == 0);
@@ -342,8 +345,8 @@
                                         ignore_whitespace, iterpool, 
                                         iterpool));
       SVN_TEST_ASSERT(patch);
-      SVN_TEST_STRING_ASSERT(patch->old_filename, "A/C/gamma");
-      SVN_TEST_STRING_ASSERT(patch->new_filename, "A/C/gamma");
+      SVN_TEST_ASSERT(! strcmp(patch->old_filename, "A/C/gamma"));
+      SVN_TEST_ASSERT(! strcmp(patch->new_filename, "A/C/gamma"));
       SVN_TEST_ASSERT(patch->hunks->nelts == 1);
 
       hunk = APR_ARRAY_IDX(patch->hunks, 0, svn_diff_hunk_t *);
@@ -362,13 +365,13 @@
       SVN_TEST_ASSERT(patch);
       if (reverse)
         {
-          SVN_TEST_STRING_ASSERT(patch->new_filename, "A/D/gamma.orig");
-          SVN_TEST_STRING_ASSERT(patch->old_filename, "A/D/gamma");
+          SVN_TEST_ASSERT(! strcmp(patch->new_filename, "A/D/gamma.orig"));
+          SVN_TEST_ASSERT(! strcmp(patch->old_filename, "A/D/gamma"));
         }
       else
         {
-          SVN_TEST_STRING_ASSERT(patch->old_filename, "A/D/gamma.orig");
-          SVN_TEST_STRING_ASSERT(patch->new_filename, "A/D/gamma");
+          SVN_TEST_ASSERT(! strcmp(patch->old_filename, "A/D/gamma.orig"));
+          SVN_TEST_ASSERT(! strcmp(patch->new_filename, "A/D/gamma"));
         }
       SVN_TEST_ASSERT(patch->hunks->nelts == 1);
 
@@ -406,8 +409,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "A/mu");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "A/mu");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "A/mu"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "A/mu"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_deleted);
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
 
@@ -417,8 +420,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "A/C/gamma");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "A/C/gamma");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "A/C/gamma"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "A/C/gamma"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_modified);
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
   
@@ -440,8 +443,8 @@
                                     pool, pool));
 
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "iota");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "iota.copied");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota.copied"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_copied);
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
 
@@ -452,8 +455,8 @@
                                     pool, pool));
 
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "new");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "new");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "new"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "new"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_added);
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
 
@@ -479,8 +482,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "iota");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "iota.copied");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota.copied"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_copied);
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
   
@@ -501,8 +504,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "A/mu");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "A/mu.moved");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "A/mu"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "A/mu.moved"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_moved);
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
   
@@ -522,8 +525,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "/dev/null");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "new");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "/dev/null"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "new"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_added);
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
   
@@ -542,8 +545,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "A/B/lambda");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "/dev/null");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "A/B/lambda"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "/dev/null"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_deleted);
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
   
@@ -576,8 +579,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "iota");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "iota.copied");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota.copied"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_copied);
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
   
@@ -614,8 +617,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "iota");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "iota");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota"));
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
   SVN_TEST_ASSERT(apr_hash_count(patch->prop_patches) == 3);
 
@@ -717,8 +720,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "iota");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "iota");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota"));
   SVN_TEST_ASSERT(patch->hunks->nelts == 1);
   SVN_TEST_ASSERT(apr_hash_count(patch->prop_patches) == 1);
 
@@ -772,8 +775,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "iota");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "iota");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "iota"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "iota"));
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
   SVN_TEST_ASSERT(apr_hash_count(patch->prop_patches) == 3);
 
@@ -870,8 +873,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "path 1");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "path 1");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "path 1"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "path 1"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_added);
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
   
@@ -880,8 +883,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "path one 1");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "path one 1");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "path one 1"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "path one 1"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_added);
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
 
@@ -890,8 +893,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, "dir/ b/path");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, "dir/ b/path");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, "dir/ b/path"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, "dir/ b/path"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_added);
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
 
@@ -900,8 +903,8 @@
                                     FALSE, /* ignore_whitespace */ 
                                     pool, pool));
   SVN_TEST_ASSERT(patch);
-  SVN_TEST_STRING_ASSERT(patch->old_filename, " b/path 1");
-  SVN_TEST_STRING_ASSERT(patch->new_filename, " b/path 1");
+  SVN_TEST_ASSERT(! strcmp(patch->old_filename, " b/path 1"));
+  SVN_TEST_ASSERT(! strcmp(patch->new_filename, " b/path 1"));
   SVN_TEST_ASSERT(patch->operation == svn_diff_op_added);
   SVN_TEST_ASSERT(patch->hunks->nelts == 0);
 
Index: subversion/tests/libsvn_wc/db-test.c
===================================================================
--- subversion/tests/libsvn_wc/db-test.c	(revision 1023844)
+++ subversion/tests/libsvn_wc/db-test.c	(revision 1005387)
@@ -87,10 +87,109 @@
    "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
    "insert into wcroot values (1, null); "
 
-   /* ### The file_externals column in NODES is temporary, and will be
+   /* ### The file_externals column in BASE_NODE is temporary, and will be
       ### removed.  However, to keep the tests passing, we need to add it
       ### to the following insert statements.  *Be sure to remove it*. */
-
+#ifndef SVN_WC__NODES_ONLY
+   "insert into base_node values ("
+   "  1, '', 1, '', null, 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', 'infinity', null, null, '()', null, 0, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'A', null, null, '', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 10, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'B', null, null, '', 'excluded', 'symlink', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'C', null, null, '', 'absent', 'unknown', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'D', null, null, '', 'not-present', 'unknown', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'E', null, null, '', 'incomplete', 'unknown', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'F', null, null, '', 'normal', 'file', "
+   "  1, '$sha1$" SHA1_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'G', 2, 'G-alt', '', 'normal', 'file', "
+   "  1, '$sha1$" SHA1_1 "', 15, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'H', null, null, '', 'normal', 'symlink', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, 'H-target', null, '()', null, "
+   "  null, null); "
+   "insert into base_node values ("
+   "  1, 'I', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e', null, null, 'J', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e/J-e-a', null, null, 'J/J-e', 'normal', 'file', "
+   "  1, '$sha1$" SHA1_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e/J-e-b', null, null, 'J/J-e', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e/J-e-b/Jeba', null, null, 'J/J-e/J-e-b', 'normal', 'file', "
+   "  1, '$sha1$" SHA1_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-f', null, null, 'J', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-f/J-f-a', null, null, 'J/J-f', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'K', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'K/K-a', null, null, 'K', 'normal', 'file', "
+   "  1, '$sha1$" SHA1_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'K/K-b', null, null, 'K', 'normal', 'file', "
+   "  1, '$sha1$" SHA1_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   " "
+#endif
+#ifdef SVN_WC__NODES
    /* load the base nodes into the nodes table */
   "insert into nodes values ("
   "  1, '', 0, null, 1, '', 1, 'normal',"
@@ -173,6 +272,116 @@
   "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
   "  15, null, null, null);"
   ""
+#endif
+#ifndef SVN_WC__NODES_ONLY
+   "insert into working_node values ("
+   "  1, 'I', '', 'normal', 'dir', "
+   "  null, null, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', 'immediates', null, "
+   "  2, 'some/dir', 2, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J', '', 'normal', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-a', 'J', 'normal', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-b', 'J', 'normal', 'dir', "
+   "  null, null, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', 'infinity', null, "
+   "  2, 'some/dir', 2, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-b/J-b-a', 'J/J-b', 'normal', 'dir', "
+   "  null, null, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', 'infinity', null, "
+   "  2, 'another/dir', 2, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-b/J-b-b', 'J/J-b', 'normal', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-c', 'J', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-c/J-c-a', 'J/J-c', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-d', 'J', 'normal', 'file', "
+   "  '$md5 $" MD5_1 "', 10, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', null, null, "
+   "  2, 'moved/file', 2, 1, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e', 'J', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, 'other/place', null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e/J-e-a', 'J/J-e', 'not-present', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e/J-e-b', 'J/J-e', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e/J-e-b/Jeba', 'J/J-e/J-e-b', 'base-deleted', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-f', 'J', 'normal', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-f/J-f-a', 'J/J-f', 'base-deleted', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'K', '', 'base-deleted', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'K/K-a', 'K', 'base-deleted', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'K/K-b', 'K', 'base-deleted', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, 'moved/away', null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'L', '', 'normal', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'L/L-a', 'L', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'L/L-a/L-a-a', 'L', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   " "
+#endif
+#ifdef SVN_WC__NODES
    /* Load data into NODES table;
       ### op_depths have not been calculated by me yet;
       the value 1 is just 'good enough' to make the nodes WORKING nodes. */
@@ -260,10 +469,24 @@
   "  1, 'L/L-a/L-a-a', 1, 'L', null, null, null, 'not-present',"
   "  0, null, 'dir', '()', 'immediates', null, null, null, null, null,"
   "  null, null, null, null);"
+#endif
    "insert into actual_node values ("
    "  1, 'I', '', null, null, null, null, null, 'changelist', null, "
    "'" I_TC_DATA "', null, null, null, null);"
    "  "
+#ifndef SVN_WC__NODES_ONLY
+   "insert into base_node values ("
+   "  1, 'M', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into working_node values ("
+   "  1, 'M/M-a', 'M', 'not-present', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+#endif
+#ifdef SVN_WC__NODES
    "insert into nodes values ("
    "  1, 'M', 0, '', null, null, null, 'normal', "
    "  1, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
@@ -272,6 +495,7 @@
    "  1, 'M/M-a', 1, 'M', null, null, null, 'not-present', "
    "  null, null, 'file', '()', null, null, null, null, null, null,"
    "  null, 0, null, null);"
+#endif
    );
 
 WC_QUERIES_SQL_DECLARE_STATEMENTS(statements);
@@ -286,7 +510,9 @@
   svn_sqlite__db_t *sdb;
   const char * const my_statements[] = {
     statements[STMT_CREATE_SCHEMA],
+#ifdef SVN_WC__NODES
     statements[STMT_CREATE_NODES],
+#endif
     TESTING_DATA,
     NULL
   };
@@ -580,41 +806,38 @@
     }
 
   value = apr_hash_get(props, "p1", APR_HASH_KEY_STRING);
-  SVN_TEST_STRING_ASSERT(value->data, "v1");
+  SVN_TEST_ASSERT(value != NULL && strcmp(value->data, "v1") == 0);
   SVN_ERR(svn_wc__db_base_get_prop(&value, db, path, "p1",
                                    scratch_pool, scratch_pool));
-  SVN_TEST_STRING_ASSERT(value->data, "v1");
+  SVN_TEST_ASSERT(value != NULL && strcmp(value->data, "v1") == 0);
 
   value = apr_hash_get(props, "for-file", APR_HASH_KEY_STRING);
-  SVN_TEST_STRING_ASSERT(value->data, relpath);
+  SVN_TEST_ASSERT(value != NULL && strcmp(value->data, relpath) == 0);
   SVN_ERR(svn_wc__db_base_get_prop(&value, db, path, "for-file",
                                    scratch_pool, scratch_pool));
-  SVN_TEST_STRING_ASSERT(value->data, relpath);
+  SVN_TEST_ASSERT(value != NULL && strcmp(value->data, relpath) == 0);
 
   SVN_ERR(svn_wc__db_read_props(&props, db, path,
                                 scratch_pool, scratch_pool));
   SVN_TEST_ASSERT(props != NULL);
   value = apr_hash_get(props, "p1", APR_HASH_KEY_STRING);
-  SVN_TEST_STRING_ASSERT(value->data, "v1");
+  SVN_TEST_ASSERT(value != NULL && strcmp(value->data, "v1") == 0);
 
   SVN_ERR(svn_wc__db_read_pristine_props(&props, db, path,
                                          scratch_pool, scratch_pool));
   SVN_TEST_ASSERT(props != NULL);
   value = apr_hash_get(props, "p1", APR_HASH_KEY_STRING);
-  SVN_TEST_STRING_ASSERT(value->data, "v1");
+  SVN_TEST_ASSERT(value != NULL && strcmp(value->data, "v1") == 0);
 
   /* Now add a property value and read it back (all on actual) */
-  {
-    apr_hash_t *actual_props = apr_hash_copy(scratch_pool, props);
-    apr_hash_set(actual_props, "p999", APR_HASH_KEY_STRING, value);
-    SVN_ERR(svn_wc__db_op_set_props(db, path, actual_props,
-                                    NULL, NULL, scratch_pool));
-    SVN_ERR(svn_wc__db_read_props(&props, db, path,
-                                  scratch_pool, scratch_pool));
-    SVN_TEST_ASSERT(props != NULL);
-    value = apr_hash_get(props, "p999", APR_HASH_KEY_STRING);
-    SVN_TEST_STRING_ASSERT(value->data, "v1");
-  }
+  apr_hash_set(props, "p999", APR_HASH_KEY_STRING, value);
+
+  SVN_ERR(svn_wc__db_op_set_props(db, path, props, NULL, NULL, scratch_pool));
+  SVN_ERR(svn_wc__db_read_props(&props, db, path,
+                                scratch_pool, scratch_pool));
+  SVN_TEST_ASSERT(props != NULL);
+  value = apr_hash_get(props, "p999", APR_HASH_KEY_STRING);
+  SVN_TEST_ASSERT(value != NULL && strcmp(value->data, "v1") == 0);
 
   return SVN_NO_ERROR;
 }
Index: subversion/tests/libsvn_wc/pristine-store-test.c
===================================================================
--- subversion/tests/libsvn_wc/pristine-store-test.c	(revision 1023844)
+++ subversion/tests/libsvn_wc/pristine-store-test.c	(revision 1005387)
@@ -256,8 +256,9 @@
 
     SVN_ERR(svn_wc__db_wclock_obtain(wc_ctx->db, dirname, 0, FALSE, pool));
 
-    SVN_ERR(svn_wc_add_from_disk(wc_ctx, versioned_abspath,
-                                 NULL, NULL, NULL, NULL, pool));
+    SVN_ERR(svn_wc_add4(wc_ctx, versioned_abspath, svn_depth_empty,
+                        NULL, SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL,
+                        pool));
     SVN_ERR(svn_wc_prop_set4(wc_ctx, versioned_abspath,
                              "svn:keywords", svn_string_create("Rev", pool),
                              FALSE, NULL, NULL, pool));
Index: subversion/tests/libsvn_wc/entries-compat.c
===================================================================
--- subversion/tests/libsvn_wc/entries-compat.c	(revision 1023844)
+++ subversion/tests/libsvn_wc/entries-compat.c	(revision 1005387)
@@ -87,10 +87,109 @@
    "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
    "insert into wcroot values (1, null); "
 
-   /* ### The file_externals column in NODES is temporary, and will be
+   /* ### The file_externals column in BASE_NODE is temporary, and will be
       ### removed.  However, to keep the tests passing, we need to add it
       ### to the following insert statements.  *Be sure to remove it*. */
-
+#ifndef SVN_WC__NODES_ONLY
+   "insert into base_node values ("
+   "  1, '', 1, '', null, 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', 'infinity', null, null, '()', null, 0, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'A', null, null, '', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 10, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'B', null, null, '', 'excluded', 'symlink', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'C', null, null, '', 'absent', 'unknown', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'D', null, null, '', 'not-present', 'unknown', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'E', null, null, '', 'incomplete', 'unknown', "
+   "  null, null, null, "
+   "  null, null, null, null, null, null, null, null, null, null); "
+   "insert into base_node values ("
+   "  1, 'F', null, null, '', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'G', 2, 'G-alt', '', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 15, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'H', null, null, '', 'normal', 'symlink', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, 'H-target', null, '()', null, "
+   "  null, null); "
+   "insert into base_node values ("
+   "  1, 'I', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e', null, null, 'J', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e/J-e-a', null, null, 'J/J-e', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e/J-e-b', null, null, 'J/J-e', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-e/J-e-b/Jeba', null, null, 'J/J-e/J-e-b', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-f', null, null, 'J', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'J/J-f/J-f-a', null, null, 'J/J-f', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'K', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'K/K-a', null, null, 'K', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into base_node values ("
+   "  1, 'K/K-b', null, null, 'K', 'normal', 'file', "
+   "  1, '$md5 $" MD5_1 "', 15, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   " "
+#endif
+#ifdef SVN_WC__NODES
    /* load the base nodes into the nodes table */
   "insert into nodes values ("
   "  1, '', 0, null, 1, '', 1, 'normal',"
@@ -173,6 +272,116 @@
   "  null, null, 'file', '()', null, '$md5 $" MD5_1 "', null, 1, " TIME_1s ", '" AUTHOR_1 "',"
   "  15, null, null, null);"
   ""
+#endif
+#ifndef SVN_WC__NODES_ONLY
+   "insert into working_node values ("
+   "  1, 'I', '', 'normal', 'dir', "
+   "  null, null, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', 'immediates', null, "
+   "  2, 'some/dir', 2, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J', '', 'normal', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-a', 'J', 'normal', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-b', 'J', 'normal', 'dir', "
+   "  null, null, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', 'infinity', null, "
+   "  2, 'some/dir', 2, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-b/J-b-a', 'J/J-b', 'normal', 'dir', "
+   "  null, null, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', 'infinity', null, "
+   "  2, 'another/dir', 2, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-b/J-b-b', 'J/J-b', 'normal', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-c', 'J', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-c/J-c-a', 'J/J-c', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-d', 'J', 'normal', 'file', "
+   "  '$md5 $" MD5_1 "', 10, "
+   "  2, " TIME_2s ", '" AUTHOR_2 "', null, null, "
+   "  2, 'moved/file', 2, 1, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e', 'J', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, 'other/place', null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e/J-e-a', 'J/J-e', 'not-present', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e/J-e-b', 'J/J-e', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-e/J-e-b/Jeba', 'J/J-e/J-e-b', 'base-deleted', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-f', 'J', 'normal', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'J/J-f/J-f-a', 'J/J-f', 'base-deleted', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'K', '', 'base-deleted', 'dir', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'K/K-a', 'K', 'base-deleted', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'K/K-b', 'K', 'base-deleted', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, 'moved/away', null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'L', '', 'normal', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'L/L-a', 'L', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   "insert into working_node values ("
+   "  1, 'L/L-a/L-a-a', 'L', 'not-present', 'dir', "
+   "  null, null, "
+   "  null, null, null, 'immediates', null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+   " "
+#endif
+#ifdef SVN_WC__NODES
    /* Load data into NODES table;
       ### op_depths have not been calculated by me yet;
       the value 1 is just 'good enough' to make the nodes WORKING nodes. */
@@ -260,10 +469,24 @@
   "  1, 'L/L-a/L-a-a', 1, 'L', null, null, null, 'not-present',"
   "  0, null, 'dir', '()', 'immediates', null, null, null, null, null,"
   "  null, null, null, null);"
+#endif
    "insert into actual_node values ("
    "  1, 'I', '', null, null, null, null, null, 'changelist', null, "
    "'" I_TC_DATA "', null, null, null, null);"
    "  "
+#ifndef SVN_WC__NODES_ONLY
+   "insert into base_node values ("
+   "  1, 'M', null, null, '', 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', null, null, null, '()', null, null, "
+   "  null); "
+   "insert into working_node values ("
+   "  1, 'M/M-a', 'M', 'not-present', 'file', "
+   "  null, null, "
+   "  null, null, null, null, null, "
+   "  null, null, null, 0, null, null, '()', 0); "
+#endif
+#ifdef SVN_WC__NODES
    "insert into nodes values ("
    "  1, 'M', 0, '', null, null, 1, 'normal', "
    "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 "', "
@@ -272,6 +495,7 @@
    "  1, 'M/M-a', 0, 'M', null, null, 1, 'not-present', "
    "  null, null, 'file', '()', null, null, null, 1, null, null, "
    "  null, null, null, null);"
+#endif
    );
 
 
@@ -285,10 +509,19 @@
    "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
    "insert into wcroot values (1, null); "
 
+#ifndef SVN_WC__NODES_ONLY
+   "insert into base_node values ("
+   "  1, '', 1, 'M', null, 'normal', 'dir', "
+   "  1, null, null, "
+   "  1, " TIME_1s ", '" AUTHOR_1 "', 'infinity', null, null, '()', null, 0, "
+   "  null); "
+#endif
+#ifdef SVN_WC__NODES
    "insert into nodes values ("
    "  1, '', 0, null, 1, 'M', 1, 'normal',"
    "  null, null, 'dir', '()', 'infinity', null, null, 1, " TIME_1s ", '" AUTHOR_1 "',"
    "  null, null, null, null);"
+#endif
    );
 
 WC_QUERIES_SQL_DECLARE_STATEMENTS(statements);
@@ -326,13 +559,17 @@
   const char *dirpath;
   const char * const my_statements[] = {
     statements[STMT_CREATE_SCHEMA],
+#ifdef SVN_WC__NODES
     statements[STMT_CREATE_NODES],
+#endif
     TESTING_DATA,
     NULL
   };
   const char * const M_statements[] = {
     statements[STMT_CREATE_SCHEMA],
+#ifdef SVN_WC__NODES
     statements[STMT_CREATE_NODES],
+#endif
     M_TESTING_DATA,
     NULL
   };
@@ -531,7 +768,7 @@
                       SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL, pool));
   SVN_ERR(svn_wc_locked(&locked, D3, pool));
   SVN_TEST_ASSERT(locked);
-  SVN_ERR(svn_wc_revert3(D, adm_access, svn_depth_infinity, FALSE,
+  SVN_ERR(svn_wc_revert3(D, adm_access, -1, FALSE,
                          NULL, NULL, NULL, NULL, NULL, pool));
   SVN_ERR(svn_wc_locked(&locked, D3, pool));
   SVN_TEST_ASSERT(!locked);
Index: subversion/tests/cmdline/revert_tests.py
===================================================================
--- subversion/tests/cmdline/revert_tests.py	(revision 1023844)
+++ subversion/tests/cmdline/revert_tests.py	(revision 1005387)
@@ -847,7 +847,15 @@
                                        dry_run = 0)
 
   # now test if the revert works ok
-  revert_paths = [G_path]
+  revert_paths = [G_path,
+                  os.path.join(G_path, 'alpha'),
+                  os.path.join(G_path, 'beta')]
+
+  if svntest.main.wc_is_singledb(wc_dir):
+    # These nodes are not lost in single-db
+    revert_paths += [ os.path.join(G_path, 'pi'),
+                      os.path.join(G_path, 'rho'),
+                      os.path.join(G_path, 'tau')]
 
   expected_output = svntest.verify.UnorderedOutput([
     "Reverted '%s'\n" % path for path in revert_paths])
Index: subversion/tests/cmdline/svnsync_tests.py
===================================================================
--- subversion/tests/cmdline/svnsync_tests.py	(revision 1023844)
+++ subversion/tests/cmdline/svnsync_tests.py	(revision 1005387)
@@ -136,14 +136,21 @@
     raise SVNUnexpectedStdout("Missing stdout")
 
 
-def setup_and_sync(sbox, dump_file_contents, subdir=None):
-  """Create a repository for SBOX, load it with DUMP_FILE_CONTENTS, then create a mirror repository and sync it with SBOX.  Return the mirror sandbox."""
+def run_test(sbox, dump_file_name, subdir = None, exp_dump_file_name = None):
+  """Load a dump file, sync repositories, and compare contents with the original
+or another dump file."""
 
   # Create the empty master repository.
   build_repos(sbox)
 
-  # Load the repository from DUMP_FILE_PATH.
-  svntest.actions.run_and_verify_load(sbox.repo_dir, dump_file_contents)
+  # This directory contains all the dump files
+  svnsync_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
+                                   'svnsync_tests_data')
+  # Load the specified dump file into the master repository.
+  master_dumpfile_contents = open(os.path.join(svnsync_tests_dir,
+                                               dump_file_name),
+                                  'rb').readlines()
+  svntest.actions.run_and_verify_load(sbox.repo_dir, master_dumpfile_contents)
 
   # Create the empty destination repository.
   dest_sbox = sbox.clone_dependent()
@@ -166,11 +173,6 @@
   run_sync(dest_sbox.repo_url, repo_url)
   run_copy_revprops(dest_sbox.repo_url, repo_url)
 
-  return dest_sbox
-
-def verify_mirror(dest_sbox, exp_dump_file_contents):
-  """Compare the contents of the DEST_SBOX repository with EXP_DUMP_FILE_CONTENTS."""
-
   # Remove some SVNSync-specific housekeeping properties from the
   # mirror repository in preparation for the comparison dump.
   for prop_name in ("svn:sync-from-url", "svn:sync-from-uuid",
@@ -182,24 +184,6 @@
   # Create a dump file from the mirror repository.
   dest_dump = svntest.actions.run_and_verify_dump(dest_sbox.repo_dir)
 
-  svntest.verify.compare_and_display_lines(
-    "Dump files", "DUMP", exp_dump_file_contents, dest_dump)
-  
-def run_test(sbox, dump_file_name, subdir=None, exp_dump_file_name=None):
-  """Load a dump file, sync repositories, and compare contents with the original
-or another dump file."""
-
-  # This directory contains all the dump files
-  svnsync_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
-                                   'svnsync_tests_data')
-
-  # Load the specified dump file into the master repository.
-  master_dumpfile_contents = open(os.path.join(svnsync_tests_dir,
-                                               dump_file_name),
-                                  'rb').readlines()
-
-  dest_sbox = setup_and_sync(sbox, master_dumpfile_contents, subdir)
-
   # Compare the dump produced by the mirror repository with either the original
   # dump file (used to create the master repository) or another specified dump
   # file.
@@ -209,8 +193,8 @@
   else:
     exp_master_dumpfile_contents = master_dumpfile_contents
 
-  verify_mirror(dest_sbox, exp_master_dumpfile_contents)
-  
+  svntest.verify.compare_and_display_lines(
+    "Dump files", "DUMP", exp_master_dumpfile_contents, dest_dump)
 
 
 ######################################################################
@@ -797,37 +781,6 @@
   run_test(sbox, "descend_into_replace.dump", subdir='/trunk/H',
            exp_dump_file_name = "descend_into_replace.expected.dump")
 
-# issue #3728
-def delete_revprops(sbox):
-  "copy-revprops with removals"
-  svnsync_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
-                                   'svnsync_tests_data')
-  initial_contents  = open(os.path.join(svnsync_tests_dir,
-                                        "delete-revprops.dump"),
-                           'rb').readlines()
-  expected_contents = open(os.path.join(svnsync_tests_dir,
-                                        "delete-revprops.expected.dump"),
-                           'rb').readlines()
-
-  # Create the initial repos and mirror, and sync 'em.
-  dest_sbox = setup_and_sync(sbox, initial_contents)
-
-  # Now remove a revprop from r1 of the source, and run 'svnsync
-  # copy-revprops' to re-sync 'em.
-  svntest.actions.enable_revprop_changes(sbox.repo_dir)
-  exit_code, out, err = svntest.main.run_svn(None,
-                                             'pdel',
-                                             '-r', '1',
-                                             '--revprop',
-                                             'issue-id',
-                                             sbox.repo_url)
-  if err:
-    raise SVNUnexpectedStderr(err)
-  run_copy_revprops(dest_sbox.repo_url, sbox.repo_url)
-
-  # Does the result look as we expected?
-  verify_mirror(dest_sbox, expected_contents)
-
 ########################################################################
 # Run the tests
 
@@ -868,7 +821,6 @@
               delete_svn_props,
               commit_a_copy_of_root,
               descend_into_replace,
-              XFail(delete_revprops),
              ]
 
 if __name__ == '__main__':
Index: subversion/tests/cmdline/svntest/tree.py
===================================================================
--- subversion/tests/cmdline/svntest/tree.py	(revision 1023844)
+++ subversion/tests/cmdline/svntest/tree.py	(revision 1005387)
@@ -413,6 +413,23 @@
     prev_node = new_node
 
 
+def compare_atts(a, b):
+  """Compare two dictionaries of attributes, A (actual) and B (expected).
+  If the attribute 'treeconflict' in B is missing or is 'None', ignore it.
+  Return 0 if the same, 1 otherwise."""
+  a = a.copy()
+  b = b.copy()
+  # Remove any attributes to ignore.
+  for att in ['treeconflict']:
+    if (att not in b) or (b[att] is None):
+      if att in a:
+        del a[att]
+      if att in b:
+        del b[att]
+  if a != b:
+    return 1
+  return 0
+
 # Helper for compare_trees
 def compare_file_nodes(a, b):
   """Compare two nodes, A (actual) and B (expected). Compare their names,
@@ -424,9 +441,7 @@
     return 1
   if a.props != b.props:
     return 1
-  if a.atts != b.atts:
-    return 1
-  return 0
+  return compare_atts(a.atts, b.atts)
 
 
 # Internal utility used by most build_tree_from_foo() routines.
@@ -643,7 +658,7 @@
     # They're both directories.
     else:
       # First, compare the directories' two hashes.
-      if (a.props != b.props) or (a.atts != b.atts):
+      if (a.props != b.props) or compare_atts(a.atts, b.atts):
         display_nodes(a, b)
         raise SVNTreeUnequal
 
Index: subversion/tests/cmdline/merge_tests.py
===================================================================
--- subversion/tests/cmdline/merge_tests.py	(revision 1023844)
+++ subversion/tests/cmdline/merge_tests.py	(revision 1005387)
@@ -11830,7 +11830,7 @@
 
   # Repeat the forward merge
   expected_output = expected_merge_output(
-    [[5],[8],[5,9]],
+    [[5],[8,9],[5,9]],
     ['U    %s\n' % (rho_COPY_2_path),
      'U    %s\n' % (psi_COPY_2_path),
      ' U   %s\n' % (H_COPY_2_path),
@@ -13678,7 +13678,7 @@
                                        expected_elision_output,
                                        expected_disk,
                                        expected_status, expected_skip,
-                                       None, None, None, None, None, 1, 0)
+                                       None, None, None, None, None, 1)
 
 #----------------------------------------------------------------------
 def no_self_referential_filtering_on_added_path(sbox):
@@ -13845,12 +13845,10 @@
   nu_path         = os.path.join(wc_dir, "A", "D", "H", "nu")
   nu_moved_path   = os.path.join(wc_dir, "A", "D", "H", "nu_moved")
   A_path          = os.path.join(wc_dir, "A")
-  alpha_path      = os.path.join(wc_dir, "A", "B", "E", "alpha")
   A_COPY_path     = os.path.join(wc_dir, "A_COPY")
   A_COPY_2_path   = os.path.join(wc_dir, "A_COPY_2")
   B_COPY_path     = os.path.join(wc_dir, "A_COPY", "B")
   B_COPY_2_path   = os.path.join(wc_dir, "A_COPY_2", "B")
-  alpha_COPY_path = os.path.join(wc_dir, "A_COPY", "B", "E", "alpha")
   beta_COPY_path  = os.path.join(wc_dir, "A_COPY", "B", "E", "beta")
   gamma_COPY_path = os.path.join(wc_dir, "A_COPY", "D", "gamma")
   rho_COPY_path   = os.path.join(wc_dir, "A_COPY", "D", "G", "rho")
@@ -13867,33 +13865,22 @@
   # r7 - Text change to A/D/H/omega
   wc_disk, wc_status = set_up_branch(sbox, False, 2)
 
-  # r8 - Text change to A/B/E/alpha  
-  svntest.main.file_write(alpha_path, "New content")
-  wc_status.tweak('A/B/E/alpha', wc_rev=8)
-  svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
-                                     'Text change', wc_dir)
-
-  # r9 - Add the file A/D/H/nu and make another change to A/B/E/alpha.
-  svntest.main.file_write(alpha_path, "Even newer content")
+  # r8 - Add the file A/D/H/nu
   svntest.main.file_write(nu_path, "This is the file 'nu'.\n")
   svntest.actions.run_and_verify_svn(None, None, [], 'add', nu_path)
-  expected_output = wc.State(wc_dir,
-                             {'A/D/H/nu'    : Item(verb='Adding'),
-                              'A/B/E/alpha' : Item(verb='Sending')})
-  wc_status.add({'A/D/H/nu' : Item(status='  ', wc_rev=9)})
-  wc_status.tweak('A/B/E/alpha', wc_rev=9)
+  expected_output = wc.State(wc_dir, {'A/D/H/nu' : Item(verb='Adding')})
+  wc_status.add({'A/D/H/nu' : Item(status='  ', wc_rev=8)})
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         wc_status, None, wc_dir)
 
-  # r10 - Merge all available revisions (i.e. -r1:9) from A to A_COPY.
-  svntest.actions.run_and_verify_svn(None, ["At revision 9.\n"], [], 'up',
+  # r9 - Merge all available revisions (i.e. -r1:8) from A to A_COPY.
+  svntest.actions.run_and_verify_svn(None, ["At revision 8.\n"], [], 'up',
                                      wc_dir)
-  wc_status.tweak(wc_rev=9)
+  wc_status.tweak(wc_rev=8)
   svntest.actions.run_and_verify_svn(
     None,
-    expected_merge_output([[2,9]],
+    expected_merge_output([[2,8]],
                           ['A    ' + nu_COPY_path  + '\n',
-                           'U    ' + alpha_COPY_path + '\n',
                            'U    ' + beta_COPY_path  + '\n',
                            'U    ' + rho_COPY_path   + '\n',
                            'U    ' + omega_COPY_path + '\n',
@@ -13903,104 +13890,98 @@
   expected_output = wc.State(wc_dir,
                              {'A_COPY'           : Item(verb='Sending'),
                               'A_COPY/D/H/nu'    : Item(verb='Adding'),
-                              'A_COPY/B/E/alpha' : Item(verb='Sending'),
                               'A_COPY/B/E/beta'  : Item(verb='Sending'),
                               'A_COPY/D/G/rho'   : Item(verb='Sending'),
                               'A_COPY/D/H/omega' : Item(verb='Sending'),
                               'A_COPY/D/H/psi'   : Item(verb='Sending')})
   wc_status.tweak('A_COPY',
-                  'A_COPY/B/E/alpha',
                   'A_COPY/B/E/beta',
                   'A_COPY/D/G/rho',
                   'A_COPY/D/H/omega',
                   'A_COPY/D/H/psi',
-                  wc_rev=10)
-  wc_status.add({'A_COPY/D/H/nu' : Item(status='  ', wc_rev=10)})
+                  wc_rev=9)
+  wc_status.add({'A_COPY/D/H/nu' : Item(status='  ', wc_rev=9)})
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         wc_status, None, wc_dir)
 
-  # r11 - Reverse merge -r9:1 from A/B to A_COPY/B
-  svntest.actions.run_and_verify_svn(None, ["At revision 10.\n"], [], 'up',
+  # r10 - Reverse merge -r8:1 from A/B to A_COPY/B
+  svntest.actions.run_and_verify_svn(None, ["At revision 9.\n"], [], 'up',
                                      wc_dir)
-  wc_status.tweak(wc_rev=10)
+  wc_status.tweak(wc_rev=9)
   svntest.actions.run_and_verify_svn(
     None,
-    expected_merge_output([[9,2]], ['U    ' + alpha_COPY_path + '\n',
-                                    'U    ' + beta_COPY_path  + '\n',
+    expected_merge_output([[8,2]], ['U    ' + beta_COPY_path  + '\n',
                                     ' G   ' + B_COPY_path     + '\n',]),
-    [], 'merge', sbox.repo_url + '/A/B', B_COPY_path, '-r9:1')
+    [], 'merge', sbox.repo_url + '/A/B', B_COPY_path, '-r8:1')
   expected_output = wc.State(wc_dir,
-                             {'A_COPY/B'         : Item(verb='Sending'),
-                              'A_COPY/B/E/alpha' : Item(verb='Sending'),
-                              'A_COPY/B/E/beta'  : Item(verb='Sending')})
+                             {'A_COPY/B'        : Item(verb='Sending'),
+                              'A_COPY/B/E/beta' : Item(verb='Sending')})
   wc_status.tweak('A_COPY/B',
-                  'A_COPY/B/E/alpha',
-                  'A_COPY/B/E/beta',                  
-                  wc_rev=11)
+                  'A_COPY/B/E/beta',
+                  wc_rev=10)
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         wc_status, None, wc_dir)
 
-  # r12 - Move A/D/H/nu to A/D/H/nu_moved
+  # r11 - Move A/D/H/nu to A/D/H/nu_moved
   svntest.actions.run_and_verify_svn(None, ["\n",
-                                            "Committed revision 12.\n"], [],
+                                            "Committed revision 11.\n"], [],
                                      'move', sbox.repo_url + '/A/D/H/nu',
                                      sbox.repo_url + '/A/D/H/nu_moved',
                                      '-m', 'Move nu to nu_moved')
   svntest.actions.run_and_verify_svn(None,
                                      ["D    " + nu_path + "\n",
                                       "A    " + nu_moved_path + "\n",
-                                      "Updated to revision 12.\n"],
+                                      "Updated to revision 11.\n"],
                                      [], 'up', wc_dir)
 
-  # Now merge -r7:12 from A to A_COPY.
-  # A_COPY needs only -r10:12, which amounts to the rename of nu.
-  # The subtree A_COPY/B needs the entire range -r7:12 because of
-  # the reverse merge we performed in r11; the only operative change
-  # here is the text mod to alpha made in r9.
+  # Now merge -r6:11 from A to A_COPY.
+  # A_COPY needs only -r8:11, which amounts only to the rename of nu.
+  # The subtree A_COPY/B needs the entire range -r6:11 because of
+  # the reverse merge we performed in r10; but none of these revisions
+  # is operative in A/B so there are no changes to A_COPY/B.
   #
-  # This merge previously failed because the delete half of the A_COPY/D/H/nu
-  # to A_COPY/D/H/nu_moved move was reported in the notifications, but didn't
+  # This merge currently fails because the delete half of the A_COPY/D/H/nu
+  # to A_COPY/D/H/nu_moved move is reported in the notifications, but doesn't
   # actually happen.
   expected_output = wc.State(A_COPY_path, {
-    'B/E/alpha'    : Item(status='U '),
     'D/H/nu'       : Item(status='D '),
     'D/H/nu_moved' : Item(status='A '),
     })
   expected_mergeinfo_output = wc.State(A_COPY_path, {
-    ''  : Item(status=' U'),
-    'B' : Item(status=' U'),
+    '' : Item(status=' U'),
     })
   expected_elision_output = wc.State(A_COPY_path, {
     })
   expected_status = wc.State(A_COPY_path, {
-    ''             : Item(status=' M', wc_rev=12),
-    'B'            : Item(status=' M', wc_rev=12),
-    'mu'           : Item(status='  ', wc_rev=12),
-    'B/E'          : Item(status='  ', wc_rev=12),
-    'B/E/alpha'    : Item(status='M ', wc_rev=12),
-    'B/E/beta'     : Item(status='  ', wc_rev=12),
-    'B/lambda'     : Item(status='  ', wc_rev=12),
-    'B/F'          : Item(status='  ', wc_rev=12),
-    'C'            : Item(status='  ', wc_rev=12),
-    'D'            : Item(status='  ', wc_rev=12),
-    'D/G'          : Item(status='  ', wc_rev=12),
-    'D/G/pi'       : Item(status='  ', wc_rev=12),
-    'D/G/rho'      : Item(status='  ', wc_rev=12),
-    'D/G/tau'      : Item(status='  ', wc_rev=12),
-    'D/gamma'      : Item(status='  ', wc_rev=12),
-    'D/H'          : Item(status='  ', wc_rev=12),
-    'D/H/nu'       : Item(status='D ', wc_rev=12),
+    ''             : Item(status=' M', wc_rev=11),
+    'B'            : Item(status='  ', wc_rev=11),
+    'mu'           : Item(status='  ', wc_rev=11),
+    'B/E'          : Item(status='  ', wc_rev=11),
+    'B/E/alpha'    : Item(status='  ', wc_rev=11),
+    'B/E/beta'     : Item(status='  ', wc_rev=11),
+    'B/lambda'     : Item(status='  ', wc_rev=11),
+    'B/F'          : Item(status='  ', wc_rev=11),
+    'C'            : Item(status='  ', wc_rev=11),
+    'D'            : Item(status='  ', wc_rev=11),
+    'D/G'          : Item(status='  ', wc_rev=11),
+    'D/G/pi'       : Item(status='  ', wc_rev=11),
+    'D/G/rho'      : Item(status='  ', wc_rev=11),
+    'D/G/tau'      : Item(status='  ', wc_rev=11),
+    'D/gamma'      : Item(status='  ', wc_rev=11),
+    'D/H'          : Item(status='  ', wc_rev=11),
+    'D/H/nu'       : Item(status='D ', wc_rev=11),
     'D/H/nu_moved' : Item(status='A ', wc_rev='-', copied='+'),
-    'D/H/chi'      : Item(status='  ', wc_rev=12),
-    'D/H/psi'      : Item(status='  ', wc_rev=12),
-    'D/H/omega'    : Item(status='  ', wc_rev=12),
+    'D/H/chi'      : Item(status='  ', wc_rev=11),
+    'D/H/psi'      : Item(status='  ', wc_rev=11),
+    'D/H/omega'    : Item(status='  ', wc_rev=11),
     })
   expected_disk = wc.State('', {
-    ''             : Item(props={SVN_PROP_MERGEINFO : '/A:2-12'}),
+    ''             : Item(props={SVN_PROP_MERGEINFO : '/A:2-11'}),
     'mu'           : Item("This is the file 'mu'.\n"),
-    'B'            : Item(props={SVN_PROP_MERGEINFO : '/A/B:8-12'}),
+    # A_COPY/B wasn't touched by the merge so keeps its existing mergeinfo.
+    'B'            : Item(props={SVN_PROP_MERGEINFO : ''}),
     'B/E'          : Item(),
-    'B/E/alpha'    : Item("Even newer content"),
+    'B/E/alpha'    : Item("This is the file 'alpha'.\n"),
     'B/E/beta'     : Item("This is the file 'beta'.\n"),
     'B/lambda'     : Item("This is the file 'lambda'.\n"),
     'B/F'          : Item(),
@@ -14018,7 +13999,7 @@
     'D/H/omega'    : Item("New content"),
     })
   expected_skip = wc.State(A_COPY_path, {})
-  svntest.actions.run_and_verify_merge(A_COPY_path, 7, 12,
+  svntest.actions.run_and_verify_merge(A_COPY_path, 6, 11,
                                        sbox.repo_url + '/A', None,
                                        expected_output,
                                        expected_mergeinfo_output,
@@ -14027,89 +14008,80 @@
                                        expected_status,
                                        expected_skip,
                                        None, None, None, None,
-                                       None, 1, 0)
+                                       None, 1, 1)
   svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
-                                     'Merge -r7:12 from A to A_COPY', wc_dir)
+                                     'Merge -r6:11 from A to A_COPY', wc_dir)
 
   # Now run a similar scenario as above on the second branch, but with
   # a reverse merge this time.
   #
-  # r14 - Merge all available revisions from A/B to A_COPY_B and then merge
-  # -r2:9 from A to A_COPY_2.  Among other things, this adds A_COPY_2/D/H/nu
+  # r13 - Merge all available revisions from A/B to A_COPY_B and then merge
+  # -r2:8 from A to A_COPY_2.  Among other things, this adds A_COPY_2/D/H/nu
   # and leaves us with mergeinfo on the A_COPY_2 branch of:
   #
   #   Properties on 'A_COPY_2':
   #     svn:mergeinfo
-  #       /A:3-9
+  #       /A:3-8
   #   Properties on 'A_COPY_2\B':
   #     svn:mergeinfo
-  #       /A/B:3-13
-  svntest.actions.run_and_verify_svn(None, ["At revision 13.\n"], [], 'up',
+  #       /A/B:3-12
+  svntest.actions.run_and_verify_svn(None, ["At revision 12.\n"], [], 'up',
                                      wc_dir)
   svntest.actions.run_and_verify_svn(None,
                                      None, # Don't check stdout, we test this
                                            # type of merge to death elsewhere.
                                      [], 'merge', sbox.repo_url + '/A/B',
                                      B_COPY_2_path)
-  svntest.actions.run_and_verify_svn(None, None,[], 'merge', '-r', '2:9',
+  svntest.actions.run_and_verify_svn(None, None,[], 'merge', '-r', '2:8',
                                      sbox.repo_url + '/A', A_COPY_2_path)  
   svntest.actions.run_and_verify_svn(
     None, None, [], 'ci', '-m',
-    'Merge all from A/B to A_COPY_2/B\nMerge -r2:9 from A to A_COPY_2',
+    'Merge all from A/B to A_COPY_2/B\nMerge -r2:8 from A to A_COPY_2',
     wc_dir)
-  svntest.actions.run_and_verify_svn(None, ["At revision 14.\n"], [], 'up',
+  svntest.actions.run_and_verify_svn(None, ["At revision 13.\n"], [], 'up',
                                      wc_dir)
 
-  # Now reverse merge -r13:7 from A to A_COPY_2.
+  # Now reverse merge -r12:7 from A to A_COPY_2.
   #
   # Recall:
   #
-  #   >svn log -r8:13 ^/A -v
+  #   >svn log -r8:12 ^/A -v
   #   ------------------------------------------------------------------------
-  #   r8 | jrandom | 2010-10-14 11:25:59 -0400 (Thu, 14 Oct 2010) | 1 line
+  #   r8 | jrandom | 2010-10-05 11:52:17 -0400 (Tue, 05 Oct 2010) | 1 line
   #   Changed paths:
-  #      M /A/B/E/alpha
-  #
-  #   Text change
-  #   ------------------------------------------------------------------------
-  #   r9 | jrandom | 2010-10-14 11:25:59 -0400 (Thu, 14 Oct 2010) | 1 line
-  #   Changed paths:
-  #      M /A/B/E/alpha
   #      A /A/D/H/nu
-  #
+  #   
   #   log msg
   #   ------------------------------------------------------------------------
-  #   r12 | jrandom | 2010-10-14 11:26:01 -0400 (Thu, 14 Oct 2010) | 1 line
+  #   r11 | jrandom | 2010-10-05 11:52:19 -0400 (Tue, 05 Oct 2010) | 1 line
   #   Changed paths:
   #      D /A/D/H/nu
-  #      A /A/D/H/nu_moved (from /A/D/H/nu:11)
+  #      A /A/D/H/nu_moved (from /A/D/H/nu:10)
   #
   #   Move nu to nu_moved
   #   ------------------------------------------------------------------------
   #
-  # We can only reverse merge changes from the explicit mergeinfo or
-  # natural history of a target, but since all of these changes intersect with
-  # the target's explicit mergeinfo (including subtrees), all should be
-  # reverse merged, including the deletion of A_COPY/D/H/nu.  Like the forward
-  # merge performed earlier, this test previously failed when A_COPY/D/H/nu
-  # was reported as deleted, but still remained as a versioned item in the WC.
+  # None of those revisions touch A/B, so A_COPY_2/B will remain unchanged by
+  # the merge.  Since we can only reverse merge changes from the explicit
+  # mergeinfo or natural history of a target, the only eligible revision to
+  # affect the remainder of the tree  rooted at A_COPY_2 is r8, the addition
+  # of A/D/H/nu.  So A_COPY/D/H/nu should deleted.  However, like the forward
+  # merge performed earlier, A_COPY/D/H/nu is reported as deleted, but still
+  # remains in the WC.
   expected_output = wc.State(A_COPY_2_path, {
-    'B/E/alpha'    : Item(status='U '),
     'D/H/nu'       : Item(status='D '),
     })
   expected_mergeinfo_output = wc.State(A_COPY_2_path, {
-    ''  : Item(status=' U'),
-    'B' : Item(status=' U'),
+    '' : Item(status=' U'),
     })
   expected_elision_output = wc.State(A_COPY_2_path, {
-    'B' : Item(status=' U'),
     })
   expected_status = wc.State(A_COPY_2_path, {
     ''             : Item(status=' M'),
-    'B'            : Item(status=' M'),
+    'B'            : Item(status='  '),
     'mu'           : Item(status='  '),
     'B/E'          : Item(status='  '),
-    'B/E/alpha'    : Item(status='M '),
+    'B/E/alpha'    : Item(status='  '),
     'B/E/beta'     : Item(status='  '),
     'B/lambda'     : Item(status='  '),
     'B/F'          : Item(status='  '),
@@ -14126,11 +14098,12 @@
     'D/H/psi'      : Item(status='  '),
     'D/H/omega'    : Item(status='  '),
     })
-  expected_status.tweak(wc_rev=14)
+  expected_status.tweak(wc_rev=13)
   expected_disk = wc.State('', {
     ''             : Item(props={SVN_PROP_MERGEINFO : '/A:3-7'}),
     'mu'           : Item("This is the file 'mu'.\n"),
-    'B'            : Item(),
+    # A_COPY_2/B wasn't touched by the merge so keeps its existing mergeinfo.
+    'B'            : Item(props={SVN_PROP_MERGEINFO : '/A/B:3-12'}),
     'B/E'          : Item(),
     'B/E/alpha'    : Item("This is the file 'alpha'.\n"),
     'B/E/beta'     : Item("New content"),
@@ -14149,7 +14122,7 @@
     'D/H/omega'    : Item("New content"),
     })
   expected_skip = wc.State(A_COPY_path, {})
-  svntest.actions.run_and_verify_merge(A_COPY_2_path, 13, 7,
+  svntest.actions.run_and_verify_merge(A_COPY_2_path, 12, 7,
                                        sbox.repo_url + '/A', None,
                                        expected_output,
                                        expected_mergeinfo_output,
@@ -16210,8 +16183,8 @@
                          server_has_mergeinfo),
               SkipUnless(no_self_referential_filtering_on_added_path,
                          server_has_mergeinfo),
-              SkipUnless(merge_range_prior_to_rename_source_existence,
-                         server_has_mergeinfo),
+              XFail(SkipUnless(merge_range_prior_to_rename_source_existence,
+                               server_has_mergeinfo)),
               SkipUnless(dont_merge_gaps_in_history,
                          server_has_mergeinfo),
               SkipUnless(mergeinfo_deleted_by_a_merge_should_disappear,
Index: subversion/tests/cmdline/svnsync_tests_data/delete-revprops.dump
===================================================================
--- subversion/tests/cmdline/svnsync_tests_data/delete-revprops.dump	(revision 1023844)
+++ subversion/tests/cmdline/svnsync_tests_data/delete-revprops.dump	(revision 1005387)
@@ -1,45 +0,0 @@
-SVN-fs-dump-format-version: 2
-
-UUID: 8e4a7212-d56e-11df-8ee9-37196cd04bc1
-
-Revision-number: 0
-Prop-content-length: 56
-Content-length: 56
-
-K 8
-svn:date
-V 27
-2010-10-11T19:34:25.487865Z
-PROPS-END
-
-Revision-number: 1
-Prop-content-length: 136
-Content-length: 136
-
-K 8
-issue-id
-V 4
-1729
-K 10
-svn:author
-V 8
-cmpilato
-K 8
-svn:date
-V 27
-2010-10-11T19:55:50.912266Z
-K 7
-svn:log
-V 11
-Create dir1
-PROPS-END
-
-Node-path: dir1
-Node-kind: dir
-Node-action: add
-Prop-content-length: 10
-Content-length: 10
-
-PROPS-END
-
-
Index: subversion/tests/cmdline/svnsync_tests_data/delete-revprops.expected.dump
===================================================================
--- subversion/tests/cmdline/svnsync_tests_data/delete-revprops.expected.dump	(revision 1023844)
+++ subversion/tests/cmdline/svnsync_tests_data/delete-revprops.expected.dump	(revision 1005387)
@@ -1,41 +0,0 @@
-SVN-fs-dump-format-version: 2
-
-UUID: 8e4a7212-d56e-11df-8ee9-37196cd04bc1
-
-Revision-number: 0
-Prop-content-length: 56
-Content-length: 56
-
-K 8
-svn:date
-V 27
-2010-10-11T19:34:25.487865Z
-PROPS-END
-
-Revision-number: 1
-Prop-content-length: 114
-Content-length: 114
-
-K 10
-svn:author
-V 8
-cmpilato
-K 8
-svn:date
-V 27
-2010-10-11T19:55:50.912266Z
-K 7
-svn:log
-V 11
-Create dir1
-PROPS-END
-
-Node-path: dir1
-Node-kind: dir
-Node-action: add
-Prop-content-length: 10
-Content-length: 10
-
-PROPS-END
-
-
Index: subversion/tests/cmdline/tree_conflict_tests.py
===================================================================
--- subversion/tests/cmdline/tree_conflict_tests.py	(revision 1023844)
+++ subversion/tests/cmdline/tree_conflict_tests.py	(revision 1005387)
@@ -1053,7 +1053,7 @@
   expected_disk = main.greek_state.copy()
   expected_disk.remove('iota')
   expected_status = get_virginal_state(wc_dir, 1)
-  expected_status.tweak('iota', status='D ', writelocked='O')
+  expected_status.tweak('iota', status='D ')
   run_and_verify_update(wc_dir,
                         None, expected_disk, expected_status,
                         None, None, None, None, None, 1,
Index: subversion/tests/cmdline/lock_tests.py
===================================================================
--- subversion/tests/cmdline/lock_tests.py	(revision 1023844)
+++ subversion/tests/cmdline/lock_tests.py	(revision 1005387)
@@ -37,24 +37,6 @@
 Item = svntest.wc.StateItem
 
 ######################################################################
-# Helpers
-
-def check_writability(path, writable):
-  bits = stat.S_IWGRP | stat.S_IWOTH | stat.S_IWRITE
-  mode = os.stat(path)[0]
-  if bool(mode & bits) != writable:
-    raise svntest.Failure("path '%s' is unexpectedly %s (mode %o)"
-                          % (path, ["writable", "read-only"][writable], mode))
-
-def is_writable(path):
-  "Raise if PATH is not writable."
-  check_writability(path, True)
-
-def is_readonly(path):
-  "Raise if PATH is not readonly."
-  check_writability(path, False)
-
-######################################################################
 # Tests
 
 #----------------------------------------------------------------------
@@ -1591,48 +1573,6 @@
                                      'commit', '-m', '', G_path)
 
 
-#----------------------------------------------------------------------
-def cp_isnt_ro(sbox):
-  "uncommitted svn:needs-lock add/cp not read-only"
-
-  sbox.build()
-  wc_dir = sbox.wc_dir
-
-  mu_URL = sbox.repo_url + '/A/mu'
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  mu2_path = os.path.join(wc_dir, 'A', 'mu2')
-  mu3_path = os.path.join(wc_dir, 'A', 'mu3')
-  kappa_path = os.path.join(wc_dir, 'kappa')
-  open(kappa_path, 'w').write("This is the file 'kappa'.\n")
-
-  ## added file
-  sbox.simple_add(kappa_path)
-  svntest.actions.set_prop('svn:needs-lock', 'yes', kappa_path)
-  is_writable(kappa_path)
-  sbox.simple_commit(kappa_path)
-  is_readonly(kappa_path)
-
-  ## versioned file
-  svntest.actions.set_prop('svn:needs-lock', 'yes', mu_path)
-  is_writable(mu_path)
-  sbox.simple_commit(mu_path)
-  is_readonly(mu_path)
-
-  # At this point, mu has 'svn:needs-lock' set
-
-  ## wc->wc copied file
-  svntest.main.run_svn(None, 'copy', mu_path, mu2_path)
-  is_writable(mu2_path)
-  sbox.simple_commit(mu2_path)
-  is_readonly(mu2_path)
-
-  ## URL->wc copied file
-  svntest.main.run_svn(None, 'copy', mu_URL, mu3_path)
-  is_writable(mu3_path)
-  sbox.simple_commit(mu3_path)
-  is_readonly(mu3_path)
-
-
 ########################################################################
 # Run the tests
 
@@ -1679,7 +1619,6 @@
               verify_path_escaping,
               XFail(replace_and_propset_locked_path,
                     svntest.main.is_ra_type_dav),
-              cp_isnt_ro,
             ]
 
 if __name__ == '__main__':
Index: subversion/tests/cmdline/switch_tests.py
===================================================================
--- subversion/tests/cmdline/switch_tests.py	(revision 1023844)
+++ subversion/tests/cmdline/switch_tests.py	(revision 1005387)
@@ -2778,7 +2778,7 @@
                         'DF/D1',
                         'DDD/D1',
                         'DDF/D1',
-                        status='! ', treeconflict='C', wc_rev=None)
+                        status='! ', wc_rev=None)
   # Remove from expected status and disk everything below the deleted paths.
   expected_status.remove('DD/D1/D2',
                          'DF/D1/beta',
Index: subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
===================================================================
--- subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout	(revision 1023844)
+++ subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout	(revision 1005387)
@@ -149,10 +149,10 @@
                                 'PREV'       revision just before COMMITTED
   -N [--non-recursive]     : obsolete; try --depth=files or --depth=immediates
   --depth ARG              : limit operation by depth ARG ('empty', 'files',
-                             'immediates', or 'infinity')
+                            'immediates', or 'infinity')
   --set-depth ARG          : set new working copy depth to ARG ('exclude',
-                             'empty', 'files', 'immediates', or 'infinity')
-                             [alias: --sd]
+                            'empty', 'files', 'immediates', or 'infinity')
+                            [alias: --sd]
   -q [--quiet]             : print nothing, or only summary information
   --diff3-cmd ARG          : use ARG as merge command
   --relocate               : relocate via URL-rewriting
@@ -160,7 +160,7 @@
                              [alias: --ie]
   --force                  : force operation to run
   --accept ARG             : specify automatic conflict resolution action
-                             ('postpone', 'base', 'mine-conflict',
+                            ('postpone', 'base', 'mine-conflict',
                              'theirs-conflict', 'mine-full', 'theirs-full',
                              'edit', 'launch')
 
Index: subversion/svn/main.c
===================================================================
--- subversion/svn/main.c	(revision 1023844)
+++ subversion/svn/main.c	(revision 1005387)
@@ -125,8 +125,6 @@
   opt_old_patch_target_names,
 } svn_cl__longopt_t;
 
-#define SVN_CL__OPTION_CONTINUATION_INDENT "                             "
-
 /* Option codes and descriptions for the command line client.
  *
  * The entire list must be terminated with an entry of nulls.
@@ -142,32 +140,27 @@
   {"quiet",         'q', 0, N_("print nothing, or only summary information")},
   {"recursive",     'R', 0, N_("descend recursively, same as --depth=infinity")},
   {"non-recursive", 'N', 0, N_("obsolete; try --depth=files or --depth=immediates")},
-  {"change",        'c', 1, 
-                    N_("the change made by revision ARG (like -r ARG-1:ARG)\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "If ARG is negative this is like -r ARG:ARG-1")},
-  {"revision",      'r', 1, 
-                    N_("ARG (some commands also take ARG1:ARG2 range)\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "A revision argument can be one of:\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   NUMBER       revision number\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   '{' DATE '}' revision at start of the date\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   'HEAD'       latest in repository\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   'BASE'       base rev of item's working copy\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   'COMMITTED'  last commit at or before BASE\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   'PREV'       revision just before COMMITTED")},
+  {"change",        'c', 1, N_
+   ("the change made by revision ARG (like -r ARG-1:ARG)\n"
+    "                             If ARG is negative this is like -r ARG:ARG-1")
+  },
+  {"revision",      'r', 1, N_
+   ("ARG (some commands also take ARG1:ARG2 range)\n"
+    "                             A revision argument can be one of:\n"
+    "                                NUMBER       revision number\n"
+    "                                '{' DATE '}' revision at start of the date\n"
+    "                                'HEAD'       latest in repository\n"
+    "                                'BASE'       base rev of item's working copy\n"
+    "                                'COMMITTED'  last commit at or before BASE\n"
+    "                                'PREV'       revision just before COMMITTED")
+   /* spacing corresponds to svn_opt_format_option */
+  },
   {"file",          'F', 1, N_("read log message from file ARG")},
   {"incremental",   opt_incremental, 0,
                     N_("give output suitable for concatenation")},
   {"encoding",      opt_encoding, 1,
                     N_("treat value as being in charset encoding ARG\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --enc]")},
   {"version",       opt_version, 0, N_("show program version information")},
   {"verbose",       'v', 0, N_("print extra information")},
@@ -176,92 +169,92 @@
   {"password",      opt_auth_password, 1, N_("specify a password ARG")},
   {"extensions",    'x', 1,
                     N_("Default: '-u'. When Subversion is invoking an\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "external diff program, ARG is simply passed along\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "to the program. But when Subversion is using its\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "default internal diff implementation, or when\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "Subversion is displaying blame annotations, ARG\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "could be any of the following:\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   -u (--unified):\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "      Output 3 lines of unified context.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   -b (--ignore-space-change):\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "      Ignore changes in the amount of white space.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   -w (--ignore-all-space):\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "      Ignore all white space.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   --ignore-eol-style:\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "      Ignore changes in EOL style.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "   -p (--show-c-function):\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "      Show C function name in diff output.")},
+                       "                            "
+                       " external diff program, ARG is simply passed along\n"
+                       "                            "
+                       " to the program. But when Subversion is using its\n"
+                       "                            "
+                       " default internal diff implementation, or when\n"
+                       "                            "
+                       " Subversion is displaying blame annotations, ARG\n"
+                       "                            "
+                       " could be any of the following:\n"
+                       "                            "
+                       "    -u (--unified):\n"
+                       "                            "
+                       "       Output 3 lines of unified context.\n"
+                       "                            "
+                       "    -b (--ignore-space-change):\n"
+                       "                            "
+                       "       Ignore changes in the amount of white space.\n"
+                       "                            "
+                       "    -w (--ignore-all-space):\n"
+                       "                            "
+                       "       Ignore all white space.\n"
+                       "                            "
+                       "    --ignore-eol-style:\n"
+                       "                            "
+                       "       Ignore changes in EOL style.\n"
+                       "                            "
+                       "    -p (--show-c-function):\n"
+                       "                            "
+                       "       Show C function name in diff output.")},
   {"targets",       opt_targets, 1,
                     N_("pass contents of file ARG as additional args")},
   {"depth",         opt_depth, 1,
                     N_("limit operation by depth ARG ('empty', 'files',\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                            "
                        "'immediates', or 'infinity')")},
   {"set-depth",     opt_set_depth, 1,
                     N_("set new working copy depth to ARG ('exclude',\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                            "
                        "'empty', 'files', 'immediates', or 'infinity')\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                            "
                        "[alias: --sd]")},
   {"xml",           opt_xml, 0, N_("output in XML")},
   {"strict",        opt_strict, 0, N_("use strict semantics")},
   {"stop-on-copy",  opt_stop_on_copy, 0,
                     N_("do not cross copies while traversing history\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --soc]")},
   {"no-ignore",     opt_no_ignore, 0,
                     N_("disregard default and svn:ignore property ignores")},
   {"no-auth-cache", opt_no_auth_cache, 0,
                     N_("do not cache authentication tokens\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --nac]")},
   {"trust-server-cert", opt_trust_server_cert, 0,
                     N_("accept unknown SSL server certificates without\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "prompting (but only with '--non-interactive')")},
   {"non-interactive", opt_non_interactive, 0,
                     N_("do no interactive prompting")},
   {"dry-run",       opt_dry_run, 0,
                     N_("try operation but make no changes\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --dry]")},
   {"no-diff-deleted", opt_no_diff_deleted, 0,
                     N_("do not print differences for deleted files\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --ndd]")},
   {"notice-ancestry", opt_notice_ancestry, 0,
                     N_("notice ancestry when calculating differences\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --na]")},
   {"ignore-ancestry", opt_ignore_ancestry, 0,
                     N_("ignore ancestry when calculating merges\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --ia]")},
   {"ignore-externals", opt_ignore_externals, 0,
                     N_("ignore externals definitions\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --ie]")},
   {"diff-cmd",      opt_diff_cmd, 1, N_("use ARG as diff command")},
   {"diff3-cmd",     opt_merge_cmd, 1, N_("use ARG as merge command")},
   {"editor-cmd",    opt_editor_cmd, 1, N_("use ARG as external editor")},
   {"record-only",   opt_record_only, 0,
                     N_("merge only mergeinfo differences\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --ro]")},
   {"old",           opt_old_cmd, 1, N_("use ARG as the older target")},
   {"new",           opt_new_cmd, 1, N_("use ARG as the newer target")},
@@ -270,40 +263,40 @@
   {"relocate",      opt_relocate, 0, N_("relocate via URL-rewriting")},
   {"config-dir",    opt_config_dir, 1,
                     N_("read user configuration files from directory ARG\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --cd]")},
   {"config-option", opt_config_options, 1,
                     N_("set user configuration option in the format:\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "    FILE:SECTION:OPTION=[VALUE]\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "For example:\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "    servers:global:http-library=serf")},
   {"auto-props",    opt_autoprops, 0, N_("enable automatic properties")},
   {"no-auto-props", opt_no_autoprops, 0, N_("disable automatic properties")},
   {"native-eol",    opt_native_eol, 1,
                     N_("use a different EOL marker than the standard\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "system marker for files with the svn:eol-style\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "property set to 'native'.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "ARG may be one of 'LF', 'CR', 'CRLF'")},
   {"limit",         'l', 1, N_("maximum number of log entries")},
   {"no-unlock",     opt_no_unlock, 0, N_("don't unlock the targets\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[aliases: --nul, --keep-lock]")},
   {"summarize",     opt_summarize, 0, N_("show a summary of the results")},
   {"remove",         opt_remove, 0, N_("remove changelist association")},
   {"changelist",    opt_changelist, 1,
                     N_("operate only on members of changelist ARG\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --cl]")},
   {"keep-changelists", opt_keep_changelists, 0,
                     N_("don't delete changelists after commit")},
   {"keep-local",    opt_keep_local, 0, N_("keep path in working copy\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --kl]")},
   {"with-all-revprops",  opt_with_all_revprops, 0,
                     N_("retrieve all revision properties")},
@@ -311,90 +304,91 @@
                     N_("retrieve no revision properties")},
   {"with-revprop",  opt_with_revprop, 1,
                     N_("set revision property ARG in new revision\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "using the name[=value] format")},
   {"parents",       opt_parents, 0, N_("make intermediate directories")},
   {"use-merge-history", 'g', 0,
                     N_("use/display additional information from merge\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "history")},
   {"accept",        opt_accept, 1,
                     N_("specify automatic conflict resolution action\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                            "
                        "('postpone', 'base', 'mine-conflict',\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "'theirs-conflict', 'mine-full', 'theirs-full',\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
-                       "'edit', 'launch')")},
+                       "                            "
+                       " 'theirs-conflict', 'mine-full', 'theirs-full',\n"
+                       "                            "
+                       " 'edit', 'launch')")},
   {"show-revs",     opt_show_revs, 1,
                     N_("specify which collection of revisions to display\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "('merged', 'eligible')\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --sr]")},
   {"reintegrate",   opt_reintegrate, 0,
                     N_("lump-merge all of source URL's unmerged changes\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --ri]")},
   {"strip-count",   opt_strip_count, 1,
                     N_("number of leading path components to strip from\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "paths parsed from the patch file. --strip-count 0\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "is the default and leaves paths unmodified.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "--strip-count 1 would change the path\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "'doc/fudge/crunchy.html' to 'fudge/crunchy.html'.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "--strip-count 2 would leave just 'crunchy.html'\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "The expected component separator is '/' on all\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "platforms. A leading '/' counts as one component.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --strip]")},
   {"show-copies-as-adds", opt_show_copies_as_adds, 0,
                     N_("don't diff copied or moved files with their source\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --sca]")},
   {"ignore-keywords", opt_ignore_keywords, 0,
                     N_("don't expand keywords\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --ik]")},
   {"reverse-diff", opt_reverse_diff, 0,
                     N_("apply the unidiff in reverse\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "This option also reverses patch target names; the\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "--old-patch-target-names option will prevent this.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --rd]")},
   {"ignore-whitespace", opt_ignore_whitespace, 0,
                        N_("ignore whitespace during pattern matching\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --iw]")},
   {"show-diff", opt_show_diff, 0,
                        N_("produce diff output\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --diff]")},
   {"internal-diff", opt_internal_diff, 0,
                        N_("override diff-cmd specified in config file\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --idiff]")},
   {"git", opt_use_git_diff_format, 0,
-                       N_("use git's extended diff format\n")},                
+                       N_("use git's extended diff format\n")},
+                  
   {"old-patch-target-names", opt_old_patch_target_names, 0,
                        N_("use target names from the old side of a patch.\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "If a diff header contains\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "  --- foo.c\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "  +++ foo.c.new\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "this option will cause the name \"foo.c\" to be used\n"
-                       SVN_CL__OPTION_CONTINUATION_INDENT
+                       "                             "
                        "[alias: --optn]")},
 
   /* Long-opt Aliases
@@ -1006,10 +1000,10 @@
      "  Note:  the --accept option is currently required.\n"),
     {opt_targets, 'R', opt_depth, 'q', opt_accept},
     {{opt_accept, N_("specify automatic conflict resolution source\n"
-                     SVN_CL__OPTION_CONTINUATION_INDENT
-                     "('base', 'working', 'mine-conflict',\n"
-                     SVN_CL__OPTION_CONTINUATION_INDENT
-                     "'theirs-conflict', 'mine-full', 'theirs-full')")}} },
+                             "                            "
+                             "('base', 'working', 'mine-conflict',\n"
+                             "                            "
+                             " 'theirs-conflict', 'mine-full', 'theirs-full')")}} },
 
   { "resolved", svn_cl__resolved, {0}, N_
     ("Remove 'conflicted' state on working copy files or directories.\n"
Index: subversion/include/svn_fs.h
===================================================================
--- subversion/include/svn_fs.h	(revision 1023844)
+++ subversion/include/svn_fs.h	(revision 1005387)
@@ -530,12 +530,12 @@
 svn_fs_access_add_lock_token2(svn_fs_access_t *access_ctx,
                               const char *path,
                               const char *token);
-
 /**
  * Same as svn_fs_access_add_lock_token2(), but with @a path set to value 1.
  *
- * @deprecated Provided for backward compatibility with the 1.5 API.
+ * @deprecated Provided for backward compatibility with the 1.1 API.
  */
+
 SVN_DEPRECATED
 svn_error_t *
 svn_fs_access_add_lock_token(svn_fs_access_t *access_ctx,
Index: subversion/include/svn_diff.h
===================================================================
--- subversion/include/svn_diff.h	(revision 1023844)
+++ subversion/include/svn_diff.h	(revision 1005387)
@@ -537,7 +537,7 @@
 /** Similar to svn_diff_file_output_unified3(), but with @a relative_to_dir
  * set to NULL and @a show_c_function to false.
  *
- * @deprecated Provided for backwards compatibility with the 1.4 API.
+ * @deprecated Provided for backwards compatibility with the 1.3 API.
  */
 SVN_DEPRECATED
 svn_error_t *
Index: subversion/include/svn_mergeinfo.h
===================================================================
--- subversion/include/svn_mergeinfo.h	(revision 1023844)
+++ subversion/include/svn_mergeinfo.h	(revision 1005387)
@@ -226,7 +226,7 @@
 
 /** Like svn_mergeinfo_remove2, but always considers inheritance.
  *
- * @deprecated Provided for backward compatibility with the 1.6 API.
+ * @deprecated Provided for backward compatibility with the 1.5 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -308,6 +308,17 @@
                      svn_boolean_t consider_inheritance,
                      apr_pool_t *pool);
 
+/** Like svn_mergeinfo_intersect2, but always considers inheritance.
+ *
+ * @deprecated Provided for backward compatibility with the 1.5 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
+                        svn_mergeinfo_t mergeinfo1,
+                        svn_mergeinfo_t mergeinfo2,
+                        apr_pool_t *pool);
+
 /** Find the intersection of two mergeinfos, @a mergeinfo1 and @a
  * mergeinfo2, and place the result in @a *mergeinfo, which is (deeply)
  * allocated in @a result_pool.  Temporary allocations will be performed
@@ -327,17 +338,6 @@
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
 
-/** Like svn_mergeinfo_intersect2, but always considers inheritance.
- *
- * @deprecated Provided for backward compatibility with the 1.6 API.
- */
-SVN_DEPRECATED
-svn_error_t *
-svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
-                        svn_mergeinfo_t mergeinfo1,
-                        svn_mergeinfo_t mergeinfo2,
-                        apr_pool_t *pool);
-
 /** Find the intersection of two rangelists consisting of @c
  * svn_merge_range_t * elements, @a rangelist1 and @a rangelist2, and
  * place the result in @a *rangelist (which is never @c NULL).
Index: subversion/include/svn_repos.h
===================================================================
--- subversion/include/svn_repos.h	(revision 1023844)
+++ subversion/include/svn_repos.h	(revision 1005387)
@@ -2556,7 +2556,7 @@
  * Similar to svn_repos_load_fs2(), but with @a use_pre_commit_hook and
  * @a use_post_commit_hook always @c FALSE.
  *
- * @deprecated Provided for backward compatibility with the 1.1 API.
+ * @deprecated Provided for backward compatibility with the 1.0 API.
  */
 SVN_DEPRECATED
 svn_error_t *
Index: subversion/include/svn_subst.h
===================================================================
--- subversion/include/svn_subst.h	(revision 1023844)
+++ subversion/include/svn_subst.h	(revision 1005387)
@@ -209,12 +209,23 @@
  * @c TRUE, convert any line ending in @a src_stream to @a eol_str in
  * @a dst_stream.  Recognized line endings are: "\n", "\r", and "\r\n".
  *
- * See svn_subst_stream_translated() for details of the keyword substitution
- * which is controlled by the @a expand and @a keywords parameters.
+ * Expand and contract keywords using the contents of @a keywords as the
+ * new values.  If @a expand is @c TRUE, expand contracted keywords and
+ * re-expand expanded keywords.  If @a expand is @c FALSE, contract expanded
+ * keywords and ignore contracted ones.  Keywords not found in the hash are
+ * ignored (not contracted or expanded).  If the @a keywords hash
+ * itself is @c NULL, keyword substitution will be altogether ignored.
+ *
+ * Detect only keywords that are no longer than @c SVN_KEYWORD_MAX_LEN
+ * bytes, including the delimiters and the keyword itself.
  *
  * Note that a translation request is *required*:  one of @a eol_str or
  * @a keywords must be non-@c NULL.
  *
+ * Recommendation: if @a expand is FALSE, then you don't care about the
+ * keyword values, so use empty strings as non-NULL signifiers when you
+ * build the keywords hash.
+ *
  * Notes:
  *
  * See svn_wc__get_keywords() and svn_wc__get_eol_style() for a
@@ -290,20 +301,6 @@
  * if @a repair is @c TRUE, convert any line ending to @a eol_str.
  * Recognized line endings are: "\n", "\r", and "\r\n".
  *
- * Expand and contract keywords using the contents of @a keywords as the
- * new values.  If @a expand is @c TRUE, expand contracted keywords and
- * re-expand expanded keywords.  If @a expand is @c FALSE, contract expanded
- * keywords and ignore contracted ones.  Keywords not found in the hash are
- * ignored (not contracted or expanded).  If the @a keywords hash
- * itself is @c NULL, keyword substitution will be altogether ignored.
- *
- * Detect only keywords that are no longer than @c SVN_KEYWORD_MAX_LEN
- * bytes, including the delimiters and the keyword itself.
- *
- * Recommendation: if @a expand is FALSE, then you don't care about the
- * keyword values, so use empty strings as non-NULL signifiers when you
- * build the keywords hash.
- *
  * The stream returned is allocated in @a result_pool.
  *
  * If the inner stream implements resetting via svn_stream_reset(),
@@ -321,8 +318,8 @@
                             apr_pool_t *result_pool);
 
 
-/** Set @a *stream to a stream which performs eol translation and keyword
- * expansion when read from or written to.  The stream @a source
+/** Return a stream which performs eol translation and keyword
+ * expansion when read from or written to.  The stream @a stream
  * is used to read and write all data.  Make sure you call
  * svn_stream_close() on @a stream to make sure all data are flushed
  * and cleaned up.
@@ -348,7 +345,7 @@
                                            apr_pool_t *pool);
 
 
-/** Set @a *stream to a readable stream containing the "normal form"
+/** Returns a readable stream in @a *stream containing the "normal form"
  * of the special file located at @a path. The stream will be allocated
  * in @a result_pool, and any temporary allocations will be made in
  * @a scratch_pool.
@@ -362,7 +359,7 @@
                            apr_pool_t *scratch_pool);
 
 
-/** Set @a *stream to a writeable stream that accepts content in
+/** Returns a writeable stream in @a *stream that accepts content in
  * the "normal form" for a special file, to be located at @a path, and
  * will create that file when the stream is closed. The stream will be
  * allocated in @a result_pool, and any temporary allocations will be
@@ -380,8 +377,8 @@
                              apr_pool_t *scratch_pool);
 
 
-/** Set @a *stream to a stream which translates the special file at @a path
- * to the internal representation for special files when read from.  When
+/** Returns a stream which translates the special file at @a path to
+ * the internal representation for special files when read from.  When
  * written to, it does the reverse: creating a special file when the
  * stream is closed.
  *
@@ -399,16 +396,17 @@
 
 
 /**
- * Copy the contents of file-path @a src to file-path @a dst atomically,
- * either creating @a dst or overwriting @a dst if it exists, possibly
- * performing line ending and keyword translations.
- *
- * The parameters @a *eol_str, @a repair, @a *keywords and @a expand are
+ * Translates the file at path @a src into a file at path @a dst.  The
+ * parameters @a *eol_str, @a repair, @a *keywords and @a expand are
  * defined the same as in svn_subst_translate_stream3().
  *
  * In addition, it will create a special file from normal form or
  * translate one to normal form if @a special is @c TRUE.
  *
+ * Copy the contents of file-path @a src to file-path @a dst atomically,
+ * either creating @a dst (or overwriting @a dst if it exists), possibly
+ * performing line ending and keyword translations.
+ *
  * If anything goes wrong during the copy, attempt to delete @a dst (if
  * it exists).
  *
@@ -488,19 +486,17 @@
 
 
 /**
- * Set @a *dst to a copy of the string @a src, possibly performing line
- * ending and keyword translations.
+ * Convenience routine: a variant of svn_subst_translate_stream3() which
+ * operates on cstrings.
  *
- * This is a variant of svn_subst_translate_stream3() that operates on
- * cstrings.  @see svn_subst_stream_translated() for details of the
- * translation and of @a eol_str, @a repair, @a keywords and @a expand.
+ * @since New in 1.3.
+ *
+ * Return a new string in @a *dst, allocated in @a pool, by copying the
+ * contents of string @a src, possibly performing line ending and keyword
+ * translations.
  *
  * If @a eol_str and @a keywords are @c NULL, behavior is just a byte-for-byte
  * copy.
- *
- * Allocate @a *dst in @a pool.
- *
- * @since New in 1.3.
  */
 svn_error_t *
 svn_subst_translate_cstring2(const char *src,
@@ -528,7 +524,7 @@
                             apr_pool_t *pool);
 
 /**
- * Translate the file @a src in working copy form to a file @a dst in
+ * Translates a file @a src in working copy form to a file @a dst in
  * normal form.
  *
  * The values specified for @a eol_style, @a *eol_str, @a keywords and
@@ -592,26 +588,20 @@
 
 /* EOL conversion and character encodings */
 
-/** Translate the string @a value from character encoding @a encoding to
- * UTF8, and also from its current line-ending style to LF line-endings.  If
- * @a encoding is @c NULL, translate from the system-default encoding.
- *
- * Recognized line endings are LF, CR, CRLF.  If @a value has inconsistent
- * line endings, return @c SVN_ERR_IO_INCONSISTENT_EOL.
- *
- * Set @a *new_value to the translated string, allocated in @a pool.
+/** Translate the data in @a value (assumed to be in encoded in charset
+ * @a encoding) to UTF8 and LF line-endings.  If @a encoding is @c NULL,
+ * then assume that @a value is in the system-default language encoding.
+ * Return the translated data in @a *new_value, allocated in @a pool.
  */
 svn_error_t *svn_subst_translate_string(svn_string_t **new_value,
                                         const svn_string_t *value,
                                         const char *encoding,
                                         apr_pool_t *pool);
 
-/** Translate the string @a value from UTF8 and LF line-endings into native
- * character encoding and native line-endings.  If @a for_output is TRUE,
- * translate to the character encoding of the output locale, else to that of
- * the default locale.
- *
- * Set @a *new_value to the translated string, allocated in @a pool.
+/** Translate the data in @a value from UTF8 and LF line-endings into
+ * native locale and native line-endings, or to the output locale if
+ * @a for_output is TRUE.  Return the translated data in @a
+ * *new_value, allocated in @a pool.
  */
 svn_error_t *svn_subst_detranslate_string(svn_string_t **new_value,
                                           const svn_string_t *value,
Index: subversion/include/svn_types.h
===================================================================
--- subversion/include/svn_types.h	(revision 1023844)
+++ subversion/include/svn_types.h	(revision 1005387)
@@ -132,15 +132,12 @@
 svn__apr_hash_index_val(const apr_hash_index_t *hi);
 
 /** On Windows, APR_STATUS_IS_ENOTDIR includes several kinds of
- * invalid-pathname error but not ERROR_INVALID_NAME, so we include it.
- * We also include ERROR_DIRECTORY as that was not included in apr versions
- * before 1.4.0 and this fix is not backported */
-/* ### These fixes should go into APR. */
+ * invalid-pathname error but not this one, so we include it. */
+/* ### This fix should go into APR. */
 #ifndef WIN32
 #define SVN__APR_STATUS_IS_ENOTDIR(s)  APR_STATUS_IS_ENOTDIR(s)
 #else
 #define SVN__APR_STATUS_IS_ENOTDIR(s)  (APR_STATUS_IS_ENOTDIR(s) \
-                      || ((s) == APR_OS_START_SYSERR + ERROR_DIRECTORY) \
                       || ((s) == APR_OS_START_SYSERR + ERROR_INVALID_NAME))
 #endif
 
Index: subversion/include/svn_config.h
===================================================================
--- subversion/include/svn_config.h	(revision 1023844)
+++ subversion/include/svn_config.h	(revision 1005387)
@@ -127,7 +127,6 @@
 #define SVN_CONFIG_OPTION_PASSWORD_DB               "password-db"
 #define SVN_CONFIG_OPTION_REALM                     "realm"
 #define SVN_CONFIG_OPTION_AUTHZ_DB                  "authz-db"
-#define SVN_CONFIG_OPTION_FORCE_USERNAME_CASE       "force-username-case"
 #define SVN_CONFIG_SECTION_SASL                 "sasl"
 #define SVN_CONFIG_OPTION_USE_SASL                  "use-sasl"
 #define SVN_CONFIG_OPTION_MIN_SSF                   "min-encryption"
Index: subversion/include/svn_string.h
===================================================================
--- subversion/include/svn_string.h	(revision 1023844)
+++ subversion/include/svn_string.h	(revision 1005387)
@@ -199,7 +199,7 @@
 /** Create a new empty bytestring with at least @a minimum_size bytes of
  * space available in the memory block.
  *
- * The allocated string buffer will be one byte larger than @a minimum_size
+ * The allocated string buffer will be one byte larger then @a minimum_size
  * to account for a final '\\0'.
  *
  * @since New in 1.6.
Index: subversion/include/svn_io.h
===================================================================
--- subversion/include/svn_io.h	(revision 1023844)
+++ subversion/include/svn_io.h	(revision 1005387)
@@ -289,7 +289,7 @@
 
 /** Like svn_io_open_unique_file2, but can't delete on pool cleanup.
  *
- * @deprecated Provided for backward compatibility with the 1.3 API
+ * @deprecated Provided for backward compatibility with the 1.0 API
  *
  * @note In 1.4 the API was extended to require either @a f or
  *       @a unique_name_p (the other can be NULL).  Before that, both were
@@ -1395,7 +1395,6 @@
  * structures instead of svn_io_dirent2_t and with only a single pool.
  *
  * @since New in 1.3.
- * @deprecated Provided for backward compatibility with the 1.6 API.
  */
 SVN_DEPRECATED
 svn_error_t *
Index: subversion/include/svn_wc.h
===================================================================
--- subversion/include/svn_wc.h	(revision 1023844)
+++ subversion/include/svn_wc.h	(revision 1005387)
@@ -1558,6 +1558,199 @@
 svn_wc_conflict_version_dup(const svn_wc_conflict_version_t *version,
                             apr_pool_t *pool);
 
+
+/** An opaque structure that describes a conflict that has occurred on a
+ * specific target in a working copy. Passed to the conflict helper
+ * functions and to #svn_wc_conflict_resolver_func2_t when performing
+ * interactive conflict resolving.
+ *
+ * @since New in 1.7.
+ */
+ /* ### We use svn_wc_conflict_t as non constant to allow delayloading
+        values. */
+typedef struct svn_wc_conflict_t svn_wc_conflict_t;
+
+/** Duplicates a @a base conflict, to a @a duplicate conflict, allocated
+ * in @a result_pool.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_conflict_dup(svn_wc_conflict_t **duplicate,
+                    const svn_wc_conflict_t *base,
+                    apr_pool_t *result_pool);
+
+/** Read information about @a conflict, as it applies to @a local_abspath
+ * in @a wc_ctx.
+ *
+ * If @a kind is not NULL, retrieves the kind of conflict.
+ *
+ * If @a property_name is not NULL, retrieves the name of the property
+ * where this conflict applies to. @a property_name is NULL, when this
+ * information is not available. (This information is not always recorded).
+ *
+ * If @a action is not NULL, retrieves the action that raised the conflict
+ * or #svn_wc_conflict_action_edit if no action was recorded.
+ *
+ * If @a reason is not NULL, retrieves the reason why the conflict was
+ * raised or #svn_wc_conflict_reason_t if no reason was recorded.
+ *
+ * If @a operation is not NULL, retrieves the operation that was performed
+ * when the conflict was raised or #svn_wc_operation_none if no operation
+ * was recorded.
+ *
+ * If @a conflict_resolved is not NULL, conflict type specific checks are
+ * performed to see if this conflict is resolved. (E.g. for file and property
+ * conflicts the marker and rejection files are tested for availablity).
+ * If the conflict is resolved sets @a *conflict_resolved to TRUE, otherwise
+ * to FALSE.
+ *
+ * @since New in 1.7.
+ */
+/* ### Separate in more methods like the WC-1.0 api, or add more
+       to remove other apis, like we do in WC-NG? */
+svn_error_t *
+svn_wc_get_conflict_info(svn_wc_conflict_kind_t *kind,
+                         const char **property_name,
+                         svn_wc_conflict_action_t *action,
+                         svn_wc_conflict_reason_t *reason,
+                         svn_wc_operation_t *operation,
+                         svn_boolean_t *conflict_resolved,
+                         svn_wc_context_t *wc_ctx,
+                         const char *local_abspath,
+                         svn_wc_conflict_t *conflict,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
+
+/** Retrieves the conflict marker file locations recorded in @a conflict,
+ * as it applies to @a local_abspath in @a wc_ctx.
+ *
+ * For text and property conflicts older is the BASE version, left the MINE
+ * version and right the THEIRS version. Depending on the type of conflict,
+ * some or all of these values might be NULL.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_get_conflict_marker_files(const char **older_abspath,
+                                 const char **left_abspath,
+                                 const char **right_abspath,
+                                 svn_wc_context_t *wc_ctx,
+                                 const char *local_abspath,
+                                 svn_wc_conflict_t *conflict,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
+
+/** Retrieves the origin of the conflict recorded in @a conflict, as it
+ * applies to @a local_abspath in @a wc_ctx.
+ *
+ * For text and property conflicts older is the BASE version, left the MINE
+ * version and right the THEIRS version. Depending on the type of conflict,
+ * some or all of these values might be NULL.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_get_conflict_sources(const svn_wc_conflict_version_t **older_version,
+                            const svn_wc_conflict_version_t **left_version,
+                            const svn_wc_conflict_version_t **right_version,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            svn_wc_conflict_t *conflict,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
+/** Retrieves the values of the conflicted property recorded in @a
+ * conflict, as it applies to @a local_abspath in @a wc_ctx.
+ *
+ * If @a older_value, @a left_value and/or @a right_value are not NULL,
+ * retrieves this property value as recorded in the conflict data. A
+ * returned NULL indicates that the property was not available in that
+ * version. (If #svn_wc_get_conflict_info doesn't provide a property
+ * name, no property data was recorded in the property conflict)
+ *
+ * For property conflicts older is the BASE version, left the MINE
+ * version and right the THEIRS version.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_get_property_conflict_data(const svn_string_t **older_value,
+                                  const svn_string_t **left_value,
+                                  const svn_string_t **right_value,
+                                  svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
+                                  svn_wc_conflict_t *conflict,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool);
+
+/** Creates a new property conflict, recording the passed values.
+ *
+ * @a property_name must be set to the conflicted property name or ""
+ * if no property name is available. (Older api compatibility)
+ *
+ * @a older_version, @a left_version and @a right_version can be
+ * NULL for compatibility with older apis.
+ *
+ * Iif @a property_name is not "", @a older_value, @a left_value and
+ * @a right_value must be set to the values of property in these versions.
+ * (which could be NULL if the property does not exist there).
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_create_property_conflict(svn_wc_conflict_t **conflict,
+                                const char *property_name,
+                                const svn_wc_conflict_version_t *older_version,
+                                const svn_wc_conflict_version_t *left_version,
+                                const svn_wc_conflict_version_t *right_version,
+                                const svn_string_t *older_value,
+                                const svn_string_t *left_value,
+                                const svn_string_t *right_value,
+                                const char *marker_abspath,
+                                svn_wc_operation_t operation,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
+
+/** Creates a new text conflict, recording the passed values.
+ *
+ * @a older_version, @a left_version and @a right_version can be NULL,
+ * for compatibility with older apis.
+ *
+ * @a older_abspath, @a left_abspath and @a right_abspath can be NULL,
+ * @a indicating that the file did not exist in that version.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_create_text_conflict(svn_wc_conflict_t **conflict,
+                            const svn_wc_conflict_version_t *older_version,
+                            const svn_wc_conflict_version_t *left_version,
+                            const svn_wc_conflict_version_t *right_version,
+                            const char *older_abspath,
+                            const char *left_abspath,
+                            const char *right_abspath,
+                            svn_wc_operation_t operation,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
+/** Creates a new tree conflict @a conflict, recording the passed values.
+ * All values except @a older_version must be non-NULL. @a older_version
+ * can be NULL for backwards compatibility with older apis.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_wc_create_tree_conflict(svn_wc_conflict_t **conflict,
+                            const svn_wc_conflict_version_t *older_version,
+                            const svn_wc_conflict_version_t *left_version,
+                            const svn_wc_conflict_version_t *right_version,
+                            svn_wc_conflict_action_t action,
+                            svn_wc_conflict_reason_t reason,
+                            svn_wc_operation_t operation,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
 /** A struct that describes a conflict that has occurred in the
  * working copy.
  *
@@ -3106,7 +3299,6 @@
  * or error handling from @a walk_callbacks, and with @a depth always
  * set to #svn_depth_infinity.
  *
- * @since New in 1.2.
  * @deprecated Provided for backward compatibility with the 1.4 API.
  */
 SVN_DEPRECATED
@@ -3123,7 +3315,7 @@
 /**
  * Similar to svn_wc_walk_entries2(), but without cancellation support.
  *
- * @deprecated Provided for backward compatibility with the 1.1 API.
+ * @deprecated Provided for backward compatibility with the 1.0 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -3934,7 +4126,7 @@
  * instead of #svn_wc_status_func3_t.
  *
  * @since New in 1.5.
- * @deprecated Provided for backward compatibility with the 1.5 API.
+ * @deprecated Provided for backward compatibility with the 1.4 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -4037,13 +4229,13 @@
  * is used for accessing the working copy and must contain a write lock for
  * the parent directory of @a dst_abspath,
  *
- * If @a metadata_only is TRUE then this is a database-only operation and
+ * If metadata_only is TRUE then this a database only operation and
  * the working directories and files are not copied.
  *
  * @a src_abspath must be a file or directory under version control;
  * the parent of @a dst_abspath must be a directory under version control
  * in the same working copy; @a dst_abspath will be the name of the copied
- * item, and it must not exist already if @a metadata_only is FALSE.  Note that
+ * item, and it must not exist already if metadata_only is FALSE.  Note that
  * when @a src points to a versioned file, the working file doesn't
  * necessarily exist in which case its text-base is used instead.
  *
@@ -4210,42 +4402,12 @@
               apr_pool_t *pool);
 
 /**
- * Schedule the node or tree that exists on disk at @a local_abspath for
- * addition to the working copy, recursively.  The added nodes will have
- * no properties.
- *
- * The versioned state of the parent path must be a modifiable directory,
- * and the versioned state of @a local_abspath must be either nonexistent or
- * deleted; if deleted, the new node will be a replacement.
- *
- * If @a local_abspath does not exist as file, directory or symlink, return
- * #SVN_ERR_WC_PATH_NOT_FOUND.
- *
- * This is equivalent to svn_wc_add4() case 2a.
- *
- * ### TODO: Cancellation isn't implemented yet.
- *
- * ### TODO: Recurse as far as a specified depth?
- *
- * ### A better API might allow the caller to walk a tree and add a single
- *     node at a time, specifying each node's properties.
- */
-svn_error_t *
-svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
-                     const char *local_abspath,
-                     svn_cancel_func_t cancel_func,
-                     void *cancel_baton,
-                     svn_wc_notify_func2_t notify_func,
-                     void *notify_baton,
-                     apr_pool_t *scratch_pool);
-
-/**
  * Put @a local_abspath under version control by registering it as addition
  * or copy in the database containing its parent. The new node is scheduled
  * for addition to the repository below its parent node.
  *
- * 1) If the node is already versioned, it MUST BE the root of a separate
- * working copy from the same repository as the parent WC. The new node
+ * 1) If the node already exists, it MUST BE the root of a separate working
+ * copy from the same repository as the parent working copy. The new node
  * and anything below it will be scheduled for addition inside the parent
  * working copy as a copy of the original location. The separate working
  * copy will be integrated by this step. In this case, which is only used
@@ -4258,7 +4420,7 @@
  * of that location. In this last case the function doesn't set the pristine
  * version (of a file) and/or pristine properties, which callers should
  * handle via different APIs. Usually it is easier to call
- * svn_wc_add_repos_file4() (### or a possible svn_wc_add_repos_dir()) than
+ * svn_wc_add_repos_file4() (### or a possible svn_wc_add_repos_dir()) then
  * using this variant.
  *
  * If @a local_abspath does not exist as file, directory or symlink, return
@@ -4618,7 +4780,6 @@
  * Similar to svn_wc_resolved_conflict4(), but without tree-conflict
  * resolution support.
  *
- * @since New in 1.5.
  * @deprecated Provided for backward compatibility with the 1.5 API.
  */
 SVN_DEPRECATED
@@ -4642,7 +4803,6 @@
  * if @a recurse is TRUE, @a depth is #svn_depth_infinity, else it is
  * #svn_depth_files.
  *
- * @since New in 1.2.
  * @deprecated Provided for backward compatibility with the 1.4 API.
  */
 SVN_DEPRECATED
@@ -4662,7 +4822,7 @@
  * Similar to svn_wc_resolved_conflict2(), but takes an
  * svn_wc_notify_func_t and doesn't have cancellation support.
  *
- * @deprecated Provided for backward compatibility with the 1.1 API.
+ * @deprecated Provided for backward compatibility with the 1.0 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -4834,7 +4994,8 @@
 /** @see svn_wc_process_committed_queue2()
  *
  * @since New in 1.5.
- * @deprecated Provided for backwards compatibility with the 1.6 API.
+ *
+ * @deprecated Provided for backwards compatibility with the 1.5 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -5663,7 +5824,6 @@
  * Like svn_wc_prop_set3(), but without the notification callbacks.
  *
  * @since New in 1.2.
- * @deprecated Provided for backwards compatibility with the 1.5 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -6019,6 +6179,7 @@
  * It also doesn't allow specifying a cancel function.
  *
  * @since New in 1.6.
+ *
  * @deprecated Provided for backward compatibility with the 1.6 API.
  */
 SVN_DEPRECATED
@@ -6036,7 +6197,6 @@
  * Similar to svn_wc_diff5(), but with a #svn_wc_diff_callbacks2_t argument
  * instead of #svn_wc_diff_callbacks3_t.
  *
- * @since New in 1.5.
  * @deprecated Provided for backward compatibility with the 1.5 API.
  */
 SVN_DEPRECATED
@@ -6055,8 +6215,7 @@
  * and @a depth set to #svn_depth_infinity if @a recurse is TRUE, or
  * #svn_depth_files if @a recurse is FALSE.
  *
- * @since New in 1.2.
- * @deprecated Provided for backward compatibility with the 1.4 API.
+ * @deprecated Provided for backward compatibility with the 1.2 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -6072,7 +6231,6 @@
  * Similar to svn_wc_diff3(), but with a #svn_wc_diff_callbacks_t argument
  * instead of #svn_wc_diff_callbacks2_t.
  *
- * @since New in 1.1.
  * @deprecated Provided for backward compatibility with the 1.1 API.
  */
 SVN_DEPRECATED
@@ -6390,7 +6548,8 @@
  * Same as svn_wc_merge_props2(), but with a @a conflict_func (and
  * baton) of NULL.
  *
- * @deprecated Provided for backward compatibility with the 1.4 API.
+ * @deprecated Provided for backward compatibility with the 1.3 API.
+ *
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -6513,7 +6672,7 @@
  * swn_wc_context_t.
  *
  * @since New in 1.2.
- * @deprecated Provided for backward compability with the 1.6 API.
+ * @deprecated Provided for backward compability with the 1.2 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -6781,8 +6940,7 @@
  * @note Most APIs map @a recurse==FALSE to @a depth==svn_depth_files;
  * revert is deliberately different.
  *
- * @since New in 1.2.
- * @deprecated Provided for backward compatibility with the 1.4 API.
+ * @deprecated Provided for backward compatibility with the 1.2 API.
  */
 SVN_DEPRECATED
 svn_error_t *
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h	(revision 1023844)
+++ subversion/include/svn_client.h	(revision 1005387)
@@ -477,7 +477,7 @@
 
 /** The commit candidate structure.
  *
- * @deprecated Provided for backward compatibility with the 1.4 API.
+ * @deprecated Provided for backward compatibility with the 1.3 API.
  */
 typedef struct svn_client_commit_item2_t
 {
@@ -576,7 +576,7 @@
  * Return a duplicate of @a item, allocated in @a pool. No part of the new
  * structure will be shared with @a item.
  *
- * @deprecated Provided for backward compatibility with the 1.4 API.
+ * @deprecated Provided for backward compatibility with the 1.3 API.
  */
 SVN_DEPRECATED
 svn_client_commit_item2_t *
@@ -1501,7 +1501,7 @@
  * rather than through @a commit_callback.
  *
  * @since New in 1.5.
- * @deprecated Provided for backward compatibility with the 1.6 API.
+ * @deprecated Provided for backward compatibility with the 1.4 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -2420,7 +2420,7 @@
  * revision 1.  That works fine, except when there are no commits in
  * the repository, hence this special case.
  *
- * @deprecated Provided for backward compatibility with the 1.1 API.
+ * @deprecated Provided for backward compatibility with the 1.0 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -2750,7 +2750,7 @@
  * Similar to svn_client_diff2(), but with @a ignore_content_type
  * always set to FALSE.
  *
- * @deprecated Provided for backward compatibility with the 1.1 API.
+ * @deprecated Provided for backward compatibility with the 1.0 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -2806,7 +2806,6 @@
  * @c FALSE and @a use_git_diff_format set to @c FALSE.
  *
  * @since New in 1.5.
- * @deprecated Provided for backward compatibility with the 1.6 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -3196,7 +3195,7 @@
  * is TRUE, set @a depth to #svn_depth_infinity, if @a recurse is
  * FALSE, set @a depth to #svn_depth_files.
  *
- * @deprecated Provided for backwards compatibility with the 1.4 API.
+ * @deprecated Provided for backwards compatibility with the 1.3 API.
  *
  * @since New in 1.4.
  */
@@ -3381,6 +3380,8 @@
  * immediately.
  *
  * Use @a scratch_pool for any temporary allocations.
+ *
+ * @since New in 1.0.
  */
 svn_error_t *
 svn_client_cleanup(const char *dir,
@@ -4161,7 +4162,7 @@
  * Similar to svn_client_revprop_set2(), but with @a original_propval
  * always @c NULL.
  *
- * @deprecated Provided for backward compatibility with the 1.5 API.
+ * @deprecated Provided for backward compatibility with the 1.0 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -4232,7 +4233,7 @@
  * @a recurse: if @a recurse is TRUE, then @a depth is
  * #svn_depth_infinity, else #svn_depth_empty.
  *
- * @deprecated Provided for backward compatibility with the 1.4 API.
+ * @deprecated Provided for backward compatibility with the 1.2 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -4338,7 +4339,7 @@
  *
  * @since New in 1.2.
  *
- * @deprecated Provided for backward compatiblility with the 1.4 API.
+ * @deprecated Provided for backward compatiblility with the 1.2 API.
  */
 SVN_DEPRECATED
 svn_error_t *
@@ -5185,7 +5186,7 @@
  * NULL, and @a depth set according to @a recurse: if @a recurse is
  * TRUE, @a depth is #svn_depth_infinity, else #svn_depth_empty.
  *
- * @deprecated Provided for backward compatibility with the 1.4 API.
+ * @deprecated Provided for backward compatibility with the 1.2 API.
  */
 SVN_DEPRECATED
 svn_error_t *
Index: subversion/include/svn_ra.h
===================================================================
--- subversion/include/svn_ra.h	(revision 1023844)
+++ subversion/include/svn_ra.h	(revision 1005387)
@@ -682,8 +682,6 @@
 
 /** Set @a *url to the repository URL to which @a ra_session was
  * opened or most recently reparented.
- *
- * @since New in 1.5.
  */
 svn_error_t *
 svn_ra_get_session_url(svn_ra_session_t *ra_session,
Index: subversion/libsvn_wc/props.c
===================================================================
--- subversion/libsvn_wc/props.c	(revision 1023844)
+++ subversion/libsvn_wc/props.c	(revision 1005387)
@@ -139,9 +139,30 @@
 static svn_error_t *
 immediate_install_props(svn_wc__db_t *db,
                         const char *local_abspath,
+                        svn_wc__db_kind_t kind,
                         apr_hash_t *working_props,
                         apr_pool_t *scratch_pool)
 {
+  apr_hash_t *base_props;
+
+  /* ### no pristines should be okay.  */
+  SVN_ERR_W(svn_wc__db_read_pristine_props(&base_props, db, local_abspath,
+                                           scratch_pool, scratch_pool),
+            _("Failed to load pristine properties"));
+
+  /* Check if the props are modified. If no changes, then wipe out
+     the ACTUAL props. No pristines defined means that any ACTUAL
+     props are okay, so go ahead and set them.  */
+  if (base_props != NULL)
+    {
+      apr_array_header_t *prop_diffs;
+
+      SVN_ERR(svn_prop_diffs(&prop_diffs, working_props, base_props,
+                             scratch_pool));
+      if (prop_diffs->nelts == 0)
+        working_props = NULL;
+    }
+
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
                                   working_props,
                                   NULL /* conflict */,
@@ -329,6 +350,7 @@
       {
         svn_wc__db_status_t status;
         svn_boolean_t have_base;
+        apr_array_header_t *prop_diffs;
 
         SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
                                      NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -343,18 +365,41 @@
           SVN_ERR(svn_wc__db_temp_base_set_props(db, local_abspath,
                                                  new_base_props, pool));
 
-        SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
-                                        NULL, NULL, pool));
+        /* Check if the props are modified. */
+        SVN_ERR(svn_prop_diffs(&prop_diffs, actual_props, new_base_props, pool));
+
+        /* Save the actual properties file if it differs from base. */
+        if (prop_diffs->nelts == 0)
+          SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, NULL, NULL, NULL,
+                                          pool));
+        else
+          SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
+                                          NULL, NULL, pool));
       }
 #else
       if (base_merge)
         return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                 U_("base_merge=TRUE is no longer supported"));
 
-      SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
-                                      NULL /* conflict */,
-                                      NULL /* work_item */,
-                                      pool));
+      {
+        apr_array_header_t *prop_diffs;
+
+        SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
+                               pool));
+
+        /* Save the actual properties file if it differs from base. */
+        if (prop_diffs->nelts == 0)
+          new_actual_props = NULL; /* Remove actual properties*/
+
+        /* For the old school: write the properties into the "working"
+           (aka ACTUAL) location. Note that PROPS may be NULL, indicating
+           a removal of the props file.  */
+
+        SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
+                                        NULL /* conflict */,
+                                        NULL /* work_item */,
+                                        pool));
+      }
 #endif
 
       SVN_ERR(svn_wc__wq_run(db, local_abspath,
@@ -2140,7 +2185,7 @@
 
   /* Drop it right onto the disk. We don't need loggy since we aren't
      coordinating this change with anything else.  */
-  SVN_ERR(immediate_install_props(db, local_abspath, prophash,
+  SVN_ERR(immediate_install_props(db, local_abspath, kind, prophash,
                                   scratch_pool));
 
   if (notify_func)
Index: subversion/libsvn_wc/wc.h
===================================================================
--- subversion/libsvn_wc/wc.h	(revision 1023844)
+++ subversion/libsvn_wc/wc.h	(revision 1005387)
@@ -129,7 +129,7 @@
  * Please document any further format changes here.
  */
 
-#define SVN_WC__VERSION 20
+#define SVN_WC__VERSION 19
 
 /* Formats <= this have no concept of "revert text-base/props".  */
 #define SVN_WC__NO_REVERT_FILES 4
@@ -164,6 +164,11 @@
 /* A version < this does not store properties in wc.db.  */
 #define SVN_WC__PROPS_IN_DB 18
 
+#if (SVN_WC__VERSION > 19)
+#define SVN_WC__NODES
+#define SVN_WC__NODES_ONLY
+#endif
+
 /* Return true iff error E indicates an "is not a working copy" type
    of error, either because something wasn't a working copy at all, or
    because it's a working copy from a previous version (in need of
Index: subversion/libsvn_wc/adm_ops.c
===================================================================
--- subversion/libsvn_wc/adm_ops.c	(revision 1023844)
+++ subversion/libsvn_wc/adm_ops.c	(revision 1005387)
@@ -735,128 +735,28 @@
   return SVN_NO_ERROR;
 }
 
-/* Schedule the single node at LOCAL_ABSPATH, of kind KIND, for addition in
- * its parent directory in the WC.  It will have no properties. */
-static svn_error_t *
-add_from_disk(svn_wc_context_t *wc_ctx,
-              const char *local_abspath,
-              svn_node_kind_t kind,
-              apr_pool_t *scratch_pool)
-{
-  svn_wc__db_t *db = wc_ctx->db;
-
-  if (kind == svn_node_file)
-    {
-      SVN_ERR(svn_wc__db_op_add_file(db, local_abspath, NULL, scratch_pool));
-    }
-  else
-    {
-      SVN_ERR(svn_wc__db_op_add_directory(db, local_abspath, NULL,
-                                          scratch_pool));
-    }
-  return SVN_NO_ERROR;
-}
-
-/* Set *REPOS_ROOT_URL and *REPOS_UUID to the repository of the parent of
-   LOCAL_ABSPATH.  REPOS_ROOT_URL and/or REPOS_UUID may be NULL if not
-   wanted.  Check that the parent of LOCAL_ABSPATH is a versioned directory
-   in a state in which a new child node can be scheduled for addition;
-   return an error if not. */
-static svn_error_t *
-check_can_add_to_parent(svn_wc__db_t *db,
-                        const char **repos_root_url,
-                        const char **repos_uuid,
-                        const char *local_abspath,
-                        apr_pool_t *result_pool,
-                        apr_pool_t *scratch_pool)
-{
-  const char *parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-  svn_wc__db_status_t parent_status;
-  svn_wc__db_kind_t parent_kind;
-  svn_error_t *err;
-
-  SVN_ERR(svn_wc__write_check(db, parent_abspath, scratch_pool));
-
-  err = svn_wc__db_read_info(&parent_status, &parent_kind, NULL,
-                             NULL, repos_root_url,
-                             repos_uuid, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL,
-                             db, parent_abspath, scratch_pool, scratch_pool);
-
-  if (err
-      || parent_status == svn_wc__db_status_not_present
-      || parent_status == svn_wc__db_status_excluded
-      || parent_status == svn_wc__db_status_absent)
-    {
-      return
-        svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, err,
-                          _("Can't find parent directory's node while"
-                            " trying to add '%s'"),
-                          svn_dirent_local_style(local_abspath,
-                                                 scratch_pool));
-    }
-  else if (parent_status == svn_wc__db_status_deleted)
-    {
-      return
-        svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
-                          _("Can't add '%s' to a parent directory"
-                            " scheduled for deletion"),
-                          svn_dirent_local_style(local_abspath,
-                                                 scratch_pool));
-    }
-  else if (parent_kind != svn_wc__db_kind_dir)
-    /* Can't happen until single db; but then it causes serious
-       trouble if we allow this. */
-    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
-                             _("Can't schedule an addition of '%s'"
-                               " below a not-directory node"),
-                             svn_dirent_local_style(local_abspath,
-                                                 scratch_pool));
-
-  /* If we haven't found the repository info yet, find it now. */
-  if ((repos_root_url && ! *repos_root_url)
-      || (repos_uuid && ! *repos_uuid))
-    {
-      if (parent_status == svn_wc__db_status_added)
-        SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
-                                         repos_root_url, repos_uuid, NULL,
-                                         NULL, NULL, NULL,
-                                         db, parent_abspath,
-                                         scratch_pool, scratch_pool));
-      else
-        SVN_ERR(svn_wc__db_scan_base_repos(NULL,
-                                           repos_root_url, repos_uuid,
-                                           db, parent_abspath,
-                                           scratch_pool, scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Check that the on-disk item at LOCAL_ABSPATH can be scheduled for
- * addition to its WC parent directory.
- *
- * Set *KIND_P to the kind of node to be added, *DB_ROW_EXISTS_P to whether
- * it is already a versioned path, and if so, *IS_WC_ROOT_P to whether it's
- * a WC root.
- *
- * ### The checks here, and the outputs, are geared towards svn_wc_add4().
- */
-static svn_error_t *
-check_can_add_node(svn_node_kind_t *kind_p,
-                   svn_boolean_t *db_row_exists_p,
-                   svn_boolean_t *is_wc_root_p,
-                   svn_wc_context_t *wc_ctx,
-                   const char *local_abspath,
-                   const char *copyfrom_url,
-                   svn_revnum_t copyfrom_rev,
-                   apr_pool_t *scratch_pool)
+svn_error_t *
+svn_wc_add4(svn_wc_context_t *wc_ctx,
+            const char *local_abspath,
+            svn_depth_t depth,
+            const char *copyfrom_url,
+            svn_revnum_t copyfrom_rev,
+            svn_cancel_func_t cancel_func,
+            void *cancel_baton,
+            svn_wc_notify_func2_t notify_func,
+            void *notify_baton,
+            apr_pool_t *scratch_pool)
 {
-  const char *base_name = svn_dirent_basename(local_abspath, scratch_pool);
-  svn_boolean_t is_wc_root;
+  const char *parent_abspath;
+  const char *base_name;
+  const char *parent_repos_relpath;
+  const char *repos_root_url, *repos_uuid;
+  svn_boolean_t is_wc_root = FALSE;
   svn_node_kind_t kind;
   svn_wc__db_t *db = wc_ctx->db;
+  svn_error_t *err;
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t db_kind;
   svn_boolean_t exists;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -864,7 +764,7 @@
                                                         scratch_pool)
                                    && SVN_IS_VALID_REVNUM(copyfrom_rev)));
 
-  /* Check that the proposed node has an acceptable name. */
+  svn_dirent_split(&parent_abspath, &base_name, local_abspath, scratch_pool);
   if (svn_wc_is_adm_dir(base_name, scratch_pool))
     return svn_error_createf
       (SVN_ERR_ENTRY_FORBIDDEN, NULL,
@@ -873,7 +773,7 @@
 
   SVN_ERR(svn_path_check_valid(local_abspath, scratch_pool));
 
-  /* Make sure something's there; set KIND and *KIND_P. */
+  /* Make sure something's there. */
   SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
   if (kind == svn_node_none)
     return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
@@ -885,106 +785,122 @@
                              _("Unsupported node kind for path '%s'"),
                              svn_dirent_local_style(local_abspath,
                                                     scratch_pool));
-  if (kind_p)
-    *kind_p = kind;
 
-  /* Determine whether a DB row for this node EXISTS, and whether it
-     IS_WC_ROOT.  If it exists, check that it is in an acceptable state for
-     adding the new node; if not, return an error. */
-  {
-    svn_wc__db_status_t status;
-    svn_error_t *err
-      = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
+  /* Get the node information for this path if one exists (perhaps
+     this is actually a replacement of a previously deleted thing). */
+  err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL,
                              db, local_abspath,
                              scratch_pool, scratch_pool);
 
-    if (err)
-      {
-        if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-          return svn_error_return(err);
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+        return svn_error_return(err);
 
-        svn_error_clear(err);
-        exists = FALSE;
-        is_wc_root = FALSE;
-      }
-    else
-      {
-        is_wc_root = FALSE;
-        exists = TRUE;
-        switch (status)
-          {
-            case svn_wc__db_status_not_present:
-              break;
-            case svn_wc__db_status_deleted:
-              /* A working copy root should never have a WORKING_NODE */
-              SVN_ERR_ASSERT(!is_wc_root);
-              break;
-            case svn_wc__db_status_normal:
-              if (copyfrom_url)
-                {
-                  SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
-                                                db, local_abspath,
-                                                scratch_pool));
+      svn_error_clear(err);
+      exists = FALSE;
+      is_wc_root = FALSE;
+    }
+  else
+    {
+      is_wc_root = FALSE;
+      exists = TRUE;
+      switch (status)
+        {
+          case svn_wc__db_status_not_present:
+            break;
+          case svn_wc__db_status_deleted:
+            /* A working copy root should never have a WORKING_NODE */
+            SVN_ERR_ASSERT(!is_wc_root);
+            break;
+          case svn_wc__db_status_normal:
+            if (copyfrom_url)
+              {
+                SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
+                                              db, local_abspath,
+                                              scratch_pool));
 
-                  if (is_wc_root)
-                    break;
-                }
-              /* else: Fall through in default error */
+                if (is_wc_root)
+                  break;
+              }
+            /* else: Fall through in default error */
 
-            default:
-              return svn_error_createf(
-                               SVN_ERR_ENTRY_EXISTS, NULL,
-                               _("'%s' is already under version control"),
-                               svn_dirent_local_style(local_abspath,
-                                                      scratch_pool));
-          }
-      } /* err */
+          default:
+            return svn_error_createf(
+                             SVN_ERR_ENTRY_EXISTS, NULL,
+                             _("'%s' is already under version control"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+        }
+    } /* err */
 
-    if (db_row_exists_p)
-      *db_row_exists_p = exists;
-    if (is_wc_root_p)
-      *is_wc_root_p = is_wc_root;
-  }
+  SVN_ERR(svn_wc__write_check(db, parent_abspath, scratch_pool));
 
-  return SVN_NO_ERROR;
-}
+  {
+    svn_wc__db_status_t parent_status;
+    svn_wc__db_kind_t parent_kind;
 
-svn_error_t *
-svn_wc_add4(svn_wc_context_t *wc_ctx,
-            const char *local_abspath,
-            svn_depth_t depth,
-            const char *copyfrom_url,
-            svn_revnum_t copyfrom_rev,
-            svn_cancel_func_t cancel_func,
-            void *cancel_baton,
-            svn_wc_notify_func2_t notify_func,
-            void *notify_baton,
-            apr_pool_t *scratch_pool)
-{
-  svn_wc__db_t *db = wc_ctx->db;
-  svn_node_kind_t kind;
-  svn_boolean_t db_row_exists, is_wc_root;
-  const char *repos_root_url, *repos_uuid;
+    err = svn_wc__db_read_info(&parent_status, &parent_kind, NULL,
+                               &parent_repos_relpath, &repos_root_url,
+                               &repos_uuid, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL,
+                               db, parent_abspath, scratch_pool, scratch_pool);
 
-  SVN_ERR(check_can_add_node(&kind, &db_row_exists, &is_wc_root,
-                             wc_ctx, local_abspath, copyfrom_url, copyfrom_rev,
-                             scratch_pool));
+    if (err
+        || parent_status == svn_wc__db_status_not_present
+        || parent_status == svn_wc__db_status_excluded
+        || parent_status == svn_wc__db_status_absent)
+      {
+        return
+          svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, err,
+                            _("Can't find parent directory's node while"
+                              " trying to add '%s'"),
+                            svn_dirent_local_style(local_abspath,
+                                                   scratch_pool));
+      }
+    else if (parent_status == svn_wc__db_status_deleted)
+      {
+        return
+          svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
+                            _("Can't add '%s' to a parent directory"
+                              " scheduled for deletion"),
+                            svn_dirent_local_style(local_abspath,
+                                                   scratch_pool));
+      }
+    else if (parent_kind != svn_wc__db_kind_dir)
+      /* Can't happen until single db; but then it causes serious
+         trouble if we allow this. */
+      return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
+                               _("Can't schedule an addition of '%s'"
+                                 " below a not-directory node"),
+                               svn_dirent_local_style(local_abspath,
+                                                   scratch_pool));
 
-  /* Get REPOS_ROOT_URL and REPOS_UUID.  Check that the
-     parent is a versioned directory in an acceptable state. */
-  SVN_ERR(check_can_add_to_parent(db, &repos_root_url, &repos_uuid,
-                                  local_abspath, scratch_pool, scratch_pool));
+    if (!repos_root_url)
+      {
+        if (parent_status == svn_wc__db_status_added)
+          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &parent_repos_relpath,
+                                           &repos_root_url, &repos_uuid, NULL,
+                                           NULL, NULL, NULL,
+                                           db, parent_abspath,
+                                           scratch_pool, scratch_pool));
+        else
+          SVN_ERR(svn_wc__db_scan_base_repos(&parent_repos_relpath,
+                                             &repos_root_url, &repos_uuid,
+                                             db, parent_abspath,
+                                             scratch_pool, scratch_pool));
+      }
 
-  /* If we're performing a repos-to-WC copy, check that the copyfrom
-     repository is the same as the parent dir's repository. */
-  if (copyfrom_url
-      && !svn_uri_is_ancestor(repos_root_url, copyfrom_url))
-    return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                             _("The URL '%s' has a different repository "
-                               "root than its parent"), copyfrom_url);
+    if (copyfrom_url
+        && !svn_uri_is_ancestor(repos_root_url, copyfrom_url))
+      return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                               _("The URL '%s' has a different repository "
+                                 "root than its parent"), copyfrom_url);
+  }
 
   /* Verify that we can actually integrate the inner working copy */
   if (is_wc_root)
@@ -1027,27 +943,11 @@
                                  copyfrom_url, inner_url);
     }
 
-  if (!copyfrom_url)  /* Case 2a: It's a simple add */
-    {
-      SVN_ERR(add_from_disk(wc_ctx, local_abspath, kind, scratch_pool));
-      if (kind == svn_node_dir && !db_row_exists)
-        {
-          /* If using the legacy 1.6 interface the parent lock may not
-             be recursive and add is expected to lock the new dir.
-
-             ### Perhaps the lock should be created in the same
-             transaction that adds the node? */
-          svn_boolean_t owns_lock;
-          SVN_ERR(svn_wc__db_wclock_owns_lock(&owns_lock, db, local_abspath,
-                                              FALSE, scratch_pool));
-          if (!owns_lock)
-            SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE,
-                                             scratch_pool));
-        }
-    }
-  else if (!is_wc_root)  /* Case 2b: It's a copy from the repository */
+  if (kind == svn_node_file)
     {
-      if (kind == svn_node_file)
+      if (!copyfrom_url)
+        SVN_ERR(svn_wc__db_op_add_file(db, local_abspath, NULL, scratch_pool));
+      else
         {
           /* This code should never be used, as it doesn't install proper
              pristine and/or properties. But it was not an error in the old
@@ -1064,27 +964,46 @@
                                          NULL, NULL,
                                          scratch_pool));
         }
-      else
-        SVN_ERR(svn_wc__db_op_copy_dir(db,
-                                       local_abspath,
-                                       apr_hash_make(scratch_pool),
-                                       copyfrom_rev,
-                                       0,
-                                       NULL,
-                                       svn_path_uri_decode(
-                                            svn_uri_skip_ancestor(repos_root_url,
-                                                                  copyfrom_url),
-                                            scratch_pool),
-                                       repos_root_url,
-                                       repos_uuid,
-                                       copyfrom_rev,
-                                       NULL,
-                                       depth,
-                                       NULL,
-                                       NULL,
-                                       scratch_pool));
     }
-  else  /* Case 1: Integrating a separate WC into this one, in place */
+  else if (!copyfrom_url)
+    {
+      SVN_ERR(svn_wc__db_op_add_directory(db, local_abspath, NULL,
+                                          scratch_pool));
+      if (!exists)
+        {
+          /* If using the legacy 1.6 interface the parent lock may not
+             be recursive and add is expected to lock the new dir.
+
+             ### Perhaps the lock should be created in the same
+             transaction that adds the node? */
+          svn_boolean_t owns_lock;
+          SVN_ERR(svn_wc__db_wclock_owns_lock(&owns_lock, db, local_abspath,
+                                              FALSE, scratch_pool));
+          if (!owns_lock)
+            SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE,
+                                             scratch_pool));
+        }
+    }
+  else if (!is_wc_root)
+    SVN_ERR(svn_wc__db_op_copy_dir(db,
+                                   local_abspath,
+                                   apr_hash_make(scratch_pool),
+                                   copyfrom_rev,
+                                   0,
+                                   NULL,
+                                   svn_path_uri_decode(
+                                        svn_uri_skip_ancestor(repos_root_url,
+                                                              copyfrom_url),
+                                        scratch_pool),
+                                   repos_root_url,
+                                   repos_uuid,
+                                   copyfrom_rev,
+                                   NULL,
+                                   depth,
+                                   NULL,
+                                   NULL,
+                                   scratch_pool));
+  else
     {
       svn_boolean_t owns_lock;
       const char *tmpdir_abspath, *moved_abspath, *moved_adm_abspath;
@@ -1096,8 +1015,7 @@
 
       /* Move the admin dir from the wc to a temporary location */
       SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
-                                             svn_dirent_dirname(local_abspath,
-                                                                scratch_pool),
+                                             parent_abspath,
                                              scratch_pool, scratch_pool));
       SVN_ERR(svn_io_open_unique_file3(NULL, &moved_abspath, tmpdir_abspath,
                                        svn_io_file_del_on_close,
@@ -1140,37 +1058,6 @@
 }
 
 svn_error_t *
-svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
-                     const char *local_abspath,
-                     svn_cancel_func_t cancel_func,
-                     void *cancel_baton,
-                     svn_wc_notify_func2_t notify_func,
-                     void *notify_baton,
-                     apr_pool_t *scratch_pool)
-{
-  svn_node_kind_t kind;
-
-  SVN_ERR(check_can_add_node(&kind, NULL, NULL, wc_ctx, local_abspath,
-                             NULL, SVN_INVALID_REVNUM, scratch_pool));
-  SVN_ERR(check_can_add_to_parent(wc_ctx->db, NULL, NULL,
-                                  local_abspath,
-                                  scratch_pool, scratch_pool));
-  SVN_ERR(add_from_disk(wc_ctx, local_abspath, kind, scratch_pool));
-
-  /* Report the addition to the caller. */
-  if (notify_func != NULL)
-    {
-      svn_wc_notify_t *notify = svn_wc_create_notify(local_abspath,
-                                                     svn_wc_notify_add,
-                                                     scratch_pool);
-      notify->kind = kind;
-      (*notify_func)(notify_baton, notify, scratch_pool);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_wc__register_file_external(svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                const char *external_url,
@@ -1246,6 +1133,193 @@
 */
 
 
+/* */
+static svn_error_t *
+revert_admin_things(svn_boolean_t *reverted,
+                    svn_wc__db_t *db,
+                    const char *local_abspath,
+                    svn_boolean_t use_commit_times,
+                    apr_pool_t *pool)
+{
+  SVN_ERR(svn_wc__wq_add_revert(reverted, db, local_abspath, use_commit_times,
+                                pool));
+  SVN_ERR(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool));
+
+  return SVN_NO_ERROR;
+}
+
+
+/* Revert LOCAL_ABSPATH in DB, where the on-disk node kind is DISK_KIND.
+   *DEPTH is the depth of the reversion crawl the caller is
+   using; this function may choose to override that value as needed.
+
+   See svn_wc_revert4() for the interpretations of
+   USE_COMMIT_TIMES, CANCEL_FUNC and CANCEL_BATON.
+
+   Set *DID_REVERT to true if actually reverting anything, else do not
+   touch *DID_REVERT.
+
+   Use POOL for allocations.
+ */
+static svn_error_t *
+revert_entry(svn_depth_t *depth,
+             svn_wc__db_t *db,
+             const char *local_abspath,
+             svn_node_kind_t disk_kind,
+             svn_boolean_t use_commit_times,
+             svn_cancel_func_t cancel_func,
+             void *cancel_baton,
+             svn_boolean_t *did_revert,
+             apr_pool_t *pool)
+{
+  svn_wc__db_status_t status, base_status;
+  svn_wc__db_kind_t kind, base_kind;
+  svn_boolean_t replaced;
+  svn_boolean_t have_base;
+  svn_revnum_t base_revision;
+  svn_boolean_t is_add_root;
+
+  /* Initialize this even though revert_admin_things() is guaranteed
+     to set it, because we don't know that revert_admin_things() will
+     be called. */
+  svn_boolean_t reverted = FALSE;
+
+  SVN_ERR(svn_wc__db_read_info(&status, &kind,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, &have_base, NULL,
+                               NULL, NULL,
+                               db, local_abspath, pool, pool));
+
+  if (have_base)
+    SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, &base_revision,
+                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                     NULL, NULL, NULL, NULL, NULL,
+                                     db, local_abspath, pool, pool));
+
+  replaced = (status == svn_wc__db_status_added
+              && have_base
+              && base_status != svn_wc__db_status_not_present);
+
+  if (status == svn_wc__db_status_added)
+    {
+      const char *op_root_abspath;
+      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, local_abspath, pool, pool));
+
+      is_add_root = (strcmp(op_root_abspath, local_abspath) == 0);
+    }
+  else
+    is_add_root = FALSE;
+
+  /* Additions. */
+  if (!replaced
+      && is_add_root)
+    {
+      const char *repos_relpath;
+      const char *repos_root_url;
+      const char *repos_uuid;
+      /* Before removing item from revision control, notice if the
+         BASE_NODE is in a 'not-present' state. */
+      svn_boolean_t was_not_present = FALSE;
+
+      /* NOTE: if WAS_NOT_PRESENT gets set, then we have BASE nodes.
+         The code below will then figure out the repository information, so
+         that we can later insert a node for the same repository. */
+
+      if (have_base
+          && base_status == svn_wc__db_status_not_present)
+        {
+          /* Remember the BASE revision. (already handled)  */
+          /* Remember the repository this node is associated with.  */
+
+          was_not_present = TRUE;
+
+          SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
+                                             &repos_root_url,
+                                             &repos_uuid,
+                                             db, local_abspath,
+                                             pool, pool));
+        }
+
+      /* ### much of this is probably bullshit. we should be able to just
+         ### remove the WORKING and ACTUAL rows, and be done. but we're
+         ### not quite there yet, so nodes get fully removed and then
+         ### shoved back into the database. this is why we need to record
+         ### the repository information, and the BASE revision.  */
+
+      if (kind == svn_wc__db_kind_file)
+        {
+          SVN_ERR(svn_wc__internal_remove_from_revision_control(db,
+                                                                local_abspath,
+                                                                FALSE, FALSE,
+                                                                cancel_func,
+                                                                cancel_baton,
+                                                                pool));
+        }
+      else if (kind == svn_wc__db_kind_dir)
+        {
+          /* Before single-db we didn't have to perform a recursive delete
+             here. With single-db we really must delete missing nodes */
+          SVN_ERR(svn_wc__internal_remove_from_revision_control(db,
+                                                                local_abspath,
+                                                                FALSE, FALSE,
+                                                                cancel_func,
+                                                                cancel_baton,
+                                                                pool));
+        }
+      else  /* Else it's `none', or something exotic like a symlink... */
+        {
+          return svn_error_createf(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
+                                   _("Unknown or unexpected kind for path "
+                                     "'%s'"),
+                                   svn_dirent_local_style(local_abspath,
+                                                          pool));
+
+        }
+
+      /* Recursivity is taken care of by svn_wc_remove_from_revision_control,
+         and we've definitely reverted PATH at this point. */
+      *depth = svn_depth_empty;
+      reverted = TRUE;
+
+      /* If the removed item was *also* in a 'not-present' state, make
+         sure we leave a not-present node behind */
+      if (was_not_present)
+        {
+          SVN_ERR(svn_wc__db_base_add_not_present_node(
+                    db, local_abspath,
+                    repos_relpath, repos_root_url, repos_uuid,
+                    base_revision,
+                    base_kind,
+                    NULL, NULL,
+                    pool));
+        }
+    }
+  /* Regular prop and text edit. */
+  /* Deletions and replacements. */
+  else if (status == svn_wc__db_status_normal
+           || status == svn_wc__db_status_deleted
+           || replaced
+           || (status == svn_wc__db_status_added && !is_add_root))
+    {
+      /* Revert the prop and text mods (if any). */
+      SVN_ERR(revert_admin_things(&reverted, db, local_abspath,
+                                  use_commit_times, pool));
+
+      /* Force recursion on replaced directories. */
+      if (kind == svn_wc__db_kind_dir && replaced)
+        *depth = svn_depth_infinity;
+    }
+
+  /* If PATH was reverted, tell our client that. */
+  if (reverted)
+    *did_revert = TRUE;
+
+  return SVN_NO_ERROR;
+}
+
 /* Verifies if an add (or copy) to LOCAL_ABSPATH can be reverted with depth
  * DEPTH, without touching nodes that are filtered by DEPTH.
  *
@@ -1319,7 +1393,6 @@
    documentation. */
 static svn_error_t *
 revert_internal(svn_wc__db_t *db,
-                const char *revert_root,
                 const char *local_abspath,
                 svn_depth_t depth,
                 svn_boolean_t use_commit_times,
@@ -1331,13 +1404,10 @@
                 apr_pool_t *pool)
 {
   svn_node_kind_t disk_kind;
-  svn_wc__db_status_t status, base_status;
+  svn_wc__db_status_t status;
   svn_wc__db_kind_t db_kind;
   svn_boolean_t unversioned;
-  svn_boolean_t have_base;
-  svn_boolean_t replaced;
   const svn_wc_conflict_description2_t *tree_conflict;
-  const char *op_root_abspath = NULL;
   svn_error_t *err;
 
   /* Check cancellation here, so recursive calls get checked early. */
@@ -1350,7 +1420,7 @@
   err = svn_wc__db_read_info(&status, &db_kind,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, &have_base, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL,
                              db, local_abspath, pool, pool);
 
@@ -1369,30 +1439,11 @@
         case svn_wc__db_status_excluded:
           unversioned = TRUE;
           break;
-        case svn_wc__db_status_incomplete:
-          /* Remove NAME from PATH's entries file
-
-             Not being able to revert incomplete entries breaks working
-             copies flat out, but the usual revert process can't be
-             applied.  Most preconditions aren't met. */
-          SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, pool));
-          return SVN_NO_ERROR;
-          break;
         default:
           unversioned = FALSE;
           break;
       }
 
-  if (! unversioned && have_base)
-    SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL,
-                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                     NULL, NULL, NULL, NULL, NULL,
-                                     db, local_abspath, pool, pool));
-
-  replaced = ! unversioned && (status == svn_wc__db_status_added
-              && have_base
-              && base_status != svn_wc__db_status_not_present);
-
   SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict, db, local_abspath,
                                            pool, pool));
   if (unversioned && tree_conflict == NULL)
@@ -1441,17 +1492,17 @@
        _("Cannot revert '%s': unsupported node kind in working copy"),
        svn_dirent_local_style(local_abspath, pool));
 
-  if (status == svn_wc__db_status_added)
-    SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
-                                     NULL, NULL, NULL, NULL, NULL,
-                                     db, local_abspath, pool, pool));
-
   /* Safeguard 4:  Make sure we don't revert deeper then asked */
   if (status == svn_wc__db_status_added
       && db_kind == svn_wc__db_kind_dir
       && depth >= svn_depth_empty
       && depth < svn_depth_infinity)
     {
+      const char *op_root_abspath;
+      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       db, local_abspath, pool, pool));
+
       /* If this node is an operation root for a copy/add, then reverting
          it will change its descendants, if it has any. */
       if (strcmp(local_abspath, op_root_abspath) == 0)
@@ -1480,19 +1531,10 @@
       /* Actually revert this entry.  If this is a working copy root,
          we provide a base_name from the parent path. */
       if (!unversioned)
-        {
-          /* Revert the prop, text and tree mods (if any). */
-          SVN_ERR(svn_wc__wq_add_revert(&reverted, db, revert_root,
-                                        local_abspath, use_commit_times,
-                                        pool));
-          SVN_ERR(svn_wc__wq_run(db, local_abspath,
-                                 cancel_func, cancel_baton, pool));
-
-          /* Force recursion on replaced directories. */
-          if (db_kind == svn_wc__db_kind_dir && replaced)
-            depth = svn_depth_infinity;
-
-        }
+        SVN_ERR(revert_entry(&depth, db, local_abspath, disk_kind,
+                             use_commit_times,
+                             cancel_func, cancel_baton,
+                             &reverted, pool));
 
       /* Notify */
       if (notify_func && reverted)
@@ -1502,15 +1544,6 @@
                        pool);
     }
 
-
-  if (op_root_abspath && strcmp(local_abspath, op_root_abspath) == 0)
-    /* If this is a copy or add root, disable notifications for the children,
-       because wc-1.0 used to behave like that. */
-    {
-      notify_func = NULL;
-      notify_baton = NULL;
-    }
-
   /* Finally, recurse if requested. */
   if (!unversioned && db_kind == svn_wc__db_kind_dir && depth > svn_depth_empty)
     {
@@ -1554,7 +1587,7 @@
             continue;
 
           /* Revert the entry. */
-          SVN_ERR(revert_internal(db, revert_root, node_abspath,
+          SVN_ERR(revert_internal(db, node_abspath,
                                   depth_under_here, use_commit_times,
                                   changelist_hash, cancel_func, cancel_baton,
                                   notify_func, notify_baton, iterpool));
@@ -1598,8 +1631,7 @@
                                 const svn_wc_conflict_description2_t *);
 
                 if (conflict->kind == svn_wc_conflict_kind_tree)
-                  SVN_ERR(revert_internal(db, revert_root,
-                                          conflict->local_abspath,
+                  SVN_ERR(revert_internal(db, conflict->local_abspath,
                                           svn_depth_empty,
                                           use_commit_times, changelist_hash,
                                           cancel_func, cancel_baton,
@@ -1612,14 +1644,6 @@
       svn_pool_destroy(iterpool);
     }
 
-  if (! replaced && status == svn_wc__db_status_added
-      && db_kind == svn_wc__db_kind_dir)
-    {
-      /* Non-replacements have their admin area deleted. wc-1.0 */
-      SVN_ERR(svn_wc__adm_destroy(db, local_abspath,
-                                  cancel_func, cancel_baton, pool));
-    }
-
   return SVN_NO_ERROR;
 }
 
@@ -1642,7 +1666,7 @@
     SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
 
   return svn_error_return(revert_internal(wc_ctx->db,
-                                          local_abspath, local_abspath, depth,
+                                          local_abspath, depth,
                                           use_commit_times, changelist_hash,
                                           cancel_func, cancel_baton,
                                           notify_func, notify_baton,
Index: subversion/libsvn_wc/status.c
===================================================================
--- subversion/libsvn_wc/status.c	(revision 1023844)
+++ subversion/libsvn_wc/status.c	(revision 1005387)
@@ -233,115 +233,6 @@
 
 
 /** Code **/
-
-/* Fill in *INFO with the information it would contain if it were
-   obtained from svn_wc__db_read_children_info. */
-static svn_error_t *
-read_info(const struct svn_wc__db_info_t **info,
-          const char *local_abspath,
-          svn_wc__db_t *db,
-          apr_pool_t *result_pool,
-          apr_pool_t *scratch_pool)
-{
-  struct svn_wc__db_info_t *mutable 
-    = apr_palloc(scratch_pool, sizeof(struct svn_wc__db_info_t));
-
-  SVN_ERR(svn_wc__db_read_info(&mutable->status, &mutable->kind,
-                               &mutable->revnum, &mutable->repos_relpath,
-                               &mutable->repos_root_url, NULL,
-                               &mutable->changed_rev,
-                               &mutable->changed_date,
-                               &mutable->changed_author,
-                               &mutable->last_mod_time,
-                               &mutable->depth, NULL,
-                               &mutable->translated_size, NULL,
-                               &mutable->changelist, NULL, NULL, NULL, NULL,
-                               &mutable->props_mod,
-                               &mutable->have_base, NULL,
-                               &mutable->conflicted, &mutable->lock,
-                               db, local_abspath,
-                               result_pool, scratch_pool));
-
-  if (mutable->status == svn_wc__db_status_deleted)
-    mutable->has_props = FALSE;
-  else if (mutable->props_mod)
-    {
-      mutable->has_props = TRUE;
-#ifdef HAVE_SYMLINK
-      SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL, &mutable->special,
-                                         db, local_abspath,
-                                         scratch_pool, scratch_pool));
-#endif
-    }
-  else
-    {
-      apr_hash_t *properties;
-
-      SVN_ERR(svn_wc__db_read_pristine_props(&properties, db, local_abspath,
-                                             scratch_pool, scratch_pool));
-      mutable->has_props = (properties && !!apr_hash_count(properties));
-#ifdef HAVE_SYMLINK
-      mutable->special = (mutable->has_props
-                          && apr_hash_get(properties, SVN_PROP_SPECIAL,
-                                          APR_HASH_KEY_STRING));
-#endif
-    }
-
-  *info = mutable;
-
-  return SVN_NO_ERROR;
-}
-
-/* Return *REPOS_RELPATH and *REPOS_ROOT_URL for LOCAL_ABSPATH using
-   information in INFO if available, falling back on
-   PARENT_REPOS_RELPATH and PARENT_REPOS_ROOT_URL if available, and
-   finally falling back on querying DB. */
-static svn_error_t *
-get_repos_root_url_relpath(const char **repos_relpath,
-                           const char **repos_root_url,
-                           const struct svn_wc__db_info_t *info,
-                           const char *parent_repos_relpath,
-                           const char *parent_repos_root_url,
-                           svn_wc__db_t *db,
-                           const char *local_abspath,
-                           apr_pool_t *result_pool,
-                           apr_pool_t *scratch_pool)
-{
-  if (info->repos_relpath && info->repos_root_url)
-    {
-      *repos_relpath = info->repos_relpath;
-      *repos_root_url = info->repos_root_url;
-    }
-  else if (parent_repos_relpath && parent_repos_root_url)
-    {
-      *repos_relpath = svn_relpath_join(parent_repos_relpath,
-                                        svn_dirent_basename(local_abspath,
-                                                            NULL),
-                                        scratch_pool);
-      *repos_root_url = parent_repos_root_url;
-    }
-  else if (info->status == svn_wc__db_status_added)
-    {
-      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL,
-                                       repos_relpath, repos_root_url,
-                                       NULL, NULL, NULL, NULL, NULL,
-                                       db, local_abspath,
-                                       result_pool, scratch_pool));
-    }
-  else if (info->have_base)
-    {
-      SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, repos_root_url, NULL,
-                                         db, local_abspath,
-                                         result_pool, scratch_pool));
-    }
-  else
-    {
-      *repos_relpath = NULL;
-      *repos_root_url = NULL;
-    }
-  return SVN_NO_ERROR;
-}
-
 static svn_error_t *
 internal_status(svn_wc_status3_t **status,
                 svn_wc__db_t *db,
@@ -371,7 +262,6 @@
                 const char *local_abspath,
                 const char *parent_repos_root_url,
                 const char *parent_repos_relpath,
-                const struct svn_wc__db_info_t *info,
                 const svn_io_dirent2_t *dirent,
                 svn_boolean_t get_all,
                 const svn_lock_t *repos_lock,
@@ -379,32 +269,76 @@
                 apr_pool_t *scratch_pool)
 {
   svn_wc_status3_t *stat;
+  svn_wc__db_status_t db_status;
+  svn_wc__db_kind_t db_kind;
+  const char *repos_relpath;
+  const char *repos_root_url;
   svn_boolean_t switched_p = FALSE;
-  svn_boolean_t copied = FALSE;
+  svn_boolean_t prop_modified_p;
+  svn_wc__db_lock_t *lock;
+  svn_revnum_t revision;
+  svn_revnum_t changed_rev;
+  const char *changed_author;
+  apr_time_t changed_date;
+  const char *changelist;
+  svn_boolean_t have_base;
   svn_boolean_t conflicted;
+  svn_boolean_t copied = FALSE;
+  svn_filesize_t translated_size;
+  apr_time_t last_mod_time;
+  svn_depth_t depth;
   svn_error_t *err;
-  const char *repos_relpath;
-  const char *repos_root_url;
 
   /* Defaults for two main variables. */
   enum svn_wc_status_kind node_status = svn_wc_status_normal;
   enum svn_wc_status_kind text_status = svn_wc_status_normal;
   enum svn_wc_status_kind prop_status = svn_wc_status_none;
 
+  SVN_ERR(svn_wc__db_read_info(&db_status, &db_kind, &revision,
+                               &repos_relpath, &repos_root_url, NULL,
+                               &changed_rev, &changed_date,
+                               &changed_author, &last_mod_time, &depth, NULL,
+                               &translated_size, NULL, &changelist, NULL, NULL,
+                               NULL, NULL, &prop_modified_p, &have_base, NULL,
+                               &conflicted, &lock, db, local_abspath,
+                               result_pool, scratch_pool));
+
+  if (!repos_relpath)
+    {
+      /* The node is not switched, so imply from parent if possible */
 
-  if (!info)
-    SVN_ERR(read_info(&info, local_abspath, db, result_pool, scratch_pool));
+      if (parent_repos_relpath != NULL)
+        repos_relpath = svn_relpath_join(parent_repos_relpath,
+                                         svn_dirent_basename(local_abspath,
+                                                             NULL),
+                                         result_pool);
+      else if (db_status == svn_wc__db_status_added)
+        SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
+                                         &repos_root_url, NULL, NULL, NULL,
+                                         NULL, NULL,
+                                         db, local_abspath,
+                                         result_pool, scratch_pool));
+      else if (have_base)
+        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
+                                           &repos_root_url, NULL,
+                                           db, local_abspath,
+                                           result_pool, scratch_pool));
 
-  if (!info->repos_relpath || !parent_repos_relpath)
+      switched_p = FALSE;
+    }
+  else if (!parent_repos_relpath)
     switched_p = FALSE;
   else
     {
       /* A node is switched if it doesn't have the implied repos_relpath */
-      const char *name = svn_relpath_is_child(parent_repos_relpath,
-                                              info->repos_relpath, NULL);
+
+      const char *name = svn_relpath_is_child(parent_repos_relpath, repos_relpath, NULL);
       switched_p = !name || (strcmp(name, svn_dirent_basename(local_abspath, NULL)) != 0);
     }
 
+  if (!repos_root_url && parent_repos_root_url)
+    repos_root_url = apr_pstrdup(result_pool, parent_repos_root_url);
+
   /* Examine whether our target is missing or obstructed or missing.
 
      While we are not completely in single-db mode yet, data about
@@ -413,14 +347,14 @@
      mode these obstructions are no longer reported and we have
      to detect obstructions by looking at the on disk status in DIRENT.
      */
-  if (info->kind == svn_wc__db_kind_dir)
+  if (db_kind == svn_wc__db_kind_dir)
     {
-      if (info->status == svn_wc__db_status_incomplete)
+      if (db_status == svn_wc__db_status_incomplete)
         {
           /* Highest precedence.  */
           node_status = svn_wc_status_incomplete;
         }
-      else if (info->status == svn_wc__db_status_deleted)
+      else if (db_status == svn_wc__db_status_deleted)
         {
           node_status = svn_wc_status_deleted;
 
@@ -440,7 +374,7 @@
     }
   else
     {
-      if (info->status == svn_wc__db_status_deleted)
+      if (db_status == svn_wc__db_status_deleted)
         {
           node_status = svn_wc_status_deleted;
 
@@ -466,11 +400,13 @@
      It means that no further information is available, and we should skip
      all this work.  */
   if (node_status == svn_wc_status_normal
-      || (node_status == svn_wc_status_missing
-          && info->kind != svn_wc__db_kind_dir))
+      || (node_status == svn_wc_status_missing && db_kind != svn_wc__db_kind_dir))
     {
       svn_boolean_t has_props;
       svn_boolean_t text_modified_p = FALSE;
+#ifdef HAVE_SYMLINK
+      svn_boolean_t wc_special;
+#endif /* HAVE_SYMLINK */
 
       /* Implement predecence rules: */
 
@@ -479,30 +415,43 @@
             precedence over M. */
 
       /* Does the node have props? */
-      if (info->status == svn_wc__db_status_deleted)
+      if (db_status == svn_wc__db_status_deleted)
         has_props = FALSE; /* Not interesting */
-      else if (info->props_mod)
+      else if (prop_modified_p)
         has_props = TRUE;
       else
-        has_props = info->has_props;
+        {
+          apr_hash_t *props;
+        
+          SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
+                                                 scratch_pool, scratch_pool));
 
+          has_props = (props != NULL && apr_hash_count(props) > 0);
+        }
       if (has_props)
         prop_status = svn_wc_status_normal;
 
       /* If the entry has a properties, see if it has local changes. */
       if (has_props)
-        prop_status = info->props_mod ? svn_wc_status_modified
+        prop_status = prop_modified_p ? svn_wc_status_modified
                                       : svn_wc_status_normal;
 
-      /* ### Don't read properties twice!  Cache wc_special in
-             svn_wc__db_read_children_info. */
+#ifdef HAVE_SYMLINK
+      if (has_props)
+        SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
+                                           &wc_special,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+      else
+        wc_special = FALSE;
+#endif /* HAVE_SYMLINK */
 
       /* If the entry is a file, check for textual modifications */
       if (node_status != svn_wc_status_missing
-          && (info->kind == svn_wc__db_kind_file
-              || info->kind == svn_wc__db_kind_symlink)
+          && (db_kind == svn_wc__db_kind_file
+              || db_kind == svn_wc__db_kind_symlink)
 #ifdef HAVE_SYMLINK
-             && (info->special == (dirent && dirent->special))
+             && (wc_special == (dirent && dirent->special))
 #endif /* HAVE_SYMLINK */
           )
         {
@@ -514,8 +463,8 @@
           if (dirent
               && dirent->filesize != SVN_INVALID_FILESIZE
               && dirent->mtime != 0
-              && info->translated_size == dirent->filesize
-              && info->last_mod_time == dirent->mtime)
+              && translated_size == dirent->filesize
+              && last_mod_time == dirent->mtime)
             text_modified_p = FALSE;
           else
             {
@@ -539,16 +488,14 @@
             }
         }
 #ifdef HAVE_SYMLINK
-      else if (info->special != (dirent && dirent->special))
+      else if (wc_special != (dirent && dirent->special))
         node_status = svn_wc_status_obstructed;
 #endif /* HAVE_SYMLINK */
 
-
       if (text_modified_p)
         text_status = svn_wc_status_modified;
     }
 
-  conflicted = info->conflicted;
   if (conflicted)
     {
       svn_boolean_t text_conflicted, prop_conflicted, tree_conflicted;
@@ -570,7 +517,7 @@
             of medium precedence.  They also override any C or M that may
             be in the prop_status field at this point, although they do not
             override a C text status.*/
-      if (info->status == svn_wc__db_status_added)
+      if (db_status == svn_wc__db_status_added)
         {
           svn_wc_schedule_t schedule;
           SVN_ERR(svn_wc__internal_node_get_schedule(&schedule, &copied,
@@ -599,26 +546,21 @@
          || (node_status == svn_wc_status_normal))
 
         && (! switched_p)
-        && (! info->lock) 
+        && (! lock) 
         && (! repos_lock)
-        && (! info->changelist)
+        && (! changelist)
         && (! conflicted))
       {
         *status = NULL;
         return SVN_NO_ERROR;
       }
 
-  SVN_ERR(get_repos_root_url_relpath(&repos_relpath, &repos_root_url, info,
-                                     parent_repos_relpath,
-                                     parent_repos_root_url,
-                                     db, local_abspath,
-                                     scratch_pool, scratch_pool));
 
   /* 6. Build and return a status structure. */
 
   stat = apr_pcalloc(result_pool, sizeof(**status));
 
-  switch (info->kind)
+  switch (db_kind)
     {
       case svn_wc__db_kind_dir:
         stat->kind = svn_node_dir;
@@ -631,7 +573,7 @@
       default:
         stat->kind = svn_node_unknown;
     }
-  stat->depth = info->depth;
+  stat->depth = depth;
   stat->node_status = node_status;
   stat->text_status = text_status;
   stat->prop_status = prop_status;
@@ -641,24 +583,24 @@
   stat->switched = switched_p;
   stat->copied = copied;
   stat->repos_lock = repos_lock;
-  stat->revision = info->revnum;
-  stat->changed_rev = info->changed_rev;
-  stat->changed_author = info->changed_author;
-  stat->changed_date = info->changed_date;
+  stat->revision = revision;
+  stat->changed_rev = changed_rev;
+  stat->changed_author = changed_author;
+  stat->changed_date = changed_date;
 
   stat->ood_kind = svn_node_none;
   stat->ood_changed_rev = SVN_INVALID_REVNUM;
   stat->ood_changed_date = 0;
   stat->ood_changed_author = NULL;
 
-  if (info->lock)
+  if (lock)
     {
       svn_lock_t *lck = apr_pcalloc(result_pool, sizeof(*lck));
       lck->path = repos_relpath;
-      lck->token = info->lock->token;
-      lck->owner = info->lock->owner;
-      lck->comment = info->lock->comment;
-      lck->creation_date = info->lock->date;
+      lck->token = lock->token;
+      lck->owner = lock->owner;
+      lck->comment = lock->comment;
+      lck->creation_date = lock->date;
       stat->lock = lck;
     }
   else
@@ -666,7 +608,7 @@
 
   stat->conflicted = conflicted;
   stat->versioned = TRUE;
-  stat->changelist = info->changelist;
+  stat->changelist = changelist;
   stat->repos_root_url = repos_root_url;
   stat->repos_relpath = repos_relpath;
 
@@ -757,7 +699,6 @@
                       const char *local_abspath,
                       const char *parent_repos_root_url,
                       const char *parent_repos_relpath,
-                      const struct svn_wc__db_info_t *info,
                       const svn_io_dirent2_t *dirent,
                       svn_boolean_t get_all,
                       svn_wc_status_func4_t status_func,
@@ -770,13 +711,30 @@
   /* Check for a repository lock. */
   if (wb->repos_locks)
     {
-      const char *repos_relpath, *repos_root_url;
+      const char *repos_relpath;
+      svn_wc__db_status_t status;
+      svn_boolean_t have_base;
+
+      SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, &repos_relpath, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, &have_base, NULL, NULL, NULL, 
+                                   wb->db, local_abspath,
+                                   scratch_pool, scratch_pool));
 
-      SVN_ERR(get_repos_root_url_relpath(&repos_relpath, &repos_root_url,
-                                         info, parent_repos_relpath,
-                                         parent_repos_root_url,
-                                         wb->db, local_abspath,
-                                         scratch_pool, scratch_pool));
+      /* A switched path can be deleted: check the right relpath */
+      if (status == svn_wc__db_status_deleted && have_base)
+        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, NULL,
+                                           NULL, wb->db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+      if (!repos_relpath && parent_repos_relpath)
+        repos_relpath = svn_relpath_join(parent_repos_relpath,
+                                         svn_dirent_basename(local_abspath,
+                                                             NULL),
+                                         scratch_pool);
+
+
       if (repos_relpath)
         {
           /* repos_lock still uses the deprecated filesystem absolute path
@@ -790,7 +748,7 @@
 
   SVN_ERR(assemble_status(&statstruct, wb->db, local_abspath,
                           parent_repos_root_url, parent_repos_relpath,
-                          info, dirent, get_all,
+                          dirent, get_all,
                           repos_lock, scratch_pool, scratch_pool));
 
   if (statstruct && status_func)
@@ -952,7 +910,6 @@
                svn_boolean_t skip_this_dir,
                const char *parent_repos_root_url,
                const char *parent_repos_relpath,
-               const struct svn_wc__db_info_t *dir_info,
                const svn_io_dirent2_t *dirent,
                const apr_array_header_t *ignores,
                svn_depth_t depth,
@@ -974,7 +931,6 @@
                  svn_wc__db_kind_t db_kind,
                  const char *dir_repos_root_url,
                  const char *dir_repos_relpath,
-                 const struct svn_wc__db_info_t *entry_info,
                  svn_io_dirent2_t *dirent,
                  const apr_array_header_t *ignores,
                  svn_depth_t depth,
@@ -1007,7 +963,6 @@
         {
           SVN_ERR(get_dir_status(wb, local_abspath, NULL, FALSE,
                                  dir_repos_root_url, dir_repos_relpath,
-                                 entry_info,
                                  dirent, ignores, depth, get_all, no_ignore,
                                  status_func, status_baton, cancel_func,
                                  cancel_baton,
@@ -1020,7 +975,7 @@
           SVN_ERR(send_status_structure(wb, local_abspath,
                                         dir_repos_root_url,
                                         dir_repos_relpath,
-                                        entry_info, dirent, get_all,
+                                        dirent, get_all,
                                         status_func, status_baton, pool));
         }
     }
@@ -1030,7 +985,7 @@
       SVN_ERR(send_status_structure(wb, local_abspath,
                                     dir_repos_root_url,
                                     dir_repos_relpath,
-                                    entry_info, dirent, get_all,
+                                    dirent, get_all,
                                     status_func, status_baton, pool));
     }
 
@@ -1112,7 +1067,6 @@
                svn_boolean_t skip_this_dir,
                const char *parent_repos_root_url,
                const char *parent_repos_relpath,
-               const struct svn_wc__db_info_t *dir_info,
                const svn_io_dirent2_t *dirent,
                const apr_array_header_t *ignore_patterns,
                svn_depth_t depth,
@@ -1129,20 +1083,29 @@
   const char *dir_repos_relpath;
   apr_hash_t *dirents, *nodes, *conflicts, *all_children;
   apr_array_header_t *patterns = NULL;
+  svn_wc__db_status_t dir_status;
+  svn_depth_t dir_depth;
   apr_pool_t *iterpool, *subpool = svn_pool_create(scratch_pool);
   svn_error_t *err;
 
+  /* See if someone wants to cancel this operation. */
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
 
   if (depth == svn_depth_unknown)
     depth = svn_depth_infinity;
 
+  /* Make our iteration pool. */
   iterpool = svn_pool_create(subpool);
 
-  SVN_ERR(svn_wc__db_read_children_info(&nodes, &conflicts,
-                                        wb->db, local_abspath,
-                                        subpool, iterpool));
+  /* Load list of childnodes. */
+  {
+    const apr_array_header_t *child_nodes;
+
+    SVN_ERR(svn_wc__db_read_children(&child_nodes, wb->db, local_abspath,
+                                     iterpool, iterpool));
+    SVN_ERR(svn_hash_from_cstring_keys(&nodes, child_nodes, subpool));
+  }
 
   err = svn_io_get_dirents3(&dirents, local_abspath, FALSE, subpool, subpool);
   if (err
@@ -1155,36 +1118,77 @@
   else
     SVN_ERR(err);
 
-  if (!dir_info)
-    SVN_ERR(read_info(&dir_info, local_abspath, wb->db,
-                      scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_read_info(&dir_status, NULL, NULL, &dir_repos_relpath,
+                               &dir_repos_root_url, NULL, NULL, NULL, NULL,
+                               NULL, &dir_depth, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, wb->db, local_abspath, scratch_pool,
+                               scratch_pool));
 
-  SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url,
-                                     dir_info, parent_repos_relpath,
-                                     parent_repos_root_url,
-                                     wb->db, local_abspath,
-                                     scratch_pool, scratch_pool));
+  if (dir_repos_relpath == NULL)
+    {
+      if (parent_repos_root_url != NULL)
+        {
+          dir_repos_root_url = parent_repos_root_url;
+          dir_repos_relpath = svn_relpath_join(
+                                    parent_repos_relpath,
+                                    svn_dirent_basename(local_abspath, NULL),
+                                    scratch_pool);
+        }
+      else if (dir_status != svn_wc__db_status_deleted
+               && dir_status != svn_wc__db_status_added)
+        SVN_ERR(svn_wc__db_scan_base_repos(&dir_repos_relpath,
+                                           &dir_repos_root_url,
+                                           NULL, wb->db, local_abspath,
+                                           scratch_pool, scratch_pool));
+      else
+        {
+          dir_repos_relpath = NULL;
+          dir_repos_root_url = NULL;
+        }
+    }
+
   if (selected == NULL)
     {
-      /* Create a hash containing all children.  The source hashes
-         don't all map the same types, but only the keys of the result
-         hash are subsequently used. */
+      const apr_array_header_t *victims;
+      /* Create a hash containing all children */
       all_children = apr_hash_overlay(subpool, nodes, dirents);
+
+      SVN_ERR(svn_wc__db_read_conflict_victims(&victims,
+                                               wb->db, local_abspath,
+                                               iterpool, iterpool));
+
+      SVN_ERR(svn_hash_from_cstring_keys(&conflicts, victims, subpool));
+
+      /* Optimize for the no-tree-conflict case */
       if (apr_hash_count(conflicts) > 0)
         all_children = apr_hash_overlay(subpool, conflicts, all_children);
     }
   else
     {
-      /* Create a hash containing just selected */
+      const svn_wc_conflict_description2_t *tc;
+      const char *selected_abspath;
+
+      conflicts = apr_hash_make(subpool);
       all_children = apr_hash_make(subpool);
+
       apr_hash_set(all_children, selected, APR_HASH_KEY_STRING, selected);
+
+      selected_abspath = svn_dirent_join(local_abspath, selected, iterpool);
+
+      SVN_ERR(svn_wc__db_op_read_tree_conflict(&tc, wb->db, selected_abspath,
+                                               iterpool, iterpool));
+
+      /* Note this path if a tree conflict is present.  */
+      if (tc != NULL)
+        apr_hash_set(conflicts, selected, APR_HASH_KEY_STRING, "");
     }
 
   /* If "this dir" has "svn:externals" property set on it, send the name and
      value to wc->external_func along with this directory's depth. (Also,
      we want to track the externals internally so we can report status more
      accurately.) */
-  SVN_ERR(handle_externals(wb, local_abspath, dir_info->depth, iterpool));
+  SVN_ERR(handle_externals(wb, local_abspath, dir_depth, iterpool));
 
   if (!selected)
     {
@@ -1193,7 +1197,7 @@
         SVN_ERR(send_status_structure(wb, local_abspath,
                                       parent_repos_root_url,
                                       parent_repos_relpath,
-                                      dir_info, dirent, get_all,
+                                      dirent, get_all,
                                       status_func, status_baton,
                                       iterpool));
 
@@ -1211,7 +1215,6 @@
       apr_ssize_t klen;
       const char *node_abspath;
       svn_io_dirent2_t *dirent_p;
-      const struct svn_wc__db_info_t *info;
 
       svn_pool_clear(iterpool);
 
@@ -1221,24 +1224,32 @@
 
       dirent_p = apr_hash_get(dirents, key, klen);
 
-      info = apr_hash_get(nodes, key, klen);
-      if (info)
+      if (apr_hash_get(nodes, key, klen))
         {
-          if (info->status != svn_wc__db_status_not_present
-              && info->status != svn_wc__db_status_excluded
-              && info->status != svn_wc__db_status_absent)
+          /* Versioned node */
+          svn_wc__db_status_t node_status;
+          svn_wc__db_kind_t node_kind;
+
+          SVN_ERR(svn_wc__db_read_info(&node_status, &node_kind, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL,
+                                   wb->db, node_abspath, iterpool, iterpool));
+
+          if (node_status != svn_wc__db_status_not_present
+              && node_status != svn_wc__db_status_excluded
+              && node_status != svn_wc__db_status_absent)
             {
-              if (depth == svn_depth_files && info->kind == svn_wc__db_kind_dir)
+              if (depth == svn_depth_files && node_kind == svn_wc__db_kind_dir)
                 continue;
 
               /* Handle this entry (possibly recursing). */
               SVN_ERR(handle_dir_entry(wb,
                                        node_abspath,
-                                       info->status,
-                                       info->kind,
+                                       node_status,
+                                       node_kind,
                                        dir_repos_root_url,
                                        dir_repos_relpath,
-                                       info,
                                        dirent_p,
                                        ignore_patterns,
                                        depth == svn_depth_infinity
@@ -1581,7 +1592,6 @@
       SVN_ERR(get_dir_status(&eb->wb, local_abspath, NULL, TRUE,
                              status_in_parent->repos_root_url,
                              status_in_parent->repos_relpath,
-                             NULL,
                              NULL /* dirent */, ignores,
                              d->depth == svn_depth_files
                                       ? svn_depth_files
@@ -1755,7 +1765,6 @@
           SVN_ERR(get_dir_status(&eb->wb,
                                  local_abspath, NULL, TRUE,
                                  dir_repos_root_url, dir_repos_relpath,
-                                 NULL,
                                  NULL /* dirent */,
                                  ignores, depth, eb->get_all, eb->no_ignore,
                                  status_func, status_baton,
@@ -2024,7 +2033,7 @@
                 {
                   SVN_ERR(get_dir_status(&eb->wb,
                                          eb->target_abspath, NULL, TRUE,
-                                         NULL, NULL, NULL, NULL /* dirent */,
+                                         NULL, NULL, NULL /* dirent */,
                                          eb->ignores,
                                          eb->default_depth,
                                          eb->get_all, eb->no_ignore,
@@ -2406,7 +2415,7 @@
                          anchor_abspath,
                          target_name,
                          skip_root,
-                         NULL, NULL, NULL, /* parent info */
+                         NULL, NULL, /* parent info */
                          dirent,
                          ignore_patterns,
                          depth,
@@ -2544,7 +2553,6 @@
   return svn_error_return(assemble_status(status, db, local_abspath,
                                           parent_repos_root_url,
                                           parent_repos_relpath,
-                                          NULL,
                                           dirent,
                                           TRUE /* get_all */,
                                           NULL /* repos_lock */,
Index: subversion/libsvn_wc/conflicts.c
===================================================================
--- subversion/libsvn_wc/conflicts.c	(revision 1023844)
+++ subversion/libsvn_wc/conflicts.c	(revision 1005387)
@@ -50,6 +50,152 @@
 
 #include "svn_private_config.h"
 
+struct svn_wc_conflict_t
+{
+  /* ### kind + property name are the primary keys of a conflict */
+  /* The kind of conflict recorded */
+  svn_wc_conflict_kind_t kind;
+
+  /* When describing a property conflict the property name
+     or "" when no property name is available. (Upgrade from old WC or
+     raised via compatibility apis). */
+  const char *property_name;
+
+  /* ### TODO: Add more fields */
+};
+
+/* */
+static svn_error_t *
+conflict_alloc(svn_wc_conflict_t **conflict, apr_pool_t *result_pool)
+{
+  svn_wc_conflict_t *c = apr_pcalloc(result_pool, sizeof(*c));
+
+  *conflict = c;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc_conflict_dup(svn_wc_conflict_t **duplicate,
+                    const svn_wc_conflict_t *base,
+                    apr_pool_t *result_pool)
+{
+  svn_wc_conflict_t *c;
+
+  SVN_ERR(conflict_alloc(&c, result_pool));
+
+  c->kind = base->kind;
+  c->property_name = base->property_name
+                          ? apr_pstrdup(result_pool, base->property_name)
+                          : NULL;
+
+  *duplicate = c;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc_create_property_conflict(svn_wc_conflict_t **conflict,
+                                const char *property_name,
+                                const svn_wc_conflict_version_t *older_version,
+                                const svn_wc_conflict_version_t *left_version,
+                                const svn_wc_conflict_version_t *right_version,
+                                const svn_string_t *older_value,
+                                const svn_string_t *left_value,
+                                const svn_string_t *right_value,
+                                const char *marker_abspath,
+                                svn_wc_operation_t operation,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool)
+{
+  SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
+}
+
+svn_error_t *
+svn_wc_create_text_conflict(svn_wc_conflict_t **conflict,
+                            const svn_wc_conflict_version_t *older_version,
+                            const svn_wc_conflict_version_t *left_version,
+                            const svn_wc_conflict_version_t *right_version,
+                            const char *older_abspath,
+                            const char *left_abspath,
+                            const char *right_abspath,
+                            svn_wc_operation_t operation,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
+}
+
+svn_error_t *
+svn_wc_create_tree_conflict(svn_wc_conflict_t **conflict,
+                            const svn_wc_conflict_version_t *older_version,
+                            const svn_wc_conflict_version_t *left_version,
+                            const svn_wc_conflict_version_t *right_version,
+                            svn_wc_conflict_action_t action,
+                            svn_wc_conflict_reason_t reason,
+                            svn_wc_operation_t operation,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
+}
+
+svn_error_t *
+svn_wc_get_conflict_info(svn_wc_conflict_kind_t *kind,
+                         const char **property_name,
+                         svn_wc_conflict_action_t *action,
+                         svn_wc_conflict_reason_t *reason,
+                         svn_wc_operation_t *operation,
+                         svn_boolean_t *conflict_resolved,
+                         svn_wc_context_t *wc_ctx,
+                         const char *local_abspath,
+                         svn_wc_conflict_t *conflict,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
+{
+  SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
+}
+
+
+svn_error_t *
+svn_wc_get_conflict_marker_files(const char **older_abspath,
+                                 const char **left_abspath,
+                                 const char **right_abspath,
+                                 svn_wc_context_t *wc_ctx,
+                                 const char *local_abspath,
+                                 svn_wc_conflict_t *conflict,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
+{
+  SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
+}
+
+svn_error_t *
+svn_wc_get_conflict_sources(const svn_wc_conflict_version_t **older_version,
+                            const svn_wc_conflict_version_t **left_version,
+                            const svn_wc_conflict_version_t **right_version,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            svn_wc_conflict_t *conflict,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
+}
+
+svn_error_t *
+svn_wc_get_property_conflict_data(const svn_string_t **older_value,
+                                  const svn_string_t **left_value,
+                                  const svn_string_t **right_value,
+                                  svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
+                                  svn_wc_conflict_t *conflict,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
+{
+  SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
+}
+
+
 svn_skel_t *
 svn_wc__conflict_skel_new(apr_pool_t *result_pool)
 {
Index: subversion/libsvn_wc/update_editor.c
===================================================================
--- subversion/libsvn_wc/update_editor.c	(revision 1023844)
+++ subversion/libsvn_wc/update_editor.c	(revision 1005387)
@@ -2925,10 +2925,22 @@
          item to write out an old-style props file.  */
       if (new_base_props != NULL)
         {
+          apr_array_header_t *prop_diffs;
+
           SVN_ERR_ASSERT(new_actual_props != NULL);
 
+          /* If the ACTUAL props are the same as the BASE props, then we
+             should "write" a NULL. This will remove the props from the
+             ACTUAL_NODE row, and remove the old-style props file, indicating
+             "no change".  */
+          props = new_actual_props;
+          SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
+                                 pool));
+          if (prop_diffs->nelts == 0)
+            props = NULL;
+
           SVN_ERR(svn_wc__db_op_set_props(eb->db, db->local_abspath,
-                                          new_actual_props,
+                                          props,
                                           NULL /* conflict */,
                                           NULL /* work_items */,
                                           pool));
@@ -4377,31 +4389,32 @@
       /* We will ALWAYS have properties to save (after a not-dry-run merge).  */
       SVN_ERR_ASSERT(new_base_props != NULL && new_actual_props != NULL);
 
-      /* Merge the text. This will queue some additional work.  */
-      SVN_ERR(merge_file(&all_work_items, &install_pristine, &install_from,
-                         &content_state, fb, new_text_base_sha1_checksum,
-                         pool, scratch_pool));
+    /* Merge the text. This will queue some additional work.  */
+    SVN_ERR(merge_file(&all_work_items, &install_pristine, &install_from,
+                       &content_state, fb, new_text_base_sha1_checksum,
+                       pool, scratch_pool));
 
-      if (install_pristine)
-        {
-          svn_boolean_t record_fileinfo;
+    if (install_pristine)
+      {
+        svn_boolean_t record_fileinfo;
 
-          /* If we are installing from the pristine contents, then go ahead and
-             record the fileinfo. That will be the "proper" values. Installing
-             from some random file means the fileinfo does NOT correspond to
-             the pristine (in which case, the fileinfo will be cleared for
-             safety's sake).  */
-          record_fileinfo = install_from == NULL;
+        /* If we are installing from the pristine contents, then go ahead and
+           record the fileinfo. That will be the "proper" values. Installing
+           from some random file means the fileinfo does NOT correspond to
+           the pristine (in which case, the fileinfo will be cleared for
+           safety's sake).  */
+        record_fileinfo = install_from == NULL;
 
-          SVN_ERR(svn_wc__wq_build_file_install(&work_item,
-                                                eb->db,
-                                                fb->local_abspath,
-                                                install_from,
-                                                eb->use_commit_times,
-                                                record_fileinfo,
-                                                pool, pool));
-          all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
-        }
+        SVN_ERR(svn_wc__wq_build_file_install(&work_item,
+                                              eb->db,
+                                              fb->local_abspath,
+                                              install_from,
+                                              eb->use_commit_times,
+                                              record_fileinfo,
+                                              pool, pool));
+        all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
+      }
+
     }
   else
     {
@@ -4574,10 +4587,23 @@
      properties merge. */
   if (! fb->adding_base_under_local_add)
     {
+      apr_hash_t *props;
+      apr_array_header_t *prop_diffs;
+
       SVN_ERR_ASSERT(new_actual_props != NULL);
 
+      /* If the ACTUAL props are the same as the BASE props, then we
+         should "write" a NULL. This will remove the props from the
+         ACTUAL_NODE row, and remove the old-style props file, indicating
+         "no change".  */
+      props = new_actual_props;
+      SVN_ERR(svn_prop_diffs(&prop_diffs, new_actual_props, new_base_props,
+                             pool));
+      if (prop_diffs->nelts == 0)
+        props = NULL;
+
       SVN_ERR(svn_wc__db_op_set_props(eb->db, fb->local_abspath,
-                                      new_actual_props,
+                                      props,
                                       NULL /* conflict */,
                                       NULL /* work_item */,
                                       pool));
@@ -5566,6 +5592,7 @@
   const char *original_root_url;
   const char *original_repos_relpath;
   const char *original_uuid;
+  apr_hash_t *actual_props;
   svn_revnum_t changed_rev;
   apr_time_t changed_date;
   const char *changed_author;
@@ -5687,6 +5714,25 @@
                                    entry_props, pool, pool));
   }
 
+  /* Add some work items to install the properties.  */
+  {
+    if (new_props == NULL)
+      {
+        actual_props = NULL;
+      }
+    else
+      {
+        apr_array_header_t *prop_diffs;
+
+        SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, new_base_props,
+                               pool));
+        if (prop_diffs->nelts == 0)
+          actual_props = NULL;
+        else
+          actual_props = new_props;
+      }
+  }
+
   /* Copy NEW_BASE_CONTENTS into a temporary file so our log can refer to
      it, and set TMP_TEXT_BASE_ABSPATH to its path.  Compute its
      NEW_TEXT_BASE_MD5_CHECKSUM and NEW_TEXT_BASE_SHA1_CHECKSUM as we copy. */
@@ -5811,7 +5857,7 @@
   /* ### if below fails, then the above db change would remain :-(  */
 
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
-                                  new_props,
+                                  actual_props,
                                   NULL /* conflict */,
                                   all_work_items,
                                   pool));
Index: subversion/libsvn_wc/translate.c
===================================================================
--- subversion/libsvn_wc/translate.c	(revision 1023844)
+++ subversion/libsvn_wc/translate.c	(revision 1005387)
@@ -376,7 +376,6 @@
                             apr_pool_t *scratch_pool)
 {
   const svn_string_t *needs_lock;
-  svn_wc__db_status_t status;
   svn_wc__db_lock_t *lock;
   svn_error_t *err;
 
@@ -385,7 +384,7 @@
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
+  err = svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL,
@@ -400,11 +399,6 @@
   else if (err)
     return svn_error_return(err);
   else if (lock)
-    /* ### Is this "we have the lock?" */
-    return SVN_NO_ERROR;
-
-  /* Files that aren't in the repository yet should be left writable. */
-  if (status == svn_wc__db_status_added)
     return SVN_NO_ERROR;
 
   SVN_ERR(svn_wc__internal_propget(&needs_lock, db, local_abspath,
Index: subversion/libsvn_wc/wc-queries.sql
===================================================================
--- subversion/libsvn_wc/wc-queries.sql	(revision 1023844)
+++ subversion/libsvn_wc/wc-queries.sql	(revision 1005387)
@@ -26,26 +26,14 @@
 
 /* these are used in wc_db.c  */
 
--- STMT_SELECT_NODE_INFO
-SELECT op_depth, repos_id, repos_path, presence, kind, revision, checksum,
-  translated_size, changed_revision, changed_date, changed_author, depth,
+-- STMT_SELECT_BASE_NODE
+SELECT repos_id, repos_relpath, presence, kind, revnum, checksum,
+  translated_size, changed_rev, changed_date, changed_author, depth,
   symlink_target, last_mod_time, properties
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2
-ORDER BY op_depth DESC;
-
--- STMT_SELECT_NODE_INFO_WITH_LOCK
-SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
-  checksum, translated_size, changed_revision, changed_date, changed_author,
-  depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
-  lock_comment, lock_date
-FROM nodes
-LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
-  AND nodes.repos_path = lock.repos_relpath
-WHERE wc_id = ?1 AND local_relpath = ?2
-ORDER BY op_depth DESC;
+FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
 
--- STMT_SELECT_BASE_NODE
+-- STMT_SELECT_BASE_NODE_1
 SELECT repos_id, repos_path, presence, kind, revision, checksum,
   translated_size, changed_revision, changed_date, changed_author, depth,
   symlink_target, last_mod_time, properties
@@ -53,6 +41,16 @@
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
 -- STMT_SELECT_BASE_NODE_WITH_LOCK
+SELECT base_node.repos_id, base_node.repos_relpath, presence, kind,
+  revnum, checksum, translated_size, changed_rev, changed_date,
+  changed_author, depth, symlink_target, last_mod_time, properties,
+  lock_token, lock_owner, lock_comment, lock_date
+FROM base_node
+LEFT OUTER JOIN lock ON base_node.repos_id = lock.repos_id
+  AND base_node.repos_relpath = lock.repos_relpath
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_SELECT_BASE_NODE_WITH_LOCK_1
 SELECT nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
   depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
@@ -64,6 +62,14 @@
 
 -- STMT_SELECT_WORKING_NODE
 SELECT presence, kind, checksum, translated_size,
+  changed_rev, changed_date, changed_author, depth, symlink_target,
+  copyfrom_repos_id, copyfrom_repos_path, copyfrom_revnum,
+  moved_here, moved_to, last_mod_time, properties
+FROM working_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_SELECT_WORKING_NODE_1
+SELECT presence, kind, checksum, translated_size,
   changed_revision, changed_date, changed_author, depth, symlink_target,
   repos_id, repos_path, revision,
   moved_here, moved_to, last_mod_time, properties
@@ -78,26 +84,6 @@
 FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
--- STMT_SELECT_NODE_CHILDREN_INFO
-/* Getting rows in an advantageous order using
-     ORDER BY local_relpath, op_depth DESC
-   turns out to be slower than getting rows in a random order and making the
-   C code handle it. */
-SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
-  checksum, translated_size, changed_revision, changed_date, changed_author,
-  depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
-  lock_comment, lock_date, local_relpath
-FROM nodes
-LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
-  AND nodes.repos_path = lock.repos_relpath
-WHERE wc_id = ?1 AND parent_relpath = ?2;
-
--- STMT_SELECT_ACTUAL_CHILDREN_INFO
-SELECT prop_reject, changelist, conflict_old, conflict_new,
-conflict_working, tree_conflict_data, properties, local_relpath
-FROM actual_node
-WHERE wc_id = ?1 AND parent_relpath = ?2;
-
 -- STMT_SELECT_REPOSITORY_BY_ID
 SELECT root, uuid FROM repository WHERE id = ?1;
 
@@ -110,6 +96,14 @@
 -- STMT_INSERT_REPOSITORY
 INSERT INTO repository (root, uuid) VALUES (?1, ?2);
 
+-- STMT_INSERT_BASE_NODE
+INSERT OR replace INTO base_node (
+  wc_id, local_relpath, repos_id, repos_relpath, parent_relpath, presence,
+  kind, revnum, properties, changed_rev, changed_date, changed_author,
+  depth, checksum, translated_size, symlink_target, dav_cache)
+VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
+        ?15, ?16, ?17);
+
 -- STMT_INSERT_NODE
 INSERT OR REPLACE INTO nodes (
   wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
@@ -119,31 +113,80 @@
 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
         ?15, ?16, ?17, ?18, ?19);
 
+-- STMT_INSERT_BASE_NODE_INCOMPLETE
+INSERT OR IGNORE INTO base_node (
+  wc_id, local_relpath, parent_relpath, presence, kind, revnum)
+VALUES (?1, ?2, ?3, 'incomplete', 'unknown', ?4);
+
+-- STMT_INSERT_BASE_NODE_INCOMPLETE_DIR
+INSERT OR IGNORE INTO base_node (
+  wc_id, local_relpath, repos_id, repos_relpath, parent_relpath, presence,
+  kind, revnum, depth)
+VALUES (?1, ?2, ?3, ?4, ?5, 'incomplete', 'dir', ?6, ?7);
+
+-- STMT_INSERT_WORKING_NODE_INCOMPLETE
+INSERT OR IGNORE INTO working_node (
+  wc_id, local_relpath, parent_relpath, presence, kind)
+VALUES (?1, ?2, ?3, 'incomplete', 'unknown');
+
 -- STMT_SELECT_BASE_NODE_CHILDREN
+SELECT local_relpath FROM base_node
+WHERE wc_id = ?1 AND parent_relpath = ?2;
+
+-- STMT_SELECT_BASE_NODE_CHILDREN_1
 SELECT local_relpath FROM nodes
 WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0;
 
--- STMT_SELECT_NODE_CHILDREN
-SELECT local_relpath FROM nodes
+-- STMT_SELECT_WORKING_NODE_CHILDREN
+SELECT local_relpath FROM working_node
 WHERE wc_id = ?1 AND parent_relpath = ?2;
 
+-- STMT_SELECT_WORKING_NODE_CHILDREN_1
+SELECT DISTINCT local_relpath FROM nodes
+WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth > 0;
+
+-- STMT_SELECT_WORKING_IS_FILE
+SELECT kind == 'file' FROM working_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_SELECT_BASE_IS_FILE
+SELECT kind == 'file' FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_SELECT_BASE_PROPS
+SELECT properties FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_SELECT_BASE_PROPS_1
 SELECT properties FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
--- STMT_SELECT_NODE_PROPS
+-- STMT_SELECT_WORKING_PROPS
+SELECT properties, presence FROM working_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_SELECT_WORKING_PROPS_1
 SELECT properties, presence FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2
-ORDER BY op_depth DESC;
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0
+ORDER BY op_depth DESC
+LIMIT 1;
 
 -- STMT_SELECT_ACTUAL_PROPS
 SELECT properties FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
+-- STMT_UPDATE_BASE_PROPS
+UPDATE base_node SET properties = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_NODE_BASE_PROPS
 UPDATE nodes SET properties = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_UPDATE_WORKING_PROPS
+UPDATE working_node SET properties = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_NODE_WORKING_PROPS
 UPDATE nodes SET properties = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2
@@ -169,15 +212,26 @@
 INSERT INTO wcroot (local_abspath)
 VALUES (?1);
 
+-- STMT_UPDATE_BASE_DAV_CACHE
+UPDATE base_node SET dav_cache = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_BASE_NODE_DAV_CACHE
 UPDATE nodes SET dav_cache = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
 -- STMT_SELECT_BASE_DAV_CACHE
-SELECT dav_cache FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
+SELECT dav_cache FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
 
 -- STMT_SELECT_DELETION_INFO
+SELECT base_node.presence, working_node.presence, moved_to
+FROM working_node
+LEFT OUTER JOIN base_node ON base_node.wc_id = working_node.wc_id
+  AND base_node.local_relpath = working_node.local_relpath
+WHERE working_node.wc_id = ?1 AND working_node.local_relpath = ?2;
+
+-- STMT_SELECT_DELETION_INFO_1
 SELECT nodes_base.presence, nodes_work.presence, nodes_work.moved_to
 FROM nodes nodes_work
 LEFT OUTER JOIN nodes nodes_base ON nodes_base.wc_id = nodes_work.wc_id
@@ -192,12 +246,30 @@
 DELETE FROM lock
 WHERE repos_id = ?1 AND repos_relpath = ?2;
 
+-- STMT_CLEAR_BASE_RECURSIVE_DAV_CACHE
+UPDATE base_node SET dav_cache = NULL
+WHERE dav_cache IS NOT NULL AND wc_id = ?1 AND
+  (local_relpath = ?2 OR
+   local_relpath LIKE ?3 ESCAPE '#');
+
 -- STMT_CLEAR_BASE_NODE_RECURSIVE_DAV_CACHE
 UPDATE nodes SET dav_cache = NULL
 WHERE dav_cache IS NOT NULL AND wc_id = ?1 AND op_depth = 0 AND
   (local_relpath = ?2 OR
    local_relpath LIKE ?3 ESCAPE '#');
 
+-- STMT_UPDATE_BASE_RECURSIVE_REPO
+UPDATE base_node SET repos_id = ?5
+WHERE repos_id = ?4 AND wc_id = ?1 AND
+  (local_relpath = ?2 OR
+   local_relpath LIKE ?3 ESCAPE '#');
+
+-- STMT_UPDATE_WORKING_RECURSIVE_COPYFROM_REPO
+UPDATE working_node SET copyfrom_repos_id = ?5
+WHERE copyfrom_repos_id = ?4 AND wc_id = ?1 AND
+  (local_relpath = ?2 OR
+   local_relpath LIKE ?3 ESCAPE '#');
+
 -- STMT_RECURSIVE_UPDATE_NODE_REPO
 UPDATE nodes SET repos_id = ?5, dav_cache = NULL
 WHERE wc_id = ?1 AND repos_id = ?4 AND
@@ -210,10 +282,18 @@
   (repos_relpath = ?2 OR
    repos_relpath LIKE ?3 ESCAPE '#');
 
+-- STMT_UPDATE_BASE_FILEINFO
+UPDATE base_node SET translated_size = ?3, last_mod_time = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_BASE_NODE_FILEINFO
 UPDATE nodes SET translated_size = ?3, last_mod_time = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_UPDATE_WORKING_FILEINFO
+UPDATE working_node SET translated_size = ?3, last_mod_time = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_WORKING_NODE_FILEINFO
 UPDATE nodes SET translated_size = ?3, last_mod_time = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2
@@ -225,9 +305,11 @@
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
 -- STMT_INSERT_ACTUAL_TREE_CONFLICTS
+/* tree conflicts are always recorded on the wcroot node, so the
+   parent_relpath will be null.  */
 INSERT INTO actual_node (
-  wc_id, local_relpath, tree_conflict_data, parent_relpath)
-VALUES (?1, ?2, ?3, ?4);
+  wc_id, local_relpath, tree_conflict_data)
+VALUES (?1, ?2, ?3);
 
 -- STMT_UPDATE_ACTUAL_TEXT_CONFLICTS
 UPDATE actual_node SET conflict_old = ?3, conflict_new = ?4,
@@ -264,9 +346,17 @@
 VALUES (?1, ?2, ?3, ?4);
 
 -- STMT_DELETE_BASE_NODE
+DELETE FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_DELETE_BASE_NODE_1
 DELETE FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_DELETE_WORKING_NODE
+DELETE FROM working_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_DELETE_WORKING_NODES
 DELETE FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0;
@@ -279,60 +369,80 @@
 DELETE FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
--- STMT_DELETE_ACTUAL_NODE_WITHOUT_CHANGELIST
-DELETE FROM actual_node
-WHERE wc_id = ?1 AND local_relpath = ?2
-      AND changelist IS NULL;
-
--- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST
-UPDATE actual_node
-SET properties = NULL,
-    text_mod = NULL,
-    conflict_data = NULL,
-    tree_conflict_data = NULL,
-    conflict_old = NULL,
-    conflict_new = NULL,
-    conflict_working = NULL,
-    prop_reject = NULL,
-    older_checksum = NULL,
-    left_checksum = NULL,
-    right_checksum = NULL
-WHERE wc_id = ?1 and local_relpath = ?2;
+-- STMT_UPDATE_BASE_DEPTH
+UPDATE base_node SET depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
 
 -- STMT_UPDATE_NODE_BASE_DEPTH
 UPDATE nodes SET depth = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_UPDATE_WORKING_DEPTH
+UPDATE working_node SET depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_NODE_WORKING_DEPTH
 UPDATE nodes SET depth = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND
       op_depth = (SELECT MAX(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0);
 
+-- STMT_UPDATE_BASE_EXCLUDED
+UPDATE base_node SET presence = 'excluded', depth = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_NODE_BASE_EXCLUDED
 UPDATE nodes SET presence = 'excluded', depth = NULL
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_UPDATE_WORKING_EXCLUDED
+UPDATE working_node SET presence = 'excluded', depth = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_NODE_WORKING_EXCLUDED
 UPDATE nodes SET presence = 'excluded', depth = NULL
 WHERE wc_id = ?1 AND local_relpath = ?2 AND
       op_depth = (SELECT MAX(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2);
 
+-- STMT_UPDATE_BASE_PRESENCE
+UPDATE base_node SET presence= ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_NODE_BASE_PRESENCE
 UPDATE nodes SET presence = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_UPDATE_BASE_PRESENCE_KIND
+UPDATE base_node SET presence = ?3, kind = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_NODE_BASE_PRESENCE_KIND
 UPDATE nodes SET presence = ?3, kind = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_UPDATE_WORKING_PRESENCE
+UPDATE working_node SET presence = ?3
+WHERE wc_id = ?1 AND local_relpath =?2;
+
 -- STMT_UPDATE_NODE_WORKING_PRESENCE
 UPDATE nodes SET presence = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2
   AND op_depth = (SELECT MAX(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0);
 
+-- STMT_UPDATE_BASE_PRESENCE_AND_REVNUM
+UPDATE base_node SET presence = ?3, revnum = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_BASE_NODE_PRESENCE_AND_REVNUM
+UPDATE nodes SET presence = ?3, revision = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
+
+-- STMT_UPDATE_BASE_PRESENCE_REVNUM_AND_REPOS_RELPATH
+UPDATE base_node SET presence = ?3, revnum = ?4, repos_relpath = ?5
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_UPDATE_BASE_NODE_PRESENCE_REVNUM_AND_REPOS_PATH
 UPDATE nodes SET presence = ?3, revision = ?4, repos_path = ?5
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
@@ -368,6 +478,19 @@
 FROM pristine
 
 -- STMT_SELECT_ANY_PRISTINE_REFERENCE
+SELECT 1 FROM base_node
+  WHERE checksum = ?1 OR checksum = ?2
+UNION ALL
+SELECT 1 FROM working_node
+  WHERE checksum = ?1 OR checksum = ?2
+UNION ALL
+SELECT 1 FROM actual_node
+  WHERE older_checksum = ?1 OR older_checksum = ?2
+    OR  left_checksum  = ?1 OR left_checksum  = ?2
+    OR  right_checksum = ?1 OR right_checksum = ?2
+LIMIT 1
+
+-- STMT_SELECT_ANY_PRISTINE_REFERENCE_1
 SELECT 1 FROM nodes
   WHERE checksum = ?1 OR checksum = ?2
 UNION ALL
@@ -426,10 +549,17 @@
 SELECT local_dir_relpath FROM wc_lock
 WHERE wc_id = ?1 AND local_dir_relpath LIKE ?2 ESCAPE '#';
 
--- STMT_APPLY_CHANGES_TO_BASE_NODE
+-- STMT_APPLY_CHANGES_TO_BASE
 /* translated_size and last_mod_time are not mentioned here because they will
    be tweaked after the working-file is installed.
    ### what to do about file_external?  */
+INSERT OR REPLACE INTO base_node (
+  wc_id, local_relpath, parent_relpath, presence, kind, revnum, changed_rev,
+  changed_author, properties, repos_id, repos_relpath, checksum, changed_date,
+  depth, symlink_target, dav_cache)
+VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16);
+
+-- STMT_APPLY_CHANGES_TO_BASE_NODE
 INSERT OR REPLACE INTO nodes (
   wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
   revision, presence, depth, kind, changed_revision, changed_date,
@@ -437,6 +567,17 @@
 VALUES (?1, ?2, 0,
         ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16);
 
+-- STMT_INSERT_WORKING_NODE_FROM_BASE_NODE
+INSERT INTO working_node (
+    wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties )
+SELECT wc_id, local_relpath, parent_relpath, ?3 AS presence, kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties
+FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_INSERT_WORKING_NODE_FROM_BASE
 INSERT INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, presence, kind, checksum,
@@ -448,6 +589,19 @@
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
+-- STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE
+INSERT INTO working_node (
+    wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, copyfrom_repos_id,
+    copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, local_relpath, parent_relpath, 'normal', kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, repos_id,
+    repos_relpath, revnum
+FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE
 INSERT INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
@@ -462,6 +616,17 @@
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
 
+-- STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE
+INSERT INTO working_node (
+    wc_id, local_relpath, parent_relpath, presence, kind, changed_rev,
+    changed_date, changed_author, copyfrom_repos_id,
+    copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, local_relpath, parent_relpath, 'not-present', kind, changed_rev,
+    changed_date, changed_author, repos_id,
+    repos_relpath, revnum
+FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE
 INSERT INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
@@ -475,6 +640,10 @@
 
 -- ### these statements below should be setting copyfrom_revision!
 -- STMT_UPDATE_COPYFROM
+UPDATE working_node SET copyfrom_repos_id = ?3, copyfrom_repos_path = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_COPYFROM_1
 UPDATE nodes SET repos_id = ?3, repos_path = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2;
   AND op_depth = (SELECT MAX(op_depth) FROM nodes
@@ -493,6 +662,13 @@
 
 
 -- STMT_UPDATE_COPYFROM_TO_INHERIT
+UPDATE working_node SET
+  copyfrom_repos_id = NULL,
+  copyfrom_repos_path = NULL,
+  copyfrom_revnum = NULL
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_COPYFROM_TO_INHERIT_1
 UPDATE nodes SET
   repos_id = NULL,
   repos_path = NULL,
@@ -502,6 +678,11 @@
                   WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0);
 
 -- STMT_DETERMINE_TREE_FOR_RECORDING
+SELECT 0 FROM base_node WHERE wc_id = ?1 AND local_relpath = ?2
+UNION
+SELECT 1 FROM working_node WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_DETERMINE_TREE_FOR_RECORDING_1
 SELECT 0 FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
 UNION
 SELECT 1 FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2
@@ -512,6 +693,19 @@
 /* ### Why can't this query not just use the BASE repository
    location values, instead of taking 3 additional parameters?! */
 -- STMT_INSERT_WORKING_NODE_COPY_FROM_BASE
+INSERT OR REPLACE INTO working_node (
+    wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, copyfrom_repos_id,
+    copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, ?3 AS local_relpath, ?4 AS parent_relpath, ?5 AS presence, kind,
+    checksum, translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, ?6 AS copyfrom_repos_id,
+    ?7 AS copyfrom_repos_path, ?8 AS copyfrom_revnum
+FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_INSERT_WORKING_NODE_COPY_FROM_BASE_1
 INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id,
     repos_path, revision, presence, depth, kind, changed_revision,
@@ -525,6 +719,19 @@
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
 -- STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING
+INSERT OR REPLACE INTO working_node (
+    wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+    translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, copyfrom_repos_id,
+    copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, ?3 AS local_relpath, ?4 AS parent_relpath, ?5 AS presence, kind,
+    checksum, translated_size, changed_rev, changed_date, changed_author, depth,
+    symlink_target, last_mod_time, properties, ?6 AS copyfrom_repos_id,
+    ?7 AS copyfrom_repos_path, ?8 AS copyfrom_revnum
+FROM working_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING_1
 INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
     revision, presence, depth, kind, changed_revision, changed_date,
@@ -551,10 +758,18 @@
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
 -- STMT_UPDATE_BASE_REVISION
+UPDATE base_node SET revnum = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_BASE_REVISION_1
 UPDATE nodes SET revision = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
 -- STMT_UPDATE_BASE_REPOS
+UPDATE base_node SET repos_id = ?3, repos_relpath = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_BASE_REPOS_1
 UPDATE nodes SET repos_id = ?3, repos_path = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
@@ -563,6 +778,15 @@
 /* these are used in entries.c  */
 
 -- STMT_INSERT_BASE_NODE_FOR_ENTRY
+INSERT OR REPLACE INTO base_node (
+  wc_id, local_relpath, repos_id, repos_relpath, parent_relpath,
+  presence,
+  revnum, kind, checksum, translated_size, changed_rev, changed_date,
+  changed_author, depth, last_mod_time, properties)
+VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
+  ?15, ?16);
+
+-- STMT_INSERT_BASE_NODE_FOR_ENTRY_1
 /* The BASE tree has a fixed op_depth '0' */
 INSERT OR REPLACE INTO nodes (
   wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
@@ -572,6 +796,32 @@
 VALUES (?1, ?2, 0, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13,
        ?14, ?15, ?16 );
 
+-- STMT_INSERT_WORKING_NODE
+INSERT OR REPLACE INTO working_node (
+  wc_id, local_relpath, parent_relpath, presence, kind,
+  copyfrom_repos_id,
+  copyfrom_repos_path, copyfrom_revnum, moved_here, moved_to, checksum,
+  translated_size, changed_rev, changed_date, changed_author, depth,
+  last_mod_time, properties, keep_local, symlink_target)
+VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
+  ?15, ?16, ?17, ?18, ?19, ?20);
+
+-- STMT_INSERT_WORKING_NODE_DATA_1
+INSERT OR REPLACE INTO node_data (
+  wc_id, local_relpath, op_depth, parent_relpath, presence, kind,
+  original_repos_id, original_repos_path, original_revision, checksum,
+  changed_revision, changed_date, changed_author, depth, properties,
+  symlink_target )
+VALUES (?1,  ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9,
+        ?10, ?11, ?12, ?13, ?14, ?15, ?16 );
+
+-- STMT_INSERT_WORKING_NODE_DATA_2
+INSERT OR REPLACE INTO working_node (
+  wc_id, local_relpath, parent_relpath, moved_here, moved_to, translated_size,
+  last_mod_time, keep_local )
+VALUES (?1,  ?2, ?3, ?4, ?5, ?6, ?7, ?8 );
+
+
 -- STMT_INSERT_ACTUAL_NODE
 INSERT OR REPLACE INTO actual_node (
   wc_id, local_relpath, parent_relpath, properties, conflict_old,
@@ -581,15 +831,27 @@
 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11);
 
 -- STMT_SELECT_NOT_PRESENT
+SELECT 1 FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2 AND presence = 'not-present';
+
+-- STMT_SELECT_NOT_PRESENT_1
 SELECT 1 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND presence = 'not-present'
   AND op_depth = 0;
 
 -- STMT_SELECT_FILE_EXTERNAL
+SELECT file_external FROM base_node
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_SELECT_FILE_EXTERNAL_1
 SELECT file_external FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
 -- STMT_UPDATE_FILE_EXTERNAL
+UPDATE base_node SET file_external = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_FILE_EXTERNAL_1
 UPDATE nodes SET file_external = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0;
 
@@ -616,10 +878,23 @@
 
 -- STMT_SELECT_ALL_FILES
 /* Should this select on wc_id as well? */
+SELECT local_relpath FROM base_node
+WHERE kind = 'file' AND parent_relpath = ?1
+UNION
+SELECT local_relpath FROM working_node
+WHERE kind = 'file' AND parent_relpath = ?1;
+
+-- STMT_SELECT_ALL_FILES_1
+/* Should this select on wc_id as well? */
 SELECT DISTINCT local_relpath FROM nodes
 WHERE kind = 'file' AND parent_relpath = ?1;
 
 -- STMT_PLAN_PROP_UPGRADE
+SELECT 0, presence, wc_id FROM base_node WHERE local_relpath = ?1
+UNION ALL
+SELECT 1, presence, wc_id FROM working_node WHERE local_relpath = ?1;
+
+-- STMT_PLAN_PROP_UPGRADE_1
 SELECT 0, nodes_base.presence, nodes_base.wc_id FROM nodes nodes_base
 WHERE nodes_base.local_relpath = ?1 AND nodes_base.op_depth = 0
 UNION ALL
Index: subversion/libsvn_wc/wc-metadata.sql
===================================================================
--- subversion/libsvn_wc/wc-metadata.sql	(revision 1023844)
+++ subversion/libsvn_wc/wc-metadata.sql	(revision 1005387)
@@ -76,9 +76,250 @@
 
 /* ------------------------------------------------------------------------- */
 
+/*
+The BASE_NODE table:
+
+  BASE is what we get from the server.  It is the *absolute* pristine copy.
+  You need to use checkout, update, switch, or commit to alter your view of
+  the repository.
+
+  In the BASE tree, each node corresponds to a particular node-rev in the
+  repository.  It can be a mixed-revision tree.  Each node holds either a
+  copy of the node-rev as it exists in the repository (if presence ==
+  'normal'), or a place-holder (if presence == 'absent' or 'excluded' or
+  'not-present').
+                                                  [Quoted from wc_db.h]
+
+Overview of BASE_NODE columns:
+
+  Indexing columns: (wc_id, local_relpath, parent_relpath)
+
+  (presence)
+
+    - The Node-Rev, Content and Last-Change column groups take one of the
+      states shown in the table below, according to the 'presence':
+
+                                    Has           Has       Has
+      'presence'      Meaning       Node-Rev?     Content?  Last-Change?
+      ----------      -----------   -----------   --------  ------------
+      normal      =>  Present       Yes           Yes       Yes
+      incomplete  =>  Incomplete    Yes           Partial   No ### ?
+      absent      =>  Unauthz       Yes           No        No
+      excluded    =>  Unwanted      Yes           No        No
+      not-present =>  Nonexistent   No            No        No
+
+    - If presence==incomplete, this node refers to an existing node-rev but
+      its Content is not fully and correctly stored.  In particular, if it
+      is a directory, some rows that should represent its children may not
+      exist or may be in the wrong state.  This is intended to be a
+      temporary state, e.g. during an update.
+
+    - If presence==absent or ==excluded, this row refers to a node that
+      exists in the repo, but the node is not stored in the WC.
+
+    - If presence==not-present, this row indicates that its parent in the WC
+      is a directory that, in its pristine state, would have a child of this
+      name.  However, this child was updated or switched to a node-revision
+      that does not exist.  Information about which node-revision it was
+      updated or switched to is lost; only the fact that it is currently not
+      present is remembered.
+
+    - The order of precedence of the negative presence values is:
+        'excluded' if administratively excluded from the WC, else
+        'absent' if server doesn't authorize reading the path, else
+        'not-present' if it does not exist in repo.
+
+  Node-Rev columns: (repos_id, repos_relpath, revnum)
+
+    - The Node-Rev group points to the corresponding repository node-rev.
+
+    - If not used (as specified by the 'presence' table above), the values
+      are undefined.
+      ### Perhaps we should set them to null to make it clearer.
+
+  Content columns: (kind, properties, depth, target, checksum)
+                    ----  ----------  -----  ------  --------
+                    'dir'    Yes      Yes    null    null
+                'symlink'    Yes      null   Yes     null
+                   'file'    Yes      null   null    Yes
+                'unknown'    null     null   null    null
+
+    - The Content columns take one of the states shown in the table above.
+      If Content is present, a copy of the Node-Rev's content is stored
+      locally according to one of the first three rows in the table above,
+      otherwise kind==unknown and the other columns are null.
+
+    - If kind==dir, the children are represented by the existence of other
+      BASE_NODE rows.  For each immediate child of 'repos_relpath'@'revnum'
+      in the repo, subject to 'depth', a BASE_NODE row exists with its
+      'local_relpath' being this node's 'local_relpath' plus the child's
+      basename.  (Rows may also exist for additional children which are
+      outside the scope of 'depth' or do not exist as children of this
+      node-rev in the repository, including 'externals' and paths updated to
+      a revision in which they do exist.)  There is no distinction between
+      depth==immediates and depth==infinity here.
+
+    - If kind==symlink, the target path is contained in 'target'.
+
+    - If kind==file, the content is contained in the Pristine Store,
+      referenced by its SHA-1 checksum 'checksum'.
+
+  Last-Change columns: (changed_rev, changed_date, changed_author)
+
+    - Specifies the revision in which the content was last changed before
+      Node-Rev, following copies and not counting the copy operation itself
+      as a change.
+
+    - Does not specify the revision in which this node first appeared at
+      the repository path 'repos_relpath', which could be more recent than
+      the last change of this node's content.
+
+    - Includes a copy of the corresponding date and author rev-props.
+
+    - If not used (as specified by the 'presence' table above), all null.
+      ### Not checked; in practice these columns may have undefined values.
+
+  Working file status: (translated_size, last_mod_time)
+
+    - Present iff kind==file and node has no WORKING_NODE row, otherwise
+      null.  (If kind==file and node has a WORKING_NODE row, the info is
+      recorded in that row).  ### True?
+
+    - Records the status of the working file on disk, for the purpose of
+      detecting quickly whether that file has been modified.
+
+    - Logically belongs to the ACTUAL_NODE table but is recorded in the
+      BASE_NODE and WORKING_NODE tables instead to avoid the overhead of
+      storing an ACTUAL_NODE row for each unmodified file.
+
+    - Records the actual size and mod-time of the disk file at the time when
+      its content was last determined to be logically unmodified relative to
+      its base, taking account of keywords and EOL style.
+
+  (dav_cache)
+
+    - Content is opaque to libsvn_wc.  ### ?
+
+    - Lifetime is managed by the WC: values cleared to null at certain times.
+      ### To be documented.
+
+  (incomplete_children)
+
+    - Obsolete, unused.
+
+  (file_external)
+
+    - ### To be obsoleted?
+*/
+
+CREATE TABLE BASE_NODE (
+  /* specifies the location of this node in the local filesystem. wc_id
+     implies an absolute path, and local_relpath is relative to that
+     location (meaning it will be "" for the wcroot). */
+  wc_id  INTEGER NOT NULL REFERENCES WCROOT (id),
+  local_relpath  TEXT NOT NULL,
+
+  /* The repository this node is part of, and the relative path (from its
+     root) within revision "revnum" of that repository.  These may be NULL,
+     implying they should be derived from the parent and local_relpath.
+     Non-NULL typically indicates a switched node.
+
+     Note: they must both be NULL, or both non-NULL. */
+  repos_id  INTEGER REFERENCES REPOSITORY (id),
+  repos_relpath  TEXT,
+
+  /* parent's local_relpath for aggregating children of a given parent.
+     this will be "" if the parent is the wcroot. NULL if this is the
+     wcroot node. */
+  parent_relpath  TEXT,
+
+  /* Is this node "present" or has it been excluded for some reason?
+     The "base-deleted" presence value is not allowed.  */
+  presence  TEXT NOT NULL,
+
+  /* The node kind: "file", "dir", or "symlink", or "unknown" if the node is
+     not present. */
+  kind  TEXT NOT NULL,
+
+  /* The revision number in which "repos_relpath" applies in "repos_id".
+     this could be NULL for non-present nodes -- no info. */
+  revnum  INTEGER,
+
+  /* If this node is a file, then the SHA-1 checksum of the pristine text. */
+  checksum  TEXT,
+
+  /* The size in bytes of the working file when it had no local text
+     modifications. This means the size of the text when translated from
+     repository-normal format to working copy format with EOL style
+     translated and keywords expanded according to the properties in the
+     "properties" column of this row.
+
+     NULL if this node is not a file or if the size has not (yet) been
+     computed. */
+  translated_size  INTEGER,
+
+  /* Information about the last change to this node. changed_rev must be
+     not-null if this node has presence=="normal". changed_date and
+     changed_author may be null if the corresponding revprops are missing.
+
+     All three values are null for a not-present node.  */
+  changed_rev  INTEGER,
+  changed_date  INTEGER,  /* an APR date/time (usec since 1970) */
+  changed_author  TEXT,
+
+  /* NULL depth means "default" (typically svn_depth_infinity) */
+  depth  TEXT,
+
+  /* for kind==symlink, this specifies the target. */
+  symlink_target  TEXT,
+
+  /* The mod-time of the working file when it was last determined to be
+     logically unmodified relative to its base, taking account of keywords
+     and EOL style.
+
+     NULL if this node is not a file or if this info has not yet been
+     determined.
+   */
+  /* ### Do we need this?  We've currently got various mod time APIs
+     ### internal to libsvn_wc, but those might be used in answering some
+     ### question which is better answered some other way. */
+  last_mod_time  INTEGER,  /* an APR date/time (usec since 1970) */
+
+  /* serialized skel of this node's properties. NULL if we
+     have no information about the properties (a non-present node). */
+  properties  BLOB,
+
+  /* serialized skel of this node's dav-cache.  could be NULL if the
+     node does not have any dav-cache. */
+  dav_cache  BLOB,
+
+  /* ### this column is removed in format 13. it will always be NULL.  */
+  incomplete_children  INTEGER,
+
+  /* The serialized file external information. */
+  /* ### hack.  hack.  hack.
+     ### This information is already stored in properties, but because the
+     ### current working copy implementation is such a pain, we can't
+     ### readily retrieve it, hence this temporary cache column.
+     ### When it is removed, be sure to remove the extra column from
+     ### the db-tests.
+
+     ### Note: This is only here as a hack, and should *NOT* be added
+     ### to any wc_db APIs.  */
+  file_external  TEXT,
+
+  PRIMARY KEY (wc_id, local_relpath)
+  );
+
+CREATE INDEX I_PARENT ON BASE_NODE (wc_id, parent_relpath);
+
+
+/* ------------------------------------------------------------------------- */
+
 /* The PRISTINE table keeps track of pristine texts. Each pristine text is
    stored in a file which may be compressed. Each pristine text is
-   referenced by any number of rows in the NODES and ACTUAL_NODE tables.
+   referenced by any number of rows in the BASE_NODE and WORKING_NODE
+   and ACTUAL_NODE tables.
  */
 CREATE TABLE PRISTINE (
   /* The SHA-1 checksum of the pristine text. This is a unique key. The
@@ -96,7 +337,7 @@
   size  INTEGER,
 
   /* ### this will probably go away, in favor of counting references
-     ### that exist in NODES. */
+     ### that exist in BASE_NODE and WORKING_NODE. */
   refcount  INTEGER NOT NULL,
 
   /* Alternative MD5 checksum used for communicating with older
@@ -108,16 +349,177 @@
 
 /* ------------------------------------------------------------------------- */
 
-/* The ACTUAL_NODE table describes text changes and property changes
-   on each node in the WC, relative to the NODES table row for the
-   same path. (A NODES row must exist if this node exists, but an
-   ACTUAL_NODE row can exist on its own if it is just recording info
-   on a non-present node - a tree conflict or a changelist, for
-   example.)
+/* The WORKING_NODE table describes tree changes in the WC relative to the
+   BASE_NODE table.
+
+   The WORKING_NODE row for a given path exists iff a node at this path
+   is itself one of:
+
+     - deleted
+     - moved away [1]
+
+   and/or one of:
+
+     - added
+     - copied here [1]
+     - moved here [1]
+
+   or if this path is a child (or grandchild, etc.) under any such node.
+   (### Exact meaning of "child" when mixed-revision, switched, etc.?)
+
+   [1] The WC-NG "move" operation requires that both the source and
+   destination paths are represented in the BASE_NODE and WORKING_NODE
+   tables. The "copy" operation takes as its source a repository node,
+   regardless whether that node is also represented in the WC.
+ */
+CREATE TABLE WORKING_NODE (
+  /* specifies the location of this node in the local filesystem */
+  wc_id  INTEGER NOT NULL REFERENCES WCROOT (id),
+  local_relpath  TEXT NOT NULL,
+
+  /* parent's local_relpath for aggregating children of a given parent.
+     this will be "" if the parent is the wcroot.  Since a wcroot will
+     never have a WORKING node the parent_relpath will never be null. */
+  /* ### would be nice to make this column NOT NULL.  */
+  parent_relpath  TEXT,
+
+  /* Is this node "present" or has it been excluded for some reason?
+     Only allowed values: normal, not-present, incomplete, base-deleted,
+     excluded.  (the others do not make sense for the WORKING tree)
+
+     normal: this node has been added/copied/moved-here. There may be an
+       underlying BASE node at this location, implying this is a replace.
+       Scan upwards from here looking for copyfrom or moved_here values
+       to detect the type of operation constructing this node.
+
+     not-present: the node (or parent) was originally copied or moved-here.
+       A subtree of that source has since been deleted. There may be
+       underlying BASE node to replace. For a move-here or copy-here, the
+       records are simply removed rather than switched to not-present.
+       Note this reflects a deletion only. It is not possible move-away
+       nodes from the WORKING tree. The purported destination would receive
+       a copy from the original source of a copy-here/move-here, or if the
+       nodes were plain adds, those nodes would be shifted to that target
+       for addition.
+
+     incomplete: nodes are being added into the WORKING tree, and the full
+       information about this node is not (yet) present.
+
+     base-deleted: the underlying BASE node has been marked for deletion due
+       to a delete or a move-away (see the moved_to column to determine
+       which), and has not been replaced.
+
+     excluded: this node is administratively excluded (sparse WC). This must
+       be a child (or grandchild etc.) of a copied directory.
+  */
+  presence  TEXT NOT NULL,
+
+  /* the kind of the new node. may be "unknown" if the node is not present. */
+  kind  TEXT NOT NULL,
+
+  /* The SHA-1 checksum of the pristine text, if this node is a file and was
+     moved here or copied here, else NULL. */
+  checksum  TEXT,
+
+  /* The size in bytes of the working file when it had no local text
+     modifications. This means the size of the text when translated from
+     repository-normal format to working copy format with EOL style
+     translated and keywords expanded according to the properties in the
+     "properties" column of this row.
+
+     NULL if this node is not a file, or is not moved here or copied here,
+     or if the size has not (yet) been computed. */
+  translated_size  INTEGER,
+
+  /* If this node was moved here or copied here, then the following fields may
+     have information about their source node. See BASE_NODE.changed_* for
+     more information.
+
+     For an added or not-present node, these are null.  */
+  changed_rev  INTEGER,
+  changed_date  INTEGER,  /* an APR date/time (usec since 1970) */
+  changed_author  TEXT,
+
+  /* NULL depth means "default" (typically svn_depth_infinity) */
+  /* ### depth on WORKING? seems this is a BASE-only concept. how do
+     ### you do "files" on an added-directory? can't really ignore
+     ### the subdirs! */
+  /* ### maybe a WC-to-WC copy can retain a depth?  */
+  depth  TEXT,
+
+  /* for kind==symlink, this specifies the target. */
+  symlink_target  TEXT,
+
+  /* Where this node was copied/moved from. All copyfrom_* fields are set
+     only on the root of the operation, and are NULL for all children. */
+  copyfrom_repos_id  INTEGER REFERENCES REPOSITORY (id),
+  copyfrom_repos_path  TEXT,
+  copyfrom_revnum  INTEGER,
+
+  /* ### JF: For an old-style move, "copyfrom" info stores its source, but a
+     new WC-NG "move" is intended to be a "true rename" so its copyfrom
+     revision is implicit, being in effect (new head - 1) at commit time.
+     For a (new) move, we need to store or deduce the copyfrom local-relpath;
+     perhaps add a column called "moved_from". */
+
+  /* Boolean value, specifying if this node was moved here (rather than just
+     copied). The source of the move is specified in copyfrom_*.  */
+  moved_here  INTEGER,
+
+  /* If the underlying node was moved away (rather than just deleted), this
+     specifies the local_relpath of where the BASE node was moved to.
+     This is set only on the root of a move, and is NULL for all children.
+
+     Note that moved_to never refers to *this* node. It always refers
+     to the "underlying" node, whether that is BASE or a child node
+     implied from a parent's move/copy.  */
+  moved_to  TEXT,
+
+  /* ### Do we need this?  We've currently got various mod time APIs
+     ### internal to libsvn_wc, but those might be used in answering some
+     ### question which is better answered some other way. */
+  last_mod_time  INTEGER,  /* an APR date/time (usec since 1970) */
+
+  /* serialized skel of this node's properties. NULL if we
+     have no information about the properties (a non-present node). */
+  properties  BLOB,
+
+  /* should the node on disk be kept after a schedule delete?
+
+     ### Bert points out that this can disappear once we get to single-db. 
+     ### The entire reason for this flag to exist is
+     ### so that the admin area can exist for the commit of a delete,
+     ### and so the post-commit cleanup knows not to actually delete the dir
+     ### from disk (which is why the flag is only ever set on the this_dir
+     ### entry in WC-OLD.)  With single-db, we don't need to keep the old
+     ### admin area around, so this flag can disappear.
+     ### neels: In contrast, the --keep-local commandline option will not
+     ### disappear. The user will still be able to do
+     ### 'svn delete --keep-local' and keep the to-be-unversioned paths
+     ### in the file system. It just won't be necessary to remember the
+     ### keep-local-ness here, because we either delete the file system paths
+     ### right away during 'svn delete' or we don't at all. There won't be a
+     ### "second pass" for file system deletion at commit time anymore. */
+  keep_local  INTEGER,
+
+  PRIMARY KEY (wc_id, local_relpath)
+  );
+
+CREATE INDEX I_WORKING_PARENT ON WORKING_NODE (wc_id, parent_relpath);
+
+
+/* ------------------------------------------------------------------------- */
+
+/* The ACTUAL_NODE table describes text changes and property changes on each
+   node in the WC, relative to the WORKING_NODE table row for the same path
+   (if present) or else to the BASE_NODE row for the same path.  (Either a
+   WORKING_NODE row or a BASE_NODE row must exist if this node exists, but
+   an ACTUAL_NODE row can exist on its own if it is just recording info on
+   a non-present node - a tree conflict or a changelist, for example.)
 
    The ACTUAL_NODE table row for a given path exists if the node at that
    path is known to have text or property changes relative to its
-   NODES row. ("Is known" because a text change on disk may not yet
+   WORKING_NODE row. ("Is known" because a text change on disk may not yet
    have been discovered and recorded here.)
 
    The ACTUAL_NODE table row for a given path may also exist in other cases,
@@ -411,9 +813,8 @@
   /* Last-Change fields */
 
   /* If this node was moved here or copied here, then the following fields may
-     have information about their source node.  changed_rev must be not-null
-     if this node has presence=="normal". changed_date and changed_author may
-     be null if the corresponding revprops are missing.
+     have information about their source node. See BASE_NODE.changed_* for
+     more information.
 
      For an added or not-present node, these are null.  */
   changed_revision  INTEGER,
@@ -590,7 +991,9 @@
 
 /* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */
 
--- STMT_UPGRADE_TO_20
+/* ### Enable this bit and take out the BASE_NODE stuff in format 99 below.
+
+-- DISABLED_STMT_UPGRADE_TO_20
 
 INSERT INTO NODES (
        wc_id, local_relpath, op_depth, parent_relpath,
@@ -625,6 +1028,7 @@
 DROP TABLE WORKING_NODE;
 
 PRAGMA user_version = 20;
+*/
 
 /* ------------------------------------------------------------------------- */
 
@@ -640,6 +1044,81 @@
    number will be, however, so we're just marking it as 99 for now.  */
 -- format: 99
 
+/* We cannot directly remove columns, so we use a temporary table instead. */
+/* First create the temporary table without the undesired column(s). */
+CREATE TEMPORARY TABLE BASE_NODE_BACKUP(
+  wc_id  INTEGER NOT NULL,
+  local_relpath  TEXT NOT NULL,
+  repos_id  INTEGER,
+  repos_relpath  TEXT,
+  parent_relpath  TEXT,
+  presence  TEXT NOT NULL,
+  kind  TEXT NOT NULL,
+  revnum  INTEGER,
+  checksum  TEXT,
+  translated_size  INTEGER,
+  changed_rev  INTEGER,
+  changed_date  INTEGER,
+  changed_author  TEXT,
+  depth  TEXT,
+  symlink_target  TEXT,
+  last_mod_time  INTEGER,
+  properties  BLOB,
+  dav_cache  BLOB,
+  file_external  TEXT
+);
+
+/* Copy everything into the temporary table. */
+INSERT INTO BASE_NODE_BACKUP SELECT
+  wc_id, local_relpath, repos_id, repos_relpath, parent_relpath, presence,
+  kind, revnum, checksum, translated_size, changed_rev, changed_date,
+  changed_author, depth, symlink_target, last_mod_time, properties, dav_cache,
+  file_external
+FROM BASE_NODE;
+
+/* Drop the original table. */
+DROP TABLE BASE_NODE;
+
+/* Recreate the original table, this time less the temporary columns.
+   Column descriptions are same as BASE_NODE in format 12 */
+CREATE TABLE BASE_NODE(
+  wc_id  INTEGER NOT NULL REFERENCES WCROOT (id),
+  local_relpath  TEXT NOT NULL,
+  repos_id  INTEGER REFERENCES REPOSITORY (id),
+  repos_relpath  TEXT,
+  parent_relpath  TEXT,
+  presence  TEXT NOT NULL,
+  kind  TEXT NOT NULL,
+  revnum  INTEGER,
+  checksum  TEXT,
+  translated_size  INTEGER,
+  changed_rev  INTEGER,
+  changed_date  INTEGER,
+  changed_author  TEXT,
+  depth  TEXT,
+  symlink_target  TEXT,
+  last_mod_time  INTEGER,
+  properties  BLOB,
+  dav_cache  BLOB,
+  file_external  TEXT,
+
+  PRIMARY KEY (wc_id, local_relpath)
+  );
+
+/* Recreate the index. */
+CREATE INDEX I_PARENT ON BASE_NODE (wc_id, parent_relpath);
+
+/* Copy everything back into the original table. */
+INSERT INTO BASE_NODE SELECT
+  wc_id, local_relpath, repos_id, repos_relpath, parent_relpath, presence,
+  kind, revnum, checksum, translated_size, changed_rev, changed_date,
+  changed_author, depth, symlink_target, last_mod_time, properties, dav_cache,
+  file_external
+FROM BASE_NODE_BACKUP;
+
+/* Drop the temporary table. */
+DROP TABLE BASE_NODE_BACKUP;
+
 /* Now "drop" the tree_conflict_data column from actual_node. */
 CREATE TABLE ACTUAL_NODE_BACKUP (
   wc_id  INTEGER NOT NULL,
Index: subversion/libsvn_wc/entries.c
===================================================================
--- subversion/libsvn_wc/entries.c	(revision 1023844)
+++ subversion/libsvn_wc/entries.c	(revision 1005387)
@@ -609,16 +609,35 @@
         {
           svn_sqlite__db_t *sdb;
           svn_sqlite__stmt_t *stmt;
+#ifdef SVN_WC__NODES
+          svn_sqlite__stmt_t *stmt_nodes;
+          svn_boolean_t have_nodes_row;
+#endif
 
           SVN_ERR(svn_wc__db_temp_borrow_sdb(
                     &sdb, db, dir_abspath,
                     svn_wc__db_openmode_readonly,
                     scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
           SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                             STMT_SELECT_NOT_PRESENT));
           SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, entry->name));
           SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+          SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+                                            STMT_SELECT_NOT_PRESENT_1));
+          SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", wc_id, entry->name));
+          SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+          SVN_ERR_ASSERT(have_row == have_nodes_row);
+          SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+          stmt = stmt_nodes;
+          have_row = have_nodes_row;
+#endif
+#endif
           SVN_ERR(svn_sqlite__reset(stmt));
         }
 
@@ -1516,9 +1535,77 @@
 {
   svn_sqlite__stmt_t *stmt;
 
+#ifndef SVN_WC__NODES_ONLY
+  /* ### NODE_DATA when switching to NODE_DATA, replace the
+     query below with STMT_INSERT_BASE_NODE_DATA_FOR_ENTRY_1
+     and adjust the parameters bound. Can't do that yet. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                     STMT_INSERT_BASE_NODE_FOR_ENTRY));
 
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 1, base_node->wc_id));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 2, base_node->local_relpath));
+
+  if (base_node->repos_id)
+    {
+      SVN_ERR(svn_sqlite__bind_int64(stmt, 3, base_node->repos_id));
+      SVN_ERR(svn_sqlite__bind_text(stmt, 4, base_node->repos_relpath));
+    }
+
+  if (base_node->parent_relpath)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, base_node->parent_relpath));
+
+  if (base_node->presence == svn_wc__db_status_not_present)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6, "not-present"));
+  else if (base_node->presence == svn_wc__db_status_normal)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6, "normal"));
+  else if (base_node->presence == svn_wc__db_status_absent)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6, "absent"));
+  else if (base_node->presence == svn_wc__db_status_incomplete)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6, "incomplete"));
+  else if (base_node->presence == svn_wc__db_status_excluded)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 6, "excluded"));
+
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 7, base_node->revision));
+
+  /* ### kind might be "symlink" or "unknown" */
+  if (base_node->kind == svn_node_none)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "unknown"));
+  else
+    SVN_ERR(svn_sqlite__bind_text(stmt, 8,
+                                  svn_node_kind_to_word(base_node->kind)));
+
+  if (base_node->checksum)
+    SVN_ERR(svn_sqlite__bind_checksum(stmt, 9, base_node->checksum,
+                                      scratch_pool));
+
+  if (base_node->translated_size != SVN_INVALID_FILESIZE)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 10, base_node->translated_size));
+
+  /* ### strictly speaking, changed_rev should be valid for present nodes. */
+  if (SVN_IS_VALID_REVNUM(base_node->changed_rev))
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 11, base_node->changed_rev));
+  if (base_node->changed_date)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 12, base_node->changed_date));
+  if (base_node->changed_author)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 13, base_node->changed_author));
+
+  SVN_ERR(svn_sqlite__bind_text(stmt, 14, svn_depth_to_word(base_node->depth)));
+
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 15, base_node->last_mod_time));
+
+  if (base_node->properties)
+    SVN_ERR(svn_sqlite__bind_properties(stmt, 16, base_node->properties,
+                                        scratch_pool));
+
+  /* Execute and reset the insert clause. */
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+#endif
+#ifdef SVN_WC__NODES
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_INSERT_BASE_NODE_FOR_ENTRY_1));
+
   SVN_ERR(svn_sqlite__bindf(stmt, "issisr",
                             base_node->wc_id,
                             base_node->local_relpath,
@@ -1571,6 +1658,8 @@
   /* Execute and reset the insert clause. */
   SVN_ERR(svn_sqlite__insert(NULL, stmt));
 
+
+#endif
   return SVN_NO_ERROR;
 }
 
@@ -1582,6 +1671,81 @@
 {
   svn_sqlite__stmt_t *stmt;
 
+#ifndef SVN_WC__NODES_ONLY
+  /* ### NODE_DATA when switching to NODE_DATA, replace the
+     query below with STMT_INSERT_WORKING_NODE_DATA_2
+     and adjust the parameters bound. Can't do that yet. */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_WORKING_NODE));
+
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 1, working_node->wc_id));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 2, working_node->local_relpath));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 3, working_node->parent_relpath));
+
+  /* ### need rest of values */
+  if (working_node->presence == svn_wc__db_status_normal)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "normal"));
+  else if (working_node->presence == svn_wc__db_status_not_present)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "not-present"));
+  else if (working_node->presence == svn_wc__db_status_base_deleted)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "base-deleted"));
+  else if (working_node->presence == svn_wc__db_status_incomplete)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "incomplete"));
+  else if (working_node->presence == svn_wc__db_status_excluded)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 4, "excluded"));
+
+  if (working_node->kind == svn_node_none)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, "unknown"));
+  else
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5,
+                                  svn_node_kind_to_word(working_node->kind)));
+
+  if (working_node->copyfrom_repos_path)
+    {
+      SVN_ERR(svn_sqlite__bind_int64(stmt, 6,
+                                     working_node->copyfrom_repos_id));
+      SVN_ERR(svn_sqlite__bind_text(stmt, 7,
+                                    working_node->copyfrom_repos_path));
+      SVN_ERR(svn_sqlite__bind_int64(stmt, 8, working_node->copyfrom_revnum));
+    }
+
+  if (working_node->moved_here)
+    SVN_ERR(svn_sqlite__bind_int(stmt, 9, working_node->moved_here));
+
+  if (working_node->moved_to)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 10, working_node->moved_to));
+
+  if (working_node->checksum)
+    SVN_ERR(svn_sqlite__bind_checksum(stmt, 11, working_node->checksum,
+                                      scratch_pool));
+
+  if (working_node->translated_size != SVN_INVALID_FILESIZE)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 12, working_node->translated_size));
+
+  if (SVN_IS_VALID_REVNUM(working_node->changed_rev))
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 13, working_node->changed_rev));
+  if (working_node->changed_date)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 14, working_node->changed_date));
+  if (working_node->changed_author)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 15, working_node->changed_author));
+
+  SVN_ERR(svn_sqlite__bind_text(stmt, 16,
+                                svn_depth_to_word(working_node->depth)));
+
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 17, working_node->last_mod_time));
+
+  if (working_node->properties)
+    SVN_ERR(svn_sqlite__bind_properties(stmt, 18, working_node->properties,
+                                        scratch_pool));
+
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 19, working_node->keep_local));
+
+  /* ### we should bind 'symlink_target' (20) as appropriate.  */
+
+  /* Execute and reset the insert clause. */
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "isisnnnnsnrisnnni",
                             working_node->wc_id, working_node->local_relpath,
@@ -1633,6 +1797,7 @@
     SVN_ERR(svn_sqlite__bind_int64(stmt, 16, working_node->translated_size));
 
   SVN_ERR(svn_sqlite__insert(NULL, stmt));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -1995,6 +2160,7 @@
                                                   &entry->file_external_rev,
                                                   scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
           SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                             STMT_UPDATE_FILE_EXTERNAL));
           SVN_ERR(svn_sqlite__bindf(stmt, "iss",
@@ -2002,6 +2168,16 @@
                                     entry->name,
                                     str));
           SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+          SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                            STMT_UPDATE_FILE_EXTERNAL_1));
+          SVN_ERR(svn_sqlite__bindf(stmt, "iss",
+                                    (apr_uint64_t)1 /* wc_id */,
+                                    entry->name,
+                                    str));
+          SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
         }
     }
 
Index: subversion/libsvn_wc/copy.c
===================================================================
--- subversion/libsvn_wc/copy.c	(revision 1023844)
+++ subversion/libsvn_wc/copy.c	(revision 1005387)
@@ -238,22 +238,10 @@
                              tmpdir_abspath,
                              TRUE, /* recursive */
                              cancel_func, cancel_baton, scratch_pool));
-
       if (tmp_dst_abspath)
         {
           svn_skel_t *work_item;
 
-          /* Remove 'read-only' from the destination file; it's a local add. */
-            {
-              const svn_string_t *needs_lock;
-              SVN_ERR(svn_wc__internal_propget(&needs_lock, db, src_abspath,
-                                               SVN_PROP_NEEDS_LOCK,
-                                               scratch_pool, scratch_pool));
-              if (needs_lock)
-                SVN_ERR(svn_io_set_file_read_write(tmp_dst_abspath,
-                                                   FALSE, scratch_pool));
-            }
-
           SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
                                              tmp_dst_abspath, dst_abspath,
                                              scratch_pool, scratch_pool));
Index: subversion/libsvn_wc/wc_db.c
===================================================================
--- subversion/libsvn_wc/wc_db.c	(revision 1023844)
+++ subversion/libsvn_wc/wc_db.c	(revision 1005387)
@@ -225,38 +225,8 @@
                const svn_skel_t *skel,
                apr_pool_t *scratch_pool);
 
-static svn_error_t *
-insert_incomplete_children(svn_sqlite__db_t *sdb,
-                           apr_int64_t wc_id,
-                           const char *local_relpath,
-                           svn_revnum_t revision,
-                           const apr_array_header_t *children,
-                           apr_int64_t op_depth,
-                           apr_pool_t *scratch_pool);
-
-static svn_error_t *
-db_read_pristine_props(apr_hash_t **props,
-                       svn_wc__db_pdh_t *pdh,
-                       const char *local_relpath,
-                       apr_pool_t *result_pool,
-                       apr_pool_t *scratch_pool);
-
-
-/* Return the absolute path, in local path style, of LOCAL_RELPATH in WCROOT. */
-static const char *
-path_for_error_message(const svn_wc__db_wcroot_t *wcroot,
-                       const char *local_relpath,
-                       apr_pool_t *result_pool)
-{
-  const char *local_abspath
-    = svn_dirent_join(wcroot->abspath, local_relpath, result_pool);
-
-  return svn_dirent_local_style(local_abspath, result_pool);
-}
-
 
-/* Return a file size from column SLOT of the SQLITE statement STMT, or
- * SVN_INVALID_FILESIZE if the column value is NULL. */
+/* */
 static svn_filesize_t
 get_translated_size(svn_sqlite__stmt_t *stmt, int slot)
 {
@@ -266,34 +236,6 @@
 }
 
 
-/* Return a lock info structure constructed from the given columns of the
- * SQLITE statement STMT, or return NULL if the token column value is null. */
-static svn_wc__db_lock_t *
-lock_from_columns(svn_sqlite__stmt_t *stmt,
-                  int col_token,
-                  int col_owner,
-                  int col_comment,
-                  int col_date,
-                  apr_pool_t *result_pool)
-{
-  svn_wc__db_lock_t *lock;
-
-  if (svn_sqlite__column_is_null(stmt, col_token))
-    {
-      lock = NULL;
-    }
-  else
-    {
-      lock = apr_pcalloc(result_pool, sizeof(svn_wc__db_lock_t));
-      lock->token = svn_sqlite__column_text(stmt, col_token, result_pool);
-      lock->owner = svn_sqlite__column_text(stmt, col_owner, result_pool);
-      lock->comment = svn_sqlite__column_text(stmt, col_comment, result_pool);
-      lock->date = svn_sqlite__column_int64(stmt, col_date);
-    }
-  return lock;
-}
-
-
 /* */
 static const char *
 escape_sqlite_like(const char * const str, apr_pool_t *result_pool)
@@ -425,9 +367,7 @@
 }
 
 
-/* Look up REPOS_ID in SDB and set *REPOS_ROOT_URL and/or *REPOS_UUID to
- * its root URL and UUID respectively.  Either output parameter may be
- * NULL if not wanted. */
+/* */
 static svn_error_t *
 fetch_repos_info(const char **repos_root_url,
                  const char **repos_uuid,
@@ -455,63 +395,183 @@
   return svn_error_return(svn_sqlite__reset(stmt));
 }
 
-/* Set *REPOS_ROOT_URL, *REPOS_UUID, *REVISION and *REPOS_RELPATH from the
- * given columns of the SQLITE statement STMT, or to NULL if the respective
- * column value is null.  Any of the output parameters may be NULL if not
- * required. */
+#ifdef SVN_WC__NODES
+
+/* Can't verify if we only have the NODES table */
+#ifndef SVN_WC__NODES_ONLY
+
+/* */
 static svn_error_t *
-repos_location_from_columns(const char **repos_root_url,
-                            const char **repos_uuid,
-                            svn_revnum_t *revision,
-                            const char **repos_relpath,
-                            svn_wc__db_pdh_t *pdh,
-                            svn_sqlite__stmt_t *stmt,
-                            int col_repos_id,
-                            int col_revision,
-                            int col_repos_relpath,
-                            apr_pool_t *result_pool)
+assert_text_columns_equal(svn_sqlite__stmt_t *stmt1,
+                          svn_sqlite__stmt_t *stmt2,
+                          int column,
+                          apr_pool_t *scratch_pool)
 {
-  svn_error_t *err = SVN_NO_ERROR;
+  const char *val1 = svn_sqlite__column_text(stmt1, column, scratch_pool);
+  const char *val2 = svn_sqlite__column_text(stmt2, column, scratch_pool);
 
-  if (repos_root_url || repos_uuid)
-    {
-      /* Fetch repository information via REPOS_ID. */
-      if (svn_sqlite__column_is_null(stmt, col_repos_id))
-        {
-          if (repos_root_url)
-            *repos_root_url = NULL;
-          if (repos_uuid)
-            *repos_uuid = NULL;
-        }
-      else
-        {
-          err = fetch_repos_info(repos_root_url, repos_uuid,
-                                 pdh->wcroot->sdb,
-                                 svn_sqlite__column_int64(stmt, col_repos_id),
-                                 result_pool);
-        }
-    }
-  if (revision)
-    {
-      *revision = svn_sqlite__column_revnum(stmt, col_revision);
-    }
-  if (repos_relpath)
-    {
-      *repos_relpath = svn_sqlite__column_text(stmt, col_repos_relpath,
-                                               result_pool);
-    }
+  if (val1 != NULL && val2 != NULL) {
+    if (strcmp(val1, val2) != 0)
+      return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+          "Value in statement 1 (%s) differs from value in statement 2 (%s)",
+                             val1, val2);
+  } else if (val1 == NULL && val2 == NULL) {
+    /* Do nothing: equal */
+  } else
+      return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+          "Value in statement 1 (%s) differs from value in statement 2 (%s)",
+                             val1, val2);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+assert_blob_columns_equal(svn_sqlite__stmt_t *stmt1,
+                          svn_sqlite__stmt_t *stmt2,
+                          int column,
+                          apr_pool_t *scratch_pool)
+{
+  apr_size_t len1, len2;
+  const void *val1 = svn_sqlite__column_blob(stmt1, column, &len1, NULL);
+  const void *val2 = svn_sqlite__column_blob(stmt2, column, &len2, NULL);
+
+  if (!len1 && !len2)
+    return SVN_NO_ERROR;
+
+  if (len1 != len2 || memcmp(val1, val2, len1))
+    return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+                             "Blob of length %ld in statement 1 differs "
+                             "from blob of length %ld in statement 2",
+                             (long int)len1, (long int)len2);
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+assert_base_rows_match(svn_boolean_t have_row1,
+                       svn_boolean_t have_row2,
+                       svn_sqlite__stmt_t *stmt1,
+                       svn_sqlite__stmt_t *stmt2,
+                       const char *relpath,
+                       apr_pool_t *scratch_pool)
+{
+
+  if (have_row1 != have_row2)
+    SVN_ERR(svn_error_createf(
+              SVN_ERR_WC_CORRUPT, NULL,
+              "Different results from BASE (%d) and NODES queries (%d), "
+              "for local_relpath %s",
+              have_row1, have_row2, relpath));
+
+  if (have_row1) {
+    SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 0)
+                   == svn_sqlite__column_int64(stmt2, 0));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 1, scratch_pool));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 2, scratch_pool));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 3, scratch_pool));
+
+    SVN_ERR_ASSERT(svn_sqlite__column_revnum(stmt1, 4)
+                   == svn_sqlite__column_revnum(stmt2, 4));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 5, scratch_pool));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 6, scratch_pool));
+
+    SVN_ERR_ASSERT(svn_sqlite__column_revnum(stmt1, 7)
+                   == svn_sqlite__column_revnum(stmt2, 7));
+
+
+    SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 8)
+                   == svn_sqlite__column_int64(stmt2, 8));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 9, scratch_pool));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 10, scratch_pool));
+
+    SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 11, scratch_pool));
+
+    SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 12)
+                   == svn_sqlite__column_int64(stmt2, 12));
+
+    /* verify props */
+    SVN_ERR(assert_blob_columns_equal(stmt1, stmt2, 13, scratch_pool));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+assert_working_rows_match(svn_boolean_t have_row1,
+                          svn_boolean_t have_row2,
+                          svn_sqlite__stmt_t *stmt1,
+                          svn_sqlite__stmt_t *stmt2,
+                          const char *relpath,
+                          apr_pool_t *scratch_pool)
+{
+  if (have_row1 != have_row2)
+    SVN_ERR(svn_error_createf(
+              SVN_ERR_WC_CORRUPT, NULL,
+              "Different results from WORKING (%d) and NODES queries (%d), "
+              "for local_relpath %s",
+              have_row1, have_row2, relpath));
+
+  if (!have_row1)
+    return SVN_NO_ERROR;
+
+  /* presence */
+  SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 0, scratch_pool));
+  /* kind */
+  SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 1, scratch_pool));
+  /* checksum */
+  SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 2, scratch_pool));
+  /* translated_size */
+  SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 3)
+                 == svn_sqlite__column_int64(stmt2, 3));
+  /* changed_rev */
+  SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 4)
+                 == svn_sqlite__column_int64(stmt2, 4));
+  /* changed_date */
+  SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 5)
+                 == svn_sqlite__column_int64(stmt2, 5));
+  /* changed_author */
+  SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 6, scratch_pool));
+  /* depth */
+  SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 7, scratch_pool));
+  /* symlink_target */
+  /* copyfrom_repos_id */
+  SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 9)
+                 == svn_sqlite__column_int64(stmt2, 9));
+  /* copyfrom_repos_path */
+  SVN_ERR(assert_text_columns_equal(stmt1, stmt2, 7, scratch_pool));
+  /* copyfrom_revnum */
+  SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 11)
+                 == svn_sqlite__column_int64(stmt2, 11));
+  /* moved_here */
+  /* moved_to */
+  /* last_mod_time */
+  SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt1, 14)
+                 == svn_sqlite__column_int64(stmt2, 14));
+  /* properties */
+  SVN_ERR(assert_blob_columns_equal(stmt1, stmt2, 15, scratch_pool));
 
-  return err;
+  return SVN_NO_ERROR;
 }
 
+#endif /* SVN_WC__NODES_ONLY */
+
+#endif /* SVN_WC__NODES */
 
 /* Scan from LOCAL_RELPATH upwards through parent nodes until we find a parent
    that has values in the 'repos_id' and 'repos_relpath' columns.  Return
-   that information in REPOS_ID and REPOS_RELPATH (either may be NULL). */
+   that information in REPOS_ID and REPOS_RELPATH (either may be NULL).
+   Use LOCAL_ABSPATH for diagnostics */
 static svn_error_t *
 scan_upwards_for_repos(apr_int64_t *repos_id,
                        const char **repos_relpath,
                        const svn_wc__db_wcroot_t *wcroot,
+                       const char *local_abspath,
                        const char *local_relpath,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
@@ -522,17 +582,56 @@
   const char *current_relpath = local_relpath;
   svn_sqlite__stmt_t *stmt;
 
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *data_stmt;
+#endif
+
   SVN_ERR_ASSERT(wcroot->sdb != NULL && wcroot->wc_id != UNKNOWN_WC_ID);
   SVN_ERR_ASSERT(repos_id != NULL || repos_relpath != NULL);
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_BASE_NODE));
+#ifndef SVN_WC__NODES_ONLY
+  /* ### is it faster to fetch fewer columns? */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_BASE_NODE));
+#endif
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&data_stmt, wcroot->sdb,
+                                    STMT_SELECT_BASE_NODE_1));
+#endif
+
   while (TRUE)
     {
       svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+      svn_boolean_t have_data_row;
+#endif
 
+#ifndef SVN_WC__NODES_ONLY
       /* Get the current node's repository information.  */
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+
+      /* Get the current node's repository information.  */
+      SVN_ERR(svn_sqlite__bindf(data_stmt, "is",
+                                wcroot->wc_id, current_relpath));
+      SVN_ERR(svn_sqlite__step(&have_data_row, data_stmt));
+
+#ifndef SVN_WC__NODES_ONLY
+      /* When switching to NODES_ONLY, stop verifying our results. */
+      SVN_ERR(assert_base_rows_match(have_row, have_data_row,
+                                     stmt, data_stmt,
+                                     current_relpath,
+                                     scratch_pool));
+      SVN_ERR(svn_sqlite__reset(data_stmt));
+#else
+      have_row = have_data_row;
+      stmt = data_stmt;
+#endif
+#endif
 
       if (!have_row)
         {
@@ -545,14 +644,14 @@
               err = svn_error_createf(
                 SVN_ERR_WC_CORRUPT, NULL,
                 _("Parent(s) of '%s' should have been present."),
-                path_for_error_message(wcroot, local_relpath, scratch_pool));
+                svn_dirent_local_style(local_abspath, scratch_pool));
             }
           else
             {
               err = svn_error_createf(
                 SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                 _("The node '%s' was not found."),
-                path_for_error_message(wcroot, local_relpath, scratch_pool));
+                svn_dirent_local_style(local_abspath, scratch_pool));
             }
 
           return svn_error_compose_create(err, svn_sqlite__reset(stmt));
@@ -586,7 +685,7 @@
           return svn_error_createf(
             SVN_ERR_WC_CORRUPT, NULL,
             _("Parent(s) of '%s' should have repository information."),
-            path_for_error_message(wcroot, local_relpath, scratch_pool));
+            svn_relpath_local_style(local_abspath, scratch_pool));
         }
 
       /* Strip a path segment off the end, and append it to the suffix
@@ -693,7 +792,12 @@
 insert_base_node(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
 {
   const insert_base_baton_t *pibb = baton;
+#ifndef SVN_WC__NODES_ONLY
   svn_sqlite__stmt_t *stmt;
+#endif
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_node;
+#endif
   /* The directory at the WCROOT has a NULL parent_relpath. Otherwise,
      bind the appropriate parent_relpath. */
   const char *parent_relpath =
@@ -703,8 +807,54 @@
   /* ### we can't handle this right now  */
   SVN_ERR_ASSERT(pibb->conflict == NULL);
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isisisr"
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_BASE_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isissttr",
+                            pibb->wc_id, pibb->local_relpath,
+                            pibb->repos_id,
+                            pibb->repos_relpath,
+                            parent_relpath,
+                            presence_map, pibb->status,
+                            kind_map, pibb->kind,
+                            pibb->revision));
+
+  SVN_ERR(svn_sqlite__bind_properties(stmt, 9, pibb->props, scratch_pool));
+
+  if (SVN_IS_VALID_REVNUM(pibb->changed_rev))
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 10, pibb->changed_rev));
+  if (pibb->changed_date)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 11, pibb->changed_date));
+  if (pibb->changed_author)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 12, pibb->changed_author));
+
+  if (pibb->kind == svn_wc__db_kind_dir)
+    {
+      SVN_ERR(svn_sqlite__bind_text(stmt, 13, svn_depth_to_word(pibb->depth)));
+    }
+  else if (pibb->kind == svn_wc__db_kind_file)
+    {
+      SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, pibb->checksum,
+                                        scratch_pool));
+      if (pibb->translated_size != SVN_INVALID_FILESIZE)
+        SVN_ERR(svn_sqlite__bind_int64(stmt, 15, pibb->translated_size));
+    }
+  else if (pibb->kind == svn_wc__db_kind_symlink)
+    {
+      /* Note: incomplete nodes may have a NULL target.  */
+      if (pibb->target)
+        SVN_ERR(svn_sqlite__bind_text(stmt, 16, pibb->target));
+    }
+
+  if (pibb->dav_cache)
+    SVN_ERR(svn_sqlite__bind_properties(stmt, 17, pibb->dav_cache,
+                                        scratch_pool));
+
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_node, sdb, STMT_INSERT_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt_node, "isisisr"
                             "tstr"               /* 8 - 11 */
                             "isnnnnns",          /* 12 - 19 */
                             pibb->wc_id,         /* 1 */
@@ -725,26 +875,63 @@
                                 pibb->target : NULL)); /* 19 */
 
   if (pibb->kind == svn_wc__db_kind_file) {
-    SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, pibb->checksum, scratch_pool));
+    SVN_ERR(svn_sqlite__bind_checksum(stmt_node, 14, pibb->checksum,
+                                      scratch_pool));
     if (pibb->translated_size != SVN_INVALID_FILESIZE)
-      SVN_ERR(svn_sqlite__bind_int64(stmt, 16, pibb->translated_size));
+      SVN_ERR(svn_sqlite__bind_int64(stmt_node, 16, pibb->translated_size));
   }
 
-  SVN_ERR(svn_sqlite__bind_properties(stmt, 15, pibb->props,
+  SVN_ERR(svn_sqlite__bind_properties(stmt_node, 15, pibb->props,
                                       scratch_pool));
   if (pibb->dav_cache)
-    SVN_ERR(svn_sqlite__bind_properties(stmt, 18, pibb->dav_cache,
+    SVN_ERR(svn_sqlite__bind_properties(stmt_node, 18, pibb->dav_cache,
                                         scratch_pool));
 
-  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+  SVN_ERR(svn_sqlite__insert(NULL, stmt_node));
+#endif
 
   if (pibb->kind == svn_wc__db_kind_dir && pibb->children)
-    SVN_ERR(insert_incomplete_children(sdb, pibb->wc_id,
-                                       pibb->local_relpath,
-                                       pibb->revision,
-                                       pibb->children,
-                                       0 /* BASE */,
-                                       scratch_pool));
+    {
+      int i;
+
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_INSERT_BASE_NODE_INCOMPLETE));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__get_statement(&stmt_node, sdb,
+                                        STMT_INSERT_NODE));
+#endif
+
+      for (i = pibb->children->nelts; i--; )
+        {
+          const char *name = APR_ARRAY_IDX(pibb->children, i, const char *);
+
+#ifndef SVN_WC__NODES_ONLY
+          SVN_ERR(svn_sqlite__bindf(stmt, "issr",
+                                    pibb->wc_id,
+                                    svn_relpath_join(pibb->local_relpath,
+                                                     name,
+                                                     scratch_pool),
+                                    pibb->local_relpath,
+                                    (apr_int64_t)pibb->revision));
+          SVN_ERR(svn_sqlite__insert(NULL, stmt));
+#endif
+#ifdef SVN_WC__NODES
+          SVN_ERR(svn_sqlite__bindf(stmt_node, "isisnnrsns",
+                                    pibb->wc_id,
+                                    svn_relpath_join(pibb->local_relpath,
+                                                     name,
+                                                     scratch_pool),
+                                    (apr_int64_t)0 /* BASE */,
+                                    pibb->local_relpath, /* parent_relpath */
+                                    pibb->revision,
+                                    "incomplete",
+                                    "unknown"));
+          SVN_ERR(svn_sqlite__insert(NULL, stmt_node));
+#endif
+        }
+    }
 
   SVN_ERR(add_work_items(sdb, pibb->work_items, scratch_pool));
 
@@ -779,6 +966,7 @@
   const insert_working_baton_t *piwb = baton;
   svn_sqlite__stmt_t *stmt;
 
+#ifdef SVN_WC__NODES
   const char *like_arg;
   svn_boolean_t have_row;
   apr_array_header_t *nodes;
@@ -827,45 +1015,76 @@
                                 piwb->op_depth));
       SVN_ERR(svn_sqlite__update(NULL, stmt));
     }
+#endif
+
+#ifndef SVN_WC__NODES_ONLY
+  /* Run the sequence below instead, which copies all the columns, including
+     those with the restrictions */
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_INSERT_WORKING_NODE_FROM_BASE_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "ist", piwb->wc_id, piwb->local_relpath,
+                            presence_map, piwb->presence));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   return SVN_NO_ERROR;
 }
 
 
-/* Insert a row in NODES for each (const char *) child name in CHILDREN,
-   whose parent directory is LOCAL_RELPATH, at op_depth=OP_DEPTH.  Set each
-   child's presence to 'incomplete', kind to 'unknown', and revision to
-   REVISION (which should match the parent's revision).  The child's
-   repos_id and repos_relpath will be inherited from the parent. */
+/* Insert WORKING rows for each (const char *) child name in CHILDREN,
+   whose parent directory is LOCAL_RELPATH.  For each child, set
+   presence='incomplete', kind='unknown', op_depth=OP_DEPTH. */
 static svn_error_t *
-insert_incomplete_children(svn_sqlite__db_t *sdb,
-                           apr_int64_t wc_id,
-                           const char *local_relpath,
-                           svn_revnum_t revision,
-                           const apr_array_header_t *children,
-                           apr_int64_t op_depth,
-                           apr_pool_t *scratch_pool)
+insert_incomplete_working_children(svn_sqlite__db_t *sdb,
+                                   apr_int64_t wc_id,
+                                   const char *local_relpath,
+                                   const apr_array_header_t *children,
+                                   apr_int64_t op_depth,
+                                   apr_pool_t *scratch_pool)
 {
+#ifndef SVN_WC__NODES_ONLY
   svn_sqlite__stmt_t *stmt;
+#endif
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_node;
+#endif
   int i;
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_INSERT_WORKING_NODE_INCOMPLETE));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_node, sdb,
+                                    STMT_INSERT_NODE));
+#endif
+
 
   for (i = children->nelts; i--; )
     {
       const char *name = APR_ARRAY_IDX(children, i, const char *);
 
-      SVN_ERR(svn_sqlite__bindf(stmt, "isisnnrsns",
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(svn_sqlite__bindf(stmt, "iss",
+                                wc_id,
+                                svn_relpath_join(local_relpath, name,
+                                                 scratch_pool),
+                                local_relpath));
+      SVN_ERR(svn_sqlite__insert(NULL, stmt));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__bindf(stmt_node, "isisnnnsns",
                                 wc_id,
                                 svn_relpath_join(local_relpath, name,
                                                  scratch_pool),
                                 op_depth,
                                 local_relpath,
-                                revision,
                                 "incomplete", /* 8, presence */
                                 "unknown"));  /* 10, kind */
 
-      SVN_ERR(svn_sqlite__insert(NULL, stmt));
+      SVN_ERR(svn_sqlite__insert(NULL, stmt_node));
+#endif
     }
 
   return SVN_NO_ERROR;
@@ -879,7 +1098,12 @@
 {
   const insert_working_baton_t *piwb = baton;
   const char *parent_relpath;
+#ifndef SVN_WC__NODES_ONLY
   svn_sqlite__stmt_t *stmt;
+#endif
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_node;
+#endif
 
   /* We cannot insert a WORKING_NODE row at the wcroot.  */
   /* ### actually, with per-dir DB, we can... */
@@ -889,8 +1113,67 @@
   else
     parent_relpath = svn_relpath_dirname(piwb->local_relpath, scratch_pool);
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isisnnntstrisn"
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isstt",
+                            piwb->wc_id, piwb->local_relpath,
+                            parent_relpath,
+                            presence_map, piwb->presence,
+                            kind_map, piwb->kind));
+
+  if (piwb->original_repos_relpath != NULL)
+    {
+      SVN_ERR_ASSERT(piwb->original_repos_id > 0);
+      SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(piwb->original_revnum));
+
+      SVN_ERR(svn_sqlite__bind_int64(stmt, 6, piwb->original_repos_id));
+      SVN_ERR(svn_sqlite__bind_text(stmt, 7, piwb->original_repos_relpath));
+      SVN_ERR(svn_sqlite__bind_int64(stmt, 8, piwb->original_revnum));
+    }
+
+  /* Do not bind 'moved_here' (9), nor 'moved_to' (10).  */
+
+  /* 'checksum' (11) is bound below.  */
+
+  /* Do not bind 'translated_size' (12).  */
+
+  if (SVN_IS_VALID_REVNUM(piwb->changed_rev))
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 13, piwb->changed_rev));
+  if (piwb->changed_date)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 14, piwb->changed_date));
+  if (piwb->changed_author)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 15, piwb->changed_author));
+
+  if (piwb->kind == svn_wc__db_kind_dir)
+    {
+      SVN_ERR(svn_sqlite__bind_text(stmt, 16, svn_depth_to_word(piwb->depth)));
+    }
+  else if (piwb->kind == svn_wc__db_kind_file)
+    {
+      SVN_ERR(svn_sqlite__bind_checksum(stmt, 11, piwb->checksum,
+                                        scratch_pool));
+    }
+  else if (piwb->kind == svn_wc__db_kind_symlink)
+    {
+      SVN_ERR_ASSERT(piwb->target != NULL);
+
+      SVN_ERR(svn_sqlite__bind_text(stmt, 20, piwb->target));
+    }
+
+  /* Do not bind 'last_mod_time' (17).  */
+
+  SVN_ERR(svn_sqlite__bind_properties(stmt, 18, piwb->props, scratch_pool));
+
+  /* Do not bind 'keep_local' (19).  */
+  /* 'symlink_target' (20) is bound above.  */
+
+  SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+#endif
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_node, sdb, STMT_INSERT_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt_node, "isisnnntstrisn"
                 "nnnn" /* properties translated_size last_mod_time dav_cache */
                 "s",
                 piwb->wc_id, piwb->local_relpath,
@@ -909,39 +1192,42 @@
 
   if (piwb->kind == svn_wc__db_kind_file)
     {
-      SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, piwb->checksum,
+      SVN_ERR(svn_sqlite__bind_checksum(stmt_node, 14, piwb->checksum,
                                         scratch_pool));
     }
   else if (piwb->kind == svn_wc__db_kind_symlink)
     {
       /* Note: incomplete nodes may have a NULL target.  */
       if (piwb->target)
-        SVN_ERR(svn_sqlite__bind_text(stmt, 19, piwb->target));
+        SVN_ERR(svn_sqlite__bind_text(stmt_node, 19, piwb->target));
     }
 
   if (piwb->original_repos_relpath != NULL)
     {
-      SVN_ERR(svn_sqlite__bind_int64(stmt, 5, piwb->original_repos_id));
-      SVN_ERR(svn_sqlite__bind_text(stmt, 6, piwb->original_repos_relpath));
-      SVN_ERR(svn_sqlite__bind_int64(stmt, 7, piwb->original_revnum));
+      SVN_ERR(svn_sqlite__bind_int64(stmt_node, 5, piwb->original_repos_id));
+      SVN_ERR(svn_sqlite__bind_text(stmt_node, 6,
+                    piwb->original_repos_relpath));
+      SVN_ERR(svn_sqlite__bind_int64(stmt_node, 7, piwb->original_revnum));
     }
 
 
-  SVN_ERR(svn_sqlite__bind_properties(stmt, 15, piwb->props, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_properties(stmt_node, 15, piwb->props,
+                      scratch_pool));
+
+  SVN_ERR(svn_sqlite__insert(NULL, stmt_node));
+#endif
 
-  SVN_ERR(svn_sqlite__insert(NULL, stmt));
 
   /* Insert incomplete children, if specified.
      The children are part of the same op and so have the same op_depth.
      (The only time we'd want a different depth is during a recursive
      simple add, but we never insert children here during a simple add.) */
   if (piwb->kind == svn_wc__db_kind_dir && piwb->children)
-    SVN_ERR(insert_incomplete_children(sdb, piwb->wc_id,
-                                       piwb->local_relpath,
-                                       piwb->original_revnum,
-                                       piwb->children,
-                                       piwb->op_depth,
-                                       scratch_pool));
+    SVN_ERR(insert_incomplete_working_children(sdb, piwb->wc_id,
+                                               piwb->local_relpath,
+                                               piwb->children,
+                                               piwb->op_depth,
+                                               scratch_pool));
 
   SVN_ERR(add_work_items(sdb, piwb->work_items, scratch_pool));
 
@@ -994,6 +1280,9 @@
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
   apr_hash_t *names_hash = apr_hash_make(scratch_pool);
+#ifdef SVN_WC__NODES
+  apr_hash_t *names_hash_1 = apr_hash_make(scratch_pool);
+#endif
   apr_array_header_t *names_array;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1004,17 +1293,31 @@
                                              scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
-  /* All of the names get allocated in RESULT_POOL.  For !base_only it
-     appears to be faster to use the hash to remove duplicates than to
-     use DISTINCT in the SQL query. */
-  if (base_only)
-    SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_BASE_NODE_CHILDREN,
+  /* All of the names get allocated in RESULT_POOL.  */
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_BASE_NODE_CHILDREN,
+                               pdh->wcroot->sdb, pdh->wcroot->wc_id,
+                               local_relpath, result_pool));
+  if (! base_only)
+    SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_WORKING_NODE_CHILDREN,
                                  pdh->wcroot->sdb, pdh->wcroot->wc_id,
                                  local_relpath, result_pool));
-  else
-    SVN_ERR(add_children_to_hash(names_hash, STMT_SELECT_NODE_CHILDREN,
+
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(add_children_to_hash(names_hash_1, STMT_SELECT_BASE_NODE_CHILDREN_1,
+                               pdh->wcroot->sdb, pdh->wcroot->wc_id,
+                               local_relpath, result_pool));
+  if (! base_only)
+    SVN_ERR(add_children_to_hash(names_hash_1, STMT_SELECT_WORKING_NODE_CHILDREN_1,
                                  pdh->wcroot->sdb, pdh->wcroot->wc_id,
                                  local_relpath, result_pool));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR_ASSERT(apr_hash_count(names_hash) == apr_hash_count(names_hash_1));
+#else
+  names_hash = names_hash_1;
+#endif
+#endif
 
   SVN_ERR(svn_hash_keys(&names_array, names_hash, result_pool));
   *children = names_array;
@@ -1116,14 +1419,33 @@
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_nodes_row;
+#endif
 
   *base_exists = FALSE;
   *working_exists = FALSE;
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                     STMT_DETERMINE_TREE_FOR_RECORDING));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+                                    STMT_DETERMINE_TREE_FOR_RECORDING_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  have_row = have_nodes_row;
+#endif
+#endif
 
   if (have_row)
     {
@@ -1163,14 +1485,32 @@
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_nodes_row;
+#endif
 
   *base_exists = FALSE;
   *working_exists = FALSE;
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_PLAN_PROP_UPGRADE));
   SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+                                    STMT_PLAN_PROP_UPGRADE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "s", local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR_ASSERT(have_row == have_nodes_row);
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  have_row = have_nodes_row;
+#endif
+#endif
   /* During a property upgrade, there better be a row corresponding to
      the provided LOCAL_RELPATH. We shouldn't even be here without a
      query for available rows.  */
@@ -1235,8 +1575,10 @@
   /* Create the database's schema.  */
   SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_SCHEMA));
 
+#ifdef SVN_WC__NODES
   /* Create the NODES table for the experimental schema */
   SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_NODES));
+#endif
 
   /* Insert the repository. */
   SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid, *sdb,
@@ -1794,11 +2136,21 @@
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_DELETE_BASE_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
 
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_DELETE_BASE_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
 
@@ -1831,6 +2183,10 @@
   const char *local_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_node_row;
+#endif
   svn_error_t *err = SVN_NO_ERROR;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1840,11 +2196,32 @@
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     lock ? STMT_SELECT_BASE_NODE_WITH_LOCK
                                          : STMT_SELECT_BASE_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+                                    lock ? STMT_SELECT_BASE_NODE_WITH_LOCK_1
+                                         : STMT_SELECT_BASE_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_node_row, stmt_nodes));
+
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_base_rows_match(have_row, have_node_row, stmt, stmt_nodes,
+                                 local_relpath, scratch_pool));
+#else
+  /* Lets assume the two queries return compatible data */
+  have_row = have_node_row;
+  stmt = stmt_nodes;
+#endif
+
+#endif /* SVN_WC__NODES */
 
   if (have_row)
     {
@@ -1859,18 +2236,57 @@
         {
           *status = svn_sqlite__column_token(stmt, 2, presence_map);
         }
-      err = repos_location_from_columns(repos_root_url, repos_uuid, revision,
-                                        repos_relpath,
-                                        pdh, stmt, 0, 4, 1, result_pool);
-      if (lock)
+      if (revision)
         {
-          *lock = lock_from_columns(stmt, 14, 15, 16, 17, result_pool);
+          *revision = svn_sqlite__column_revnum(stmt, 4);
         }
-      if (changed_rev)
+      if (repos_relpath)
         {
-          *changed_rev = svn_sqlite__column_revnum(stmt, 7);
+          *repos_relpath = svn_sqlite__column_text(stmt, 1, result_pool);
         }
-      if (changed_date)
+      if (lock)
+        {
+          if (svn_sqlite__column_is_null(stmt, 14))
+            {
+              *lock = NULL;
+            }
+          else
+            {
+              *lock = apr_pcalloc(result_pool, sizeof(svn_wc__db_lock_t));
+              (*lock)->token = svn_sqlite__column_text(stmt, 14, result_pool);
+              if (!svn_sqlite__column_is_null(stmt, 15))
+                (*lock)->owner = svn_sqlite__column_text(stmt, 15,
+                                                         result_pool);
+              if (!svn_sqlite__column_is_null(stmt, 16))
+                (*lock)->comment = svn_sqlite__column_text(stmt, 16,
+                                                           result_pool);
+              if (!svn_sqlite__column_is_null(stmt, 17))
+                (*lock)->date = svn_sqlite__column_int64(stmt, 17);
+            }
+        }
+      if (repos_root_url || repos_uuid)
+        {
+          /* Fetch repository information via REPOS_ID. */
+          if (svn_sqlite__column_is_null(stmt, 0))
+            {
+              if (repos_root_url)
+                *repos_root_url = NULL;
+              if (repos_uuid)
+                *repos_uuid = NULL;
+            }
+          else
+            {
+              err = fetch_repos_info(repos_root_url, repos_uuid,
+                                     pdh->wcroot->sdb,
+                                     svn_sqlite__column_int64(stmt, 0),
+                                     result_pool);
+            }
+        }
+      if (changed_rev)
+        {
+          *changed_rev = svn_sqlite__column_revnum(stmt, 7);
+        }
+      if (changed_date)
         {
           *changed_date = svn_sqlite__column_int64(stmt, 8);
         }
@@ -1936,6 +2352,12 @@
                                                      scratch_pool));
     }
 
+#ifdef SVN_WC__NODES
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#endif
+#endif
+
   /* Note: given the composition, no need to wrap for tracing.  */
   return svn_error_compose_create(err, svn_sqlite__reset(stmt));
 }
@@ -1977,10 +2399,29 @@
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
   svn_error_t *err;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_node;
+  svn_boolean_t have_node_row;
+#endif
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
                                  STMT_SELECT_BASE_PROPS, scratch_pool));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(get_statement_for_path(&stmt_node, db, local_abspath,
+                                 STMT_SELECT_BASE_PROPS_1, scratch_pool));
+  SVN_ERR(svn_sqlite__step(&have_node_row, stmt_node));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR_ASSERT(have_row == have_node_row);
+  SVN_ERR(assert_blob_columns_equal(stmt, stmt_node, 0, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_node));
+#else
+  stmt = stmt_node;
+  have_row = have_node_row;
+#endif
+#endif
   if (!have_row)
     {
       err = svn_sqlite__reset(stmt);
@@ -2024,6 +2465,20 @@
   svn_sqlite__stmt_t *stmt;
   int affected_rows;
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
+                                 STMT_UPDATE_BASE_DAV_CACHE, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
+
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+
+  if (affected_rows != 1)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("The node '%s' was not found."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+#endif
+#ifdef SVN_WC__NODES
   SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
                                  STMT_UPDATE_BASE_NODE_DAV_CACHE,
                                  scratch_pool));
@@ -2036,6 +2491,7 @@
                              _("The node '%s' was not found."),
                              svn_dirent_local_style(local_abspath,
                                                     scratch_pool));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -2085,12 +2541,21 @@
 
   like_arg = construct_like_arg(local_relpath, scratch_pool);
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_CLEAR_BASE_RECURSIVE_DAV_CACHE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "iss", pdh->wcroot->wc_id, local_relpath,
+                            like_arg));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_CLEAR_BASE_NODE_RECURSIVE_DAV_CACHE));
   SVN_ERR(svn_sqlite__bindf(stmt, "iss", pdh->wcroot->wc_id, local_relpath,
                             like_arg));
 
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -2437,17 +2902,39 @@
   {
     const svn_checksum_t *md5_checksum;
     svn_sqlite__stmt_t *stmt;
+#ifdef SVN_WC__NODES
+    svn_sqlite__stmt_t *stmt_nodes;
+    svn_boolean_t is_referenced_nodes;
+#endif
 
     /* ### Transitional: look for references to its MD-5 as well. */
     SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db, wri_abspath,
                                         sha1_checksum, scratch_pool,
                                         scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
     SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                       STMT_SELECT_ANY_PRISTINE_REFERENCE));
     SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
     SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
     SVN_ERR(svn_sqlite__step(&is_referenced, stmt));
+#endif
+#ifdef SVN_WC__NODES
+    SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+                                      STMT_SELECT_ANY_PRISTINE_REFERENCE_1));
+    SVN_ERR(svn_sqlite__bind_checksum(stmt_nodes, 1, sha1_checksum,
+                                      scratch_pool));
+    SVN_ERR(svn_sqlite__bind_checksum(stmt_nodes, 2, md5_checksum,
+                                      scratch_pool));
+    SVN_ERR(svn_sqlite__step(&is_referenced_nodes, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+    SVN_ERR_ASSERT(is_referenced == is_referenced_nodes);
+    SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+    is_referenced = is_referenced_nodes;
+    stmt = stmt_nodes;
+#endif
+#endif
 
     SVN_ERR(svn_sqlite__reset(stmt));
   }
@@ -2571,6 +3058,27 @@
 }
 
 
+svn_error_t *
+svn_wc__db_repos_ensure(apr_int64_t *repos_id,
+                        svn_wc__db_t *db,
+                        const char *local_abspath,
+                        const char *repos_root_url,
+                        const char *repos_uuid,
+                        apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+
+  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
+                              local_abspath, svn_sqlite__mode_readwrite,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
+
+  return svn_error_return(create_repos_id(repos_id, repos_root_url,
+                                          repos_uuid, pdh->wcroot->sdb,
+                                          scratch_pool));
+}
+
 /* Helper for svn_wc__db_op_copy to handle copying from one db to
    another */
 static svn_error_t *
@@ -2626,8 +3134,8 @@
                                NULL /* lock */,
                                db, src_abspath, scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_wc__db_read_pristine_props(&props, db, src_abspath,
-                                         scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__get_pristine_props(&props, db, src_abspath,
+                                     scratch_pool, scratch_pool));
 
   blank_iwb(&iwb);
   iwb.presence = dst_status;
@@ -2937,12 +3445,36 @@
       const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,
                                                            scratch_pool);
 
+#ifndef SVN_WC__NODES_ONLY
+      if (have_work)
+        SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
+                                  STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING));
+      else
+        SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
+                                  STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "issst",
+                                src_pdh->wcroot->wc_id, src_relpath,
+                                dst_relpath, dst_parent_relpath,
+                                presence_map, dst_status));
+
+      if (copyfrom_relpath)
+        {
+          SVN_ERR(svn_sqlite__bind_int64(stmt, 6, copyfrom_id));
+          SVN_ERR(svn_sqlite__bind_text(stmt, 7, copyfrom_relpath));
+          SVN_ERR(svn_sqlite__bind_int64(stmt, 8, copyfrom_rev));
+        }
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+
       if (have_work)
         SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
-                         STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING));
+                         STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING_1));
       else
         SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
-                          STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
+                          STMT_INSERT_WORKING_NODE_COPY_FROM_BASE_1));
 
       SVN_ERR(svn_sqlite__bindf(stmt, "issisnnnt",
                     src_pdh->wcroot->wc_id, src_relpath,
@@ -2959,6 +3491,8 @@
         }
       SVN_ERR(svn_sqlite__step_done(stmt));
 
+#endif
+
       /* ### Copying changelist is OK for a move but what about a copy? */
       SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
                                   STMT_INSERT_ACTUAL_NODE_FROM_ACTUAL_NODE));
@@ -2968,13 +3502,12 @@
       SVN_ERR(svn_sqlite__step_done(stmt));
 
       if (kind == svn_wc__db_kind_dir)
-        SVN_ERR(insert_incomplete_children(dst_pdh->wcroot->sdb,
-                                           dst_pdh->wcroot->wc_id,
-                                           dst_relpath,
-                                           copyfrom_rev,
-                                           children,
-                                           op_depth,
-                                           scratch_pool));
+        SVN_ERR(insert_incomplete_working_children(dst_pdh->wcroot->sdb,
+                                                   dst_pdh->wcroot->wc_id,
+                                                   dst_relpath,
+                                                   children,
+                                                   op_depth,
+                                                   scratch_pool));
     }
   else
     {
@@ -3125,16 +3658,7 @@
       iwb.original_revnum = original_revision;
     }
 
-#ifdef SVN_WC__OP_DEPTH
-  iwb.op_depth = relpath_depth(local_relpath);
-
-  /* ### TODO? If the WC parent dir is already a copy from
-   * dirname(original_repos_relpath)@original_revision, then this is a
-   * redundant copy as far is the repos is concerned, so it should share
-   * the same op_depth.  But that's a degenerate case.  Is it needed? */
-#else
   iwb.op_depth = 2;  /* ### temporary op_depth */
-#endif
 
   iwb.checksum = checksum;
 
@@ -3346,7 +3870,7 @@
 {
   apr_hash_t *props;
 
-  svn_wc__db_pdh_t *pdh;
+  apr_int64_t wc_id;
   const char *local_relpath;
 
   const svn_skel_t *conflict;
@@ -3354,38 +3878,6 @@
 };
 
 
-/* Set the ACTUAL_NODE properties column for (WC_ID, LOCAL_RELPATH) to
- * PROPS. */
-static svn_error_t *
-set_actual_props(apr_int64_t wc_id,
-                 const char *local_relpath,
-                 apr_hash_t *props,
-                 svn_sqlite__db_t *db,
-                 apr_pool_t *scratch_pool)
-{
-  svn_sqlite__stmt_t *stmt;
-  int affected_rows;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_UPDATE_ACTUAL_PROPS));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
-  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
-
-  if (affected_rows == 1 || !props)
-    return SVN_NO_ERROR; /* We are done */
-
-  /* We have to insert a row in ACTUAL */
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_ACTUAL_PROPS));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-  if (*local_relpath != '\0')
-    SVN_ERR(svn_sqlite__bind_text(stmt, 3,
-                                  svn_relpath_dirname(local_relpath,
-                                                      scratch_pool)));
-  SVN_ERR(svn_sqlite__bind_properties(stmt, 4, props, scratch_pool));
-  return svn_error_return(svn_sqlite__step_done(stmt));
-}
-
 /* Set the 'properties' column in the 'ACTUAL_NODE' table to BATON->props.
    Create an entry in the ACTUAL table for the node if it does not yet
    have one.
@@ -3395,7 +3887,8 @@
 set_props_txn(void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool)
 {
   struct set_props_baton *spb = baton;
-  apr_hash_t *pristine_props;
+  svn_sqlite__stmt_t *stmt;
+  int affected_rows;
 
   /* ### we dunno what to do with CONFLICT yet.  */
   SVN_ERR_ASSERT(spb->conflict == NULL);
@@ -3403,25 +3896,24 @@
   /* First order of business: insert all the work items.  */
   SVN_ERR(add_work_items(db, spb->work_items, scratch_pool));
 
-  /* Check if the props are modified. If no changes, then wipe out the
-     ACTUAL props.  PRISTINE_PROPS==NULL means that any
-     ACTUAL props are okay as provided, so go ahead and set them.  */
-  SVN_ERR(db_read_pristine_props(&pristine_props, spb->pdh, spb->local_relpath,
-                                 scratch_pool, scratch_pool));
-  if (spb->props && pristine_props)
-    {
-      apr_array_header_t *prop_diffs;
+  SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_UPDATE_ACTUAL_PROPS));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", spb->wc_id, spb->local_relpath));
+  SVN_ERR(svn_sqlite__bind_properties(stmt, 3, spb->props, scratch_pool));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-      SVN_ERR(svn_prop_diffs(&prop_diffs, spb->props, pristine_props,
-                             scratch_pool));
-      if (prop_diffs->nelts == 0)
-        spb->props = NULL;
-    }
+  if (affected_rows == 1 || !spb->props)
+    return SVN_NO_ERROR; /* We are done */
 
-  SVN_ERR(set_actual_props(spb->pdh->wcroot->wc_id, spb->local_relpath,
-                           spb->props, db, scratch_pool));
+  /* We have to insert a row in ACTUAL */
 
-  return SVN_NO_ERROR;
+  SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_ACTUAL_PROPS));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", spb->wc_id, spb->local_relpath));
+  if (*spb->local_relpath != '\0')
+    SVN_ERR(svn_sqlite__bind_text(stmt, 3,
+                                  svn_relpath_dirname(spb->local_relpath,
+                                                      scratch_pool)));
+  SVN_ERR(svn_sqlite__bind_properties(stmt, 4, spb->props, scratch_pool));
+  return svn_error_return(svn_sqlite__step_done(stmt));
 }
 
 svn_error_t *
@@ -3443,7 +3935,7 @@
   VERIFY_USABLE_PDH(pdh);
 
   spb.props = props;
-  spb.pdh = pdh;
+  spb.wc_id = pdh->wcroot->wc_id;
   spb.conflict = conflict;
   spb.work_items = work_items;
 
@@ -3493,10 +3985,20 @@
                                const apr_hash_t *props,
                                apr_pool_t *scratch_pool)
 {
+#ifdef SVN_WC__NODES
   SVN_ERR(set_properties(db, local_abspath, props,
                          STMT_UPDATE_NODE_BASE_PROPS,
                          "base node", scratch_pool));
+#endif
+
+#ifndef SVN_WC__NODES_ONLY
+  return svn_error_return(set_properties(db, local_abspath, props,
+                                         STMT_UPDATE_BASE_PROPS,
+                                         "base_node",
+                                         scratch_pool));
+#else
   return SVN_NO_ERROR;
+#endif
 }
 
 
@@ -3506,10 +4008,20 @@
                                   const apr_hash_t *props,
                                   apr_pool_t *scratch_pool)
 {
+#ifdef SVN_WC__NODES
   SVN_ERR(set_properties(db, local_abspath, props,
                          STMT_UPDATE_NODE_WORKING_PROPS,
                          "working node", scratch_pool));
+#endif
+
+#ifndef SVN_WC__NODES_ONLY
+  return svn_error_return(set_properties(db, local_abspath, props,
+                                         STMT_UPDATE_WORKING_PROPS,
+                                         "working_node",
+                                         scratch_pool));
+#else
   return SVN_NO_ERROR;
+#endif
 }
 
 #endif /* SVN__SUPPORT_BASE_MERGE  */
@@ -3770,11 +4282,6 @@
   SVN_ERR(svn_sqlite__bindf(stmt, "iss", stb->wc_id, stb->local_relpath,
                             tree_conflict_data));
 
-  if (!have_row && stb->local_relpath[0])
-    SVN_ERR(svn_sqlite__bind_text(stmt, 4,
-                                  svn_dirent_dirname(stb->local_relpath,
-                                                     scratch_pool)));
-
   return svn_error_return(svn_sqlite__step_done(stmt));
 }
 
@@ -3811,46 +4318,6 @@
 
 
 svn_error_t *
-svn_wc__db_op_revert_actual(svn_wc__db_t *db,
-                            const char *local_abspath,
-                            apr_pool_t *scratch_pool)
-{
-  svn_wc__db_pdh_t *pdh;
-  const char *local_relpath;
-  svn_sqlite__stmt_t *stmt;
-  int affected_rows;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
-                              local_abspath, svn_sqlite__mode_readwrite,
-                              scratch_pool, scratch_pool));
-  VERIFY_USABLE_PDH(pdh);
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                                    STMT_DELETE_ACTUAL_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
-
-  if (affected_rows == 0) {
-    /* Failed to delete the row.
-       Presumably because there was a changelist set on it */
-
-    SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                               STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST));
-    SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
-    SVN_ERR(svn_sqlite__step_done(stmt));
-    /* We're not interested here if there was an affected row or not:
-       If there isn't by now, then there simply was no row to begin with */
-  }
-
-  /* Some entries have cached the above values. Kapow!!  */
-  SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_wc__db_op_revert(svn_wc__db_t *db,
                      const char *local_abspath,
                      svn_depth_t depth,
@@ -3974,9 +4441,21 @@
   sdb = pdh->wcroot->sdb;
   wc_id = pdh->wcroot->wc_id;
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_BASE_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_NODES));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_ACTUAL_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
@@ -4005,10 +4484,19 @@
 
   SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_DELETE_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_DELETE_WORKING_NODES));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -4028,6 +4516,18 @@
   /* Flush any entries before we start monkeying the database.  */
   SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    excluded
+                                      ? STMT_UPDATE_BASE_EXCLUDED
+                                      : STMT_UPDATE_BASE_DEPTH));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+  if (!excluded)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 3, svn_depth_to_word(depth)));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     excluded
                                       ? STMT_UPDATE_NODE_BASE_EXCLUDED
@@ -4036,7 +4536,20 @@
   if (!excluded)
     SVN_ERR(svn_sqlite__bind_text(stmt, 3, svn_depth_to_word(depth)));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    excluded
+                                      ? STMT_UPDATE_WORKING_EXCLUDED
+                                      : STMT_UPDATE_WORKING_DEPTH));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+  if (!excluded)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 3, svn_depth_to_word(depth)));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     excluded
                                       ? STMT_UPDATE_NODE_WORKING_EXCLUDED
@@ -4045,6 +4558,7 @@
   if (!excluded)
     SVN_ERR(svn_sqlite__bind_text(stmt, 3, svn_depth_to_word(depth)));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -4094,11 +4608,21 @@
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_UPDATE_WORKING_PRESENCE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "ist", pdh->wcroot->wc_id, local_relpath,
+                            presence_map, status));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_UPDATE_NODE_WORKING_PRESENCE));
   SVN_ERR(svn_sqlite__bindf(stmt, "ist", pdh->wcroot->wc_id, local_relpath,
                             presence_map, status));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -4121,10 +4645,19 @@
 
   VERIFY_USABLE_PDH(pdh);
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_DELETE_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_DELETE_WORKING_NODES));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_DELETE_ACTUAL_NODE));
@@ -4427,10 +4960,18 @@
 {
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
-  svn_sqlite__stmt_t *stmt_info;
+  svn_sqlite__stmt_t *stmt_base;
+  svn_sqlite__stmt_t *stmt_work;
   svn_sqlite__stmt_t *stmt_act;
-  svn_boolean_t have_info;
+  svn_boolean_t local_have_base;
+  svn_boolean_t local_have_work;
   svn_boolean_t have_act;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes_base;
+  svn_sqlite__stmt_t *stmt_nodes_work;
+  svn_boolean_t local_have_nodes_base;
+  svn_boolean_t local_have_nodes_work;
+#endif
   svn_error_t *err = NULL;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -4440,46 +4981,99 @@
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
-  /* Obtain the most likely to exist record first, to make sure we don't
-     have to obtain the SQLite read-lock multiple times */
-  SVN_ERR(svn_sqlite__get_statement(&stmt_info, pdh->wcroot->sdb,
-                                    lock ? STMT_SELECT_NODE_INFO_WITH_LOCK
-                                         : STMT_SELECT_NODE_INFO));
-  SVN_ERR(svn_sqlite__bindf(stmt_info, "is",
+  if (!have_base)
+    have_base = &local_have_base;
+  if (!have_work)
+    have_work = &local_have_work;
+    
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt_base, pdh->wcroot->sdb,
+                                    lock ? STMT_SELECT_BASE_NODE_WITH_LOCK
+                                         : STMT_SELECT_BASE_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt_base, "is",
                             pdh->wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step(&have_info, stmt_info));
+  SVN_ERR(svn_sqlite__step(have_base, stmt_base));
 
-  if (changelist || conflicted || props_mod)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt_act, pdh->wcroot->sdb,
-                                        STMT_SELECT_ACTUAL_NODE));
-      SVN_ERR(svn_sqlite__bindf(stmt_act, "is",
-                                pdh->wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__step(&have_act, stmt_act));
-    }
-  else
-    {
-      have_act = FALSE;
-      stmt_act = NULL;
-    }
+  SVN_ERR(svn_sqlite__get_statement(&stmt_work, pdh->wcroot->sdb,
+                                    STMT_SELECT_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt_work, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(have_work, stmt_work));
+#endif
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt_act, pdh->wcroot->sdb,
+                                    STMT_SELECT_ACTUAL_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt_act, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_act, stmt_act));
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_base, pdh->wcroot->sdb,
+                                    lock ? STMT_SELECT_BASE_NODE_WITH_LOCK_1
+                                         : STMT_SELECT_BASE_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes_base, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&local_have_nodes_base, stmt_nodes_base));
+
+  /* Possible optimisation: if we didn't select op_depth > 0 then this
+     would give us the base node when there is no working node. */
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_work, pdh->wcroot->sdb,
+                                    STMT_SELECT_WORKING_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes_work, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&local_have_nodes_work, stmt_nodes_work));
+
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_base_rows_match(*have_base, local_have_nodes_base,
+                                 stmt_base, stmt_nodes_base,
+                                 local_relpath, scratch_pool));
+  SVN_ERR(assert_working_rows_match(*have_work, local_have_nodes_work,
+                                    stmt_work, stmt_nodes_work,
+                                    local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes_base));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes_work));
+#else
+  /* Lets assume the queries return compatible data */
+  *have_base = local_have_nodes_base;
+  *have_work = local_have_nodes_work;
+  stmt_base = stmt_nodes_base;
+  stmt_work = stmt_nodes_work;
+#endif
+
+#endif /* SVN_WC__NODES */
 
-  if (have_info)
+  if (*have_base || *have_work)
     {
-      int op_depth;
       svn_wc__db_kind_t node_kind;
 
-      op_depth = svn_sqlite__column_int(stmt_info, 0);
-      node_kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
+      if (*have_work)
+        node_kind = svn_sqlite__column_token(stmt_work, 1, kind_map);
+      else
+        node_kind = svn_sqlite__column_token(stmt_base, 3, kind_map);
 
       if (status)
         {
-          *status = svn_sqlite__column_token(stmt_info, 3, presence_map);
+          if (*have_base)
+            {
+              *status = svn_sqlite__column_token(stmt_base, 2, presence_map);
+
+              /* We have a presence that allows a WORKING_NODE override
+                 (normal or not-present), or we don't have an override.  */
+              /* ### for now, allow an override of an incomplete BASE_NODE
+                 ### row. it appears possible to get rows in BASE/WORKING
+                 ### both set to 'incomplete'.  */
+              SVN_ERR_ASSERT((*status != svn_wc__db_status_absent
+                              && *status != svn_wc__db_status_excluded
+                              /* && *status != svn_wc__db_status_incomplete */)
+                             || !*have_work);
+            }
 
-          if (op_depth != 0) /* WORKING */
+          if (*have_work)
             {
               svn_wc__db_status_t work_status;
 
-              work_status = *status;
+              work_status = svn_sqlite__column_token(stmt_work, 0,
+                                                     presence_map);
               SVN_ERR_ASSERT(work_status == svn_wc__db_status_normal
                              || work_status == svn_wc__db_status_not_present
                              || work_status == svn_wc__db_status_base_deleted
@@ -4518,48 +5112,77 @@
         {
           *kind = node_kind;
         }
-      if (op_depth != 0)
+      if (revision)
         {
-          if (repos_root_url)
-            *repos_root_url = NULL;
-          if (repos_uuid)
-            *repos_uuid = NULL;
-          if (revision)
+          if (*have_work)
             *revision = SVN_INVALID_REVNUM;
-          if (repos_relpath)
-            /* Our path is implied by our parent somewhere up the tree.
-               With the NULL value and status, the caller will know to
-               search up the tree for the base of our path.  */
-            *repos_relpath = NULL;
+          else
+            *revision = svn_sqlite__column_revnum(stmt_base, 4);
         }
-      else
+      if (repos_relpath)
+        {
+          if (*have_work)
+            {
+              /* Our path is implied by our parent somewhere up the tree.
+                 With the NULL value and status, the caller will know to
+                 search up the tree for the base of our path.  */
+              *repos_relpath = NULL;
+            }
+          else
+            *repos_relpath = svn_sqlite__column_text(stmt_base, 1,
+                                                     result_pool);
+        }
+      if (repos_root_url || repos_uuid)
         {
           /* Fetch repository information via REPOS_ID. If we have a
              WORKING_NODE (and have been added), then the repository
              we're being added to will be dependent upon a parent. The
              caller can scan upwards to locate the repository.  */
-          err = svn_error_compose_create(
-            err, repos_location_from_columns(repos_root_url, repos_uuid,
-                                             revision, repos_relpath,
-                                             pdh, stmt_info, 1, 5, 2,
-                                             result_pool));
+          if (*have_work || svn_sqlite__column_is_null(stmt_base, 0))
+            {
+              if (repos_root_url)
+                *repos_root_url = NULL;
+              if (repos_uuid)
+                *repos_uuid = NULL;
+            }
+          else
+            err = svn_error_compose_create(
+                     err,
+                     fetch_repos_info(repos_root_url,
+                                      repos_uuid,
+                                      pdh->wcroot->sdb,
+                                      svn_sqlite__column_int64(stmt_base, 0),
+                                      result_pool));
         }
       if (changed_rev)
         {
-          *changed_rev = svn_sqlite__column_revnum(stmt_info, 8);
+          if (*have_work)
+            *changed_rev = svn_sqlite__column_revnum(stmt_work, 4);
+          else
+            *changed_rev = svn_sqlite__column_revnum(stmt_base, 7);
         }
       if (changed_date)
         {
-          *changed_date = svn_sqlite__column_int64(stmt_info, 9);
+          if (*have_work)
+            *changed_date = svn_sqlite__column_int64(stmt_work, 5);
+          else
+            *changed_date = svn_sqlite__column_int64(stmt_base, 8);
         }
       if (changed_author)
         {
-          *changed_author = svn_sqlite__column_text(stmt_info, 10,
-                                                    result_pool);
+          if (*have_work)
+            *changed_author = svn_sqlite__column_text(stmt_work, 6,
+                                                      result_pool);
+          else
+            *changed_author = svn_sqlite__column_text(stmt_base, 9,
+                                                      result_pool);
         }
       if (last_mod_time)
         {
-          *last_mod_time = svn_sqlite__column_int64(stmt_info, 13);
+          if (*have_work)
+            *last_mod_time = svn_sqlite__column_int64(stmt_work, 14);
+          else
+            *last_mod_time = svn_sqlite__column_int64(stmt_base, 12);
         }
       if (depth)
         {
@@ -4571,7 +5194,10 @@
             {
               const char *depth_str;
 
-              depth_str = svn_sqlite__column_text(stmt_info, 11, NULL);
+              if (*have_work)
+                depth_str = svn_sqlite__column_text(stmt_work, 7, NULL);
+              else
+                depth_str = svn_sqlite__column_text(stmt_base, 10, NULL);
 
               if (depth_str == NULL)
                 *depth = svn_depth_unknown;
@@ -4588,8 +5214,12 @@
           else
             {
               svn_error_t *err2;
-              err2 = svn_sqlite__column_checksum(checksum, stmt_info, 6,
-                                                 result_pool);
+              if (*have_work)
+                err2 = svn_sqlite__column_checksum(checksum, stmt_work, 2,
+                                                   result_pool);
+              else
+                err2 = svn_sqlite__column_checksum(checksum, stmt_base, 5,
+                                                   result_pool);
 
               if (err2 != NULL)
                 err = svn_error_compose_create(
@@ -4603,14 +5233,19 @@
         }
       if (translated_size)
         {
-          *translated_size = get_translated_size(stmt_info, 7);
+          if (*have_work)
+            *translated_size = get_translated_size(stmt_work, 3);
+          else
+            *translated_size = get_translated_size(stmt_base, 6);
         }
       if (target)
         {
           if (node_kind != svn_wc__db_kind_symlink)
             *target = NULL;
+          else if (*have_work)
+            *target = svn_sqlite__column_text(stmt_work, 8, result_pool);
           else
-            *target = svn_sqlite__column_text(stmt_info, 12, result_pool);
+            *target = svn_sqlite__column_text(stmt_base, 11, result_pool);
         }
       if (changelist)
         {
@@ -4619,25 +5254,37 @@
           else
             *changelist = NULL;
         }
-      if (op_depth == 0)
+      if (original_repos_relpath)
+        {
+          if (*have_work)
+            *original_repos_relpath = svn_sqlite__column_text(stmt_work, 10,
+                                                              result_pool);
+          else
+            *original_repos_relpath = NULL;
+        }
+      if (!*have_work || svn_sqlite__column_is_null(stmt_work, 9))
         {
           if (original_root_url)
             *original_root_url = NULL;
           if (original_uuid)
             *original_uuid = NULL;
-          if (original_revision)
-            *original_revision = SVN_INVALID_REVNUM;
-          if (original_repos_relpath)
-            *original_repos_relpath = NULL;
         }
-      else
+      else if (original_root_url || original_uuid)
         {
+          /* Fetch repository information via COPYFROM_REPOS_ID. */
           err = svn_error_compose_create(
-            err, repos_location_from_columns(original_root_url, original_uuid,
-                                             original_revision,
-                                             original_repos_relpath,
-                                             pdh, stmt_info, 1, 5, 2,
-                                             result_pool));
+                     err,
+                     fetch_repos_info(original_root_url, original_uuid,
+                                      pdh->wcroot->sdb,
+                                      svn_sqlite__column_int64(stmt_work, 9),
+                                      result_pool));
+        }
+      if (original_revision)
+        {
+          if (*have_work)
+            *original_revision = svn_sqlite__column_revnum(stmt_work, 11);
+          else
+            *original_revision = SVN_INVALID_REVNUM;
         }
       if (props_mod)
         {
@@ -4658,32 +5305,24 @@
           else
             *conflicted = FALSE;
         }
-
       if (lock)
         {
-          if (op_depth != 0)
+          if (svn_sqlite__column_is_null(stmt_base, 14))
             *lock = NULL;
           else
-            *lock = lock_from_columns(stmt_info, 15, 16, 17, 18, result_pool);
-        }
-
-      if (have_work)
-        *have_work = (op_depth != 0);
-
-      if (have_base)
-        {
-          while (!err && op_depth != 0)
             {
-              err = svn_sqlite__step(&have_info, stmt_info);
-
-              if (err || !have_info)
-                break;
-
-              op_depth = svn_sqlite__column_int(stmt_info, 0);
+              *lock = apr_pcalloc(result_pool, sizeof(svn_wc__db_lock_t));
+              (*lock)->token = svn_sqlite__column_text(stmt_base, 14,
+                                                       result_pool);
+              if (!svn_sqlite__column_is_null(stmt_base, 15))
+                (*lock)->owner = svn_sqlite__column_text(stmt_base, 15,
+                                                         result_pool);
+              if (!svn_sqlite__column_is_null(stmt_base, 16))
+                (*lock)->comment = svn_sqlite__column_text(stmt_base, 16,
+                                                           result_pool);
+              if (!svn_sqlite__column_is_null(stmt_base, 17))
+                (*lock)->date = svn_sqlite__column_int64(stmt_base, 17);
             }
-
-          if (have_base)
-            *have_base = (op_depth == 0);
         }
     }
   else if (have_act)
@@ -4703,10 +5342,9 @@
                                                      scratch_pool));
     }
 
-  if (stmt_act != NULL)
-    err = svn_error_compose_create(err, svn_sqlite__reset(stmt_act));
-
-  SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_info)));
+  err = svn_error_compose_create(err, svn_sqlite__reset(stmt_base));
+  err = svn_error_compose_create(err, svn_sqlite__reset(stmt_work));
+  SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_act)));
 
   /* ### And finally, check for tree conflicts via parent.
          This reuses stmt_act and throws an error in Sqlite if
@@ -4724,251 +5362,6 @@
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_wc__db_read_children_info(apr_hash_t **nodes,
-                              apr_hash_t **conflicts,
-                              svn_wc__db_t *db,
-                              const char *dir_abspath,
-                              apr_pool_t *result_pool,
-                              apr_pool_t *scratch_pool)
-{
-  svn_wc__db_pdh_t *pdh;
-  const char *dir_relpath;
-  svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
-  const char *repos_root_url = NULL;
-  apr_int64_t last_repos_id;
-  apr_hash_t *tree_conflicts;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
-
-  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &dir_relpath, db,
-                                             dir_abspath,
-                                             svn_sqlite__mode_readonly,
-                                             scratch_pool, scratch_pool));
-  VERIFY_USABLE_PDH(pdh);
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                                    STMT_SELECT_NODE_CHILDREN_INFO));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, dir_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  *nodes = apr_hash_make(result_pool);
-  while (have_row)
-    {
-      struct svn_wc__db_info_t *child;
-      const char *child_relpath = svn_sqlite__column_text(stmt, 19, NULL);
-      const char *name = svn_relpath_basename(child_relpath, NULL);
-      svn_error_t *err;
-      int *op_depth, row_op_depth;
-      svn_boolean_t new_child;
-
-      child = apr_hash_get(*nodes, name, APR_HASH_KEY_STRING);
-      if (child)
-        new_child = FALSE;
-      else
-        {
-          child = apr_palloc(result_pool,
-                             sizeof(struct svn_wc__db_info_t) + sizeof(int));
-          new_child = TRUE;
-        }
-
-      op_depth = (int *)(char*)(child + 1);
-      row_op_depth = svn_sqlite__column_int(stmt, 0);
-
-      if (new_child || *op_depth < row_op_depth)
-        {
-          apr_hash_t *properties;
-
-          *op_depth = row_op_depth;
-
-          child->kind = svn_sqlite__column_token(stmt, 4, kind_map);
-
-          child->status = svn_sqlite__column_token(stmt, 3, presence_map);
-          if (*op_depth != 0)
-            {
-              if (child->status == svn_wc__db_status_not_present
-                  || child->status == svn_wc__db_status_base_deleted)
-                child->status = svn_wc__db_status_deleted;
-              else if (child->status == svn_wc__db_status_normal)
-                child->status = svn_wc__db_status_added;
-            }
-
-          if (*op_depth != 0)
-            child->revnum = SVN_INVALID_REVNUM;
-          else
-            child->revnum = svn_sqlite__column_revnum(stmt, 5);
-
-
-          if (*op_depth != 0)
-            child->repos_relpath = NULL;
-          else
-            child->repos_relpath = svn_sqlite__column_text(stmt, 2,
-                                                           result_pool);
-
-          if (*op_depth != 0 || svn_sqlite__column_is_null(stmt, 1))
-            {
-              child->repos_root_url = NULL;
-            }
-          else
-            {
-              const char *repos_uuid;
-              apr_int64_t repos_id = svn_sqlite__column_int64(stmt, 1);
-              if (!repos_root_url)
-                {
-                  err = fetch_repos_info(&repos_root_url, &repos_uuid,
-                                         pdh->wcroot->sdb, repos_id,
-                                         result_pool);
-                  if (err)
-                    SVN_ERR(svn_error_compose_create(err,
-                                                     svn_sqlite__reset(stmt)));
-                  last_repos_id = repos_id;
-                }
-
-              /* Assume working copy is all one repos_id so that a
-                 single cached value is sufficient. */
-              SVN_ERR_ASSERT(repos_id == last_repos_id);
-              child->repos_root_url = repos_root_url;
-            }
-
-          child->changed_rev = svn_sqlite__column_revnum(stmt, 8);
-
-          child->changed_date = svn_sqlite__column_int64(stmt, 9);
-
-          child->changed_author = svn_sqlite__column_text(stmt, 10,
-                                                          result_pool);
-
-          child->last_mod_time = svn_sqlite__column_int64(stmt, 13);
-
-          if (child->kind != svn_wc__db_kind_dir)
-            child->depth = svn_depth_unknown;
-          else
-            {
-              const char *depth = svn_sqlite__column_text(stmt, 11,
-                                                          scratch_pool);
-              if (depth)
-                child->depth = svn_depth_from_word(depth);
-              else
-                child->depth = svn_depth_unknown;
-            }
-
-          child->translated_size = get_translated_size(stmt, 7);
-
-          child->lock = lock_from_columns(stmt, 15, 16, 17, 18, result_pool);
-
-          err = svn_sqlite__column_properties(&properties, stmt, 14,
-                                              scratch_pool, scratch_pool);
-          if (err)
-            SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-          child->has_props = properties && !!apr_hash_count(properties);
-#ifdef HAVE_SYMLINK
-          child->special = (child->has_props
-                            && apr_hash_get(properties, SVN_PROP_SPECIAL,
-                                            APR_HASH_KEY_STRING));
-#endif
-
-          child->changelist = NULL;
-          child->have_base = (*op_depth == 0);
-          child->props_mod = FALSE;
-          child->conflicted = FALSE;
-
-          apr_hash_set(*nodes, apr_pstrdup(result_pool, name),
-                       APR_HASH_KEY_STRING, child);
-        }
-      else if (row_op_depth == 0)
-        {
-          child->have_base = TRUE;
-        }
-
-      err = svn_sqlite__step(&have_row, stmt);
-      if (err)
-        SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-    }
-
-  SVN_ERR(svn_sqlite__reset(stmt));
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                                    STMT_SELECT_ACTUAL_CHILDREN_INFO));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, dir_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  while (have_row)
-    {
-      struct svn_wc__db_info_t *child;
-      const char *child_relpath = svn_sqlite__column_text(stmt, 7, NULL);
-      const char *name = svn_relpath_basename(child_relpath, NULL);
-      svn_error_t *err;
-
-      child = apr_hash_get(*nodes, name, APR_HASH_KEY_STRING);
-      if (!child)
-        {
-          err = svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
-                                  _("Corrupt data for '%s'"),
-                                  svn_dirent_local_style(child_relpath,
-                                                         scratch_pool));
-          SVN_ERR(svn_error_compose_create(err,
-                                           svn_sqlite__step(&have_row, stmt)));
-        }
-
-      child->changelist = svn_sqlite__column_text(stmt, 1, result_pool);
-
-      child->props_mod = !svn_sqlite__column_is_null(stmt, 6);
-      if (child->props_mod)
-        {
-          apr_hash_t *properties;
-
-          err = svn_sqlite__column_properties(&properties, stmt, 6,
-                                              scratch_pool, scratch_pool);
-          if (err)
-            SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-          child->has_props = properties && !!apr_hash_count(properties);
-#ifdef HAVE_SYMLINK
-          child->special = (child->has_props
-                            && apr_hash_get(properties, SVN_PROP_SPECIAL,
-                                            APR_HASH_KEY_STRING));
-#endif
-        }
-
-
-      child->conflicted = (svn_sqlite__column_text(stmt, 2, NULL)     /* old */
-                           || svn_sqlite__column_text(stmt, 3, NULL)  /* new */
-                           || svn_sqlite__column_text(stmt, 4, NULL)  /* work */
-                           || svn_sqlite__column_text(stmt, 0, NULL));/* prop */
-
-      err = svn_sqlite__step(&have_row, stmt);
-      if (err)
-        SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-    }
-
-  SVN_ERR(svn_sqlite__reset(stmt));
-
-  SVN_ERR(svn_wc__db_op_read_all_tree_conflicts(&tree_conflicts, db,
-                                                dir_abspath,
-                                                scratch_pool, scratch_pool));
-  *conflicts = apr_hash_make(result_pool);
-  if (tree_conflicts)
-    {
-      apr_hash_index_t *hi;
-
-      for (hi = apr_hash_first(scratch_pool, tree_conflicts);
-           hi;
-           hi = apr_hash_next(hi))
-        {
-          const char *name = svn__apr_hash_index_key(hi);
-          struct svn_wc__db_info_t *child
-            = apr_hash_get(*nodes, name, APR_HASH_KEY_STRING);
-
-          if (child)
-            child->conflicted = TRUE;
-
-          apr_hash_set(*conflicts, apr_pstrdup(result_pool, name),
-                       APR_HASH_KEY_STRING, "");
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
 
 svn_error_t *
 svn_wc__db_read_prop(const svn_string_t **propval,
@@ -5041,88 +5434,81 @@
 }
 
 
-static svn_error_t *
-db_read_pristine_props(apr_hash_t **props,
-                       svn_wc__db_pdh_t *pdh,
-                       const char *local_relpath,
-                       apr_pool_t *result_pool,
-                       apr_pool_t *scratch_pool)
+svn_error_t *
+svn_wc__db_read_pristine_props(apr_hash_t **props,
+                               svn_wc__db_t *db,
+                               const char *local_abspath,
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
-  svn_wc__db_status_t presence;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb, STMT_SELECT_NODE_PROPS));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_node;
+  svn_boolean_t have_node_row;
+#endif
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
+                                 STMT_SELECT_WORKING_PROPS, scratch_pool));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
 
-  if (!have_row)
-    {
-      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
-                               svn_sqlite__reset(stmt),
-                               _("The node '%s' was not found."),
-                               path_for_error_message(pdh->wcroot,
-                                                      local_relpath,
-                                                      scratch_pool));
-    }
+#ifdef SVN_WC__NODES
+  SVN_ERR(get_statement_for_path(&stmt_node, db, local_abspath,
+                                 STMT_SELECT_WORKING_PROPS_1, scratch_pool));
+  SVN_ERR(svn_sqlite__step(&have_node_row, stmt_node));
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR_ASSERT(have_row == have_node_row);
+  SVN_ERR(assert_blob_columns_equal(stmt, stmt_node, 0, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_node));
+#else
+  stmt = stmt_node;
+  have_row = have_node_row;
+#endif
+#endif
 
-  /* Examine the presence: */
-  presence = svn_sqlite__column_token(stmt, 1, presence_map);
+  /* If there is a WORKING row, then examine its status:
 
-  /* For "base-deleted", it is obvious the pristine props are located
-     in the BASE table. Fall through to fetch them.
-     ### BH: Is this really the behavior we want here? */
-  if (presence == svn_wc__db_status_base_deleted)
+     For adds/copies/moves, then pristine properties are in this row.
+
+     For deletes, the pristines may be located here (as a result of a
+     copy/move-here), or they are located in BASE.
+     ### right now, we don't have a strong definition yet. moving to the
+     ### proposed NODE_DATA system will create more determinism around
+     ### where props are located and their relation to layered operations.  */
+  if (have_row)
     {
-      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      svn_wc__db_status_t presence;
 
-      SVN_ERR_ASSERT(have_row);
+      /* For "base-deleted", it is obvious the pristine props are located
+         in the BASE table. Fall through to fetch them.
 
+         ### for regular deletes, the properties should be in the WORKING
+         ### row. though operation layering and the suggested NODE_DATA may
+         ### really be needed to ensure the props are always available,
+         ### and what "pristine" really means.  */
       presence = svn_sqlite__column_token(stmt, 1, presence_map);
-    }
-
-  /* normal or copied: Fetch properties */
-  if (presence == svn_wc__db_status_normal)
-    {
-      svn_error_t *err;
-
-      err = svn_sqlite__column_properties(props, stmt, 0, result_pool,
-                                          scratch_pool);
-      SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+      if (presence != svn_wc__db_status_base_deleted)
+        {
+          svn_error_t *err;
 
-      if (!*props)
-        *props = apr_hash_make(result_pool);
+          err = svn_sqlite__column_properties(props, stmt, 0, result_pool,
+                                              scratch_pool);
+          SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
 
-      return SVN_NO_ERROR;
+          /* ### *PROPS may be NULL. is this okay?  */
+          return SVN_NO_ERROR;
+        }
     }
 
-  *props = NULL;
-  return svn_error_return(svn_sqlite__reset(stmt));
-}
-
-
-svn_error_t *
-svn_wc__db_read_pristine_props(apr_hash_t **props,
-                               svn_wc__db_t *db,
-                               const char *local_abspath,
-                               apr_pool_t *result_pool,
-                               apr_pool_t *scratch_pool)
-{
-  svn_wc__db_pdh_t *pdh;
-  const char *local_relpath;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
-                              local_abspath, svn_sqlite__mode_readwrite,
-                              scratch_pool, scratch_pool));
-  VERIFY_USABLE_PDH(pdh);
+  SVN_ERR(svn_sqlite__reset(stmt));
 
-  SVN_ERR(db_read_pristine_props(props, pdh, local_relpath,
-                                 result_pool, scratch_pool));
-  return SVN_NO_ERROR;
+  /* No WORKING node, so the props must be in the BASE node.  */
+  return svn_error_return(svn_wc__db_base_get_props(props, db, local_abspath,
+                                                    result_pool,
+                                                    scratch_pool));
 }
 
 
@@ -5171,6 +5557,16 @@
 
   like_arg = construct_like_arg(rb->local_relpath, scratch_pool);
 
+#ifndef SVN_WC__NODES_ONLY
+  /* Update non-NULL WORKING_NODE.copyfrom_repos_id. */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                               STMT_UPDATE_WORKING_RECURSIVE_COPYFROM_REPO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "issii", rb->wc_id, rb->local_relpath,
+                            like_arg, rb->old_repos_id, new_repos_id));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   /* Set the (base and working) repos_ids and clear the dav_caches */
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                     STMT_RECURSIVE_UPDATE_NODE_REPO));
@@ -5179,9 +5575,28 @@
                             like_arg, rb->old_repos_id,
                             new_repos_id));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
+  /* Do a bunch of stuff which is conditional on us actually having a
+     base_node in the first place. */
   if (rb->have_base_node)
     {
+#ifndef SVN_WC__NODES_ONLY
+      /* Purge the DAV cache (wcprops) from any BASE that have 'em. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_CLEAR_BASE_RECURSIVE_DAV_CACHE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "iss", rb->wc_id, rb->local_relpath,
+                                like_arg));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+
+      /* Update any BASE which have non-NULL repos_id's */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_UPDATE_BASE_RECURSIVE_REPO));
+      SVN_ERR(svn_sqlite__bindf(stmt, "issii", rb->wc_id, rb->local_relpath,
+                                like_arg, rb->old_repos_id, new_repos_id));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
       /* Update any locks for the root or its children. */
       like_arg = construct_like_arg(rb->repos_relpath, scratch_pool);
 
@@ -5356,8 +5771,13 @@
   svn_wc__db_kind_t new_kind;
   const char *new_depth_str = NULL;
   svn_sqlite__stmt_t *stmt;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes_base, *stmt_nodes_work;
+  svn_boolean_t have_nodes_base, have_nodes_work;
+#endif
 
   /* ### is it better to select only the data needed?  */
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt_base, cb->pdh->wcroot->sdb,
                                     STMT_SELECT_BASE_NODE));
   SVN_ERR(svn_sqlite__get_statement(&stmt_work, cb->pdh->wcroot->sdb,
@@ -5368,7 +5788,34 @@
                             cb->pdh->wcroot->wc_id, cb->local_relpath));
   SVN_ERR(svn_sqlite__step(&have_base, stmt_base));
   SVN_ERR(svn_sqlite__step(&have_work, stmt_work));
-
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_base, cb->pdh->wcroot->sdb,
+                                    STMT_SELECT_BASE_NODE_1));
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes_work, cb->pdh->wcroot->sdb,
+                                    STMT_SELECT_WORKING_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes_base, "is",
+                            cb->pdh->wcroot->wc_id, cb->local_relpath));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes_work, "is",
+                            cb->pdh->wcroot->wc_id, cb->local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_nodes_base, stmt_nodes_base));
+  SVN_ERR(svn_sqlite__step(&have_nodes_work, stmt_nodes_work));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_base_rows_match(have_base, have_nodes_base,
+                                 stmt_base, stmt_nodes_base,
+                                 cb->local_relpath, scratch_pool));
+  SVN_ERR(assert_working_rows_match(have_work, have_nodes_work,
+                                    stmt_work, stmt_nodes_work,
+                                    cb->local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes_base));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes_work));
+#else
+  stmt_base = stmt_nodes_base;
+  stmt_work = stmt_nodes_work;
+  have_base = have_nodes_base;
+  have_work = have_nodes_work;
+#endif
+#endif
   SVN_ERR(svn_sqlite__get_statement(&stmt_act, cb->pdh->wcroot->sdb,
                                     STMT_SELECT_ACTUAL_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt_act, "is",
@@ -5444,6 +5891,40 @@
   /* ### other presences? or reserve that for separate functions?  */
   new_presence = svn_wc__db_status_normal;
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, cb->pdh->wcroot->sdb,
+                                    STMT_APPLY_CHANGES_TO_BASE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "issttiisb",
+                            cb->pdh->wcroot->wc_id, cb->local_relpath,
+                            parent_relpath,
+                            presence_map, new_presence,
+                            kind_map, new_kind,
+                            (apr_int64_t)cb->new_revision,
+                            (apr_int64_t)cb->changed_rev,
+                            cb->changed_author,
+                            prop_blob.data, prop_blob.len));
+
+  /* ### for now, always set the repos_id/relpath. we should make these
+     ### null whenever possible. but that also means we'd have to check
+     ### on whether this node is switched, so the values would need to
+     ### remain unchanged.  */
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 10, cb->repos_id));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 11, cb->repos_relpath));
+
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 12, cb->new_checksum,
+                                    scratch_pool));
+  if (cb->changed_date > 0)
+    SVN_ERR(svn_sqlite__bind_int64(stmt, 13, cb->changed_date));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 14, new_depth_str));
+  /* ### 15. target.  */
+  SVN_ERR(svn_sqlite__bind_properties(stmt, 16, cb->new_dav_cache,
+                                      scratch_pool));
+
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+
   SVN_ERR(svn_sqlite__get_statement(&stmt, cb->pdh->wcroot->sdb,
                                     STMT_APPLY_CHANGES_TO_BASE_NODE));
   /* symlink_target not yet used */
@@ -5468,13 +5949,26 @@
 
   SVN_ERR(svn_sqlite__step_done(stmt));
 
+#endif
+
+
   if (have_work)
     {
+#ifndef SVN_WC__NODES_ONLY
+      /* Get rid of the WORKING_NODE row.  */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, cb->pdh->wcroot->sdb,
+                                        STMT_DELETE_WORKING_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                cb->pdh->wcroot->wc_id, cb->local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
       SVN_ERR(svn_sqlite__get_statement(&stmt, cb->pdh->wcroot->sdb,
                                         STMT_DELETE_WORKING_NODES));
       SVN_ERR(svn_sqlite__bindf(stmt, "is",
                                 cb->pdh->wcroot->wc_id, cb->local_relpath));
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
     }
 
   if (have_act)
@@ -5550,14 +6044,36 @@
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
   const char *repos_parent_relpath;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_nodes_row;
+#endif
 
   /* ### is it faster to fetch fewer columns? */
 
   /* Prefer the current node's repository information.  */
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_SELECT_BASE_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+                                    STMT_SELECT_BASE_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_base_rows_match(have_row, have_nodes_row,
+                                 stmt, stmt_nodes,
+                                 local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  have_row = have_nodes_row;
+#endif
+#endif
 
   if (have_row && !svn_sqlite__column_is_null(stmt, 0))
     {
@@ -5578,7 +6094,8 @@
 
   /* The REPOS_ID will be the same (### until we support mixed-repos)  */
   SVN_ERR(scan_upwards_for_repos(repos_id, &repos_parent_relpath,
-                                 pdh->wcroot, local_relpath,
+                                 pdh->wcroot, pdh->local_abspath,
+                                 local_relpath,
                                  scratch_pool, scratch_pool));
 
   *repos_relpath = svn_relpath_join(repos_parent_relpath, name, result_pool);
@@ -5751,11 +6268,14 @@
 
 
 struct record_baton {
-  svn_wc__db_wcroot_t *wcroot;
+  apr_int64_t wc_id;
   const char *local_relpath;
 
   svn_filesize_t translated_size;
   apr_time_t last_mod_time;
+
+  /* For error reporting.  */
+  const char *local_abspath;
 };
 
 
@@ -5772,15 +6292,27 @@
   int affected_rows;
 
   SVN_ERR(which_trees_exist(&base_exists, &working_exists,
-                            sdb, rb->wcroot->wc_id, rb->local_relpath));
+                            sdb, rb->wc_id, rb->local_relpath));
   if (!base_exists && !working_exists)
     return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                              _("Could not find node '%s' for recording file "
                                "information."),
-                             path_for_error_message(rb->wcroot,
-                                                    rb->local_relpath,
+                             svn_dirent_local_style(rb->local_abspath,
                                                     scratch_pool));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    working_exists
+                                      ? STMT_UPDATE_WORKING_FILEINFO
+                                      : STMT_UPDATE_BASE_FILEINFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isii",
+                            rb->wc_id, rb->local_relpath,
+                            rb->translated_size, rb->last_mod_time));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+
+  SVN_ERR_ASSERT(affected_rows == 1);
+#endif
 
+#ifdef SVN_WC__NODES
   /* ### Instead of doing it this way, we just ought to update the highest
      op_depth level. That way, there's no need to find out which
      tree to update first */
@@ -5789,11 +6321,12 @@
                                       ? STMT_UPDATE_WORKING_NODE_FILEINFO
                                       : STMT_UPDATE_BASE_NODE_FILEINFO));
   SVN_ERR(svn_sqlite__bindf(stmt, "isii",
-                            rb->wcroot->wc_id, rb->local_relpath,
+                            rb->wc_id, rb->local_relpath,
                             rb->translated_size, rb->last_mod_time));
   SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
   SVN_ERR_ASSERT(affected_rows == 1);
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -5817,12 +6350,14 @@
                               scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
-  rb.wcroot = pdh->wcroot;
+  rb.wc_id = pdh->wcroot->wc_id;
   rb.local_relpath = local_relpath;
 
   rb.translated_size = translated_size;
   rb.last_mod_time = last_mod_time;
 
+  rb.local_abspath = local_abspath;
+
   SVN_ERR(svn_sqlite__with_transaction(pdh->wcroot->sdb, record_fileinfo, &rb,
                                        scratch_pool));
 
@@ -5854,7 +6389,7 @@
   VERIFY_USABLE_PDH(pdh);
 
   SVN_ERR(scan_upwards_for_repos(&repos_id, &repos_relpath,
-                                 pdh->wcroot, local_relpath,
+                                 pdh->wcroot, local_abspath, local_relpath,
                                  scratch_pool, scratch_pool));
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
@@ -5899,7 +6434,7 @@
   VERIFY_USABLE_PDH(pdh);
 
   SVN_ERR(scan_upwards_for_repos(&repos_id, &repos_relpath,
-                                 pdh->wcroot, local_relpath,
+                                 pdh->wcroot, local_abspath, local_relpath,
                                  scratch_pool, scratch_pool));
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
@@ -5936,7 +6471,7 @@
   VERIFY_USABLE_PDH(pdh);
 
   SVN_ERR(scan_upwards_for_repos(&repos_id, repos_relpath,
-                                 pdh->wcroot, local_relpath,
+                                 pdh->wcroot, local_abspath, local_relpath,
                                  result_pool, scratch_pool));
 
   if (repos_root_url || repos_uuid)
@@ -6005,12 +6540,34 @@
       svn_sqlite__stmt_t *stmt;
       svn_boolean_t have_row;
       svn_wc__db_status_t presence;
+#ifdef SVN_WC__NODES
+      svn_sqlite__stmt_t *stmt_nodes;
+      svn_boolean_t have_nodes_row;
+#endif
 
       /* ### is it faster to fetch fewer columns? */
+#ifndef SVN_WC__NODES_ONLY
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_SELECT_WORKING_NODE));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, wcroot->sdb,
+                                        STMT_SELECT_WORKING_NODE_1));
+      SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+                                wcroot->wc_id, current_relpath));
+      SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(assert_working_rows_match(have_row, have_nodes_row,
+                                        stmt, stmt_nodes,
+                                        current_relpath, scratch_pool));
+      SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+      stmt = stmt_nodes;
+      have_row = have_nodes_row;
+#endif
+#endif
 
       if (!have_row)
         {
@@ -6190,11 +6747,34 @@
       svn_boolean_t have_row;
       svn_boolean_t have_base;
       svn_wc__db_status_t work_presence;
+#ifdef SVN_WC__NODES
+      svn_sqlite__stmt_t *stmt_nodes;
+      svn_boolean_t have_nodes_row;
+#endif
 
+#ifndef SVN_WC__NODES_ONLY
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_SELECT_DELETION_INFO));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, wcroot->sdb,
+                                        STMT_SELECT_DELETION_INFO_1));
+      SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+                                wcroot->wc_id, current_relpath));
+      SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt, 0)
+                     == svn_sqlite__column_int64(stmt_nodes, 0));
+      SVN_ERR_ASSERT(svn_sqlite__column_int64(stmt, 1)
+                     == svn_sqlite__column_int64(stmt_nodes, 1));
+      SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+      stmt = stmt_nodes;
+      have_row = have_nodes_row;
+#endif
+#endif
 
       if (!have_row)
         {
@@ -6385,12 +6965,23 @@
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_int64_t wc_id;
   apr_hash_index_t *hi;
+#ifndef SVN_WC__NODES_ONLY
   svn_sqlite__stmt_t *stmt;
+#endif
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_node;
+#endif
 
   SVN_ERR(svn_wc__db_util_fetch_wc_id(&wc_id, sdb, iterpool));
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_BASE_DAV_CACHE));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_node, sdb,
                                     STMT_UPDATE_BASE_NODE_DAV_CACHE));
+#endif
+
 
   /* Iterate over all the wcprops, writing each one to the wc_db. */
   for (hi = apr_hash_first(scratch_pool, cache_values);
@@ -6405,9 +6996,17 @@
 
       local_relpath = svn_relpath_join(dir_relpath, name, iterpool);
 
+#ifndef SVN_WC__NODES_ONLY
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
       SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, iterpool));
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__bindf(stmt_node, "is", wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__bind_properties(stmt_node, 3, props, iterpool));
+      SVN_ERR(svn_sqlite__step_done(stmt_node));
+#endif
+
     }
 
   svn_pool_destroy(iterpool);
@@ -6492,6 +7091,16 @@
     {
       apr_hash_t *props = revert_props ? revert_props : base_props;
 
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_BASE_PROPS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+
+      /* ### should we provide a nicer error message?  */
+      SVN_ERR_ASSERT(affected_rows == 1);
+#endif
+#ifdef SVN_WC__NODES
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                         STMT_UPDATE_NODE_BASE_PROPS));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
@@ -6500,6 +7109,7 @@
 
       /* ### should we provide a nicer error message?  */
       SVN_ERR_ASSERT(affected_rows == 1);
+#endif
     }
 
   if (have_work)
@@ -6516,6 +7126,18 @@
           && (work_presence == svn_wc__db_status_normal
               || work_presence == svn_wc__db_status_incomplete))
         {
+#ifndef SVN_WC__NODES_ONLY
+          SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                            STMT_UPDATE_WORKING_PROPS));
+          SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
+          SVN_ERR(svn_sqlite__bind_properties(stmt, 3, base_props,
+                                              scratch_pool));
+          SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+
+          /* ### should we provide a nicer error message?  */
+          SVN_ERR_ASSERT(affected_rows == 1);
+#endif
+#ifdef SVN_WC__NODES
           SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                             STMT_UPDATE_NODE_WORKING_PROPS));
           SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
@@ -6525,6 +7147,7 @@
 
           /* ### should we provide a nicer error message?  */
           SVN_ERR_ASSERT(affected_rows == 1);
+#endif
         }
       /* else other states should have no properties.  */
       /* ### should we insert empty props for <= SVN_WC__NO_REVERT_FILES?  */
@@ -6544,8 +7167,13 @@
 
   if (working_props != NULL)
     {
-      SVN_ERR(set_actual_props(wc_id, local_relpath, working_props,
-                               sdb, scratch_pool));
+      struct set_props_baton spb = { 0 };
+
+      spb.props = working_props;
+      spb.wc_id = wc_id;
+      spb.local_relpath = local_relpath;
+      /* NULL for .conflict and .work_items  */
+      SVN_ERR(set_props_txn(&spb, sdb, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -7192,6 +7820,10 @@
   svn_wc__db_status_t base_status;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_nodes_row;
+#endif
 
   /* This uses an optimisation that first reads the working node and
      then may read the base node.  It could call svn_wc__db_read_info
@@ -7205,10 +7837,27 @@
   VERIFY_USABLE_PDH(pdh);
 
   /* First check the working node. */
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_SELECT_WORKING_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+                                    STMT_SELECT_WORKING_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_working_rows_match(have_row, have_nodes_row, stmt, stmt_nodes,
+                                    local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  have_row = have_nodes_row;
+#endif
+#endif
 
   if (have_row)
     {
@@ -7296,6 +7945,7 @@
   svn_wc__db_t *db;
   svn_wc__db_pdh_t *pdh;
   const char *local_relpath;
+  const char *local_abspath;
   int levels_to_lock;
   svn_boolean_t steal_lock;
 };
@@ -7349,8 +7999,7 @@
         return svn_error_createf(
                                  SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                  _("The node '%s' was not found."),
-                                 path_for_error_message(bt->pdh->wcroot,
-                                                        bt->local_relpath,
+                                 svn_dirent_local_style(bt->local_abspath,
                                                         scratch_pool));
     }
 
@@ -7407,8 +8056,7 @@
                                                           scratch_pool));
           return svn_error_createf(SVN_ERR_WC_LOCKED, err,
                                    _("Working copy '%s' locked."),
-                                   path_for_error_message(bt->pdh->wcroot,
-                                                          bt->local_relpath,
+                                   svn_dirent_local_style(bt->local_abspath,
                                                           scratch_pool));
         }
       else if (!own_lock)
@@ -7458,8 +8106,7 @@
               return svn_error_createf(
                               SVN_ERR_WC_LOCKED, err,
                               _("Working copy '%s' locked."),
-                              path_for_error_message(bt->pdh->wcroot,
-                                                     bt->local_relpath,
+                              svn_dirent_local_style(bt->local_abspath,
                                                      scratch_pool));
             }
 
@@ -7483,8 +8130,7 @@
   if (err)
     return svn_error_createf(SVN_ERR_WC_LOCKED, err,
                              _("Working copy '%s' locked"),
-                             path_for_error_message(bt->pdh->wcroot,
-                                                    bt->local_relpath,
+                             svn_dirent_local_style(bt->local_abspath,
                                                     scratch_pool));
 
   /* And finally store that we obtained the lock */
@@ -7546,6 +8192,7 @@
     }
 
   baton.db = db;
+  baton.local_abspath = local_abspath;
   baton.steal_lock = steal_lock;
   baton.levels_to_lock = levels_to_lock;
 
@@ -7741,7 +8388,9 @@
   svn_sqlite__stmt_t *stmt;
   svn_wc__db_pdh_t *pdh;
   int affected_rows;
+#ifdef SVN_WC__NODES
   int affected_node_rows;
+#endif
   svn_wc__db_status_t base_status;
 
   SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL, NULL, NULL, NULL,
@@ -7753,12 +8402,25 @@
   SVN_ERR_ASSERT(base_status == svn_wc__db_status_normal ||
                  base_status == svn_wc__db_status_incomplete);
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(get_statement_for_path(&stmt, db, local_dir_abspath,
+                                 STMT_UPDATE_BASE_PRESENCE, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_text(stmt, 3, incomplete ? "incomplete" : "normal"));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   SVN_ERR(get_statement_for_path(&stmt, db, local_dir_abspath,
                                  STMT_UPDATE_NODE_BASE_PRESENCE, scratch_pool));
   SVN_ERR(svn_sqlite__bind_text(stmt, 3, incomplete ? "incomplete" : "normal"));
   SVN_ERR(svn_sqlite__update(&affected_node_rows, stmt));
 
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR_ASSERT(affected_rows == affected_node_rows);
+#else
   affected_rows = affected_node_rows;
+#endif
+#endif
 
   if (affected_rows > 0)
    {
@@ -7788,22 +8450,73 @@
                            apr_pool_t *scratch_pool)
 {
   struct start_directory_update_baton *du = baton;
+  const char *repos_relpath;
   svn_sqlite__stmt_t *stmt;
 
-  /* Note: In the majority of calls, the repos_relpath is unchanged. */
-  /* ### TODO: Maybe check if we can make repos_relpath NULL. */
-  SVN_ERR(svn_sqlite__get_statement(
-               &stmt, db,
-               STMT_UPDATE_BASE_NODE_PRESENCE_REVNUM_AND_REPOS_PATH));
+  SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, NULL, NULL,
+                                     du->db, du->local_abspath,
+                                     scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_sqlite__bindf(stmt, "istis",
-                            du->wc_id,
-                            du->local_relpath,
-                            presence_map, svn_wc__db_status_incomplete,
-                            (apr_int64_t)du->new_rev,
-                            du->new_repos_relpath));
-  SVN_ERR(svn_sqlite__step_done(stmt));
+  if (strcmp(du->new_repos_relpath, repos_relpath) == 0)
+    {
+#ifndef SVN_WC__NODES_ONLY
+      /* Just update revision and status */
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, db,
+                        STMT_UPDATE_BASE_PRESENCE_AND_REVNUM));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "isti",
+                                du->wc_id,
+                                du->local_relpath,
+                                presence_map, svn_wc__db_status_incomplete,
+                                (apr_int64_t)du->new_rev));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+      /* Just update revision and status */
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, db,
+                        STMT_UPDATE_BASE_NODE_PRESENCE_AND_REVNUM));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "isti",
+                                du->wc_id,
+                                du->local_relpath,
+                                presence_map, svn_wc__db_status_incomplete,
+                                (apr_int64_t)du->new_rev));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+    }
+  else
+    {
+#ifndef SVN_WC__NODES_ONLY
+      /* ### TODO: Maybe check if we can make repos_relpath NULL. */
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, db,
+                        STMT_UPDATE_BASE_PRESENCE_REVNUM_AND_REPOS_RELPATH));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "istis",
+                                du->wc_id,
+                                du->local_relpath,
+                                presence_map, svn_wc__db_status_incomplete,
+                                (apr_int64_t)du->new_rev,
+                                du->new_repos_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+      /* ### TODO: Maybe check if we can make repos_relpath NULL. */
+      SVN_ERR(svn_sqlite__get_statement(
+                   &stmt, db,
+                   STMT_UPDATE_BASE_NODE_PRESENCE_REVNUM_AND_REPOS_PATH));
 
+      SVN_ERR(svn_sqlite__bindf(stmt, "istis",
+                                du->wc_id,
+                                du->local_relpath,
+                                presence_map, svn_wc__db_status_incomplete,
+                                (apr_int64_t)du->new_rev,
+                                du->new_repos_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+    }
   return SVN_NO_ERROR;
 }
 
@@ -7869,11 +8582,33 @@
   const apr_array_header_t *children;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   int i;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_nodes_row;
+#endif
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WORKING_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", mcb->pdh->wcroot->wc_id,
                             mcb->local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+                                    STMT_SELECT_WORKING_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", mcb->pdh->wcroot->wc_id,
+                            mcb->local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_working_rows_match(have_row, have_nodes_row,
+                                    stmt, stmt_nodes,
+                                    mcb->local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  have_row = have_nodes_row;
+#endif
+#endif
 
   if (have_row)
     {
@@ -7903,11 +8638,28 @@
     {
       svn_wc__db_status_t base_status;
 
-      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                        STMT_SELECT_BASE_NODE));
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_BASE_NODE));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", mcb->pdh->wcroot->wc_id, 
                                 mcb->local_relpath));
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, sdb,
+                                        STMT_SELECT_BASE_NODE_1));
+      SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is", mcb->pdh->wcroot->wc_id, 
+                                mcb->local_relpath));
+      SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(assert_base_rows_match(have_row, have_nodes_row,
+                                     stmt, stmt_nodes,
+                                     mcb->local_relpath, scratch_pool));
+      SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+      stmt = stmt_nodes;
+      have_row = have_nodes_row;
+#endif
+#endif
 
       /* If there is no BASE_NODE, we don't have to copy anything */
       if (!have_row)
@@ -7965,17 +8717,44 @@
 
   if (remove_working)
     {
+
+#ifndef SVN_WC__NODES_ONLY
+      /* Remove current WORKING_NODE record */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_DELETE_WORKING_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                         STMT_DELETE_WORKING_NODES));
       SVN_ERR(svn_sqlite__bindf(stmt, "is",
                                 mcb->pdh->wcroot->wc_id,
                                 mcb->local_relpath));
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
     }
 
   if (add_working_normal)
     {
       /* Add a copy of the BASE_NODE to WORKING_NODE */
+
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, sdb,
+                        STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
       SVN_ERR(svn_sqlite__get_statement(
                     &stmt, sdb,
                     STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE));
@@ -7986,10 +8765,26 @@
                                 (apr_int64_t)2)); /* ### temporary op_depth */
 
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
     }
   else if (add_working_not_present)
     {
       /* Add a not present WORKING_NODE */
+
+#ifndef SVN_WC__NODES_ONLY
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, sdb,
+                        STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
       SVN_ERR(svn_sqlite__get_statement(
                 &stmt, sdb,
                 STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE));
@@ -8000,6 +8795,8 @@
                                 (apr_int64_t)2)); /* ### temporary op_depth */
 
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
     }
 
   if (mcb->is_root && (add_working_normal || add_working_not_present))
@@ -8018,7 +8815,8 @@
                               iterpool));
 
       /* ### this is not setting the COPYFROM_REVISION column!!  */
-      /* ### The regression tests passed without this, is it necessary? */
+
+#ifndef SVN_WC__NODES_ONLY
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_COPYFROM));
       SVN_ERR(svn_sqlite__bindf(stmt, "isis",
                                 mcb->pdh->wcroot->wc_id,
@@ -8026,17 +8824,41 @@
                                 repos_id,
                                 repos_relpath));
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+      /* ### The regression tests passed without this, is it necessary? */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_COPYFROM_1));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isis",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath,
+                                repos_id,
+                                repos_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
     }
 
   /* Remove the BASE_NODE if the caller asked us to do that */
   if (mcb->remove_base)
     {
+#ifndef SVN_WC__NODES_ONLY
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                         STMT_DELETE_BASE_NODE));
       SVN_ERR(svn_sqlite__bindf(stmt, "is",
                                 mcb->pdh->wcroot->wc_id,
                                 mcb->local_relpath));
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_DELETE_BASE_NODE_1));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                mcb->pdh->wcroot->wc_id,
+                                mcb->local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
     }
 
   SVN_ERR(flush_entries(mcb->db, mcb->pdh, mcb->local_abspath, iterpool));
@@ -8088,6 +8910,10 @@
   const char *local_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_nodes_row;
+#endif
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
@@ -8097,10 +8923,27 @@
                                              scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_SELECT_WORKING_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+                                    STMT_SELECT_WORKING_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_working_rows_match(have_row, have_nodes_row, stmt, stmt_nodes,
+                                    local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  have_row = have_nodes_row;
+#endif
+#endif
   if (!have_row)
     {
       *copyfrom_repos_id = 0;  /* What's a good value to return? */
@@ -8122,18 +8965,16 @@
                            db, parent_abspath, scratch_pool, scratch_pool));
       if (parent_copyfrom_relpath)
         *copyfrom_relpath = svn_relpath_join(parent_copyfrom_relpath, name,
-                                             result_pool);
+                                             scratch_pool);
       else
         *copyfrom_relpath = NULL;
       return SVN_NO_ERROR;
     }
 
   *copyfrom_repos_id = svn_sqlite__column_int64(stmt, 9);
-  *copyfrom_relpath = svn_sqlite__column_text(stmt, 10, result_pool);
+  *copyfrom_relpath = svn_sqlite__column_text(stmt, 10, scratch_pool);
   *copyfrom_revnum = svn_sqlite__column_revnum(stmt, 11);
 
-  SVN_ERR(svn_sqlite__reset(stmt));
-
   return SVN_NO_ERROR;
 }
 
@@ -8147,6 +8988,10 @@
   const char *local_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_node;
+  svn_boolean_t have_node_row;
+#endif
   apr_int64_t original_repos_id;
   const char *original_repos_relpath;
   svn_revnum_t original_revision;
@@ -8166,10 +9011,28 @@
 
   /* Examine the current WORKING_NODE row's copyfrom information. If there
      is no WORKING node, then simply exit.  */
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_SELECT_WORKING_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_node, pdh->wcroot->sdb,
+                                    STMT_SELECT_WORKING_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_node, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_node_row, stmt_node));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_working_rows_match(have_row, have_node_row, stmt, stmt_node,
+                                    local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_node));
+#else
+  stmt = stmt_node;
+  have_row = have_node_row;
+#endif
+#endif
 
   if (!have_row)
     return svn_error_return(svn_sqlite__reset(stmt));
@@ -8220,12 +9083,22 @@
 
   /* The child's copyfrom information is derivable from the parent.
      The data should be reset to null, indicating the derivation.  */
-  /* Should probably use the op_depth from query above and simplify this
-     query. */
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_UPDATE_COPYFROM_TO_INHERIT));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__update(NULL, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+  /* Should probably use the op_depth from query above and simplify this
+     query. */
+  SVN_ERR(svn_sqlite__get_statement(&stmt_node, pdh->wcroot->sdb,
+                                    STMT_UPDATE_COPYFROM_TO_INHERIT_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_node, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__update(NULL, stmt_node));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -8240,10 +9113,28 @@
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t have_nodes_row;
+#endif
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(get_statement_for_path(&stmt, db, local_abspath,
                                  STMT_SELECT_FILE_EXTERNAL, scratch_pool));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(get_statement_for_path(&stmt_nodes, db, local_abspath,
+                                 STMT_SELECT_FILE_EXTERNAL_1, scratch_pool));
+  SVN_ERR(svn_sqlite__step(&have_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_text_columns_equal(stmt, stmt_nodes, 0, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  have_row = have_nodes_row;
+#endif
+#endif
 
   /* ### file externals are pretty bogus right now. they have just a
      ### WORKING_NODE for a while, eventually settling into just a BASE_NODE.
@@ -8280,6 +9171,10 @@
   const char *local_relpath;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t got_row;
+#ifdef SVN_WC__NODES
+  svn_sqlite__stmt_t *stmt_nodes;
+  svn_boolean_t got_nodes_row;
+#endif
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(!repos_relpath 
@@ -8291,10 +9186,27 @@
                                              scratch_pool, scratch_pool));
   VERIFY_USABLE_PDH(pdh);
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_SELECT_BASE_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
   SVN_ERR(svn_sqlite__step(&got_row, stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt_nodes, pdh->wcroot->sdb,
+                                    STMT_SELECT_BASE_NODE_1));
+  SVN_ERR(svn_sqlite__bindf(stmt_nodes, "is",
+                            pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&got_nodes_row, stmt_nodes));
+#ifndef SVN_WC__NODES_ONLY
+  SVN_ERR(assert_base_rows_match(got_row, got_nodes_row, stmt, stmt_nodes,
+                                 local_relpath, scratch_pool));
+  SVN_ERR(svn_sqlite__reset(stmt_nodes));
+#else
+  stmt = stmt_nodes;
+  got_row = got_nodes_row;
+#endif
+#endif
   SVN_ERR(svn_sqlite__reset(stmt));
 
   if (!got_row)
@@ -8312,6 +9224,27 @@
       SVN_ERR(create_repos_id(&repos_id, repos_root_url, repos_uuid,
                               pdh->wcroot->sdb, scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
+      /* ### Insert a switched not present base node. Luckily this hack
+             is not as ugly as the original file externals hack. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                        STMT_INSERT_BASE_NODE));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "isisstt",
+                                pdh->wcroot->wc_id,
+                                local_relpath,
+                                repos_id,
+                                repos_relpath,
+                                svn_relpath_dirname(local_relpath,
+                                                    scratch_pool),
+                                presence_map, svn_wc__db_status_not_present,
+                                kind_map, svn_wc__db_kind_file));
+
+      SVN_ERR(svn_sqlite__insert(NULL, stmt));
+#endif
+
+#ifdef SVN_WC__NODES
+
       SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                         STMT_INSERT_NODE));
 
@@ -8327,8 +9260,11 @@
                                 kind_map, svn_wc__db_kind_file));
 
       SVN_ERR(svn_sqlite__insert(NULL, stmt));
+
+#endif
     }
 
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
                                     STMT_UPDATE_FILE_EXTERNAL));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id,
@@ -8346,6 +9282,26 @@
       SVN_ERR(svn_sqlite__bind_text(stmt, 3, str));
     }
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_UPDATE_FILE_EXTERNAL_1));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id,
+                            local_relpath));
+  if (repos_relpath)
+    {
+      const char *str;
+
+      SVN_ERR(svn_wc__serialize_file_external(&str,
+                                              repos_relpath,
+                                              peg_rev,
+                                              rev,
+                                              scratch_pool));
+
+      SVN_ERR(svn_sqlite__bind_text(stmt, 3, str));
+    }
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
 
   SVN_ERR(flush_entries(db, pdh, local_abspath, scratch_pool));
 
@@ -8493,6 +9449,7 @@
 
   if (SVN_IS_VALID_REVNUM(rrb->rev))
     {
+#ifndef SVN_WC__NODES_ONLY
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                         STMT_UPDATE_BASE_REVISION));
 
@@ -8501,6 +9458,17 @@
                                              (apr_int64_t)rrb->rev));
 
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_UPDATE_BASE_REVISION_1));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "isi", rrb->pdh->wcroot->wc_id,
+                                             rrb->local_relpath,
+                                             (apr_int64_t)rrb->rev));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
     }
 
   if (rrb->set_repos_relpath)
@@ -8509,6 +9477,7 @@
       SVN_ERR(create_repos_id(&repos_id, rrb->repos_root_url, rrb->repos_uuid,
                               rrb->pdh->wcroot->sdb, scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                         STMT_UPDATE_BASE_REPOS));
 
@@ -8518,6 +9487,18 @@
                                               rrb->repos_relpath));
 
       SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+#ifdef SVN_WC__NODES
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_UPDATE_BASE_REPOS_1));
+
+      SVN_ERR(svn_sqlite__bindf(stmt, "isis", rrb->pdh->wcroot->wc_id,
+                                              rrb->local_relpath,
+                                              repos_id,
+                                              rrb->repos_relpath));
+
+      SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
     }
 
   return SVN_NO_ERROR;
@@ -8587,13 +9568,52 @@
   SVN_ERR(create_repos_id(&repos_id, dtb->repos_root_url, dtb->repos_uuid,
                           sdb, scratch_pool));
 
+#ifndef SVN_WC__NODES_ONLY
+  /* Delete the working node */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, dtb->pdh->wcroot->sdb,
+                                    STMT_DELETE_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", dtb->pdh->wcroot->wc_id,
+                                        dtb->local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  /* Delete the base node if there is a not present one */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, dtb->pdh->wcroot->sdb,
+                                    STMT_DELETE_BASE_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", dtb->pdh->wcroot->wc_id,
+                                        dtb->local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifdef SVN_WC__NODES
   /* Delete the base and working node data */
   SVN_ERR(svn_sqlite__get_statement(&stmt, dtb->pdh->wcroot->sdb,
                                     STMT_DELETE_NODES));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", dtb->pdh->wcroot->wc_id,
                             dtb->local_relpath));
   SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
+#ifndef SVN_WC__NODES_ONLY
+  /* Insert the incomplete base node */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, dtb->pdh->wcroot->sdb,
+                                    STMT_INSERT_BASE_NODE_INCOMPLETE_DIR));
+
+  SVN_ERR(svn_sqlite__bindf(stmt, "isissi", dtb->pdh->wcroot->wc_id,
+                                            dtb->local_relpath,
+                                            repos_id,
+                                            dtb->repos_relpath,
+                                            parent_relpath,
+                                            (apr_int64_t)dtb->revision));
+
+  /* If depth is not unknown: record depth */
+  if (dtb->depth >= svn_depth_empty && dtb->depth <= svn_depth_infinity)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 7, svn_depth_to_word(dtb->depth)));
+
+  SVN_ERR(svn_sqlite__step_done(stmt));
+#endif
+
 
+#ifdef SVN_WC__NODES
   /* Insert the incomplete base node */
   SVN_ERR(svn_sqlite__get_statement(&stmt, dtb->pdh->wcroot->sdb,
                                     STMT_INSERT_NODE));
@@ -8616,6 +9636,8 @@
 
   SVN_ERR(svn_sqlite__step_done(stmt));
 
+#endif
+
   return SVN_NO_ERROR;
 }
 
Index: subversion/libsvn_wc/wc_db.h
===================================================================
--- subversion/libsvn_wc/wc_db.h	(revision 1023844)
+++ subversion/libsvn_wc/wc_db.h	(revision 1005387)
@@ -46,8 +46,6 @@
 #include "private/svn_skel.h"
 #include "private/svn_sqlite.h"
 
-#include "svn_private_config.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -1006,6 +1004,28 @@
 /* @} */
 
 
+/* @defgroup svn_wc__db_repos  Repository information management
+   @{
+*/
+
+/* Ensure an entry for the repository at REPOS_ROOT_URL with UUID exists
+   in DB for LOCAL_ABSPATH, either by finding the correct row, or inserting
+   a new row.  In either case return the id in *REPOS_ID.
+
+   Use SCRATCH_POOL for temporary allocations.
+*/
+svn_error_t *
+svn_wc__db_repos_ensure(apr_int64_t *repos_id,
+                        svn_wc__db_t *db,
+                        const char *local_abspath,
+                        const char *repos_root_url,
+                        const char *repos_uuid,
+                        apr_pool_t *scratch_pool);
+
+
+/* @} */
+
+
 /* @defgroup svn_wc__db_op  Operations on WORKING tree
    @{
 */
@@ -1122,9 +1142,6 @@
    To specify no properties, PROPS must be an empty hash, not NULL.
    If the node is not present, return an error.
 
-   If PROPS is NULL, set the properties to be the same as the pristine
-   properties.
-
    CONFLICT is used to register a conflict on this node at the same time
    the properties are changed.
 
@@ -1237,16 +1254,6 @@
                             apr_pool_t *scratch_pool);
 
 
-/* Revert all local changes which are being maintained in the database,
- * including conflict storage, properties and text modification status.
- */
-svn_error_t *
-svn_wc__db_op_revert_actual(svn_wc__db_t *db,
-                            const char *local_abspath,
-                            apr_pool_t *scratch_pool);
-
-
-
 svn_error_t *
 svn_wc__db_op_revert(svn_wc__db_t *db,
                      const char *local_abspath,
@@ -1487,41 +1494,6 @@
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool);
 
-/* Structure returned by svn_wc__db_read_children_info.  Only has the
-   fields needed by status. */
-struct svn_wc__db_info_t {
-  svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
-  svn_revnum_t revnum;
-  const char *repos_relpath;
-  const char *repos_root_url;
-  svn_revnum_t changed_rev;
-  const char *changed_author;
-  apr_time_t changed_date;
-  apr_time_t last_mod_time;
-  svn_depth_t depth;
-  svn_filesize_t translated_size;
-  const char *changelist;
-  svn_boolean_t has_props;
-#ifdef HAVE_SYMLINK
-  svn_boolean_t special;
-#endif
-  svn_boolean_t props_mod;
-  svn_boolean_t have_base;
-  svn_boolean_t conflicted;
-  svn_wc__db_lock_t *lock;
-};
-
-/* Return in *NODES a hash mapping name->struct svn_wc__db_info_t for
-   the children of DIR_ABSPATH, and in *CONFLICTS a hash of names in
-   conflict.  */
-svn_error_t *
-svn_wc__db_read_children_info(apr_hash_t **nodes,
-                              apr_hash_t **conflicts,
-                              svn_wc__db_t *db,
-                              const char *dir_abspath,
-                              apr_pool_t *result_pool,
-                              apr_pool_t *scratch_pool);
 
 /* Set *PROPVAL to the value of the property named PROPNAME of the node
    LOCAL_ABSPATH in the ACTUAL tree (looking through to the WORKING or BASE
Index: subversion/libsvn_wc/node.c
===================================================================
--- subversion/libsvn_wc/node.c	(revision 1023844)
+++ subversion/libsvn_wc/node.c	(revision 1005387)
@@ -1122,22 +1122,14 @@
                            apr_pool_t *scratch_pool)
 {
   svn_wc__db_lock_t *lock;
-  svn_error_t *err;
-
-  err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 &lock,
-                                 wc_ctx->db, local_abspath,
-                                 result_pool, scratch_pool);
 
-  if (err)
-    {
-      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-        return svn_error_return(err);
-
-      svn_error_clear(err);
-      lock = NULL;
-    }
+  SVN_ERR(svn_wc__db_read_info(NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, &lock,
+                               wc_ctx->db, local_abspath,
+                               result_pool, scratch_pool));
   if (lock_token)
     *lock_token = lock ? lock->token : NULL;
   if (lock_owner)
Index: subversion/libsvn_wc/upgrade.c
===================================================================
--- subversion/libsvn_wc/upgrade.c	(revision 1023844)
+++ subversion/libsvn_wc/upgrade.c	(revision 1005387)
@@ -346,7 +346,11 @@
   svn_boolean_t have_row;
 
   /* ### just select 'file' children. do we need 'symlink' in the future?  */
+#ifndef SVN_WC__NODES_ONLY
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ALL_FILES));
+#else
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ALL_FILES_1));
+#endif
   SVN_ERR(svn_sqlite__bindf(stmt, "s", parent_relpath));
 
   /* ### 10 is based on Subversion's average of 8.5 files per versioned
Index: subversion/libsvn_wc/workqueue.c
===================================================================
--- subversion/libsvn_wc/workqueue.c	(revision 1023844)
+++ subversion/libsvn_wc/workqueue.c	(revision 1005387)
@@ -181,23 +181,18 @@
 {
   const svn_skel_t *arg1 = work_item->children->next;
   const char *local_abspath;
+  svn_boolean_t replaced;
   svn_wc__db_kind_t kind;
   svn_wc__db_status_t status;
   const char *parent_abspath;
   svn_boolean_t conflicted;
   apr_int64_t val;
-  svn_boolean_t reinstall_working;
-  svn_boolean_t remove_working;
 
   /* We need a NUL-terminated path, so copy it out of the skel.  */
   local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
-
   SVN_ERR(svn_skel__parse_int(&val, arg1->next, scratch_pool));
-  remove_working = (val != 0);
-
-  SVN_ERR(svn_skel__parse_int(&val, arg1->next->next, scratch_pool));
-  reinstall_working = (val != 0);
-
+  replaced = (val != 0);
+  /* magic_changed is extracted further below.  */
   /* use_commit_times is extracted further below.  */
 
   /* NOTE: we can read KIND here since uncommitted kind changes are not
@@ -211,50 +206,73 @@
             db, local_abspath,
             scratch_pool, scratch_pool));
 
-  if (kind == svn_wc__db_kind_dir)
-    {
-      parent_abspath = local_abspath;
-    }
-  else
-    {
-      parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-    }
+  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, NULL, NULL, NULL,
+                                  scratch_pool));
 
-  if (conflicted)
+  /* Deal with the working file, as needed.  */
+  if (kind == svn_wc__db_kind_file)
     {
-      const apr_array_header_t *conflicts;
-      int i;
+      svn_boolean_t magic_changed;
+      svn_boolean_t reinstall_working;
 
-      SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
-                                        scratch_pool, scratch_pool));
+      SVN_ERR(svn_skel__parse_int(&val, arg1->next->next, scratch_pool));
+      magic_changed = (val != 0);
 
-      for (i = 0; i < conflicts->nelts; i++)
-        {
-          const svn_wc_conflict_description2_t *cd;
+      /* If there was a magic property change, then we'll reinstall the
+         working-file to pick up any/all appropriate changes. If there was
+         a replacement, then we definitely want to reinstall the working-file
+         using the original base.  */
+      reinstall_working = magic_changed || replaced;
 
-          cd = APR_ARRAY_IDX(conflicts, i,
-                             const svn_wc_conflict_description2_t *);
+      /* ### This "if (replaced)" looks very likely to be an artifact of the
+         old WC-1 "revert-base and normal-base" system, and if so then it
+         should go away. */
+      if (replaced)
+        {
+          /* With the Pristine Store, there is no longer a "revert-base"
+             text that needs to be moved to a "normal text-base" location.
 
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->base_file,
-                                        local_abspath, scratch_pool));
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->their_file,
-                                        local_abspath, scratch_pool));
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->my_file,
-                                        local_abspath, scratch_pool));
-          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->merged_file,
-                                        local_abspath, scratch_pool));
+             ### JAF: I wonder why the "revert-base" properties weren't being
+             handled the same way in this same code path.  An oversight? */
         }
-    }
+      else if (!reinstall_working)
+        {
+          svn_node_kind_t check_kind;
 
-  /* Reverting the actual node destroys conflict markers and local props.
-     Don't use svn_wc__db_op_set_props() and svn_wc__db_op_mark_resolved()
-     because those leave a record in the ACTUALS table, which is a
-     performance issue.  Besides, this does all that in one blow. */
-  SVN_ERR(svn_wc__db_op_revert_actual(db, local_abspath, scratch_pool));
+          /* If the working file is missing, we need to reinstall it.  */
+          SVN_ERR(svn_io_check_path(local_abspath, &check_kind,
+                                    scratch_pool));
+          reinstall_working = (check_kind == svn_node_none);
 
-  /* Deal with the working file, as needed.  */
-  if (kind == svn_wc__db_kind_file)
-    {
+          if (!reinstall_working)
+            {
+              /* ### can we optimize this call? we already fetched some
+                 ### info about the node. and *definitely* never want a
+                 ### full file-scan.  */
+
+              /* ### for now, just always reinstall. without some extra work,
+                 ### we could end up in a situation where the file is copied
+                 ### from the base, but then something fails immediately
+                 ### after that. on the second time through here, we would
+                 ### see the file is "the same" and fail to complete those
+                 ### follow-on actions. in some future work, examine the
+                 ### points of failure, and possibly precompue the
+                 ### "reinstall_working" flag, or maybe do some follow-on
+                 ### actions unconditionally.  */
+#if 1
+              reinstall_working = TRUE;
+#endif
+#if 0
+              /* ### try to avoid altering the timestamp if the intended
+                 ### contents are the same as current-contents.  */
+              SVN_ERR(svn_wc__text_modified_internal_p(&reinstall_working,
+                                                       db, local_abspath,
+                                                       FALSE, FALSE,
+                                                       scratch_pool));
+#endif
+            }
+        }
+
       if (reinstall_working)
         {
           svn_boolean_t use_commit_times;
@@ -278,25 +296,79 @@
     {
       SVN__NOT_IMPLEMENTED();
     }
-  else if (reinstall_working && kind == svn_wc__db_kind_dir)
+  else if (kind == svn_wc__db_kind_dir)
     {
-      svn_node_kind_t on_disk;
+      svn_node_kind_t disk_kind;
+      SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
 
-      /* Unfortunately we need another stat(), because I don't want
-         to resort to APR error macros to see if we're creating a
-         directory on top of an existing path */
-      SVN_ERR(svn_io_check_path(local_abspath, &on_disk, scratch_pool));
-      if (on_disk == svn_node_none)
+      if (disk_kind == svn_node_none)
         SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
     }
 
+  if (kind == svn_wc__db_kind_dir)
+    parent_abspath = local_abspath;
+  else
+    parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
-  if (remove_working)
+  /* ### in wc-ng: the following block clears ACTUAL_NODE.  */
+  if (conflicted)
     {
-      SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
-                                                scratch_pool));
+      const apr_array_header_t *conflicts;
+      int i;
+
+      SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
+                                        scratch_pool, scratch_pool));
+
+      for (i = 0; i < conflicts->nelts; i++)
+        {
+          const svn_wc_conflict_description2_t *cd;
+
+          cd = APR_ARRAY_IDX(conflicts, i,
+                             const svn_wc_conflict_description2_t *);
+
+          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->base_file,
+                                        local_abspath, scratch_pool));
+          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->their_file,
+                                        local_abspath, scratch_pool));
+          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->my_file,
+                                        local_abspath, scratch_pool));
+          SVN_ERR(maybe_remove_conflict(parent_abspath, cd->merged_file,
+                                        local_abspath, scratch_pool));
+        }
+
+      SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
+                                          TRUE, TRUE, FALSE,
+                                          scratch_pool));
     }
 
+  {
+    svn_boolean_t is_wc_root;
+
+    SVN_ERR(svn_wc__check_wc_root(&is_wc_root, NULL, NULL,
+                                  db, local_abspath, scratch_pool));
+
+    /* Remove the WORKING_NODE from the node and (if there) its parent stub */
+    /* ### A working copy root can't have a working node and trying
+       ### to delete it fails because the root doesn't have a stub. */
+    if (!is_wc_root)
+      {
+        const char *op_root_abspath = NULL;
+
+        /* If the node is not the operation root, we should not delete
+           the working node */
+        if (status == svn_wc__db_status_added)
+          SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+        if (!op_root_abspath
+            || (strcmp(op_root_abspath, local_abspath) == 0))
+          SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
+                                                    scratch_pool));
+      }
+  }
+
   return SVN_NO_ERROR;
 }
 
@@ -345,7 +417,6 @@
 svn_error_t *
 svn_wc__wq_add_revert(svn_boolean_t *will_revert,
                       svn_wc__db_t *db,
-                      const char *revert_root,
                       const char *local_abspath,
                       svn_boolean_t use_commit_times,
                       apr_pool_t *scratch_pool)
@@ -353,8 +424,7 @@
   svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
   svn_boolean_t replaced;
-  svn_boolean_t remove_working = FALSE;
-  svn_boolean_t reinstall_working;
+  svn_boolean_t magic_changed = FALSE;
 
   SVN_ERR(svn_wc__db_read_info(
             &status, &kind, NULL, NULL, NULL, NULL,
@@ -364,11 +434,8 @@
             db, local_abspath,
             scratch_pool, scratch_pool));
 
-  /* Special handling for issue #2101, which is specifically
-     about reverting copies of 'deleted' files and dirs, being inserted
-     in the copy as a schedule-delete files, yet can't be reverted. */
-  if (kind == svn_wc__db_kind_file
-      && status == svn_wc__db_status_deleted)
+  /* Special handling for issue #2101.  */
+  if (kind == svn_wc__db_kind_file)
     SVN_ERR(verify_pristine_present(db, local_abspath, scratch_pool));
 
   /* Gather a few items *before* the revert work-item has a chance to run.
@@ -379,9 +446,9 @@
                                        scratch_pool));
 
   /* If a replacement has occurred, then a revert definitely happens.  */
-  *will_revert = reinstall_working = replaced;
+  *will_revert = replaced;
 
-  if (status == svn_wc__db_status_normal)
+  if (!replaced)
     {
       apr_hash_t *base_props;
       apr_hash_t *working_props;
@@ -395,64 +462,50 @@
                                        scratch_pool, scratch_pool));
       SVN_ERR(svn_prop_diffs(&prop_diffs, working_props, base_props,
                              scratch_pool));
-      if (svn_wc__has_magic_property(prop_diffs))
-        reinstall_working = TRUE;
+      magic_changed = svn_wc__has_magic_property(prop_diffs);
 
       if (prop_diffs->nelts > 0)
         {
           /* Property changes cause a revert to occur.  */
           *will_revert = TRUE;
         }
-    }
-  else
-    {
-      *will_revert = TRUE;
-      if (status != svn_wc__db_status_added)
-        reinstall_working = TRUE;
-    }
-
-  /* We may need to restore a missing working file.  */
-  if (! reinstall_working
-      && status != svn_wc__db_status_added)
-    {
-      svn_node_kind_t on_disk;
-
-      SVN_ERR(svn_io_check_path(local_abspath, &on_disk, scratch_pool));
-      reinstall_working = on_disk == svn_node_none;
-      *will_revert = *will_revert || reinstall_working;
-    }
-
-  if (! reinstall_working
-      && status == svn_wc__db_status_normal)
-    {
-      /* ### there may be ways to simplify this test, rather than
-         ### doing file comparisons and junk... */
-      SVN_ERR(svn_wc__internal_text_modified_p(&reinstall_working,
-                                               db, local_abspath,
-                                               FALSE, FALSE,
-                                               scratch_pool));
-      *will_revert = *will_revert || reinstall_working;
-    }
-
+      else
+        {
+          /* There is nothing to do for NORMAL or ADDED nodes. Typically,
+             we won't even be called for added nodes (since a revert
+             simply removes it from version control), but it is possible
+             that a parent replacement was turned from a replaced copy
+             into a normal node, and the (broken) old ENTRY->COPIED logic
+             then turns the copied children into typical ADDED nodes.
+             Since the recursion has already started, these children are
+             visited (unlike most added nodes).  */
+          if (status != svn_wc__db_status_normal
+              && status != svn_wc__db_status_added)
+            {
+              *will_revert = TRUE;
+            }
 
-  if (status == svn_wc__db_status_added)
-    {
-      /* When looking at an added, non-replacing node, it's entry
-         will have to be removed after revert: if not, it'll look
-         like it's still under version control. */
-      const char *op_root_abspath;
+          /* We may need to restore a missing working file.  */
+          if (! *will_revert)
+            {
+              svn_node_kind_t on_disk;
 
-      SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
-                                       NULL, NULL, NULL, NULL, NULL,
-                                       db, local_abspath,
-                                       scratch_pool, scratch_pool));
+              SVN_ERR(svn_io_check_path(local_abspath, &on_disk,
+                                        scratch_pool));
+              *will_revert = on_disk == svn_node_none;
+            }
 
-      if (svn_dirent_is_ancestor(revert_root, op_root_abspath))
-        remove_working = TRUE;
+          if (! *will_revert)
+            {
+              /* ### there may be ways to simplify this test, rather than
+                 ### doing file comparisons and junk... */
+              SVN_ERR(svn_wc__internal_text_modified_p(will_revert,
+                                                       db, local_abspath,
+                                                       FALSE, FALSE,
+                                                       scratch_pool));
+            }
+        }
     }
-  else
-    remove_working = TRUE;
-
 
   /* Don't even bother to queue a work item if there is nothing to do.  */
   if (*will_revert)
@@ -464,8 +517,8 @@
       /* These skel atoms hold references to very transitory state, but
          we only need the work_item to survive for the duration of wq_add.  */
       svn_skel__prepend_int(use_commit_times, work_item, scratch_pool);
-      svn_skel__prepend_int(reinstall_working, work_item, scratch_pool);
-      svn_skel__prepend_int(remove_working, work_item, scratch_pool);
+      svn_skel__prepend_int(magic_changed, work_item, scratch_pool);
+      svn_skel__prepend_int(replaced, work_item, scratch_pool);
       svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
       svn_skel__prepend_str(OP_REVERT, work_item, scratch_pool);
 
Index: subversion/libsvn_wc/workqueue.h
===================================================================
--- subversion/libsvn_wc/workqueue.h	(revision 1023844)
+++ subversion/libsvn_wc/workqueue.h	(revision 1005387)
@@ -188,12 +188,10 @@
                                  apr_pool_t *result_pool);
 
 
-/* Record a work item to revert LOCAL_ABSPATH;
-   REVERT_ROOT designates the root of the entire revert operation. */
+/* Record a work item to revert LOCAL_ABSPATH.  */
 svn_error_t *
 svn_wc__wq_add_revert(svn_boolean_t *will_revert,
                       svn_wc__db_t *db,
-                      const char *revert_root,
                       const char *local_abspath,
                       svn_boolean_t use_commit_times,
                       apr_pool_t *scratch_pool);
Index: subversion/libsvn_client/merge.c
===================================================================
--- subversion/libsvn_client/merge.c	(revision 1023844)
+++ subversion/libsvn_client/merge.c	(revision 1005387)
@@ -8028,18 +8028,7 @@
                    apr_pool_t *pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
-
-  /* The range defining the mergeinfo we will record to describe the merge
-     (assuming we are recording mergeinfo
-
-     Note: This may be a subset of REVISION1:REVISION2 if
-     populate_remaining_ranges() determines that some part of
-     REVISION1:REVISION2 has already been wholly merged to TARGET_ABSPATH.
-     Also, the actual editor drive(s) may be a subset of RANGE, if
-     remove_noop_subtree_ranges() and/or fix_deleted_subtree_ranges()
-     further tweak things. */
   svn_merge_range_t range;
-
   svn_ra_session_t *ra_session;
   svn_client__merge_path_t *target_merge_path;
   svn_boolean_t is_rollback = (revision1 > revision2);
@@ -8112,22 +8101,17 @@
 
   if (honor_mergeinfo && !merge_b->reintegrate_merge)
     {
-      svn_revnum_t new_range_start, start_rev, end_rev;
+      svn_revnum_t start_rev, end_rev;
       apr_pool_t *iterpool = svn_pool_create(pool);
 
-      /* The merge target TARGET_ABSPATH and/or its subtrees may not need all
+      /* The merge target target_wcpath and/or its subtrees may not need all
          of REVISION1:REVISION2 applied.  So examine
          NOTIFY_B->CHILDREN_WITH_MERGEINFO to find the oldest starting
          revision that actually needs to be merged (for reverse merges this is
-         the youngest starting revision).
-         
-         We'll do this twice, right now for the start of the mergeinfo we will
-         ultimately record to describe this merge and then later for the 
-         start of the actual editor drive. */
-      new_range_start = get_most_inclusive_start_rev(
-        notify_b->children_with_mergeinfo, is_rollback);
-      if (SVN_IS_VALID_REVNUM(new_range_start))
-        range.start = new_range_start;
+         the youngest starting revision). */
+      start_rev =
+        get_most_inclusive_start_rev(notify_b->children_with_mergeinfo,
+                                     is_rollback);
 
       /* Remove inoperative ranges from any subtrees' remaining_ranges
          to spare the expense of noop editor drives. */
@@ -8137,20 +8121,16 @@
                                            notify_b, merge_b,
                                            pool, iterpool));
 
-      /* Adjust subtrees' remaining_ranges to deal with issue #3067 */
       SVN_ERR(fix_deleted_subtree_ranges(url1, revision1, url2, revision2,
                                          ra_session, notify_b, merge_b, pool));
 
-      /* remove_noop_subtree_ranges() and/or fix_deleted_subtree_range()
-         may have further refined the starting revision for our editor
-         drive. */
-      start_rev =
-        get_most_inclusive_start_rev(notify_b->children_with_mergeinfo,
-                                     is_rollback);
-
       /* Is there anything to merge? */
       if (SVN_IS_VALID_REVNUM(start_rev))
         {
+          /* Adjust range to describe the start of our most
+             inclusive merge. */
+          range.start = start_rev;
+
           /* Now examine NOTIFY_B->CHILDREN_WITH_MERGEINFO to find the youngest
              ending revision that actually needs to be merged (for reverse
              merges this is the oldest starting revision). */
@@ -8190,33 +8170,6 @@
               svn_revnum_t next_end_rev;
               const char *real_url1 = url1, *real_url2 = url2;
               const char *old_sess1_url = NULL, *old_sess2_url = NULL;
-              svn_merge_range_t *first_target_range = APR_ARRAY_IDX(
-                target_merge_path->remaining_ranges, 0, svn_merge_range_t *);
-
-              /* Issue #3324: Stop editor abuse!  Don't call
-                 drive_merge_report_editor() in such a way that we request an
-                 editor with svn_client__get_diff_editor() for some rev X,
-                 then call svn_ra_do_diff3() for some revision Y, and then
-                 call reporter->set_path(PATH=="") to set the root revision
-                 for the editor drive to revision Z where
-                 (X != Z && X < Z < Y).  This is bogus because the server will
-                 send us the diff between X:Y but the client is expecting the
-                 diff between Y:Z.  See issue #3324 for full details on the
-                 problems this can cause. */
-              if (first_target_range
-                  && start_rev != first_target_range->start)
-                {
-                  if (is_rollback)
-                    {
-                      if (end_rev < first_target_range->start)
-                        end_rev = first_target_range->start;
-                    }
-                  else
-                    {
-                      if (end_rev > first_target_range->start)
-                        end_rev = first_target_range->start;
-                    }
-                }
 
               svn_pool_clear(iterpool);
 
Index: subversion/libsvn_client/patch.c
===================================================================
--- subversion/libsvn_client/patch.c	(revision 1023844)
+++ subversion/libsvn_client/patch.c	(revision 1005387)
@@ -2023,10 +2023,14 @@
                * to version control. Allow cancellation since we
                * have not modified the working copy yet for this
                * target. */
-              SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, local_abspath,
-                                           ctx->cancel_func, ctx->cancel_baton,
-                                           ctx->notify_func2, ctx->notify_baton2,
-                                           iterpool));
+              SVN_ERR(svn_wc_add4(ctx->wc_ctx, local_abspath,
+                                  svn_depth_infinity,
+                                  NULL, SVN_INVALID_REVNUM,
+                                  ctx->cancel_func,
+                                  ctx->cancel_baton,
+                                  ctx->notify_func2,
+                                  ctx->notify_baton2,
+                                  iterpool));
             }
         }
     }
@@ -2106,8 +2110,10 @@
                * Suppress notification, we'll do that later (and also
                * during dry-run). Also suppress cancellation because
                * we'd rather notify about what we did before aborting. */
-              SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
-                                           NULL, NULL, NULL, NULL, pool));
+              SVN_ERR(svn_wc_add4(ctx->wc_ctx, target->local_abspath,
+                                  svn_depth_infinity,
+                                  NULL, SVN_INVALID_REVNUM,
+                                  NULL, NULL, NULL, NULL, pool));
             }
 
           /* Restore the target's executable bit if necessary. */
@@ -2228,10 +2234,13 @@
           && ! target->added)
         {
           SVN_ERR(svn_io_file_create(target->local_abspath, "", scratch_pool));
-          SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
-                                       ctx->cancel_func, ctx->cancel_baton,
-                                       NULL, NULL, /* suppress notification */
-                                       iterpool));
+          SVN_ERR(svn_wc_add4(ctx->wc_ctx, target->local_abspath,
+                              svn_depth_infinity,
+                              NULL, SVN_INVALID_REVNUM,
+                              ctx->cancel_func,
+                              ctx->cancel_baton,
+                              NULL, NULL, /* suppress notification */
+                              iterpool));
           target->added = TRUE;
         }
 
Index: subversion/libsvn_client/copy.c
===================================================================
--- subversion/libsvn_client/copy.c	(revision 1023844)
+++ subversion/libsvn_client/copy.c	(revision 1005387)
@@ -300,7 +300,7 @@
   const char *dst_parent, *dst_parent_abspath;
   struct do_wc_to_wc_copies_with_write_lock_baton baton;
 
-  SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool));
+  get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool);
   if (copy_pairs->nelts == 1)
     dst_parent = svn_dirent_dirname(dst_parent, pool);
 
@@ -821,8 +821,7 @@
      *and* destinations might be an optimization when the user is
      authorized to access all that stuff, but could cause the
      operation to fail altogether otherwise.  See issue #3242.  */
-  SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &top_url_dst, &top_url_all, 
-                                  pool));
+  get_copy_pair_ancestors(copy_pairs, NULL, &top_url_dst, &top_url_all, pool);
   top_url = is_move ? top_url_all : top_url_dst;
 
   /* Check each src/dst pair for resurrection, and verify that TOP_URL
@@ -1169,7 +1168,7 @@
   int i;
 
   /* Find the common root of all the source paths */
-  SVN_ERR(get_copy_pair_ancestors(copy_pairs, &top_src_path, NULL, NULL, pool));
+  get_copy_pair_ancestors(copy_pairs, &top_src_path, NULL, NULL, pool);
 
   /* Do we need to lock the working copy?  1.6 didn't take a write
      lock, but what happens if the working copy changes during the copy
@@ -1410,9 +1409,7 @@
 }
 
 /* Peform each individual copy operation for a repos -> wc copy.  A
-   helper for repos_to_wc_copy().
-
-   Resolve PAIR->src_revnum to a real revision number if it isn't already. */
+   helper for repos_to_wc_copy(). */
 static svn_error_t *
 repos_to_wc_copy_single(svn_client__copy_pair_t *pair,
                         svn_boolean_t same_repositories,
@@ -1421,6 +1418,7 @@
                         svn_client_ctx_t *ctx,
                         apr_pool_t *pool)
 {
+  svn_revnum_t src_revnum = pair->src_revnum;
   apr_hash_t *src_mergeinfo;
   const char *dst_abspath = pair->dst_abspath_or_url;
 
@@ -1428,11 +1426,7 @@
 
   if (pair->src_kind == svn_node_dir)
     {
-      /* Make a new checkout of the requested source. While doing so,
-       * resolve pair->src_revnum to an actual revision number in case it
-       * was until now 'invalid' meaning 'head'. */
-      SVN_ERR(svn_client__checkout_internal(&pair->src_revnum,
-                                            pair->src_original,
+      SVN_ERR(svn_client__checkout_internal(NULL, pair->src_original,
                                             pair->dst_abspath_or_url,
                                             &pair->src_peg_revision,
                                             &pair->src_op_revision, NULL,
@@ -1446,11 +1440,34 @@
          way to do this; see its doc for more about the controversy.) */
       if (same_repositories)
         {
+          if (pair->src_op_revision.kind == svn_opt_revision_head)
+            {
+              /* If we just checked out from the "head" revision,
+                 that's fine, but we don't want to pass a '-1' as a
+                 copyfrom_rev to svn_wc_add3().  That function will
+                 dump it right into the entry, and when we try to
+                 commit later on, the 'add-dir-with-history' step will
+                 be -very- unhappy; it only accepts specific
+                 revisions.
+
+                 On the other hand, we *could* say that -1 is a
+                 legitimate copyfrom_rev, but I think that's bogus.
+                 Somebody made a copy from a particular revision; if
+                 they wait a long time to commit, it would be terrible
+                 if the copied happened from a newer revision!! */
+
+              /* We just did a checkout; whatever revision we just
+                 got, that should be the copyfrom_revision when we
+                 commit later. */
+              SVN_ERR(svn_wc__node_get_base_rev(&src_revnum, ctx->wc_ctx,
+                                                dst_abspath, pool));
+            }
+
           /* Schedule dst_path for addition in parent, with copy history.
              (This function also recursively puts a 'copied' flag on every
              entry). */
           SVN_ERR(svn_wc_add4(ctx->wc_ctx, dst_abspath, svn_depth_infinity,
-                              pair->src_abspath_or_url, pair->src_revnum,
+                              pair->src_abspath_or_url, src_revnum,
                               ctx->cancel_func, ctx->cancel_baton,
                               ctx->notify_func2, ctx->notify_baton2, pool));
 
@@ -1460,7 +1477,7 @@
              ### source path. */
           SVN_ERR(calculate_target_mergeinfo(ra_session, &src_mergeinfo, NULL,
                                              pair->src_abspath_or_url,
-                                             pair->src_revnum, ctx, pool));
+                                             src_revnum, ctx, pool));
           SVN_ERR(extend_wc_mergeinfo(dst_abspath, src_mergeinfo, ctx, pool));
         }
       else  /* different repositories */
@@ -1483,6 +1500,7 @@
   else if (pair->src_kind == svn_node_file)
     {
       svn_stream_t *fstream;
+      svn_revnum_t real_rev;
       const char *new_text_path;
       apr_hash_t *new_props;
       const char *src_rel;
@@ -1495,26 +1513,30 @@
       SVN_ERR(svn_ra_get_path_relative_to_session(ra_session, &src_rel,
                                                   pair->src_abspath_or_url,
                                                   pool));
-      /* Fetch the file content. While doing so, resolve pair->src_revnum
-       * to an actual revision number if it's 'invalid' meaning 'head'. */
-      SVN_ERR(svn_ra_get_file(ra_session, src_rel, pair->src_revnum, fstream,
-                              &pair->src_revnum, &new_props, pool));
+      SVN_ERR(svn_ra_get_file(ra_session, src_rel, src_revnum, fstream,
+                              &real_rev, &new_props, pool));
       SVN_ERR(svn_stream_close(fstream));
 
+      /* If SRC_REVNUM is invalid (HEAD), then REAL_REV is now the
+         revision that was actually retrieved.  This is the value we
+         want to use as 'copyfrom_rev' below. */
+      if (! SVN_IS_VALID_REVNUM(src_revnum))
+        src_revnum = real_rev;
+
       SVN_ERR(svn_stream_open_readonly(&new_base_contents, new_text_path,
                                        pool, pool));
       SVN_ERR(svn_wc_add_repos_file4(
          ctx->wc_ctx, dst_abspath,
          new_base_contents, NULL, new_props, NULL,
          same_repositories ? pair->src_abspath_or_url : NULL,
-         same_repositories ? pair->src_revnum : SVN_INVALID_REVNUM,
+         same_repositories ? src_revnum : SVN_INVALID_REVNUM,
          ctx->cancel_func, ctx->cancel_baton,
          ctx->notify_func2, ctx->notify_baton2,
          pool));
 
       SVN_ERR(calculate_target_mergeinfo(ra_session, &src_mergeinfo,
                                          NULL, pair->src_abspath_or_url,
-                                         pair->src_revnum, ctx, pool));
+                                         src_revnum, ctx, pool));
       SVN_ERR(extend_wc_mergeinfo(dst_abspath, src_mergeinfo, ctx, pool));
 
       /* Ideally, svn_wc_add_repos_file3() would take a notify function
@@ -1732,8 +1754,7 @@
       pair->src_abspath_or_url = apr_pstrdup(pool, src);
     }
 
-  SVN_ERR(get_copy_pair_ancestors(copy_pairs, &top_src_url, &top_dst_path,
-                                  NULL, pool));
+  get_copy_pair_ancestors(copy_pairs, &top_src_url, &top_dst_path, NULL, pool);
   lock_abspath = top_dst_path;
   if (copy_pairs->nelts == 1)
     {
Index: subversion/libsvn_client/add.c
===================================================================
--- subversion/libsvn_client/add.c	(revision 1023844)
+++ subversion/libsvn_client/add.c	(revision 1005387)
@@ -273,7 +273,6 @@
   return SVN_NO_ERROR;
 }
 
-/* Only call this if the on-disk node kind is a file. */
 static svn_error_t *
 add_file(const char *local_abspath,
          svn_client_ctx_t *ctx,
@@ -299,9 +298,9 @@
                                        ctx, pool));
 
   /* Add the file */
-  SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, local_abspath,
-                               ctx->cancel_func, ctx->cancel_baton,
-                               NULL, NULL, pool));
+  SVN_ERR(svn_wc_add4(ctx->wc_ctx, local_abspath, svn_depth_infinity, NULL,
+                      SVN_INVALID_REVNUM, ctx->cancel_func, ctx->cancel_baton,
+                      NULL, NULL, pool));
 
   if (is_special)
     /* This must be a special file. */
@@ -386,10 +385,9 @@
   iterpool = svn_pool_create(scratch_pool);
 
   /* Add this directory to revision control. */
-  err = svn_wc_add_from_disk(ctx->wc_ctx, dir_abspath,
-                             ctx->cancel_func, ctx->cancel_baton,
-                             ctx->notify_func2, ctx->notify_baton2,
-                             iterpool);
+  err = svn_wc_add4(ctx->wc_ctx, dir_abspath, svn_depth_infinity, NULL,
+                    SVN_INVALID_REVNUM, ctx->cancel_func, ctx->cancel_baton,
+                    ctx->notify_func2, ctx->notify_baton2, iterpool);
   if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
     svn_error_clear(err);
   else if (err)
@@ -548,10 +546,11 @@
     SVN_ERR(svn_wc__acquire_write_lock(NULL, wc_ctx, parent_abspath, FALSE,
                                        scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_wc_add_from_disk(wc_ctx, local_abspath,
-                               ctx->cancel_func, ctx->cancel_baton,
-                               ctx->notify_func2, ctx->notify_baton2,
-                               scratch_pool));
+  SVN_ERR(svn_wc_add4(wc_ctx, local_abspath, svn_depth_infinity,
+                      NULL, SVN_INVALID_REVNUM,
+                      ctx->cancel_func, ctx->cancel_baton,
+                      ctx->notify_func2, ctx->notify_baton2,
+                      scratch_pool));
   /* ### New dir gets added with its own per-directory lock which we
      must release.  This code should be redundant when we move to a
      single db. */
Index: subversion/libsvn_repos/repos.c
===================================================================
--- subversion/libsvn_repos/repos.c	(revision 1023844)
+++ subversion/libsvn_repos/repos.c	(revision 1005387)
@@ -1141,13 +1141,6 @@
 "### have the same password database, and vice versa.  The default realm"    NL
 "### is repository's uuid."                                                  NL
 "# realm = My First Repository"                                              NL
-"### The force-username-case option causes svnserve to case-normalize"       NL
-"### usernames before comparing them against the authorization rules in the" NL
-"### authz-db file configured above.  Valid values are \"upper\" (to upper-" NL
-"### case the usernames), \"lower\" (to lowercase the usernames), and"       NL
-"### \"none\" (to compare usernames as-is without case conversion, which"    NL
-"### is the default behavior)."                                              NL
-"# force-username-case = none"                                               NL
 ""                                                                           NL
 "[sasl]"                                                                     NL
 "### This option specifies whether you want to use the Cyrus SASL"           NL
Index: subversion/svnserve/main.c
===================================================================
--- subversion/svnserve/main.c	(revision 1023844)
+++ subversion/svnserve/main.c	(revision 1005387)
@@ -372,7 +372,6 @@
   apr_sockaddr_t *sa;
   apr_pool_t *pool;
   apr_pool_t *connection_pool;
-  apr_allocator_t *allocator;
   svn_error_t *err;
   apr_getopt_t *os;
   int opt;
@@ -432,7 +431,6 @@
   params.pwdb = NULL;
   params.authzdb = NULL;
   params.log_file = NULL;
-  params.username_case = CASE_ASIS;
 
   while (1)
     {
@@ -594,11 +592,11 @@
   /* If a configuration file is specified, load it and any referenced
    * password and authorization files. */
   if (config_filename)
-    SVN_INT_ERR(load_configs(&params.cfg, &params.pwdb, &params.authzdb,
-                             &params.username_case, config_filename, TRUE,
-                             svn_dirent_dirname(config_filename, pool),
-                             NULL, NULL, /* server baton, conn */
-                             pool));
+      SVN_INT_ERR(load_configs(&params.cfg, &params.pwdb, &params.authzdb,
+                               config_filename, TRUE,
+                               svn_dirent_dirname(config_filename, pool),
+                               NULL, NULL, /* server baton, conn */
+                               pool));
 
   if (log_filename)
     SVN_INT_ERR(svn_io_file_open(&params.log_file, log_filename,
@@ -795,22 +793,10 @@
         return ERROR_SUCCESS;
 #endif
 
-      /* If we are using fulltext caches etc., we will allocate many large
-         chunks of memory of various sizes outside the cachde for those
-         fulltexts. Make sure, we use the memory wisely: use an allocator
-         that causes memory fragments to be given back to the OS early. */
-
-      if (apr_allocator_create(&allocator))
-        return EXIT_FAILURE;
-
-      apr_allocator_max_free_set(allocator, SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);
-
       /* Non-standard pool handling.  The main thread never blocks to join
          the connection threads so it cannot clean up after each one.  So
          separate pools, that can be cleared at thread exit, are used */
-
-      connection_pool = svn_pool_create_ex(NULL, allocator);
-      apr_allocator_owner_set(allocator, connection_pool);
+      connection_pool = svn_pool_create(NULL);
 
       status = apr_socket_accept(&usock, sock, connection_pool);
       if (handling_mode == connection_mode_fork)
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c	(revision 1023844)
+++ subversion/svnserve/serve.c	(revision 1005387)
@@ -223,7 +223,6 @@
 svn_error_t *load_configs(svn_config_t **cfg,
                           svn_config_t **pwdb,
                           svn_authz_t **authzdb,
-                          enum username_case_type *username_case,
                           const char *filename,
                           svn_boolean_t must_exist,
                           const char *base,
@@ -287,8 +286,6 @@
                  SVN_CONFIG_OPTION_AUTHZ_DB, NULL);
   if (authzdb_path)
     {
-      const char *case_force_val;
-
       authzdb_path = svn_dirent_join(base, authzdb_path, pool);
       err = svn_repos_authz_read(authzdb, authzdb_path, TRUE, pool);
       if (err)
@@ -307,25 +304,10 @@
              * will go to standard error for the admin to see. */
             return err;
         }
-      
-      /* Are we going to be case-normalizing usernames when we consult
-       * this authz file? */
-      svn_config_get(*cfg, &case_force_val, SVN_CONFIG_SECTION_GENERAL,
-                     SVN_CONFIG_OPTION_FORCE_USERNAME_CASE, NULL);
-      if (case_force_val)
-        {
-          if (strcmp(case_force_val, "upper") == 0)
-            *username_case = CASE_FORCE_UPPER;
-          else if (strcmp(case_force_val, "lower") == 0)
-            *username_case = CASE_FORCE_LOWER;
-          else
-            *username_case = CASE_ASIS;
-        }
     }
   else
     {
       *authzdb = NULL;
-      *username_case = CASE_ASIS;
     }
 
   return SVN_NO_ERROR;
@@ -358,18 +340,6 @@
 
 /* --- AUTHENTICATION AND AUTHORIZATION FUNCTIONS --- */
 
-/* Convert TEXT to upper case if TO_UPPERCASE is TRUE, else
-   converts it to lower case. */
-static void convert_case(char *text, svn_boolean_t to_uppercase)
-{
-  char *c = text;
-  while (*c)
-    {
-      *c = (to_uppercase ? apr_toupper(*c) : apr_tolower(*c));
-      ++c;
-    }
-}
-
 /* Set *ALLOWED to TRUE if PATH is accessible in the REQUIRED mode to
    the user described in BATON according to the authz rules in BATON.
    Use POOL for temporary allocations only.  If no authz rules are
@@ -399,20 +369,8 @@
   if (path && *path != '/')
     path = svn_uri_join("/", path, pool);
 
-  /* If we have a username, and we've not yet used it + any username
-     case normalization that might be requested to determine "the
-     username we used for authz purposes", do so now. */
-  if (b->user && (! b->authz_user))
-    {
-      b->authz_user = apr_pstrdup(b->pool, b->user);
-      if (b->username_case == CASE_FORCE_UPPER)
-        convert_case((char *)b->authz_user, TRUE);
-      else if (b->username_case == CASE_FORCE_LOWER)
-        convert_case((char *)b->authz_user, FALSE);
-    }
-
   return svn_repos_authz_check_access(b->authzdb, b->authz_repos_name,
-                                      path, b->authz_user, required,
+                                      path, b->user, required,
                                       allowed, pool);
 }
 
@@ -3004,7 +2962,7 @@
   /* If the svnserve configuration files have not been loaded then
      load them from the repository. */
   if (NULL == b->cfg)
-    SVN_ERR(load_configs(&b->cfg, &b->pwdb, &b->authzdb, &b->username_case,
+    SVN_ERR(load_configs(&b->cfg, &b->pwdb, &b->authzdb,
                          svn_repos_svnserve_conf(b->repos, pool), FALSE,
                          svn_repos_conf_dir(b->repos, pool),
                          b, conn,
@@ -3073,8 +3031,6 @@
   b.tunnel_user = get_tunnel_user(params, pool);
   b.read_only = params->read_only;
   b.user = NULL;
-  b.username_case = params->username_case;
-  b.authz_user = NULL;
   b.cfg = params->cfg;
   b.pwdb = params->pwdb;
   b.authzdb = params->authzdb;
Index: subversion/svnserve/cyrus_auth.c
===================================================================
--- subversion/svnserve/cyrus_auth.c	(revision 1023844)
+++ subversion/svnserve/cyrus_auth.c	(revision 1005387)
@@ -360,10 +360,8 @@
         return fail_cmd(conn, pool, sasl_ctx);
 
       if ((p = strchr(user, '@')) != NULL)
-        {
-          /* Drop the realm part. */
-          b->user = apr_pstrndup(b->pool, user, p - (const char *)user);
-        }
+        /* Drop the realm part. */
+        b->user = apr_pstrndup(b->pool, user, p - (const char *)user);
       else
         {
           svn_error_t *err;
Index: subversion/svnserve/server.h
===================================================================
--- subversion/svnserve/server.h	(revision 1023844)
+++ subversion/svnserve/server.h	(revision 1005387)
@@ -36,8 +36,6 @@
 #include "svn_repos.h"
 #include "svn_ra_svn.h"
 
-enum username_case_type { CASE_FORCE_UPPER, CASE_FORCE_LOWER, CASE_ASIS };
-
 typedef struct server_baton_t {
   svn_repos_t *repos;
   const char *repos_name;  /* URI-encoded name of repository (not for authz) */
@@ -49,9 +47,7 @@
   const char *realm;       /* Authentication realm */
   const char *repos_url;   /* URL to base of repository */
   svn_stringbuf_t *fs_path;/* Decoded base in-repos path (w/ leading slash) */
-  const char *user;        /* Authenticated username of the user */
-  enum username_case_type username_case; /* Case-normalize the username? */
-  const char *authz_user;  /* Username for authz ('user' + 'username_case') */
+  const char *user;
   svn_boolean_t tunnel;    /* Tunneled through login agent */
   const char *tunnel_user; /* Allow EXTERNAL to authenticate as this */
   svn_boolean_t read_only; /* Disallow write access (global flag) */
@@ -105,10 +101,6 @@
 
   /* A filehandle open for writing logs to; possibly NULL. */
   apr_file_t *log_file;
-
-  /* Username case normalization style. */
-  enum username_case_type username_case;
-
 } serve_params_t;
 
 /* Serve the connection CONN according to the parameters PARAMS. */
@@ -116,16 +108,11 @@
                    apr_pool_t *pool);
 
 /* Load a svnserve configuration file located at FILENAME into CFG,
-   and if such as found, then:
-
-    - set *PWDB to any referenced password database,
-    - set *AUTHZDB to any referenced authorization database, and
-    - set *USERNAME_CASE to the enumerated value of the
-      'force-username-case' configuration value (or its default).
-
-   If MUST_EXIST is true and FILENAME does not exist, then return an
-   error.  BASE may be specified as the base path to any referenced
-   password and authorization files found in FILENAME.
+   any referenced password database into PWDB and any referenced
+   authorization database into AUTHZDB.  If MUST_EXIST is true and
+   FILENAME does not exist, then this returns an error.  BASE may be
+   specified as the base path to any referenced password and
+   authorization files found in FILENAME.
 
    If SERVER is not NULL, log the real errors with SERVER and CONN but
    return generic errors to the client.  CONN must not be NULL if SERVER
@@ -133,7 +120,6 @@
 svn_error_t *load_configs(svn_config_t **cfg,
                           svn_config_t **pwdb,
                           svn_authz_t **authzdb,
-                          enum username_case_type *username_case,
                           const char *filename,
                           svn_boolean_t must_exist,
                           const char *base,

Property changes on: build/win32
___________________________________________________________________
Modified: svn:ignore
   - build_locale.bat
build_neon.bat
build_zlib.bat
make_dist.conf
make_dist.log
*.dsp
msvc-dsp
*.vcproj
*.vcxproj
vcnet-vcproj
*.user
*.log

   + build_locale.bat
build_neon.bat
build_zlib.bat
make_dist.conf
make_dist.log
*.dsp
msvc-dsp
*.vcproj
*.vcxproj
vcnet-vcproj
*.user


Index: tools/client-side/svnmucc/svnmucc.c
===================================================================
--- tools/client-side/svnmucc/svnmucc.c	(revision 1023844)
+++ tools/client-side/svnmucc/svnmucc.c	(revision 1005387)
@@ -1023,10 +1023,8 @@
               if (++i == action_args->nelts)
                 insufficient(pool);
 
-              err = read_propvalue_file(&(action->prop_value), propval_file, pool);
-              if (err)
-                handle_error(err, pool);
-
+              handle_error(read_propvalue_file(&(action->prop_value),
+                                               propval_file, pool), pool);
               action->action = ACTION_PROPSET;
             }
         }
@@ -1086,11 +1084,9 @@
                      svn_string_create("committed using svnmucc", pool));
     }
   else
-    {
-      /* -F or -m specified; use that even if --with-revprop=svn:log. */
-      apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
-                   svn_string_create(message, pool));
-    }
+    /* -F or -m specified; use that even if --with-revprop=svn:log. */
+    apr_hash_set(revprops, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
+                 svn_string_create(message, pool));
 
   if ((err = execute(actions, anchor, revprops, username, password,
                      config_dir, non_interactive, base_revision, pool)))
Index: tools/client-side/svnmucc/svnmucc-test.py
===================================================================
--- tools/client-side/svnmucc/svnmucc-test.py	(revision 1023844)
+++ tools/client-side/svnmucc/svnmucc-test.py	(revision 1005387)
@@ -286,13 +286,6 @@
               'propset', 'testprop', 'true', 'foo/z.c',
               'propset', 'testprop', 'true', 'foo/foo')
 
-  # revision 19
-  run_svnmucc(['M /foo/z.c',
-               'M /foo/foo',
-               ], #---------
-              'propsetf', 'testprop', sys.argv[0], 'foo/z.c',
-              'propsetf', 'testprop', sys.argv[0], 'foo/foo')
-
   # Expected missing revision error
   xrun_svnmucc(['svnmucc: \'a\' is not a revision'
                 ], #---------
Index: tools/server-side/svn-rep-sharing-stats.c
===================================================================
--- tools/server-side/svn-rep-sharing-stats.c	(revision 1023844)
+++ tools/server-side/svn-rep-sharing-stats.c	(revision 1005387)
@@ -329,10 +329,12 @@
   for (hi = apr_hash_first(scratch_pool, reps_ref_counts);
        hi; hi = apr_hash_next(hi))
     {
+      const struct key_t *key;
       struct value_t *value;
 
       SVN_ERR(cancel_func(NULL));
 
+      key = svn__apr_hash_index_key(hi);
       value = svn__apr_hash_index_val(hi);
       SVN_ERR(svn_cmdline_printf(scratch_pool, "%s %" APR_UINT64_T_FMT " %s\n",
                                  name, value->refcount,
Index: tools/dev/unix-build/Makefile.svn
===================================================================
--- tools/dev/unix-build/Makefile.svn	(revision 1023844)
+++ tools/dev/unix-build/Makefile.svn	(revision 1005387)
@@ -917,7 +917,7 @@
 	echo 'RedirectMatch ^/svn-test-work/repositories/REDIRECT-TEMP-(.*)$$ /svn-test-work/repositories/$$1' >> $(HTTPD_CHECK_CONF)
 
 # We need this to make sure some targets below pick up the right libraries
-LD_LIBRARY_PATH=$(PREFIX)/apr/lib:$(PREFIX)/iconv/lib:$(PREFIX)/bdb/lib:$(PREFIX)/neon/lib:$(PREFIX)/serf/lib:$(PREFIX)/sqlite/lib:$(PREFIX)/cyrus-sasl/lib:$(PREFIX)/iconv/lib:$(PREFIX)/svn-$(WC)/lib
+LD_LIBRARY_PATH=$(PREFIX)/apr/lib:$(PREFIX)/iconv/lib:$(PREFIX)/bdb/lib:$(PREFIX)/neon/lib:$(PREFIX)/serf/lib:$(PREFIX)/sqlite/lib:$(PREFIX)/svn-$(WC)/lib
 
 .PHONY: start-svnserve stop-svnserve start-httpd stop-httpd
 
Index: tools/dev/wc-format.py
===================================================================
--- tools/dev/wc-format.py	(revision 1023844)
+++ tools/dev/wc-format.py	(revision 1005387)
@@ -4,9 +4,8 @@
 import sqlite3
 import sys
 
-MIN_SINGLE_DB_FORMAT = 19
 
-def get_format(wc_path):
+def print_format(wc_path):
   entries = os.path.join(wc_path, '.svn', 'entries')
   wc_db = os.path.join(wc_path, '.svn', 'wc.db')
 
@@ -18,26 +17,14 @@
     curs.execute('pragma user_version;')
     formatno = curs.fetchone()[0]
   else:
-    parent_path = os.path.dirname(os.path.abspath(wc_path))
-    if wc_path != parent_path:
-      formatno = get_format(parent_path)
-      if formatno >= MIN_SINGLE_DB_FORMAT:
-      	return formatno
-      else:
-      	return 'not under version control'
-    else:
-      return 'not under version control'
+    formatno = 'not under version control'
 
-  return formatno
-
-def print_format(wc_path):
   # see subversion/libsvn_wc/wc.h for format values and information
   #   1.0.x -> 1.3.x: format 4
   #   1.4.x: format 8
   #   1.5.x: format 9
   #   1.6.x: format 10
   #   1.7.x: format XXX
-  formatno = get_format(wc_path)
   print '%s: %s' % (wc_path, formatno)
 
 

Property changes on: 
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /subversion/branches/performance:r982355,985472,987888

