/**
 * @copyright
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 * @endcopyright
 */
package org.apache.subversion.javahl;

import static org.junit.Assert.*;

import org.apache.subversion.javahl.callback.*;
import org.apache.subversion.javahl.remote.*;
import org.apache.subversion.javahl.types.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.text.ParseException;
import java.util.Collection;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.text.DateFormat;
import java.text.SimpleDateFormat;


/**
 * Tests the basic functionality of javahl binding (inspired by the
 * tests in subversion/tests/cmdline/basic_tests.py).
 */
public class BasicTests extends SVNTests
{
    /**
     * Base name of all our tests.
     */
    public final static String testName = "basic_test";

    public BasicTests()
    {
        init();
    }

    public BasicTests(String name)
    {
        super(name);
        init();
    }

    /**
     * Initialize the testBaseName and the testCounter, if this is the
     * first test of this class.
     */
    private void init()
    {
        if (!testName.equals(testBaseName))
        {
            testCounter = 0;
            testBaseName = testName;
        }
    }

    /**
     * Test LogDate().
     * @throws Throwable
     */
    public void testLogDate() throws Throwable
    {
        String goodDate = "2007-10-04T03:00:52.134992Z";
        String badDate = "2008-01-14";
        LogDate logDate;

        try
        {
            logDate = new LogDate(goodDate);
            assertEquals(1191466852134992L, logDate.getTimeMicros());
        } catch (ParseException e) {
            fail("Failed to parse date " + goodDate);
        }

        try
        {
            logDate = new LogDate(badDate);
            fail("Failed to throw exception on bad date " + badDate);
        } catch (ParseException e) {
        }
    }

    /**
     * Test SVNClient.getVersion().
     * @throws Throwable
     */
    public void testVersion() throws Throwable
    {
        try
        {
            Version version = client.getVersion();
            String versionString = version.toString();
            if (versionString == null || versionString.trim().length() == 0)
            {
                throw new Exception("Version string empty");
            }
        }
        catch (Exception e)
        {
            fail("Version should always be available unless the " +
                 "native libraries failed to initialize: " + e);
        }
    }

    /**
     * Test SVNClient.getVersionExtended().
     * @throws Throwable
     */
    public void testVersionExtendedQuiet() throws Throwable
    {
        VersionExtended vx = null;
        try
        {
            vx = client.getVersionExtended(false);
            String result = vx.getBuildDate();
            if (result == null || result.trim().length() == 0)
                throw new Exception("Build date empty");
            result = vx.getBuildTime();
            if (result == null || result.trim().length() == 0)
                throw new Exception("Build time empty");
            result = vx.getBuildHost();
            if (result == null || result.trim().length() == 0)
                throw new Exception("Build host empty");
            result = vx.getCopyright();
            if (result == null || result.trim().length() == 0)
                throw new Exception("Copyright empty");
        }
        catch (Exception e)
        {
            fail("VersionExtended should always be available unless the " +
                 "native libraries failed to initialize: " + e);
        }
        finally
        {
            if (vx != null)
                vx.dispose();
        }
    }

    /**
     * Test SVNClient.getVersionExtended().
     * @throws Throwable
     */
    public void testVersionExtendedVerbose() throws Throwable
    {
        VersionExtended vx = null;
        try
        {
            vx = client.getVersionExtended(true);
            String result = vx.getRuntimeHost();
            if (result == null || result.trim().length() == 0)
                throw new Exception("Runtime host empty");

            // OS name is allowed to be null, but not empty
            result = vx.getRuntimeOSName();
            if (result != null && result.trim().length() == 0)
                throw new Exception("Runtime OS name empty");

            java.util.Iterator<VersionExtended.LinkedLib> ikl;
            ikl = vx.getLinkedLibs();
            if (ikl.hasNext())
            {
                VersionExtended.LinkedLib lib = ikl.next();
                result = lib.getName();
                if (result == null || result.trim().length() == 0)
                    throw new Exception("Linked lib name empty");
                result = lib.getCompiledVersion();
                if (result == null || result.trim().length() == 0)
                    throw new Exception("Linked lib compiled version empty");
                // Runtime version is allowed to be null, but not empty
                result = lib.getRuntimeVersion();
                if (result != null && result.trim().length() == 0)
                    throw new Exception("Linked lib runtime version empty");
            }

            java.util.Iterator<VersionExtended.LoadedLib> ill;
            ill = vx.getLoadedLibs();
            if (ill.hasNext())
            {
                VersionExtended.LoadedLib lib = ill.next();
                result = lib.getName();
                if (result == null || result.trim().length() == 0)
                    throw new Exception("Loaded lib name empty");
                // Version is allowed to be null, but not empty
                result = lib.getVersion();
                if (result != null && result.trim().length() == 0)
                    throw new Exception("Loaded lib version empty");
            }
        }
        catch (Exception e)
        {
            fail("VersionExtended should always be available unless the " +
                 "native libraries failed to initialize: " + e);
        }
        finally
        {
            if (vx != null)
                vx.dispose();
        }
    }

    /**
     * Test RuntimeVersion
     */
    public void testRuntimeVersion() throws Throwable
    {
        try
        {
            RuntimeVersion runtimeVersion = client.getRuntimeVersion();
            String versionString = runtimeVersion.toString();
            if (versionString == null || versionString.trim().length() == 0)
            {
                throw new Exception("Version string empty");
            }
        }
        catch (Exception e)
        {
            fail("RuntimeVersion should always be available unless the " +
                 "native libraries failed to initialize: " + e);
        }

        RuntimeVersion runtimeVersion = client.getRuntimeVersion();
        Version version = client.getVersion();
        assertTrue(runtimeVersion.getMajor() > version.getMajor()
                   || (runtimeVersion.getMajor() == version.getMajor()
                       && runtimeVersion.getMinor() >= version.getMinor()));
    }

    /**
     * Test the JNIError class functionality
     * @throws Throwable
     */
    public void testJNIError() throws Throwable
    {
        // build the test setup.
        OneTest thisTest = new OneTest();

        // Create a client, dispose it, then try to use it later
        ISVNClient tempclient = new SVNClient();
        tempclient.dispose();

        // create Y and Y/Z directories in the repository
        addExpectedCommitItem(null, thisTest.getUrl().toString(), "Y", NodeKind.dir,
                              CommitItemStateFlags.Add);
        Set<String> urls = new HashSet<String>(1);
        urls.add(thisTest.getUrl() + "/Y");
        try
        {
            tempclient.mkdir(urls, false, null, new ConstMsg("log_msg"), null);
        }
        catch(JNIError e)
        {
            return; // Test passes!
        }
        fail("A JNIError should have been thrown here.");
    }

    /**
     * Tests Mergeinfo and RevisionRange classes.
     * @since 1.5
     */
    public void testMergeinfoParser() throws Throwable
    {
        String mergeInfoPropertyValue =
            "/trunk:1-300,305*,307,400-405*\n" +
            "/branches/branch:308-400";
        Mergeinfo info = new Mergeinfo(mergeInfoPropertyValue);
        Set<String> paths = info.getPaths();
        assertEquals(2, paths.size());
        List<RevisionRange> trunkRange = info.getRevisionRange("/trunk");
        assertEquals(4, trunkRange.size());
        assertEquals("1-300", trunkRange.get(0).toString());
        assertEquals("305*", trunkRange.get(1).toString());
        assertEquals("307", trunkRange.get(2).toString());
        assertEquals("400-405*", trunkRange.get(3).toString());
        List<RevisionRange> branchRange =
            info.getRevisionRange("/branches/branch");
        assertEquals(1, branchRange.size());
    }

    /**
     * Test the basic SVNClient.status functionality.
     * @throws Throwable
     */
    public void testBasicStatus() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();

        // check the status of the working copy
        thisTest.getWc().setItemDepth("", Depth.infinity);
        thisTest.getWc().setItemDepth("iota", Depth.unknown);
        thisTest.checkStatus();

        // Test status of non-existent file
        File fileC = new File(thisTest.getWorkingCopy() + "/A", "foo.c");

        MyStatusCallback statusCallback = new MyStatusCallback();
        client.status(fileToSVNPath(fileC, false), Depth.unknown,
                      false, true, true, false, false, false,
                      null, statusCallback);

        final int statusCount = statusCallback.getStatusArray().length;
        if (statusCount == 1)
        {
            Status st = statusCallback.getStatusArray()[0];
            if (st.isConflicted()
                || st.getNodeStatus() != Status.Kind.none
                || st.getRepositoryNodeStatus() != Status.Kind.none)
                fail("File foo.c should return empty status.");
        }
        else if (statusCount > 1)
            fail("File foo.c should not return more than one status.");
        else
            fail("File foo.c should return exactly one empty status.");
    }

    /**
     * Test the "out of date" info from {@link
     * org.apache.subversion.javahl.SVNClient#status()}.
     *
     * @throws SubversionException
     * @throws IOException
     */
    public void testOODStatus() throws SubversionException, IOException
    {
        // build the test setup
        OneTest thisTest = new OneTest();

        // Make a whole slew of changes to a WC:
        //
        //  (root)               r7 - prop change
        //  iota
        //  A
        //  |__mu
        //  |
        //  |__B
        //  |   |__lambda
        //  |   |
        //  |   |__E             r12 - deleted
        //  |   |  |__alpha
        //  |   |  |__beta
        //  |   |
        //  |   |__F             r9 - prop change
        //  |   |__I             r6 - added dir
        //  |
        //  |__C                 r5 - deleted
        //  |
        //  |__D
        //     |__gamma
        //     |
        //     |__G
        //     |  |__pi          r3 - deleted
        //     |  |__rho         r2 - modify text
        //     |  |__tau         r4 - modify text
        //     |
        //     |__H
        //        |__chi         r10-11 replaced with file
        //        |__psi         r13-14 replaced with dir
        //        |__omega
        //        |__nu          r8 - added file
        File file, dir;
        PrintWriter pw;
        Status status;
        MyStatusCallback statusCallback;
        long rev;             // Resulting rev from co or update
        long expectedRev = 2;  // Keeps track of the latest rev committed

        // ----- r2: modify file A/D/G/rho --------------------------
        file = new File(thisTest.getWorkingCopy(), "A/D/G/rho");
        pw = new PrintWriter(new FileOutputStream(file, true));
        pw.print("modification to rho");
        pw.close();
        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/D/G/rho",
                              NodeKind.file, CommitItemStateFlags.TextMods);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", rev);
        thisTest.getWc().setItemContent("A/D/G/rho",
            thisTest.getWc().getItemContent("A/D/G/rho")
            + "modification to rho");

        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/D/G/rho", Depth.immediates,
                      false, true, true, false, false, false,
                      null, statusCallback);
        status = statusCallback.getStatusArray()[0];
        long rhoCommitDate = status.getLastChangedDate().getTime();
        long rhoCommitRev = rev;
        String rhoAuthor = status.getLastCommitAuthor();

        // ----- r3: delete file A/D/G/pi ---------------------------
        client.remove(thisTest.getWCPathSet("/A/D/G/pi"),
                      false, false, null, null, null);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/D/G/pi", NodeKind.file,
                              CommitItemStateFlags.Delete);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().removeItem("A/D/G/pi");

        thisTest.getWc().setItemWorkingCopyRevision("A/D/G", rev);
        assertEquals("wrong revision from update",
                     update(thisTest, "/A/D/G"), rev);
        long GCommitRev = rev;

        // ----- r4: modify file A/D/G/tau --------------------------
        file = new File(thisTest.getWorkingCopy(), "A/D/G/tau");
        pw = new PrintWriter(new FileOutputStream(file, true));
        pw.print("modification to tau");
        pw.close();
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/D/G/tau",NodeKind.file,
                              CommitItemStateFlags.TextMods);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().setItemWorkingCopyRevision("A/D/G/tau", rev);
        thisTest.getWc().setItemContent("A/D/G/tau",
                thisTest.getWc().getItemContent("A/D/G/tau")
                + "modification to tau");
        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/D/G/tau", Depth.immediates,
                      false, true, true, false, false, false,
                      null, statusCallback);
        status = statusCallback.getStatusArray()[0];
        long tauCommitDate = status.getLastChangedDate().getTime();
        long tauCommitRev = rev;
        String tauAuthor = status.getLastCommitAuthor();

        // ----- r5: delete dir with no children  A/C ---------------
        client.remove(thisTest.getWCPathSet("/A/C"),
                      false, false, null, null, null);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/C", NodeKind.dir,
                              CommitItemStateFlags.Delete);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().removeItem("A/C");
        long CCommitRev = rev;

        // ----- r6: Add dir A/B/I ----------------------------------
        dir = new File(thisTest.getWorkingCopy(), "A/B/I");
        dir.mkdir();

        client.add(dir.getAbsolutePath(), Depth.infinity, false, false, false);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/B/I", NodeKind.dir, CommitItemStateFlags.Add);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().addItem("A/B/I", null);
        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/B/I", Depth.immediates,
                      false, true, true, false, false, false,
                      null, statusCallback);
        status = statusCallback.getStatusArray()[0];
        long ICommitDate = status.getLastChangedDate().getTime();
        long ICommitRev = rev;
        String IAuthor = status.getLastCommitAuthor();

        // ----- r7: Update then commit prop change on root dir -----
        thisTest.getWc().setRevision(rev);
        assertEquals("wrong revision from update",
                     update(thisTest), rev);
        thisTest.checkStatus();
        setprop(thisTest.getWCPath(), "propname", "propval");
        thisTest.getWc().setItemPropStatus("", Status.Kind.modified);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                             null, NodeKind.dir, CommitItemStateFlags.PropMods);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().setItemWorkingCopyRevision("", rev);
        thisTest.getWc().setItemPropStatus("", Status.Kind.normal);

        // ----- r8: Add a file A/D/H/nu ----------------------------
        file = new File(thisTest.getWorkingCopy(), "A/D/H/nu");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("This is the file 'nu'.");
        pw.close();
        client.add(file.getAbsolutePath(), Depth.empty, false, false, false);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/D/H/nu", NodeKind.file,
                              CommitItemStateFlags.TextMods +
                              CommitItemStateFlags.Add);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().addItem("A/D/H/nu", "This is the file 'nu'.");
        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/D/H/nu", Depth.immediates,
                      false, true, true, false, false, false,
                      null, statusCallback);
        status = statusCallback.getStatusArray()[0];
        long nuCommitDate = status.getLastChangedDate().getTime();
        long nuCommitRev = rev;
        String nuAuthor = status.getLastCommitAuthor();

        // ----- r9: Prop change on A/B/F ---------------------------
        setprop(thisTest.getWCPath() + "/A/B/F", "propname", "propval");
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/B/F", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().setItemPropStatus("A/B/F", Status.Kind.normal);
        thisTest.getWc().setItemWorkingCopyRevision("A/B/F", rev);
        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/B/F", Depth.immediates,
                      false, true, true, false, false, false,
                      null, statusCallback);
        status = statusCallback.getStatusArray()[0];
        long FCommitDate = status.getLastChangedDate().getTime();
        long FCommitRev = rev;
        String FAuthor = status.getLastCommitAuthor();

        // ----- r10-11: Replace file A/D/H/chi with file -----------
        client.remove(thisTest.getWCPathSet("/A/D/H/chi"),
                      false, false, null, null, null);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/D/H/chi", NodeKind.file,
                              CommitItemStateFlags.Delete);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().removeItem("A/D/G/pi");

        file = new File(thisTest.getWorkingCopy(), "A/D/H/chi");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("This is the replacement file 'chi'.");
        pw.close();
        client.add(file.getAbsolutePath(), Depth.empty, false, false, false);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/D/H/chi", NodeKind.file,
                              CommitItemStateFlags.TextMods +
                              CommitItemStateFlags.Add);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().addItem("A/D/H/chi",
                                 "This is the replacement file 'chi'.");
        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/D/H/chi", Depth.immediates,
                      false, true, true, false, false, false,
                      null, statusCallback);
        status = statusCallback.getStatusArray()[0];
        long chiCommitDate = status.getLastChangedDate().getTime();
        long chiCommitRev = rev;
        String chiAuthor = status.getLastCommitAuthor();

        // ----- r12: Delete dir A/B/E with children ----------------
        client.remove(thisTest.getWCPathSet("/A/B/E"),
                      false, false, null, null, null);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/B/E", NodeKind.dir,
                              CommitItemStateFlags.Delete);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().removeItem("A/B/E/alpha");
        thisTest.getWc().removeItem("A/B/E/beta");
        thisTest.getWc().removeItem("A/B/E");

        thisTest.getWc().setItemWorkingCopyRevision("A/B", rev);
        assertEquals("wrong revision from update",
                     update(thisTest, "/A/B"), rev);
        Info Binfo = collectInfos(thisTest.getWCPath() + "/A/B", null, null,
                                   Depth.empty, null)[0];
        long BCommitDate = Binfo.getLastChangedDate().getTime();
        long BCommitRev = rev;
        long ECommitRev = BCommitRev;
        String BAuthor = Binfo.getLastChangedAuthor();

        // ----- r13-14: Replace file A/D/H/psi with dir ------------
        client.remove(thisTest.getWCPathSet("/A/D/H/psi"),
                      false, false, null, null, null);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/D/H/psi", NodeKind.file,
                              CommitItemStateFlags.Delete);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        thisTest.getWc().removeItem("A/D/H/psi");
        thisTest.getWc().setRevision(rev);
        assertEquals("wrong revision from update",
                     update(thisTest), rev);
        thisTest.getWc().addItem("A/D/H/psi", null);
        dir = new File(thisTest.getWorkingCopy(), "A/D/H/psi");
        dir.mkdir();
        client.add(dir.getAbsolutePath(), Depth.infinity, false, false, false);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "A/D/H/psi", NodeKind.dir,
                              CommitItemStateFlags.Add);
        rev = commit(thisTest, "log msg");
        assertEquals("wrong revision number from commit", rev, expectedRev++);
        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/D/H/psi", Depth.immediates,
                      false, true, true, false, false, false,
                      null, statusCallback);
        status = statusCallback.getStatusArray()[0];
        long psiCommitDate = status.getLastChangedDate().getTime();
        long psiCommitRev = rev;
        String psiAuthor = status.getLastCommitAuthor();

        // ----- Check status of modfied WC then update it back
        // -----  to rev 1 so it's out of date
        thisTest.checkStatus();

        assertEquals("wrong revision from update",
                     client.update(thisTest.getWCPathSet(),
                                   Revision.getInstance(1), Depth.unknown,
                                   false, false, false, false)[0],
                     1);
        thisTest.getWc().setRevision(1);

        thisTest.getWc().setItemOODInfo("A", psiCommitRev, psiAuthor,
                                        psiCommitDate, NodeKind.dir);

        thisTest.getWc().setItemOODInfo("A/B", BCommitRev, BAuthor,
                                        BCommitDate, NodeKind.dir);

        thisTest.getWc().addItem("A/B/I", null);
        thisTest.getWc().setItemOODInfo("A/B/I", ICommitRev, IAuthor,
                                        ICommitDate, NodeKind.dir);
        thisTest.getWc().setItemTextStatus("A/B/I", Status.Kind.none);
        thisTest.getWc().setItemNodeKind("A/B/I", NodeKind.unknown);

        thisTest.getWc().addItem("A/C", null);
        thisTest.getWc().setItemReposLastCmtRevision("A/C", CCommitRev);
        thisTest.getWc().setItemReposKind("A/C", NodeKind.dir);

        thisTest.getWc().addItem("A/B/E", null);
        thisTest.getWc().setItemReposLastCmtRevision("A/B/E", ECommitRev);
        thisTest.getWc().setItemReposKind("A/B/E", NodeKind.dir);
        thisTest.getWc().addItem("A/B/E/alpha", "This is the file 'alpha'.");
        thisTest.getWc().addItem("A/B/E/beta", "This is the file 'beta'.");

        thisTest.getWc().setItemPropStatus("A/B/F", Status.Kind.none);
        thisTest.getWc().setItemOODInfo("A/B/F", FCommitRev, FAuthor,
                                        FCommitDate, NodeKind.dir);

        thisTest.getWc().setItemOODInfo("A/D", psiCommitRev, psiAuthor,
                                        psiCommitDate, NodeKind.dir);

        thisTest.getWc().setItemOODInfo("A/D/G", tauCommitRev, tauAuthor,
                                        tauCommitDate, NodeKind.dir);

        thisTest.getWc().addItem("A/D/G/pi", "This is the file 'pi'.");
        thisTest.getWc().setItemReposLastCmtRevision("A/D/G/pi", GCommitRev);
        thisTest.getWc().setItemReposKind("A/D/G/pi", NodeKind.file);

        thisTest.getWc().setItemContent("A/D/G/rho",
                                        "This is the file 'rho'.");
        thisTest.getWc().setItemOODInfo("A/D/G/rho", rhoCommitRev, rhoAuthor,
                                        rhoCommitDate, NodeKind.file);

        thisTest.getWc().setItemContent("A/D/G/tau",
                                        "This is the file 'tau'.");
        thisTest.getWc().setItemOODInfo("A/D/G/tau", tauCommitRev, tauAuthor,
                                        tauCommitDate, NodeKind.file);

        thisTest.getWc().setItemOODInfo("A/D/H", psiCommitRev, psiAuthor,
                                        psiCommitDate, NodeKind.dir);

        thisTest.getWc().setItemWorkingCopyRevision("A/D/H/nu",
            Revision.SVN_INVALID_REVNUM);
        thisTest.getWc().setItemTextStatus("A/D/H/nu", Status.Kind.none);
        thisTest.getWc().setItemNodeKind("A/D/H/nu", NodeKind.unknown);
        thisTest.getWc().setItemOODInfo("A/D/H/nu", nuCommitRev, nuAuthor,
                                        nuCommitDate, NodeKind.file);

        thisTest.getWc().setItemContent("A/D/H/chi",
                                        "This is the file 'chi'.");
        thisTest.getWc().setItemOODInfo("A/D/H/chi", chiCommitRev, chiAuthor,
                                        chiCommitDate, NodeKind.file);

        thisTest.getWc().removeItem("A/D/H/psi");
        thisTest.getWc().addItem("A/D/H/psi", "This is the file 'psi'.");
        // psi was replaced with a directory
        thisTest.getWc().setItemOODInfo("A/D/H/psi", psiCommitRev, psiAuthor,
                                        psiCommitDate, NodeKind.dir);

        thisTest.getWc().setItemPropStatus("", Status.Kind.none);
        thisTest.getWc().setItemOODInfo("", psiCommitRev, psiAuthor,
                                        psiCommitDate, NodeKind.dir);

        thisTest.checkStatus(true);
    }

    /**
     * Test SVNClient.status on externals.
     * @throws Throwable
     */
    public void testExternalStatus() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();


        // Add an externals reference to the working copy.
        client.propertySetLocal(thisTest.getWCPathSet(), "svn:externals",
                                "^/A/D/H ADHext".getBytes(),
                                Depth.empty, null, false);

        // Update the working copy to bring in the external subtree.
        client.update(thisTest.getWCPathSet(), Revision.HEAD,
                      Depth.unknown, false, false, false, false);

        // Test status of an external file
        File psi = new File(thisTest.getWorkingCopy() + "/ADHext", "psi");

        MyStatusCallback statusCallback = new MyStatusCallback();
        client.status(fileToSVNPath(psi, false), Depth.unknown,
                      false, true, true, false, false, false,
                      null, statusCallback);

        final int statusCount = statusCallback.getStatusArray().length;
        if (statusCount == 1)
        {
            Status st = statusCallback.getStatusArray()[0];
            assertFalse(st.isConflicted());
            assertEquals(Status.Kind.normal, st.getNodeStatus());
            assertEquals(NodeKind.file, st.getNodeKind());
        }
        else if (statusCount > 1)
            fail("File psi should not return more than one status.");
        else
            fail("File psi should return exactly one status.");
    }

    /**
     * Test the basic SVNClient.checkout functionality.
     * @throws Throwable
     */
    public void testBasicCheckout() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        try
        {
            // obstructed checkout must fail
            client.checkout(thisTest.getUrl() + "/A", thisTest.getWCPath(),
                            null, null, Depth.infinity, false, false);
            fail("missing exception");
        }
        catch (ClientException expected)
        {
        }
        // modify file A/mu
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter muWriter = new PrintWriter(new FileOutputStream(mu, true));
        muWriter.print("appended mu text");
        muWriter.close();
        thisTest.getWc().setItemTextStatus("A/mu", Status.Kind.modified);

        // delete A/B/lambda without svn
        File lambda = new File(thisTest.getWorkingCopy(), "A/B/lambda");
        lambda.delete();
        thisTest.getWc().setItemTextStatus("A/B/lambda", Status.Kind.missing);

        // remove A/D/G
        client.remove(thisTest.getWCPathSet("/A/D/G"),
                      false, false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/D/G", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/pi", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/rho", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/tau", Status.Kind.deleted);

        // check the status of the working copy
        thisTest.checkStatus();

        // recheckout the working copy
        client.checkout(thisTest.getUrl().toString(), thisTest.getWCPath(),
                   null, null, Depth.infinity, false, false);

        // deleted file should reapear
        thisTest.getWc().setItemTextStatus("A/B/lambda", Status.Kind.normal);

        // check the status of the working copy
        thisTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.commit functionality.
     * @throws Throwable
     */
    public void testBasicCommit() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();

        // modify file A/mu
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter muWriter = new PrintWriter(new FileOutputStream(mu, true));
        muWriter.print("appended mu text");
        muWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/mu", 2);
        thisTest.getWc().setItemContent("A/mu",
                thisTest.getWc().getItemContent("A/mu") + "appended mu text");
        addExpectedCommitItem(thisTest.getWCPath(),
                thisTest.getUrl().toString(), "A/mu",NodeKind.file,
                CommitItemStateFlags.TextMods);

        // modify file A/D/G/rho
        File rho = new File(thisTest.getWorkingCopy(), "A/D/G/rho");
        PrintWriter rhoWriter =
            new PrintWriter(new FileOutputStream(rho, true));
        rhoWriter.print("new appended text for rho");
        rhoWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 2);
        thisTest.getWc().setItemContent("A/D/G/rho",
                thisTest.getWc().getItemContent("A/D/G/rho")
                + "new appended text for rho");
        addExpectedCommitItem(thisTest.getWCPath(),
                thisTest.getUrl().toString(), "A/D/G/rho",NodeKind.file,
                CommitItemStateFlags.TextMods);

        // commit the changes
        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // check the status of the working copy
        thisTest.checkStatus();
    }

    /**
     * Test the basic property setting/getting functionality.
     * @throws Throwable
     */
    public void testBasicProperties() throws Throwable
    {
        OneTest thisTest = new OneTest();
        WC wc = thisTest.getWc();

        // Check getting properties the non-callback way
        String itemPath = fileToSVNPath(new File(thisTest.getWCPath(),
                                                 "iota"),
                                        false);

        byte[] BINARY_DATA = {-12, -125, -51, 43, 5, 47, 116, -72, -120,
                2, -98, -100, -73, 61, 118, 74, 36, 38, 56, 107, 45, 91, 38, 107, -87,
                119, -107, -114, -45, -128, -69, 96};
        setprop(itemPath, "abc", BINARY_DATA);
        Map<String, byte[]> properties = collectProperties(itemPath, null,
                                                    null, Depth.empty, null);

        assertTrue(Arrays.equals(BINARY_DATA, properties.get("abc")));

        wc.setItemPropStatus("iota", Status.Kind.modified);
        thisTest.checkStatus();

        // Check getting properties the callback way
        itemPath = fileToSVNPath(new File(thisTest.getWCPath(),
                                          "/A/B/E/alpha"),
                                 false);
        String alphaVal = "qrz";
        setprop(itemPath, "cqcq", alphaVal.getBytes());

        final Map<String, Map<String, byte[]>> propMaps =
                                    new HashMap<String, Map<String, byte[]>>();
        client.properties(itemPath, null, null, Depth.empty, null,
            new ProplistCallback () {
                public void singlePath(String path, Map<String, byte[]> props)
                { propMaps.put(path, props); }
            });
        Map<String, byte[]> propMap = propMaps.get(itemPath);
        for (String key : propMap.keySet())
        {
            assertEquals("cqcq", key);
            assertEquals(alphaVal, new String(propMap.get(key)));
        }

        wc.setItemPropStatus("A/B/E/alpha", Status.Kind.modified);
        thisTest.checkStatus();
    }

    /**
     * Test property inheritance.
     * @throws Throwable
     */
    public void testInheritedProperties() throws Throwable
    {
        OneTest thisTest = new OneTest();
        WC wc = thisTest.getWc();

        String adirPath = fileToSVNPath(new File(thisTest.getWCPath(),
                                                 "/A"),
                                        false);
        String alphaPath = fileToSVNPath(new File(thisTest.getWCPath(),
                                                  "/A/B/E/alpha"),
                                         false);

        String propval = "ybg";
        setprop(adirPath, "ahqrtz", propval.getBytes());

        final Map<String, Collection<InheritedProplistCallback.InheritedItem>> ipropMaps =
            new HashMap<String, Collection<InheritedProplistCallback.InheritedItem>>();

        client.properties(alphaPath, null, null, Depth.empty, null,
            new InheritedProplistCallback () {
                public void singlePath(
                    String path, Map<String, byte[]> props,
                    Collection<InheritedProplistCallback.InheritedItem> iprops)
                { ipropMaps.put(path, iprops); }
            });
        Collection<InheritedProplistCallback.InheritedItem> iprops = ipropMaps.get(alphaPath);
        for (InheritedProplistCallback.InheritedItem item : iprops)
        {
            for (String key : item.properties.keySet())
            {
                assertEquals("ahqrtz", key);
                assertEquals(propval, new String(item.properties.get(key)));
            }
        }

        wc.setItemPropStatus("A", Status.Kind.modified);
        thisTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.update functionality.
     * @throws Throwable
     */
    public void testBasicUpdate() throws Throwable
    {
        // build the test setup. Used for the changes
        OneTest thisTest = new OneTest();

        // build the backup test setup. That is the one that will be updated
        OneTest backupTest = thisTest.copy(".backup");

        // modify A/mu
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter muWriter = new PrintWriter(new FileOutputStream(mu, true));
        muWriter.print("appended mu text");
        muWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/mu", 2);
        thisTest.getWc().setItemContent("A/mu",
                thisTest.getWc().getItemContent("A/mu") + "appended mu text");
        addExpectedCommitItem(thisTest.getWCPath(),
                thisTest.getUrl().toString(), "A/mu",NodeKind.file,
                CommitItemStateFlags.TextMods);

        // modify A/D/G/rho
        File rho = new File(thisTest.getWorkingCopy(), "A/D/G/rho");
        PrintWriter rhoWriter =
            new PrintWriter(new FileOutputStream(rho, true));
        rhoWriter.print("new appended text for rho");
        rhoWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 2);
        thisTest.getWc().setItemContent("A/D/G/rho",
                thisTest.getWc().getItemContent("A/D/G/rho")
                + "new appended text for rho");
        addExpectedCommitItem(thisTest.getWCPath(),
                thisTest.getUrl().toString(), "A/D/G/rho",NodeKind.file,
                CommitItemStateFlags.TextMods);

        // commit the changes
        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // check the status of the working copy
        thisTest.checkStatus();

        // update the backup test
        assertEquals("wrong revision number from update",
                     update(backupTest), 2);

        // set the expected working copy layout for the backup test
        backupTest.getWc().setItemWorkingCopyRevision("A/mu", 2);
        backupTest.getWc().setItemContent("A/mu",
                backupTest.getWc().getItemContent("A/mu") + "appended mu text");
        backupTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 2);
        backupTest.getWc().setItemContent("A/D/G/rho",
                backupTest.getWc().getItemContent("A/D/G/rho")
                + "new appended text for rho");

        // check the status of the working copy of the backup test
        backupTest.checkStatus();
    }

    /**
     * Test basic SVNClient.mkdir with URL parameter functionality.
     * @throws Throwable
     */
    public void testBasicMkdirUrl() throws Throwable
    {
        // build the test setup.
        OneTest thisTest = new OneTest();

        // create Y and Y/Z directories in the repository
        addExpectedCommitItem(null, thisTest.getUrl().toString(), "Y", NodeKind.dir,
                              CommitItemStateFlags.Add);
        addExpectedCommitItem(null, thisTest.getUrl().toString(), "Y/Z", NodeKind.dir,
                              CommitItemStateFlags.Add);
        Set<String> urls = new HashSet<String>(2);
        urls.add(thisTest.getUrl() + "/Y");
        urls.add(thisTest.getUrl() + "/Y/Z");
        client.mkdir(urls, false, null, new ConstMsg("log_msg"), null);

        // add the new directories the expected working copy layout
        thisTest.getWc().addItem("Y", null);
        thisTest.getWc().setItemWorkingCopyRevision("Y", 2);
        thisTest.getWc().addItem("Y/Z", null);
        thisTest.getWc().setItemWorkingCopyRevision("Y/Z", 2);

        // update the working copy
        assertEquals("wrong revision from update",
                     update(thisTest), 2);

        // check the status of the working copy
        thisTest.checkStatus();
    }

    /**
     * Test the {@link SVNClientInterface.copy()} API.
     * @since 1.5
     */
    public void testCopy()
        throws SubversionException, IOException
    {
        OneTest thisTest = new OneTest();

        WC wc = thisTest.getWc();
        final Revision firstRevision = Revision.getInstance(1);
        final Revision pegRevision = null;  // Defaults to Revision.HEAD.

        // Copy files from A/B/E to A/B/F.
        String[] srcPaths = { "alpha", "beta" };
        List<CopySource> sources = new ArrayList<CopySource>(srcPaths.length);
        for (String fileName : srcPaths)
        {
            sources.add(
                new CopySource(new File(thisTest.getWorkingCopy(),
                                        "A/B/E/" + fileName).getPath(),
                               firstRevision, pegRevision));
            wc.addItem("A/B/F/" + fileName,
                       wc.getItemContent("A/B/E/" + fileName));
            wc.setItemWorkingCopyRevision("A/B/F/" + fileName, 2);
            addExpectedCommitItem(thisTest.getWCPath(),
                                 thisTest.getUrl().toString(),
                                  "A/B/F/" + fileName, NodeKind.file,
                                  CommitItemStateFlags.Add |
                                  CommitItemStateFlags.IsCopy);
        }
        client.copy(sources,
                    new File(thisTest.getWorkingCopy(), "A/B/F").getPath(),
                    true, false, false, false, false, null, null, null, null);

        // Commit the changes, and check the state of the WC.
        checkCommitRevision(thisTest,
                            "Unexpected WC revision number after commit", 2,
                            thisTest.getWCPathSet(), "Copy files",
                            Depth.infinity, false, false, null, null);
        thisTest.checkStatus();

        assertExpectedSuggestion(thisTest.getUrl() + "/A/B/E/alpha", "A/B/F/alpha", thisTest);

        // Now test a WC to URL copy
        List<CopySource> wcSource = new ArrayList<CopySource>(1);
        wcSource.add(new CopySource(new File(thisTest.getWorkingCopy(),
                                        "A/B").getPath(), Revision.WORKING,
                                    Revision.WORKING));
        client.copy(wcSource, thisTest.getUrl() + "/parent/A/B",
                    true, true, false, false, false, null, null,
                    new ConstMsg("Copy WC to URL"), null);

        // update the WC to get new folder and confirm the copy
        assertEquals("wrong revision number from update",
                     update(thisTest), 3);
    }


    // Set up externals references in the working copy for the
    // pin-externals tests.
    private void setupPinExternalsTest(OneTest thisTest) throws Throwable
    {
        byte[] extref = ("^/A/D/H ADHext\n" +
                         "^/A/D/H ADHext2\n" +
                         "^/A/D/H@1 peggedADHext\n" +
                         "-r1 ^/A/D/H revvedADHext\n").getBytes();
        Set<String> paths = new HashSet<String>();
        paths.add(thisTest.getWCPath() + "/A/B");

        // Add an externals reference to the working copy.
        client.propertySetLocal(paths, "svn:externals", extref,
                                Depth.empty, null, false);

        // Commit the externals definition
        client.commit(thisTest.getWCPathSet(), Depth.infinity,
                      false, false, null, null,
                      new ConstMsg("Set svn:externals"), null);

        // Update the working copy to bring in the external subtree.
        client.update(thisTest.getWCPathSet(), Revision.HEAD,
                      Depth.unknown, false, false, false, false);
    }

    /**
     * Test WC-to-WC copy with implicit pinned externals
     * @throws Throwable
     */
    public void testCopyPinExternals_wc2wc() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        setupPinExternalsTest(thisTest);

        List<CopySource> sources = new ArrayList<CopySource>(1);
        sources.add(new CopySource(thisTest.getWCPath() + "/A/B", null, null));
        String target = thisTest.getWCPath() + "/A/Bcopy";
        client.copy(sources, target, true, false, false, false,
                    true,       // pinExternals
                    null,       // externalsToPin
                    null, null, null);

        // Verification
        String expected = ("^/A/D/H@2 ADHext\n" +
                           "^/A/D/H@2 ADHext2\n" +
                           "^/A/D/H@1 peggedADHext\n" +
                           "-r1 ^/A/D/H@2 revvedADHext\n");
        String actual =
            new String(client.propertyGet(target, "svn:externals", null, null));

        assertEquals(expected, actual);
    }

    /**
     * Test WC-to-REPO copy with implicit pinned externals
     * @throws Throwable
     */
    public void testCopyPinExternals_wc2repo() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        setupPinExternalsTest(thisTest);

        List<CopySource> sources = new ArrayList<CopySource>(1);
        sources.add(new CopySource(thisTest.getWCPath() + "/A/B", null, null));
        String target = thisTest.getUrl() + "/A/Bcopy";
        client.copy(sources, target, true, false, false, false,
                    true,       // pinExternals
                    null,       // externalsToPin
                    null, new ConstMsg("Copy WC to REPO"), null);

        // Verification
        String expected = ("^/A/D/H@2 ADHext\n" +
                           "^/A/D/H@2 ADHext2\n" +
                           "^/A/D/H@1 peggedADHext\n" +
                           "-r1 ^/A/D/H@2 revvedADHext\n");
        String actual =
            new String(client.propertyGet(target, "svn:externals", null, null));

        assertEquals(expected, actual);
    }

    /**
     * Test REPO-to-WC copy with implicit pinned externals
     * @throws Throwable
     */
    public void testCopyPinExternals_repo2wc() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        setupPinExternalsTest(thisTest);

        List<CopySource> sources = new ArrayList<CopySource>(1);
        sources.add(new CopySource(thisTest.getUrl() + "/A/B", null, null));
        String target = thisTest.getWCPath() + "/A/Bcopy";
        client.copy(sources, target, true, false, false, false,
                    true,       // pinExternals
                    null,       // externalsToPin
                    null, null, null);

        // Verification
        String expected = ("^/A/D/H@2 ADHext\n" +
                           "^/A/D/H@2 ADHext2\n" +
                           "^/A/D/H@1 peggedADHext\n" +
                           "-r1 ^/A/D/H@2 revvedADHext\n");
        String actual =
            new String(client.propertyGet(target, "svn:externals", null, null));

        assertEquals(expected, actual);
    }

    /**
     * Test REPO-to-REPO copy with implicit pinned externals
     * @throws Throwable
     */
    public void testCopyPinExternals_repo2repo() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        setupPinExternalsTest(thisTest);

        List<CopySource> sources = new ArrayList<CopySource>(1);
        sources.add(new CopySource(thisTest.getUrl() + "/A/B", null, null));
        String target = thisTest.getUrl() + "/A/Bcopy";
        client.copy(sources, target, true, false, false, false,
                    true,       // pinExternals
                    null,       // externalsToPin
                    null, new ConstMsg("Copy WC to REPO"), null);

        // Verification
        String expected = ("^/A/D/H@2 ADHext\n" +
                           "^/A/D/H@2 ADHext2\n" +
                           "^/A/D/H@1 peggedADHext\n" +
                           "-r1 ^/A/D/H@2 revvedADHext\n");
        String actual =
            new String(client.propertyGet(target, "svn:externals", null, null));

        assertEquals(expected, actual);
    }

    /**
     * Test REPO-to-REPO copy with eplicit pinned externals
     * @throws Throwable
     */
    public void testCopyPinExternals_repo2repo_explicit() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        setupPinExternalsTest(thisTest);

        String sourceUrl = thisTest.getUrl() + "/A/B";
        Map<String, List<ExternalItem>> externalsToPin =
            new HashMap<String, List<ExternalItem>>();
        List<ExternalItem> items = new ArrayList<ExternalItem>(1);
        items.add(new ExternalItem("ADHext", "^/A/D/H", null, null));
        externalsToPin.put(sourceUrl, items);

        List<CopySource> sources = new ArrayList<CopySource>(1);
        sources.add(new CopySource(sourceUrl, null, null));
        String target = thisTest.getUrl() + "/A/Bcopy";
        client.copy(sources, target, true, false, false, false,
                    true,       // pinExternals
                    externalsToPin,
                    null, new ConstMsg("Copy WC to REPO"), null);

        // Verification
        String expected = ("^/A/D/H@2 ADHext\n" +
                           "^/A/D/H ADHext2\n" +
                           "^/A/D/H@1 peggedADHext\n" +
                           "-r1 ^/A/D/H revvedADHext\n");
        String actual =
            new String(client.propertyGet(target, "svn:externals", null, null));

        assertEquals(expected, actual);
    }

    /**
     * Test REPO-to-REPO copy with explicit pinned externals that
     * don't correspond to actual externals
     * @throws Throwable
     */
    public void testCopyPinExternals_repo2repo_corkscrew() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        setupPinExternalsTest(thisTest);

        String sourceUrl = thisTest.getUrl() + "/A/B";
        Map<String, List<ExternalItem>> externalsToPin =
            new HashMap<String, List<ExternalItem>>();
        List<ExternalItem> items = new ArrayList<ExternalItem>(1);
        items.add(new ExternalItem("ADHext", "^/A/D/H", null, null));
        externalsToPin.put(sourceUrl + "/A", items);

        List<CopySource> sources = new ArrayList<CopySource>(1);
        sources.add(new CopySource(sourceUrl, null, null));
        String target = thisTest.getUrl() + "/A/Bcopy";
        client.copy(sources, target, true, false, false, false,
                    true,       // pinExternals
                    externalsToPin,
                    null, new ConstMsg("Copy WC to REPO"), null);

        // Verification
        String expected = ("^/A/D/H ADHext\n" +
                           "^/A/D/H ADHext2\n" +
                           "^/A/D/H@1 peggedADHext\n" +
                           "-r1 ^/A/D/H revvedADHext\n");
        String actual =
            new String(client.propertyGet(target, "svn:externals", null, null));

        assertEquals(expected, actual);
    }

    /**
     * Test the {@link SVNClientInterface.move()} API.
     * @since 1.5
     */
    public void testMove()
        throws SubversionException, IOException
    {
        OneTest thisTest = new OneTest();
        WC wc = thisTest.getWc();

        // Move files from A/B/E to A/B/F.
        Set<String> relPaths = new HashSet<String>(2);
        relPaths.add("alpha");
        relPaths.add("beta");
        Set<String> srcPaths = new HashSet<String>(2);
        for (String fileName : relPaths)
        {
            srcPaths.add(new File(thisTest.getWorkingCopy(),
                                  "A/B/E/" + fileName).getPath());

            wc.addItem("A/B/F/" + fileName,
                       wc.getItemContent("A/B/E/" + fileName));
            wc.setItemWorkingCopyRevision("A/B/F/" + fileName, 2);
            addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                                  "A/B/F/" + fileName, NodeKind.file,
                                  CommitItemStateFlags.Add |
                                  CommitItemStateFlags.IsCopy);

            wc.removeItem("A/B/E/" + fileName);
            addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                                  "A/B/E/" + fileName, NodeKind.file,
                                  CommitItemStateFlags.Delete);
        }
        client.move(srcPaths,
                    new File(thisTest.getWorkingCopy(), "A/B/F").getPath(),
                    false, true, false, false, false, null, null, null);

        MyStatusCallback statusCallback = new MyStatusCallback();
        String statusPath = fileToSVNPath(new File(thisTest.getWCPath() + "/A/B"), true);
        client.status(statusPath, Depth.infinity,
                      false, true, false, false, true, false,
                      null, statusCallback);
        Status[] statusList = statusCallback.getStatusArray();
        assertEquals(statusPath + "/F/alpha",
                     statusList[0].getMovedToAbspath());
        assertEquals(statusPath + "/F/beta",
                     statusList[1].getMovedToAbspath());
        assertEquals(statusPath + "/E/alpha",
                     statusList[2].getMovedFromAbspath());
        assertEquals(statusPath + "/E/beta",
                     statusList[3].getMovedFromAbspath());

        // Commit the changes, and check the state of the WC.
        checkCommitRevision(thisTest,
                            "Unexpected WC revision number after commit", 2,
                            thisTest.getWCPathSet(), "Move files",
                            Depth.infinity, false, false, null, null);
        thisTest.checkStatus();

        assertExpectedSuggestion(thisTest.getUrl() + "/A/B/E/alpha", "A/B/F/alpha", thisTest);
    }

    /**
     * Check that half a move cannot be committed.
     * @since 1.9
     */
    public void testCommitPartialMove() throws Throwable
    {
        OneTest thisTest = new OneTest();
        String root = thisTest.getWorkingCopy().getAbsolutePath();
        ClientException caught = null;

        Set<String> srcPaths = new HashSet<String>(1);
        srcPaths.add(root + "/A/B/E/alpha");
        client.move(srcPaths, root + "/moved-alpha",
                    false, false, false, false, false, null, null, null);

        try {
            client.commit(srcPaths, Depth.infinity, false, false, null, null,
                          new ConstMsg("Commit half of a move"), null);
        } catch (ClientException ex) {
            caught = ex;
        }

        assertNotNull("Commit of partial move did not fail", caught);

        List<ClientException.ErrorMessage> msgs = caught.getAllMessages();
        assertTrue(msgs.size() >= 3);
        assertTrue(msgs.get(0).getMessage().startsWith("Illegal target"));
        assertTrue(msgs.get(1).getMessage().startsWith("Commit failed"));
        assertTrue(msgs.get(2).getMessage().startsWith("Cannot commit"));
    }

    /**
     * Assert that the first merge source suggested for
     * <code>destPath</code> at {@link Revision#WORKING} and {@link
     * Revision#HEAD} is equivalent to <code>expectedSrc</code>.
     * @exception SubversionException If retrieval of the copy source fails.
     * @since 1.5
     */
    private void assertExpectedSuggestion(String expectedSrc,
                                          String destPath, OneTest thisTest)
        throws SubversionException
    {
        String wcPath = fileToSVNPath(new File(thisTest.getWCPath(),
                                               destPath), false);
        Set<String> suggestions = client.suggestMergeSources(wcPath,
                                                             Revision.WORKING);
        assertNotNull(suggestions);
        assertTrue(suggestions.size() >= 1);
        assertTrue("Copy source path not found in suggestions: " +
                   expectedSrc,
                   suggestions.contains(expectedSrc));

        // Same test using URL
        String url = thisTest.getUrl() + "/" + destPath;
        suggestions = client.suggestMergeSources(url, Revision.HEAD);
        assertNotNull(suggestions);
        assertTrue(suggestions.size() >= 1);
        assertTrue("Copy source path not found in suggestions: " +
                   expectedSrc,
                   suggestions.contains(expectedSrc));

    }

    /**
     * Tests that the passed start and end revision are contained
     * within the array of revisions.
     * @since 1.5
     */
    private void assertExpectedMergeRange(long start, long end,
                                          long[] revisions)
    {
        Arrays.sort(revisions);
        for (int i = 0; i < revisions.length; i++) {
            if (revisions[i] <= start) {
                for (int j = i; j < revisions.length; j++)
                {
                    if (end <= revisions[j])
                        return;
                }
                fail("End revision: " + end + " was not in range: " + revisions[0] +
                        " : " + revisions[revisions.length - 1]);
                return;
            }
        }
        fail("Start revision: " + start + " was not in range: " + revisions[0] +
                " : " + revisions[revisions.length - 1]);
    }

    /**
     * Test the basic SVNClient.update functionality with concurrent
     * changes in the repository and the working copy.
     * @throws Throwable
     */
    public void testBasicMergingUpdate() throws Throwable
    {
        // build the first working copy
        OneTest thisTest = new OneTest();

        // append 10 lines to A/mu
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter muWriter = new PrintWriter(new FileOutputStream(mu, true));
        String muContent = thisTest.getWc().getItemContent("A/mu");
        for (int i = 2; i < 11; i++)
        {
            muWriter.print("\nThis is line " + i + " in mu");
            muContent = muContent + "\nThis is line " + i + " in mu";
        }
        muWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/mu", 2);
        thisTest.getWc().setItemContent("A/mu", muContent);
        addExpectedCommitItem(thisTest.getWorkingCopy().getAbsolutePath(),
                              thisTest.getUrl().toString(), "A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);

        // append 10 line to A/D/G/rho
        File rho = new File(thisTest.getWorkingCopy(), "A/D/G/rho");
        PrintWriter rhoWriter =
            new PrintWriter(new FileOutputStream(rho, true));
        String rhoContent = thisTest.getWc().getItemContent("A/D/G/rho");
        for (int i = 2; i < 11; i++)
        {
            rhoWriter.print("\nThis is line " + i + " in rho");
            rhoContent = rhoContent + "\nThis is line " + i + " in rho";
        }
        rhoWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 2);
        thisTest.getWc().setItemContent("A/D/G/rho", rhoContent);
        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/D/G/rho",
                              NodeKind.file, CommitItemStateFlags.TextMods);

        // commit the changes
        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // check the status of the first working copy
        thisTest.checkStatus();

        // create a backup copy of the working copy
        OneTest backupTest = thisTest.copy(".backup");

        // change the last line of A/mu in the first working copy
        muWriter = new PrintWriter(new FileOutputStream(mu, true));
        muContent = thisTest.getWc().getItemContent("A/mu");
        muWriter.print(" Appended to line 10 of mu");
        muContent = muContent + " Appended to line 10 of mu";
        muWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/mu", 3);
        thisTest.getWc().setItemContent("A/mu", muContent);
        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);

        // change the last line of A/mu in the first working copy
        rhoWriter = new PrintWriter(new FileOutputStream(rho, true));
        rhoContent = thisTest.getWc().getItemContent("A/D/G/rho");
        rhoWriter.print(" Appended to line 10 of rho");
        rhoContent = rhoContent + " Appended to line 10 of rho";
        rhoWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 3);
        thisTest.getWc().setItemContent("A/D/G/rho", rhoContent);
        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/D/G/rho",
                              NodeKind.file,
                              CommitItemStateFlags.TextMods);

        // commit these changes to the repository
        checkCommitRevision(thisTest, "wrong revision number from commit", 3,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // check the status of the first working copy
        thisTest.checkStatus();

        // modify the first line of A/mu in the backup working copy
        mu = new File(backupTest.getWorkingCopy(), "A/mu");
        muWriter = new PrintWriter(new FileOutputStream(mu));
        muWriter.print("This is the new line 1 in the backup copy of mu");
        muContent = "This is the new line 1 in the backup copy of mu";
        for (int i = 2; i < 11; i++)
        {
            muWriter.print("\nThis is line " + i + " in mu");
            muContent = muContent + "\nThis is line " + i + " in mu";
        }
        muWriter.close();
        backupTest.getWc().setItemWorkingCopyRevision("A/mu", 3);
        muContent = muContent + " Appended to line 10 of mu";
        backupTest.getWc().setItemContent("A/mu", muContent);
        backupTest.getWc().setItemTextStatus("A/mu", Status.Kind.modified);

        // modify the first line of A/D/G/rho in the backup working copy
        rho = new File(backupTest.getWorkingCopy(), "A/D/G/rho");
        rhoWriter = new PrintWriter(new FileOutputStream(rho));
        rhoWriter.print("This is the new line 1 in the backup copy of rho");
        rhoContent = "This is the new line 1 in the backup copy of rho";
        for (int i = 2; i < 11; i++)
        {
            rhoWriter.print("\nThis is line " + i + " in rho");
            rhoContent = rhoContent + "\nThis is line " + i + " in rho";
        }
        rhoWriter.close();
        backupTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 3);
        rhoContent = rhoContent + " Appended to line 10 of rho";
        backupTest.getWc().setItemContent("A/D/G/rho", rhoContent);
        backupTest.getWc().setItemTextStatus("A/D/G/rho", Status.Kind.modified);

        // update the backup working copy
        assertEquals("wrong revision number from update",
                     update(backupTest), 3);

        // check the status of the backup working copy
        backupTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.update functionality with concurrent
     * changes in the repository and the working copy that generate
     * conflicts.
     * @throws Throwable
     */
    public void testBasicConflict() throws Throwable
    {
        // build the first working copy
        OneTest thisTest = new OneTest();

        // copy the first working copy to the backup working copy
        OneTest backupTest = thisTest.copy(".backup");

        // append a line to A/mu in the first working copy
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter muWriter = new PrintWriter(new FileOutputStream(mu, true));
        String muContent = thisTest.getWc().getItemContent("A/mu");
        muWriter.print("\nOriginal appended text for mu");
        muContent = muContent + "\nOriginal appended text for mu";
        muWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/mu", 2);
        thisTest.getWc().setItemContent("A/mu", muContent);
        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);

        // append a line to A/D/G/rho in the first working copy
        File rho = new File(thisTest.getWorkingCopy(), "A/D/G/rho");
        PrintWriter rhoWriter =
            new PrintWriter(new FileOutputStream(rho, true));
        String rhoContent = thisTest.getWc().getItemContent("A/D/G/rho");
        rhoWriter.print("\nOriginal appended text for rho");
        rhoContent = rhoContent + "\nOriginal appended text for rho";
        rhoWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 2);
        thisTest.getWc().setItemContent("A/D/G/rho", rhoContent);
        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/D/G/rho", NodeKind.file,
                              CommitItemStateFlags.TextMods);

        // commit the changes in the first working copy
        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // test the status of the working copy after the commit
        thisTest.checkStatus();

        // append a different line to A/mu in the backup working copy
        mu = new File(backupTest.getWorkingCopy(), "A/mu");
        muWriter = new PrintWriter(new FileOutputStream(mu, true));
        muWriter.print("\nConflicting appended text for mu");
        muContent = "<<<<<<< .mine\nThis is the file 'mu'.\n"+
                    "Conflicting appended text for mu=======\n"+
                    "This is the file 'mu'.\n"+
                    "Original appended text for mu>>>>>>> .r2";
        muWriter.close();
        backupTest.getWc().setItemWorkingCopyRevision("A/mu", 2);
        backupTest.getWc().setItemContent("A/mu", muContent);
        backupTest.getWc().setItemTextStatus("A/mu", Status.Kind.conflicted);
        backupTest.getWc().addItem("A/mu.r1", "");
        backupTest.getWc().setItemNodeKind("A/mu.r1", NodeKind.unknown);
        backupTest.getWc().setItemTextStatus("A/mu.r1",
                                             Status.Kind.unversioned);
        backupTest.getWc().addItem("A/mu.r2", "");
        backupTest.getWc().setItemNodeKind("A/mu.r2", NodeKind.unknown);
        backupTest.getWc().setItemTextStatus("A/mu.r2",
                                             Status.Kind.unversioned);
        backupTest.getWc().addItem("A/mu.mine", "");
        backupTest.getWc().setItemNodeKind("A/mu.mine", NodeKind.unknown);
        backupTest.getWc().setItemTextStatus("A/mu.mine",
                                             Status.Kind.unversioned);

        // append a different line to A/D/G/rho in the backup working copy
        rho = new File(backupTest.getWorkingCopy(), "A/D/G/rho");
        rhoWriter = new PrintWriter(new FileOutputStream(rho, true));
        rhoWriter.print("\nConflicting appended text for rho");
        rhoContent = "<<<<<<< .mine\nThis is the file 'rho'.\n"+
                    "Conflicting appended text for rho=======\n"+
                    "his is the file 'rho'.\n"+
                    "Original appended text for rho>>>>>>> .r2";
        rhoWriter.close();
        backupTest.getWc().setItemWorkingCopyRevision("A/D/G/rho", 2);
        backupTest.getWc().setItemContent("A/D/G/rho", rhoContent);
        backupTest.getWc().setItemTextStatus("A/D/G/rho",
                                             Status.Kind.conflicted);
        backupTest.getWc().addItem("A/D/G/rho.r1", "");
        backupTest.getWc().setItemNodeKind("A/D/G/rho.r1", NodeKind.unknown);
        backupTest.getWc().setItemTextStatus("A/D/G/rho.r1",
                                             Status.Kind.unversioned);
        backupTest.getWc().addItem("A/D/G/rho.r2", "");
        backupTest.getWc().setItemNodeKind("A/D/G/rho.r2", NodeKind.unknown);
        backupTest.getWc().setItemTextStatus("A/D/G/rho.r2",
                                             Status.Kind.unversioned);
        backupTest.getWc().addItem("A/D/G/rho.mine", "");
        backupTest.getWc().setItemNodeKind("A/D/G/rho.mine", NodeKind.unknown);
        backupTest.getWc().setItemTextStatus("A/D/G/rho.mine",
                                             Status.Kind.unversioned);

        // update the backup working copy from the repository
        assertEquals("wrong revision number from update",
                     update(backupTest), 2);

        // check the status of the backup working copy
        backupTest.checkStatus();

        // flag A/mu as resolved
        client.resolve(backupTest.getWCPath()+"/A/mu", Depth.empty,
                ConflictResult.Choice.chooseMerged);
        backupTest.getWc().setItemTextStatus("A/mu", Status.Kind.modified);
        backupTest.getWc().removeItem("A/mu.r1");
        backupTest.getWc().removeItem("A/mu.r2");
        backupTest.getWc().removeItem("A/mu.mine");

        // flag A/D/G/rho as resolved
        client.resolve(backupTest.getWCPath()+"/A/D/G/rho", Depth.empty,
                ConflictResult.Choice.chooseMerged);
        backupTest.getWc().setItemTextStatus("A/D/G/rho",
                                             Status.Kind.modified);
        backupTest.getWc().removeItem("A/D/G/rho.r1");
        backupTest.getWc().removeItem("A/D/G/rho.r2");
        backupTest.getWc().removeItem("A/D/G/rho.mine");

        // check the status after the conflicts are flaged as resolved
        backupTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.cleanup functionality.
     * Without a way to force a lock, this test just verifies
     * the method can be called successfully.
     * @throws Throwable
     */
    public void testBasicCleanup() throws Throwable
    {
        // create a test working copy
        OneTest thisTest = new OneTest();

        // run cleanup
        client.cleanup(thisTest.getWCPath());

    }

    /**
     * Test the basic SVNClient.revert functionality.
     * @throws Throwable
     */
    public void testBasicRevert() throws Throwable
    {
        // create a test working copy
        OneTest thisTest = new OneTest();

        // modify A/B/E/beta
        File file = new File(thisTest.getWorkingCopy(), "A/B/E/beta");
        PrintWriter pw = new PrintWriter(new FileOutputStream(file, true));
        pw.print("Added some text to 'beta'.");
        pw.close();
        thisTest.getWc().setItemTextStatus("A/B/E/beta", Status.Kind.modified);

        // modify iota
        file = new File(thisTest.getWorkingCopy(), "iota");
        pw = new PrintWriter(new FileOutputStream(file, true));
        pw.print("Added some text to 'iota'.");
        pw.close();
        thisTest.getWc().setItemTextStatus("iota", Status.Kind.modified);

        // modify A/D/G/rho
        file = new File(thisTest.getWorkingCopy(), "A/D/G/rho");
        pw = new PrintWriter(new FileOutputStream(file, true));
        pw.print("Added some text to 'rho'.");
        pw.close();
        thisTest.getWc().setItemTextStatus("A/D/G/rho", Status.Kind.modified);

        // create new file A/D/H/zeta and add it to subversion
        file = new File(thisTest.getWorkingCopy(), "A/D/H/zeta");
        pw = new PrintWriter(new FileOutputStream(file, true));
        pw.print("Added some text to 'zeta'.");
        pw.close();
        thisTest.getWc().addItem("A/D/H/zeta", "Added some text to 'zeta'.");
        thisTest.getWc().setItemTextStatus("A/D/H/zeta", Status.Kind.added);
        client.add(file.getAbsolutePath(), Depth.empty, false, false, false);

        // test the status of the working copy
        thisTest.checkStatus();

        // revert the changes
        client.revert(thisTest.getWCPath()+"/A/B/E/beta", Depth.empty, null);
        thisTest.getWc().setItemTextStatus("A/B/E/beta", Status.Kind.normal);
        client.revert(thisTest.getWCPath()+"/iota", Depth.empty, null);
        thisTest.getWc().setItemTextStatus("iota", Status.Kind.normal);
        client.revert(thisTest.getWCPath()+"/A/D/G/rho", Depth.empty, null);
        thisTest.getWc().setItemTextStatus("A/D/G/rho", Status.Kind.normal);
        client.revert(thisTest.getWCPath()+"/A/D/H/zeta", Depth.empty, null);
        thisTest.getWc().setItemTextStatus("A/D/H/zeta",
                Status.Kind.unversioned);
        thisTest.getWc().setItemNodeKind("A/D/H/zeta", NodeKind.unknown);

        // test the status of the working copy
        thisTest.checkStatus();

        // delete A/B/E/beta and revert the change
        file = new File(thisTest.getWorkingCopy(), "A/B/E/beta");
        file.delete();
        client.revert(file.getAbsolutePath(), Depth.empty, null);

        // resurected file should not be readonly
        assertTrue("reverted file is not readonly",
                file.canWrite()&& file.canRead());

        // test the status of the working copy
        thisTest.checkStatus();

        // create & add the directory X
        client.mkdir(thisTest.getWCPathSet("/X"), false, null, null, null);
        thisTest.getWc().addItem("X", null);
        thisTest.getWc().setItemTextStatus("X", Status.Kind.added);

        // test the status of the working copy
        thisTest.checkStatus();

        // remove & revert X
        removeDirOrFile(new File(thisTest.getWorkingCopy(), "X"));
        client.revert(thisTest.getWCPath()+"/X", Depth.empty, null);
        thisTest.getWc().removeItem("X");

        // test the status of the working copy
        thisTest.checkStatus();

        // delete the directory A/B/E
        client.remove(thisTest.getWCPathSet("/A/B/E"), true,
                      false, null, null, null);
        removeDirOrFile(new File(thisTest.getWorkingCopy(), "A/B/E"));
        thisTest.getWc().setItemTextStatus("A/B/E", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/B/E/alpha", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/B/E/beta", Status.Kind.deleted);

        // test the status of the working copy
        thisTest.checkStatus();

        // revert A/B/E -> this will resurect it
        client.revert(thisTest.getWCPath()+"/A/B/E", Depth.infinity, null);
        thisTest.getWc().setItemTextStatus("A/B/E", Status.Kind.normal);
        thisTest.getWc().setItemTextStatus("A/B/E/alpha", Status.Kind.normal);
        thisTest.getWc().setItemTextStatus("A/B/E/beta", Status.Kind.normal);

        // test the status of the working copy
        thisTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.switch functionality.
     * @throws Throwable
     */
    public void testBasicSwitch() throws Throwable
    {
        // create the test working copy
        OneTest thisTest = new OneTest();

        // switch iota to A/D/gamma
        String iotaPath = thisTest.getWCPath() + "/iota";
        String gammaUrl = thisTest.getUrl() + "/A/D/gamma";
        thisTest.getWc().setItemContent("iota",
                greekWC.getItemContent("A/D/gamma"));
        thisTest.getWc().setItemIsSwitched("iota", true);
        client.doSwitch(iotaPath, gammaUrl, null, Revision.HEAD, Depth.unknown,
                        false, false, false, true);

        // check the status of the working copy
        thisTest.checkStatus();

        // switch A/D/H to /A/D/G
        String adhPath = thisTest.getWCPath() + "/A/D/H";
        String adgURL = thisTest.getUrl() + "/A/D/G";
        thisTest.getWc().setItemIsSwitched("A/D/H",true);
        thisTest.getWc().removeItem("A/D/H/chi");
        thisTest.getWc().removeItem("A/D/H/omega");
        thisTest.getWc().removeItem("A/D/H/psi");
        thisTest.getWc().addItem("A/D/H/pi",
                thisTest.getWc().getItemContent("A/D/G/pi"));
        thisTest.getWc().addItem("A/D/H/rho",
                thisTest.getWc().getItemContent("A/D/G/rho"));
        thisTest.getWc().addItem("A/D/H/tau",
                thisTest.getWc().getItemContent("A/D/G/tau"));
        client.doSwitch(adhPath, adgURL, null, Revision.HEAD, Depth.files,
                        false, false, false, true);

        // check the status of the working copy
        thisTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.remove functionality.
     * @throws Throwable
     */
    public void testBasicDelete() throws Throwable
    {
        // create the test working copy
        OneTest thisTest = new OneTest();

        // modify A/D/H/chi
        File file = new File(thisTest.getWorkingCopy(), "A/D/H/chi");
        Set<String> pathSet = new HashSet<String>();
        PrintWriter pw = new PrintWriter(new FileOutputStream(file, true));
        pw.print("added to chi");
        pw.close();
        thisTest.getWc().setItemTextStatus("A/D/H/chi", Status.Kind.modified);

        // set a property on A/D/G/rho file
        pathSet.clear();
        pathSet.add(thisTest.getWCPath()+"/A/D/G/rho");
        client.propertySetLocal(pathSet, "abc", (new String("def")).getBytes(),
                                Depth.infinity, null, false);
        thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.modified);

        // set a property on A/B/F directory
        setprop(thisTest.getWCPath()+"/A/B/F", "abc", "def");
        thisTest.getWc().setItemPropStatus("A/B/F", Status.Kind.modified);

        // create a unversioned A/C/sigma file
        file = new File(thisTest.getWCPath(),"A/C/sigma");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("unversioned sigma");
        pw.close();
        thisTest.getWc().addItem("A/C/sigma", "unversioned sigma");
        thisTest.getWc().setItemTextStatus("A/C/sigma", Status.Kind.unversioned);
        thisTest.getWc().setItemNodeKind("A/C/sigma", NodeKind.unknown);

        // create unversioned directory A/C/Q
        file = new File(thisTest.getWCPath(), "A/C/Q");
        file.mkdir();
        thisTest.getWc().addItem("A/C/Q", null);
        thisTest.getWc().setItemNodeKind("A/C/Q", NodeKind.unknown);
        thisTest.getWc().setItemTextStatus("A/C/Q", Status.Kind.unversioned);

        // create & add the directory A/B/X
        file = new File(thisTest.getWCPath(), "A/B/X");
        pathSet.clear();
        pathSet.add(file.getAbsolutePath());
        client.mkdir(pathSet, false, null, null, null);
        thisTest.getWc().addItem("A/B/X", null);
        thisTest.getWc().setItemTextStatus("A/B/X", Status.Kind.added);

        // create & add the file A/B/X/xi
        file = new File(file, "xi");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("added xi");
        pw.close();
        client.add(file.getAbsolutePath(), Depth.empty, false, false, false);
        thisTest.getWc().addItem("A/B/X/xi", "added xi");
        thisTest.getWc().setItemTextStatus("A/B/X/xi", Status.Kind.added);

        // create & add the directory A/B/Y
        file = new File(thisTest.getWCPath(), "A/B/Y");
        pathSet.clear();
        pathSet.add(file.getAbsolutePath());
        client.mkdir(pathSet, false, null, null, null);
        thisTest.getWc().addItem("A/B/Y", null);
        thisTest.getWc().setItemTextStatus("A/B/Y", Status.Kind.added);

        // test the status of the working copy
        thisTest.checkStatus();

        // the following removes should all fail without force

        try
        {
            // remove of A/D/H/chi without force should fail, because it is
            // modified
            client.remove(thisTest.getWCPathSet("/A/D/H/chi"),
                    false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/D/H without force should fail, because A/D/H/chi is
            // modified
            client.remove(thisTest.getWCPathSet("/A/D/H"),
                    false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/D/G/rho without force should fail, because it has
            // a new property
            client.remove(thisTest.getWCPathSet("/A/D/G/rho"),
                    false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/D/G without force should fail, because A/D/G/rho has
            // a new property
            client.remove(thisTest.getWCPathSet("/A/D/G"),
                    false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/B/F without force should fail, because it has
            // a new property
            client.remove(thisTest.getWCPathSet("/A/B/F"),
                    false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/B without force should fail, because A/B/F has
            // a new property
            client.remove(thisTest.getWCPathSet("/A/B"),
                    false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/C/sigma without force should fail, because it is
            // unversioned
            client.remove(thisTest.getWCPathSet("/A/C/sigma"),
                          false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/C without force should fail, because A/C/sigma is
            // unversioned
            client.remove(thisTest.getWCPathSet("/A/C"),
                          false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        try
        {
            // remove of A/B/X without force should fail, because it is new
            client.remove(thisTest.getWCPathSet("/A/B/X"),
                          false, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        // check the status of the working copy
        thisTest.checkStatus();

        // the following removes should all work
        client.remove(thisTest.getWCPathSet("/A/B/E"),
                      false, false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/B/E",Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/B/E/alpha",Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/B/E/beta",Status.Kind.deleted);
        client.remove(thisTest.getWCPathSet("/A/D/H"), true,
                      false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/D/H",Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/H/chi",Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/H/omega",Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/H/psi",Status.Kind.deleted);
        client.remove(thisTest.getWCPathSet("/A/D/G"), true,
                      false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/D/G",Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/rho",Status.Kind.deleted);
        thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.none);
        thisTest.getWc().setItemTextStatus("A/D/G/pi",Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/tau",Status.Kind.deleted);
        client.remove(thisTest.getWCPathSet("/A/B/F"), true,
                      false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/B/F",Status.Kind.deleted);
        thisTest.getWc().setItemPropStatus("A/B/F", Status.Kind.none);
        client.remove(thisTest.getWCPathSet("/A/C"), true,
                      false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/C",Status.Kind.deleted);
        client.remove(thisTest.getWCPathSet("/A/B/X"), true,
                      false, null, null, null);
        file = new File(thisTest.getWorkingCopy(), "iota");
        file.delete();
        pathSet.clear();
        pathSet.add(file.getAbsolutePath());
        client.remove(pathSet, true, false, null, null, null);
        thisTest.getWc().setItemTextStatus("iota",Status.Kind.deleted);
        file = new File(thisTest.getWorkingCopy(), "A/D/gamma");
        file.delete();
        pathSet.clear();
        pathSet.add(file.getAbsolutePath());
        client.remove(pathSet, false, false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/D/gamma",Status.Kind.deleted);
        pathSet.clear();
        pathSet.add(file.getAbsolutePath());
        client.remove(pathSet, true, false, null, null, null);
        client.remove(thisTest.getWCPathSet("/A/B/E"),
                      false, false, null, null, null);
        thisTest.getWc().removeItem("A/B/X");
        thisTest.getWc().removeItem("A/B/X/xi");
        thisTest.getWc().removeItem("A/C/sigma");
        thisTest.getWc().removeItem("A/C/Q");
        thisTest.checkStatus();
        client.remove(thisTest.getWCPathSet("/A/D"), true,
                      false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/D", Status.Kind.deleted);
        thisTest.getWc().removeItem("A/D/Y");

        // check the status of the working copy
        thisTest.checkStatus();

        // confirm that the file are really deleted
        assertFalse("failed to remove text modified file",
                new File(thisTest.getWorkingCopy(), "A/D/G/rho").exists());
        assertFalse("failed to remove prop modified file",
                new File(thisTest.getWorkingCopy(), "A/D/H/chi").exists());
        assertFalse("failed to remove unversioned file",
                new File(thisTest.getWorkingCopy(), "A/C/sigma").exists());
        assertFalse("failed to remove unmodified file",
                new File(thisTest.getWorkingCopy(), "A/B/E/alpha").exists());
        file = new File(thisTest.getWorkingCopy(),"A/B/F");
        assertFalse("failed to remove versioned dir", file.exists());
        assertFalse("failed to remove unversioned dir",
                new File(thisTest.getWorkingCopy(), "A/C/Q").exists());
        assertFalse("failed to remove added dir",
                new File(thisTest.getWorkingCopy(), "A/B/X").exists());

        // delete unversioned file foo
        file = new File(thisTest.getWCPath(),"foo");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("unversioned foo");
        pw.close();
        pathSet.clear();
        pathSet.add(file.getAbsolutePath());
        client.remove(pathSet, true, false, null, null, null);
        assertFalse("failed to remove unversioned file foo", file.exists());

        try
        {
            // delete non-existent file foo
            Set<String> paths = new HashSet<String>(1);
            paths.add(file.getAbsolutePath());
            client.remove(paths, true, false, null, null, null);
            fail("missing exception");
        }
        catch(ClientException expected)
        {
        }

        // delete file iota in the repository
        addExpectedCommitItem(null, thisTest.getUrl().toString(), "iota",
                             NodeKind.none, CommitItemStateFlags.Delete);
        client.remove(thisTest.getUrlSet("/iota"), false, false, null,
                      new ConstMsg("delete iota URL"), null);
    }

    public void testBasicCheckoutDeleted() throws Throwable
    {
        // create working copy
        OneTest thisTest = new OneTest();

        // delete A/D and its content
        client.remove(thisTest.getWCPathSet("/A/D"), true,
                      false, null, null, null);
        thisTest.getWc().setItemTextStatus("A/D", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/rho", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/pi", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/G/tau", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/H", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/H/chi", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/H/psi", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/H/omega", Status.Kind.deleted);
        thisTest.getWc().setItemTextStatus("A/D/gamma", Status.Kind.deleted);

        // check the working copy status
        thisTest.checkStatus();

        // commit the change
        addExpectedCommitItem(thisTest.getWCPath(),
                thisTest.getUrl().toString(), "A/D", NodeKind.dir,
                CommitItemStateFlags.Delete);
        checkCommitRevision(thisTest, "wrong revision from commit", 2,
                            thisTest.getWCPathSet(), "log message",
                            Depth.infinity, false, false, null, null);
        thisTest.getWc().removeItem("A/D");
        thisTest.getWc().removeItem("A/D/G");
        thisTest.getWc().removeItem("A/D/G/rho");
        thisTest.getWc().removeItem("A/D/G/pi");
        thisTest.getWc().removeItem("A/D/G/tau");
        thisTest.getWc().removeItem("A/D/H");
        thisTest.getWc().removeItem("A/D/H/chi");
        thisTest.getWc().removeItem("A/D/H/psi");
        thisTest.getWc().removeItem("A/D/H/omega");
        thisTest.getWc().removeItem("A/D/gamma");

        // check the working copy status
        thisTest.checkStatus();

        // check out the previous revision
        client.checkout(thisTest.getUrl()+"/A/D",
                thisTest.getWCPath()+"/new_D", new Revision.Number(1),
                new Revision.Number(1), Depth.infinity, false, false);
    }

    /**
     * Test the basic SVNClient.import functionality.
     * @throws Throwable
     */
    public void testBasicImport() throws Throwable
    {
        // create the working copy
        OneTest thisTest = new OneTest();

        // create new_file
        File file = new File(thisTest.getWCPath(),"new_file");
        PrintWriter pw = new PrintWriter(new FileOutputStream(file));
        pw.print("some text");
        pw.close();

        // import new_file info dirA/dirB/newFile
        addExpectedCommitItem(thisTest.getWCPath(),
                null, "new_file", NodeKind.none, CommitItemStateFlags.Add);
        client.doImport(file.getAbsolutePath(),
                thisTest.getUrl()+"/dirA/dirB/new_file", Depth.infinity,
                false, false, null,
                new ConstMsg("log message for new import"), null);

        // delete new_file
        file.delete();

        // update the working
        assertEquals("wrong revision from update",
                     update(thisTest), 2);
        thisTest.getWc().addItem("dirA", null);
        thisTest.getWc().setItemWorkingCopyRevision("dirA",2);
        thisTest.getWc().addItem("dirA/dirB", null);
        thisTest.getWc().setItemWorkingCopyRevision("dirA/dirB",2);
        thisTest.getWc().addItem("dirA/dirB/new_file", "some text");
        thisTest.getWc().setItemWorkingCopyRevision("dirA/dirB/new_file",2);

        // test the working copy status
        thisTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.fileContent functionality.
     * @throws Throwable
     */
    public void testBasicCat() throws Throwable
    {
        // create the working copy
        OneTest thisTest = new OneTest();

        // modify A/mu
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter pw = new PrintWriter(new FileOutputStream(mu, true));
        pw.print("some text");
        pw.close();
        // get the content from the repository
        byte[] content = client.fileContent(thisTest.getWCPath()+"/A/mu", null,
                                    null);
        byte[] testContent = thisTest.getWc().getItemContent("A/mu").getBytes();

        // the content should be the same
        assertTrue("content changed", Arrays.equals(content, testContent));
    }

    /**
     * Test the basic SVNClient.fileContent functionality.
     * @throws Throwable
     */
    public void testBasicCatStream() throws Throwable
    {
        // create the working copy
        OneTest thisTest = new OneTest();

        // modify A/mu
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter pw = new PrintWriter(new FileOutputStream(mu, true));
        pw.print("some text");
        pw.close();
        // get the content from the repository
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        client.streamFileContent(thisTest.getWCPath() + "/A/mu", null, null,
                                 baos);

        byte[] content = baos.toByteArray();
        byte[] testContent = thisTest.getWc().getItemContent("A/mu").getBytes();

        // the content should be the same
        assertTrue("content changed", Arrays.equals(content, testContent));
    }

    /**
     * Test the basic SVNClient.list functionality.
     * @throws Throwable
     */
    public void testBasicLs() throws Throwable
    {
        // create the working copy
        OneTest thisTest = new OneTest();

        // list the repository root dir
        DirEntry[] entries = collectDirEntries(thisTest.getWCPath(), null,
                                               null, Depth.immediates,
                                               DirEntry.Fields.all, false);
        thisTest.getWc().check(entries, "", false);

        // list directory A
        entries = collectDirEntries(thisTest.getWCPath() + "/A", null, null,
                                    Depth.immediates, DirEntry.Fields.all,
                                    false);
        thisTest.getWc().check(entries, "A", false);

        // list directory A in BASE revision
        entries = collectDirEntries(thisTest.getWCPath() + "/A", Revision.BASE,
                                    Revision.BASE, Depth.immediates,
                                    DirEntry.Fields.all, false);
        thisTest.getWc().check(entries, "A", false);

        // list file A/mu
        entries = collectDirEntries(thisTest.getWCPath() + "/A/mu", null, null,
                                    Depth.immediates, DirEntry.Fields.all,
                                    false);
        thisTest.getWc().check(entries, "A/mu");
    }

    /**
     * Test the basis SVNClient.add functionality with files that
     * should be ignored.
     * @throws Throwable
     */
    public void testBasicAddIgnores() throws Throwable
    {
        // create working copy
        OneTest thisTest = new OneTest();

        // create dir
        File dir = new File(thisTest.getWorkingCopy(), "dir");
        dir.mkdir();

        // create dir/foo.c
        File fileC = new File(dir, "foo.c");
        new FileOutputStream(fileC).close();

        // create dir/foo.o (should be ignored)
        File fileO = new File(dir, "foo.o");
        new FileOutputStream(fileO).close();

        // add dir
        client.add(dir.getAbsolutePath(), Depth.infinity, false, false, false);
        thisTest.getWc().addItem("dir", null);
        thisTest.getWc().setItemTextStatus("dir",Status.Kind.added);
        thisTest.getWc().addItem("dir/foo.c", "");
        thisTest.getWc().setItemTextStatus("dir/foo.c",Status.Kind.added);
        thisTest.getWc().addItem("dir/foo.o", "");
        thisTest.getWc().setItemTextStatus("dir/foo.o",Status.Kind.ignored);
        thisTest.getWc().setItemNodeKind("dir/foo.o", NodeKind.unknown);

        // test the working copy status
        thisTest.checkStatus();
    }

    /**
     * Test the basis SVNClient.import functionality with files that
     * should be ignored.
     * @throws Throwable
     */
    public void testBasicImportIgnores() throws Throwable
    {
        // create working copy
        OneTest thisTest = new OneTest();

        // create dir
        File dir = new File(thisTest.getWorkingCopy(), "dir");
        dir.mkdir();

        // create dir/foo.c
        File fileC = new File(dir, "foo.c");
        new FileOutputStream(fileC).close();

        // create dir/foo.o (should be ignored)
        File fileO = new File(dir, "foo.o");
        new FileOutputStream(fileO).close();

        // import dir
        addExpectedCommitItem(thisTest.getWCPath(),
                null, "dir", NodeKind.none, CommitItemStateFlags.Add);
        client.doImport(dir.getAbsolutePath(), thisTest.getUrl()+"/dir",
                Depth.infinity, false, false, null,
                new ConstMsg("log message for import"), null);

        // remove dir
        removeDirOrFile(dir);

        // udpate the working copy
        assertEquals("wrong revision from update",
                     update(thisTest), 2);
        thisTest.getWc().addItem("dir", null);
        thisTest.getWc().addItem("dir/foo.c", "");

        // test the working copy status
        thisTest.checkStatus();
    }

    /**
     * Test the basic SVNClient.info functionality.
     * @throws Throwable
     */
    public void testBasicInfo() throws Throwable
    {
        // create the working copy
        OneTest thisTest = new OneTest();

        // get the item information and test it
        Info info = collectInfos(thisTest.getWCPath()+"/A/mu", null, null,
                                  Depth.empty, null)[0];
        assertEquals("wrong revision from info", 1,
                     info.getLastChangedRev());
        assertEquals("wrong schedule kind from info",
                     Info.ScheduleKind.normal, info.getSchedule());
        assertEquals("wrong node kind from info", NodeKind.file,
                     info.getKind());
    }

    /**
     * Test the basic SVNClient.logMessages functionality.
     * @throws Throwable
     */
    public void testBasicLogMessage() throws Throwable
    {
        // create the working copy
        OneTest thisTest = new OneTest();

        // get the commit message of the initial import and test it
        List<RevisionRange> ranges = new ArrayList<RevisionRange>(1);
        ranges.add(new RevisionRange(null, null));
        LogMessage lm[] = collectLogMessages(thisTest.getWCPath(), null,
                                             ranges, false, true, false, 0);
        assertEquals("wrong number of objects", 1, lm.length);
        assertEquals("wrong message", "Log Message", lm[0].getMessage());
        assertEquals("wrong revision", 1, lm[0].getRevisionNumber());
        assertEquals("wrong user", "jrandom", lm[0].getAuthor());
        assertNotNull("changed paths set", lm[0].getChangedPaths());
        Set<ChangePath> cp = lm[0].getChangedPaths();
        assertEquals("wrong number of chang pathes", 20, cp.size());
        ChangePath changedApath = cp.toArray(new ChangePath[1])[0];
        assertNotNull("wrong path", changedApath);
        assertEquals("wrong copy source rev", -1,
                      changedApath.getCopySrcRevision());
        assertNull("wrong copy source path", changedApath.getCopySrcPath());
        assertEquals("wrong action", ChangePath.Action.add,
                     changedApath.getAction());
        assertEquals("wrong time with getTimeMicros()",
                     lm[0].getTimeMicros()/1000,
                     lm[0].getDate().getTime());
        assertEquals("wrong time with getTimeMillis()",
                     lm[0].getTimeMillis(),
                     lm[0].getDate().getTime());
        assertEquals("wrong date with getTimeMicros()",
                     lm[0].getDate(),
                     new java.util.Date(lm[0].getTimeMicros()/1000));
        assertEquals("wrong date with getTimeMillis()",
                     lm[0].getDate(),
                     new java.util.Date(lm[0].getTimeMillis()));

        // Ensure that targets get canonicalized
        String non_canonical = thisTest.getUrl().toString() + "/";
        LogMessage lm2[] = collectLogMessages(non_canonical, null,
                                              ranges, false, true, false, 0);
    }

    /**
     * Test the basic SVNClient.getVersionInfo functionality.
     * @throws Throwable
     * @since 1.2
     */
    public void testBasicVersionInfo() throws Throwable
    {
        // create the working copy
        OneTest thisTest = new OneTest();
        assertEquals("wrong version info",
                     "1",
                     client.getVersionInfo(thisTest.getWCPath(), null, false));
    }

    /**
     * Test the basic SVNClient locking functionality.
     * @throws Throwable
     * @since 1.2
     */
    public void testBasicLocking() throws Throwable
    {
        // build the first working copy
        OneTest thisTest = new OneTest();
        Set<String> muPathSet = new HashSet<String>(1);
        muPathSet.add(thisTest.getWCPath()+"/A/mu");

        setprop(thisTest.getWCPath()+"/A/mu", Property.NEEDS_LOCK, "*");

        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/mu",NodeKind.file,
                              CommitItemStateFlags.PropMods);
        checkCommitRevision(thisTest, "bad revision number on commit", 2,
                            thisTest.getWCPathSet(), "message", Depth.infinity,
                            false, false, null, null);
        File f = new File(thisTest.getWCPath()+"/A/mu");
        assertEquals("file should be read only now", false, f.canWrite());
        client.lock(muPathSet, "comment", false);
        assertEquals("file should be read write now", true, f.canWrite());
        client.unlock(muPathSet, false);
        assertEquals("file should be read only now", false, f.canWrite());
        client.lock(muPathSet, "comment", false);
        assertEquals("file should be read write now", true, f.canWrite());
        addExpectedCommitItem(thisTest.getWCPath(),
                              thisTest.getUrl().toString(), "A/mu",
                              NodeKind.file, 0);
        checkCommitRevision(thisTest, "rev number from commit", -1,
                            thisTest.getWCPathSet(), "message", Depth.infinity,
                            false, false, null, null);
        assertEquals("file should be read write now", true, f.canWrite());

        try
        {
            // Attempt to lock an invalid path
            client.lock(thisTest.getWCPathSet("/A/mu2"), "comment", false);
            fail("missing exception");
        }
        catch (ClientException expected)
        {
        }
    }

    /**
     * Test the basic SVNClient.info functionality.
     * @throws Throwable
     * @since 1.2
     */
    public void testBasicInfo2() throws Throwable
    {
        // build the first working copy
        OneTest thisTest = new OneTest();

        final String failureMsg = "Incorrect number of info objects";
        Info[] infos = collectInfos(thisTest.getWCPath(), null, null,
                                     Depth.empty, null);
        assertEquals(failureMsg, 1, infos.length);
        infos = collectInfos(thisTest.getWCPath(), null, null, Depth.infinity,
                             null);
        assertEquals(failureMsg, 21, infos.length);
        for (Info info : infos)
        {
            assertNull("Unexpected changelist present",
                       info.getChangelistName());

            boolean isFile = info.getKind() == NodeKind.file;
            assertTrue("Unexpected working file size " + info.getWorkingSize()
                       + " for '" + info + '\'',
                       (isFile ? info.getWorkingSize() > -1 :
                        info.getWorkingSize() == -1));
            // We shouldn't know the repository file size when only
            // examining the WC.
            assertEquals("Unexpected repos file size for '" + info + '\'',
                         -1, info.getReposSize());

           // Examine depth
           assertEquals("Unexpected depth for '" + info + "'",
                        (isFile ? Depth.unknown : Depth.infinity),
                        info.getDepth());
        }

        // Create wc with a depth of Depth.empty
        String secondWC = thisTest.getWCPath() + ".empty";
        removeDirOrFile(new File(secondWC));

        client.checkout(thisTest.getUrl().toString(), secondWC, null, null,
                       Depth.empty, false, true);

        infos = collectInfos(secondWC, null, null, Depth.empty, null);

        // Examine that depth is Depth.empty
        assertEquals(Depth.empty, infos[0].getDepth());
    }

    /**
     * Test basic changelist functionality.
     * @throws Throwable
     * @since 1.5
     */
    public void testBasicChangelist() throws Throwable
    {
        // build the working copy
        OneTest thisTest = new OneTest();
        String changelistName = "changelist1";
        Collection<String> changelists = new ArrayList<String>();
        changelists.add(changelistName);
        MyChangelistCallback clCallback = new MyChangelistCallback();

        String path = fileToSVNPath(new File(thisTest.getWCPath(), "iota"),
                                    true);
        Set<String> paths = new HashSet<String>(1);
        paths.add(path);
        // Add a path to a changelist, and check to see if it got added
        client.addToChangelist(paths, changelistName, Depth.infinity, null);
        client.getChangelists(thisTest.getWCPath(), changelists,
                              Depth.infinity, clCallback);
        Collection<String> cl = clCallback.get(path);
        assertTrue(changelists.equals(cl));
        // Does status report this changelist?
        MyStatusCallback statusCallback = new MyStatusCallback();
        client.status(path, Depth.immediates,
                      false, true, false, false, false, false,
                      null, statusCallback);
        Status[] status = statusCallback.getStatusArray();
        assertEquals(status[0].getChangelist(), changelistName);

        // Remove the path from the changelist, and check to see if the path is
        // actually removed.
        client.removeFromChangelists(paths, Depth.infinity, changelists);
        clCallback.clear();
        client.getChangelists(thisTest.getWCPath(), changelists,
                              Depth.infinity, clCallback);
        assertTrue(clCallback.isEmpty());
    }

    public void testGetAllChangelists() throws Throwable
    {
        OneTest thisTest = new OneTest();
        final String cl1 = "changelist_one";
        final String cl2 = "changelist_too";
        MyChangelistCallback clCallback = new MyChangelistCallback();

        String path = fileToSVNPath(new File(thisTest.getWCPath(), "iota"),
                                    true);
        Set<String> paths = new HashSet<String>(1);
        paths.add(path);
        client.addToChangelist(paths, cl1, Depth.infinity, null);
        paths.remove(path);

        path = fileToSVNPath(new File(thisTest.getWCPath(), "A/B/lambda"),
                             true);
        paths.add(path);
        client.addToChangelist(paths, cl2, Depth.infinity, null);

        client.getChangelists(thisTest.getWCPath(), null,
                              Depth.infinity, clCallback);
        Collection<String> changelists = clCallback.getChangelists();
        assertEquals(2, changelists.size());
        assertTrue("Contains " + cl1, changelists.contains(cl1));
        assertTrue("Contains " + cl2, changelists.contains(cl2));
    }

    /**
     * Helper method for testing mergeinfo retrieval.  Assumes
     * that <code>targetPath</code> has both merge history and
     * available merges.
     * @param expectedMergedStart The expected start revision from the
     * merge history for <code>mergeSrc</code>.
     * @param expectedMergedEnd The expected end revision from the
     * merge history for <code>mergeSrc</code>.
     * @param expectedAvailableStart The expected start available revision
     * from the merge history for <code>mergeSrc</code>.  Zero if no need
     * to test the available range.
     * @param expectedAvailableEnd The expected end available revision
     * from the merge history for <code>mergeSrc</code>.
     * @param targetPath The path for which to acquire mergeinfo.
     * @param mergeSrc The URL from which to consider merges.
     */
    private void acquireMergeinfoAndAssertEquals(long expectedMergeStart,
                                                 long expectedMergeEnd,
                                                 long expectedAvailableStart,
                                                 long expectedAvailableEnd,
                                                 String targetPath,
                                                 String mergeSrc)
        throws SubversionException
    {
        // Verify expected merge history.
        Mergeinfo mergeInfo = client.getMergeinfo(targetPath, Revision.HEAD);
        assertNotNull("Missing merge info on '" + targetPath + '\'',
                      mergeInfo);
        List<RevisionRange> ranges = mergeInfo.getRevisions(mergeSrc);
        assertTrue("Missing merge info for source '" + mergeSrc + "' on '" +
                   targetPath + '\'', ranges != null && !ranges.isEmpty());
        RevisionRange range = ranges.get(0);
        String expectedMergedRevs = expectedMergeStart + "-" + expectedMergeEnd;
        assertEquals("Unexpected first merged revision range for '" +
                     mergeSrc + "' on '" + targetPath + '\'',
                     expectedMergedRevs, range.toString());

        // Verify expected available merges.
        if (expectedAvailableStart > 0)
        {
            long[] availableRevs =
                    getMergeinfoRevisions(Mergeinfo.LogKind.eligible, targetPath,
                                          Revision.HEAD, mergeSrc,
                                          Revision.HEAD);
            assertNotNull("Missing eligible merge info on '"+targetPath + '\'',
                          availableRevs);
            assertExpectedMergeRange(expectedAvailableStart,
                                     expectedAvailableEnd, availableRevs);
            }
    }

    /**
     * Calls the API to get mergeinfo revisions and returns
     * the revision numbers in a sorted array, or null if there
     * are no revisions to return.
     * @since 1.5
     */
    private long[] getMergeinfoRevisions(Mergeinfo.LogKind kind,
                                         String pathOrUrl,
                                         Revision pegRevision,
                                         String mergeSourceUrl,
                                         Revision srcPegRevision)
        throws SubversionException
    {
        final List<Long> revList = new ArrayList<Long>();

        client.getMergeinfoLog(kind, pathOrUrl, pegRevision, mergeSourceUrl,
            srcPegRevision, false, Depth.empty, null,
            new LogMessageCallback () {
                public void singleMessage(Set<ChangePath> changedPaths,
                    long revision, Map<String, byte[]> revprops,
                    boolean hasChildren)
                { revList.add(Long.valueOf(revision)); }
            });

        long[] revisions = new long[revList.size()];
        int i = 0;
        for (Long revision : revList)
        {
            revisions[i] = revision.longValue();
            i++;
        }
        return revisions;
    }

    /**
     * Append the text <code>toAppend</code> to the WC file at
     * <code>path</code>, and update the expected WC state
     * accordingly.
     *
     * @param thisTest The test whose expected WC to tweak.
     * @param path The working copy-relative path to change.
     * @param toAppend The text to append to <code>path</code>.
     * @param rev The expected revision number for thisTest's WC.
     * @return The file created during the setup.
     * @since 1.5
     */
    private File appendText(OneTest thisTest, String path, String toAppend,
                            int rev)
        throws FileNotFoundException
    {
        File f = new File(thisTest.getWorkingCopy(), path);
        PrintWriter writer = new PrintWriter(new FileOutputStream(f, true));
        writer.print(toAppend);
        writer.close();
        if (rev > 0)
        {
            WC wc = thisTest.getWc();
            wc.setItemWorkingCopyRevision(path, rev);
            wc.setItemContent(path, wc.getItemContent(path) + toAppend);
        }
        addExpectedCommitItem(thisTest.getWCPath(),
                             thisTest.getUrl().toString(), path,
                              NodeKind.file, CommitItemStateFlags.TextMods);
        return f;
    }

    /**
     * Test the basic functionality of SVNClient.merge().
     * @throws Throwable
     * @since 1.2
     */
    public void testBasicMerge() throws Throwable
    {
        OneTest thisTest = setupAndPerformMerge();

        // Verify that there are now potential merge sources.
        Set<String> suggestedSrcs =
            client.suggestMergeSources(thisTest.getWCPath() + "/branches/A",
                                       Revision.WORKING);
        assertNotNull(suggestedSrcs);
        assertEquals(1, suggestedSrcs.size());

        // Test that getMergeinfo() returns null.
        assertNull(client.getMergeinfo(new File(thisTest.getWCPath(), "A")
                                       .toString(), Revision.HEAD));

        // Merge and commit some changes (r4).
        appendText(thisTest, "A/mu", "xxx", 4);
        appendText(thisTest, "A/D/G/rho", "yyy", 4);
        checkCommitRevision(thisTest, "wrong revision number from commit", 4,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // Add a "begin merge" notification handler.
        final Revision[] actualRange = new Revision[2];
        ClientNotifyCallback notify = new ClientNotifyCallback()
        {
            public void onNotify(ClientNotifyInformation info)
            {
                if (info.getAction() == ClientNotifyInformation.Action.merge_begin)
                {
                    RevisionRange r = info.getMergeRange();
                    actualRange[0] = r.getFromRevision();
                    actualRange[1] = r.getToRevision();
                }
            }
        };
        client.notification2(notify);

        // merge changes in A to branches/A
        String branchPath = thisTest.getWCPath() + "/branches/A";
        String modUrl = thisTest.getUrl() + "/A";
        // test --dry-run
        client.merge(modUrl, new Revision.Number(2), modUrl, Revision.HEAD,
                     branchPath, false, Depth.infinity, false, true, false);
        assertEquals("Notification of beginning of merge reported incorrect " +
                     "start revision", new Revision.Number(2), actualRange[0]);
        assertEquals("Notification of beginning of merge reported incorrect " +
                     "end revision", new Revision.Number(4), actualRange[1]);

        // now do the real merge
        client.merge(modUrl, new Revision.Number(2), modUrl, Revision.HEAD,
                     branchPath, false, Depth.infinity, false, false, false);
        assertEquals("Notification of beginning of merge reported incorrect " +
                     "start revision", new Revision.Number(2), actualRange[0]);
        assertEquals("Notification of beginning of merge reported incorrect " +
                     "end revision", new Revision.Number(4), actualRange[1]);

        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A/D/G/rho", NodeKind.file,
                              CommitItemStateFlags.TextMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 5,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // Merge and commit some more changes (r6).
        appendText(thisTest, "A/mu", "xxxr6", 6);
        appendText(thisTest, "A/D/G/rho", "yyyr6", 6);
        checkCommitRevision(thisTest, "wrong revision number from commit", 6,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // Test retrieval of mergeinfo from a WC path.
        String targetPath =
            new File(thisTest.getWCPath(), "branches/A/mu").getPath();
        final String mergeSrc = thisTest.getUrl() + "/A/mu";
        acquireMergeinfoAndAssertEquals(2, 4, 6, 6, targetPath, mergeSrc);

        // Test retrieval of mergeinfo from the repository.
        targetPath = thisTest.getUrl() + "/branches/A/mu";
        acquireMergeinfoAndAssertEquals(2, 4, 6, 6, targetPath, mergeSrc);
    }

    /**
     * Test merge with automatic source and revision determination
     * (e.g. 'svn merge -g').
     * @throws Throwable
     * @since 1.5
     */
    public void testMergeUsingHistory() throws Throwable
    {
        OneTest thisTest = setupAndPerformMerge();

        // Test that getMergeinfo() returns null.
        assertNull(client.getMergeinfo(new File(thisTest.getWCPath(), "A")
                                       .toString(), Revision.HEAD));

        // Merge and commit some changes (r4).
        appendText(thisTest, "A/mu", "xxx", 4);
        checkCommitRevision(thisTest, "wrong revision number from commit", 4,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        String branchPath = thisTest.getWCPath() + "/branches/A";
        String modUrl = thisTest.getUrl() + "/A";
        Revision unspec = new Revision(Revision.Kind.unspecified);
        List<RevisionRange> ranges = new ArrayList<RevisionRange>(1);
        ranges.add(new RevisionRange(unspec, unspec));
        client.merge(modUrl, Revision.HEAD, ranges,
                     branchPath, true, Depth.infinity, false, false, false);

        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 5,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);
    }

    /**
     * Test merge with automatic source and revision determination
     * (e.g. 'svn merge -g) with implied revision range.
     * @throws Throwable
     * @since 1.8
     */
    public void testMergeUsingHistoryImpliedRange() throws Throwable
    {
        OneTest thisTest = setupAndPerformMerge();

        // Test that getMergeinfo() returns null.
        assertNull(client.getMergeinfo(new File(thisTest.getWCPath(), "A")
                                       .toString(), Revision.HEAD));

        // Merge and commit some changes (r4).
        appendText(thisTest, "A/mu", "xxx", 4);
        checkCommitRevision(thisTest, "wrong revision number from commit", 4,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        String branchPath = thisTest.getWCPath() + "/branches/A";
        String modUrl = thisTest.getUrl() + "/A";
        client.merge(modUrl, Revision.HEAD, null,
                     branchPath, true, Depth.infinity, false, false, false);

        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 5,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);
    }

    /**
     * Test reintegrating a branch with trunk
     * (e.g. 'svn merge --reintegrate').
     * @throws Throwable
     * @since 1.5
     */
    @SuppressWarnings("deprecation")
    public void testMergeReintegrate() throws Throwable
    {
        OneTest thisTest = setupAndPerformMerge();

        // Test that getMergeinfo() returns null.
        assertNull(client.getMergeinfo(new File(thisTest.getWCPath(), "A")
                                       .toString(), Revision.HEAD));

        // Merge and commit some changes to main (r4).
        appendText(thisTest, "A/mu", "xxx", 4);
        checkCommitRevision(thisTest,
                            "wrong revision number from main commit", 4,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);
        // Merge and commit some changes to branch (r5).
        appendText(thisTest, "branches/A/D/G/rho", "yyy", -1);
        checkCommitRevision(thisTest,
                            "wrong revision number from branch commit", 5,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // update the branch WC (to r5) before merge
        update(thisTest, "/branches");

        String branchPath = thisTest.getWCPath() + "/branches/A";
        String modUrl = thisTest.getUrl() + "/A";
        Revision unspec = new Revision(Revision.Kind.unspecified);
        List<RevisionRange> ranges = new ArrayList<RevisionRange>(1);
        ranges.add(new RevisionRange(unspec, unspec));
        client.merge(modUrl, Revision.HEAD, ranges,
                     branchPath, true, Depth.infinity, false, false, false);

        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 6,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // now we --reintegrate the branch with main
        String branchUrl = thisTest.getUrl() + "/branches/A";
        try
        {
            client.mergeReintegrate(branchUrl, Revision.HEAD,
                                    thisTest.getWCPath() + "/A", false);
            fail("reintegrate merged into a mixed-revision WC");
        }
        catch(ClientException e)
        {
            // update the WC (to r6) and try again
            update(thisTest);
            client.mergeReintegrate(branchUrl, Revision.HEAD,
                                    thisTest.getWCPath() + "/A", false);
        }
        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(),
                             thisTest.getUrl().toString(), "A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        addExpectedCommitItem(thisTest.getWCPath(),
                             thisTest.getUrl().toString(), "A/D/G/rho",
                             NodeKind.file, CommitItemStateFlags.TextMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 7,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

    }


    /**
     * Test reintegrating a branch with trunk, using automatic reintegrate.
     */
    public void testMergeAutoReintegrate() throws Throwable
    {
        OneTest thisTest = setupAndPerformMerge();

        // Test that getMergeinfo() returns null.
        assertNull(client.getMergeinfo(new File(thisTest.getWCPath(), "A")
                                       .toString(), Revision.HEAD));

        // Merge and commit some changes to main (r4).
        appendText(thisTest, "A/mu", "xxx", 4);
        checkCommitRevision(thisTest,
                            "wrong revision number from main commit", 4,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);
        // Merge and commit some changes to branch (r5).
        appendText(thisTest, "branches/A/D/G/rho", "yyy", -1);
        checkCommitRevision(thisTest,
                            "wrong revision number from branch commit", 5,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // update the branch WC (to r5) before merge
        update(thisTest, "/branches");

        String branchPath = thisTest.getWCPath() + "/branches/A";
        String modUrl = thisTest.getUrl() + "/A";
        Revision unspec = new Revision(Revision.Kind.unspecified);
        List<RevisionRange> ranges = new ArrayList<RevisionRange>(1);
        ranges.add(new RevisionRange(unspec, unspec));
        client.merge(modUrl, Revision.HEAD, ranges,
                     branchPath, true, Depth.infinity, false, false, false);

        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A/mu", NodeKind.file,
                              CommitItemStateFlags.TextMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 6,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // now we reintegrate the branch with main
        String branchUrl = thisTest.getUrl() + "/branches/A";
        client.merge(branchUrl, Revision.HEAD, null,
                     thisTest.getWCPath() + "/A", false,
                     Depth.unknown, false, false, false, false);

        // make the working copy up-to-date, so that mergeinfo can be committed
        update(thisTest);
        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(),
                             thisTest.getUrl().toString(), "A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        addExpectedCommitItem(thisTest.getWCPath(),
                             thisTest.getUrl().toString(), "A/D/G/rho",
                             NodeKind.file, CommitItemStateFlags.TextMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 7,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

    }

    /**
     * Test automatic merge conflict resolution.
     * @throws Throwable
     * @since 1.5
     */
    public void testMergeConflictResolution() throws Throwable
    {
        // Add a conflict resolution callback which always chooses the
        // user's version of a conflicted file.
        client.setConflictResolver(new ConflictResolverCallback()
            {
                public ConflictResult resolve(ConflictDescriptor descrip)
                {
                    return new ConflictResult(ConflictResult.Choice.chooseTheirsConflict,
                                              null);
                }
            });

        OneTest thisTest = new OneTest();
        String originalContents = thisTest.getWc().getItemContent("A/mu");
        String expectedContents = originalContents + "xxx";

        // Merge and commit a change (r2).
        File mu = appendText(thisTest, "A/mu", "xxx", 2);
        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // Backdate the WC to the previous revision (r1).
        client.update(thisTest.getWCPathSet(), Revision.getInstance(1),
                      Depth.unknown, false, false, false, false);

        // Prep for a merge conflict by changing A/mu in a different
        // way.
        mu = appendText(thisTest, "A/mu", "yyy", 1);

        // Merge in the previous changes to A/mu (from r2).
        List<RevisionRange> ranges = new ArrayList<RevisionRange>(1);
        ranges.add(new RevisionRange(new Revision.Number(1),
                                     new Revision.Number(2)));
        client.merge(thisTest.getUrl().toString(), Revision.HEAD, ranges,
                     thisTest.getWCPath(), false, Depth.infinity, false,
                     false, false);

        assertFileContentsEquals("Unexpected conflict resolution",
                                 expectedContents, mu);
    }

    /**
     * Test merge --record-only
     * @throws Throwable
     * @since 1.5
     */
    public void testRecordOnlyMerge() throws Throwable
    {
        OneTest thisTest = setupAndPerformMerge();

        // Verify that there are now potential merge sources.
        Set<String> suggestedSrcs =
            client.suggestMergeSources(thisTest.getWCPath() + "/branches/A",
                                       Revision.WORKING);
        assertNotNull(suggestedSrcs);
        assertEquals(1, suggestedSrcs.size());

        // Test that getMergeinfo() returns null.
        assertNull(client.getMergeinfo(new File(thisTest.getWCPath(), "A")
                                       .toString(), Revision.HEAD));

        // Merge and commit some changes (r4).
        appendText(thisTest, "A/mu", "xxx", 4);
        appendText(thisTest, "A/D/G/rho", "yyy", 4);
        checkCommitRevision(thisTest, "wrong revision number from commit", 4,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // --record-only merge changes in A to branches/A
        String branchPath = thisTest.getWCPath() + "/branches/A";
        String modUrl = thisTest.getUrl() + "/A";

        List<RevisionRange> ranges = new ArrayList<RevisionRange>(1);
        ranges.add(new RevisionRange(new Revision.Number(2),
                                     new Revision.Number(4)));
        client.merge(modUrl, Revision.HEAD, ranges,
                     branchPath, true, Depth.infinity, false, false, true);

        // commit the changes so that we can verify merge
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                              "branches/A", NodeKind.dir,
                              CommitItemStateFlags.PropMods);
        checkCommitRevision(thisTest, "wrong revision number from commit", 5,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        // Test retrieval of mergeinfo from a WC path.
        String targetPath =
            new File(thisTest.getWCPath(), "branches/A").getPath();
        final String mergeSrc = thisTest.getUrl() + "/A";
        acquireMergeinfoAndAssertEquals(2, 4, 0, 0, targetPath, mergeSrc);
    }

    /**
     * Setup a test with a WC.  In the repository, create a
     * "/branches" directory, with a branch of "/A" underneath it.
     * Update the WC to reflect these modifications.
     * @return This test.
     */
    private OneTest setupAndPerformMerge()
        throws Exception
    {
        OneTest thisTest = new OneTest();

        // Verify that there are initially no potential merge sources.
        Set<String> suggestedSrcs =
            client.suggestMergeSources(thisTest.getWCPath(),
                                       Revision.WORKING);
        assertNotNull(suggestedSrcs);
        assertEquals(0, suggestedSrcs.size());

        // create branches directory in the repository (r2)
        addExpectedCommitItem(null, thisTest.getUrl().toString(), "branches",
                              NodeKind.none, CommitItemStateFlags.Add);
        Set<String> paths = new HashSet<String>(1);
        paths.add(thisTest.getUrl() + "/branches");
        client.mkdir(paths, false, null, new ConstMsg("log_msg"), null);

        // copy A to branches (r3)
        addExpectedCommitItem(null, thisTest.getUrl().toString(), "branches/A",
                              NodeKind.none, CommitItemStateFlags.Add);
        List<CopySource> srcs = new ArrayList<CopySource>(1);
        srcs.add(new CopySource(thisTest.getUrl() + "/A", Revision.HEAD,
                                Revision.HEAD));
        client.copy(srcs, thisTest.getUrl() + "/branches/A",
                    true, false, false, false, false, null, null,
                    new ConstMsg("create A branch"), null);

        // update the WC (to r3) so that it has the branches folder
        update(thisTest);

        return thisTest;
    }

    /**
     * Test the patch API.  This doesn't yet test the results, it only ensures
     * that execution goes down to the C layer and back.
     * @throws Throwable
     */
    public void testPatch() throws SubversionException, IOException
    {
        OneTest thisTest = new OneTest(true);
        File patchInput = new File(super.localTmp, thisTest.testName);
        final String NL = System.getProperty("line.separator");

        final String patchText = "Index: iota" + NL +
            "===================================================================" + NL +
            "--- iota\t(revision 1)" + NL +
            "+++ iota\t(working copy)" + NL +
            "@@ -1 +1,2 @@" + NL +
            " This is the file 'iota'." + NL +
            "+No, this is *really* the file 'iota'." + NL;

        PrintWriter writer = new PrintWriter(new FileOutputStream(patchInput));
        writer.print(patchText);
        writer.flush();
        writer.close();

        client.patch(patchInput.getAbsolutePath(),
                     thisTest.getWCPath().replace('\\', '/'), false, 0,
                     false, true, true,
                     new PatchCallback() {
                         public boolean singlePatch(String pathFromPatchfile,
                                                    String patchPath,
                                                    String rejectPath) {
                             // Do nothing, right now.
                            return false;
                         }
        });
    }

    /**
     * Test the {@link ISVNClient.diff()} APIs.
     * @since 1.5
     */
    public void testDiff()
        throws SubversionException, IOException
    {
        OneTest thisTest = new OneTest(true);
        File diffOutput = new File(super.localTmp, thisTest.testName);
        final String NL = System.getProperty("line.separator");
        final String sepLine =
            "===================================================================" + NL;
        final String underSepLine =
            "___________________________________________________________________" + NL;
        final String expectedDiffBody =
            "@@ -1 +1 @@" + NL +
            "-This is the file 'iota'." + NL +
            "\\ No newline at end of file" + NL +
            "+This is the file 'mu'." + NL +
            "\\ No newline at end of file" + NL;

        final String iotaPath = thisTest.getWCPath().replace('\\', '/') + "/iota";
        final String wcPath = fileToSVNPath(new File(thisTest.getWCPath()),
                false);

        // make edits to iota
        PrintWriter writer = new PrintWriter(new FileOutputStream(iotaPath));
        writer.print("This is the file 'mu'.");
        writer.flush();
        writer.close();

        /*
         * This test does tests with and without svn:eol-style set to native
         * We will first run all of the tests where this does not matter so
         * that they are not run twice.
         */

        // Two-path diff of URLs.
        String expectedDiffOutput = "Index: iota" + NL + sepLine +
            "--- iota\t(.../iota)\t(revision 1)" + NL +
            "+++ iota\t(.../A/mu)\t(revision 1)" + NL +
            expectedDiffBody;
        client.diff(thisTest.getUrl() + "/iota", Revision.HEAD,
                    thisTest.getUrl() + "/A/mu", Revision.HEAD,
                    null, diffOutput.getPath(), Depth.files, null, true, true,
                    false, false);
        assertFileContentsEquals("Unexpected diff output in file '" +
                                 diffOutput.getPath() + '\'',
                                 expectedDiffOutput, diffOutput);

        // Test relativeToDir fails with urls. */
        try
        {
            client.diff(thisTest.getUrl().toString() + "/iota", Revision.HEAD,
                        thisTest.getUrl().toString() + "/A/mu", Revision.HEAD,
                        thisTest.getUrl().toString(), diffOutput.getPath(),
                        Depth.infinity, null, true, true, false, false);

            fail("This test should fail because the relativeToDir parameter " +
                 "does not work with URLs");
        }
        catch (Exception ignored)
        {
        }

        /* Testing the expected failure when relativeToDir is not a parent
           path of the target. */
        try
        {
            client.diff(iotaPath, Revision.BASE, iotaPath, Revision.WORKING,
                        "/non/existent/path", diffOutput.getPath(),
                        Depth.infinity, null, true, true, false, false);

            fail("This test should fail because iotaPath is not a child of " +
                 "the relativeToDir parameter");
        }
        catch (Exception ignored)
        {
        }

        // Test diff with a relative path on a directory with prop
        // changes.
        String aPath = fileToSVNPath(new File(thisTest.getWCPath() + "/A"),
                                     false);

        expectedDiffOutput = "Index: A" + NL + sepLine +
            "--- A\t(revision 1)" + NL +
            "+++ A\t(working copy)" + NL +
            NL + "Property changes on: A" + NL +
            underSepLine +
            "Added: testprop" + NL +
            "## -0,0 +1 ##" + NL +
            "+Test property value." + NL;

        setprop(aPath, "testprop", "Test property value." + NL);
        client.diff(aPath, Revision.BASE, aPath, Revision.WORKING, wcPath,
                    diffOutput.getPath(), Depth.infinity, null, true, true,
                    false, false);
        assertFileContentsEquals("Unexpected diff output in file '" +
                                 diffOutput.getPath() + '\'',
                                 expectedDiffOutput, diffOutput);

        // Test diff where relativeToDir and path are the same.
        expectedDiffOutput = "Index: ." + NL + sepLine +
            "--- .\t(revision 1)" + NL +
            "+++ .\t(working copy)" + NL +
            NL + "Property changes on: ." + NL +
            underSepLine +
            "Added: testprop" + NL +
            "## -0,0 +1 ##" + NL +
            "+Test property value." + NL;

        setprop(aPath, "testprop", "Test property value." + NL);
        client.diff(aPath, Revision.BASE, aPath, Revision.WORKING, aPath,
                    diffOutput.getPath(), Depth.infinity, null, true, true,
                    false, false);
        assertFileContentsEquals("Unexpected diff output in file '" +
                                 diffOutput.getPath() + '\'',
                                 expectedDiffOutput, diffOutput);


        /*
         * The rest of these tests are run twice.  The first time
         * without svn:eol-style set and the second time with the
         * property set to native.  This is tracked by the int named
         * operativeRevision.  It will have a value = 2 after the
         * commit which sets the property
         */

        for (int operativeRevision = 1; operativeRevision < 3; operativeRevision++)
         {
                String revisionPrefix = "While processing operativeRevison=" + operativeRevision + ". ";
                String assertPrefix = revisionPrefix + "Unexpected diff output in file '";

                // Undo previous edits to working copy
                client.revert(wcPath, Depth.infinity, null);

                if (operativeRevision == 2) {
                    // Set svn:eol-style=native on iota
                    setprop(iotaPath, "svn:eol-style", "native");
                    Set<String> paths = new HashSet<String>(1);
                    paths.add(iotaPath);
                    addExpectedCommitItem(thisTest.getWCPath(),
                            thisTest.getUrl().toString(), "iota",NodeKind.file,
                            CommitItemStateFlags.PropMods);
                    client.commit(paths, Depth.empty, false, false, null, null,
                                  new ConstMsg("Set svn:eol-style to native"),
                                  null);
                }

                // make edits to iota and set expected output.
                writer = new PrintWriter(new FileOutputStream(iotaPath));
                writer.print("This is the file 'mu'.");
                writer.flush();
                writer.close();
                expectedDiffOutput = "Index: " + iotaPath + NL + sepLine +
                    "--- " + iotaPath + "\t(revision " + operativeRevision + ")" + NL +
                    "+++ " + iotaPath + "\t(working copy)" + NL +
                    expectedDiffBody;

                try
                {
                    // Two-path diff of WC paths.
                    client.diff(iotaPath, Revision.BASE, iotaPath,
                                Revision.WORKING, null, diffOutput.getPath(),
                                Depth.files, null, true, true, false, false);
                    assertFileContentsEquals(assertPrefix +
                                             diffOutput.getPath() + '\'',
                                             expectedDiffOutput, diffOutput);
                    diffOutput.delete();
                }
                catch (ClientException e)
                {
                    fail(revisionPrefix + e.getMessage());
                }

                try
                {
                    // Peg revision diff of a single file.
                    client.diff(thisTest.getUrl() + "/iota", Revision.HEAD,
                                new Revision.Number(operativeRevision),
                                Revision.HEAD, null, diffOutput.getPath(),
                                Depth.files, null, true, true, false, false);
                    assertFileContentsEquals(assertPrefix +
                                             diffOutput.getPath() + '\'',
                                             "", diffOutput);

                    diffOutput.delete();
                }
                catch (ClientException e)
                {
                    fail(revisionPrefix + e.getMessage());
                }

               // Test svn diff with a relative path.
                expectedDiffOutput = "Index: iota" + NL + sepLine +
                    "--- iota\t(revision " + operativeRevision + ")" + NL +
                    "+++ iota\t(working copy)" + NL +
                    expectedDiffBody;
                try
                {
                    client.diff(iotaPath, Revision.BASE, iotaPath,
                                Revision.WORKING, wcPath, diffOutput.getPath(),
                                Depth.infinity, null, true, true, false,
                                false);
                    assertFileContentsEquals(assertPrefix +
                                             diffOutput.getPath() + '\'',
                                             expectedDiffOutput, diffOutput);
                    diffOutput.delete();
                }
                catch (ClientException e)
                {
                    fail(revisionPrefix + e.getMessage());
                }

                try
                {
                    // Test svn diff with a relative path and trailing slash.
                    client.diff(iotaPath, Revision.BASE, iotaPath,
                                Revision.WORKING, wcPath + "/",
                                diffOutput.getPath(), Depth.infinity, null,
                                true, true, false, false);
                    assertFileContentsEquals(assertPrefix +
                                             diffOutput.getPath() + '\'',
                                             expectedDiffOutput, diffOutput);
                    diffOutput.delete();
                }
                catch (ClientException e)
                {
                    fail(revisionPrefix + e.getMessage());
                }

            }

    }

    /**
     * Test the {@link ISVNClient.diff()} with {@link DiffOptions}.
     * @since 1.8
     */
    public void testDiffOptions()
        throws SubversionException, IOException
    {
        OneTest thisTest = new OneTest(true);
        File diffOutput = new File(super.localTmp, thisTest.testName);
        final String NL = System.getProperty("line.separator");
        final String sepLine =
            "===================================================================" + NL;
        final String underSepLine =
            "___________________________________________________________________" + NL;
        final String iotaPath = thisTest.getWCPath().replace('\\', '/') + "/iota";
        final String wcPath = fileToSVNPath(new File(thisTest.getWCPath()),
                false);
        final String expectedDiffHeader =
            "Index: iota" + NL + sepLine +
            "--- iota\t(revision 1)" + NL +
            "+++ iota\t(working copy)" + NL;

        // make edits to iota
        PrintWriter writer = new PrintWriter(new FileOutputStream(iotaPath));
        writer.print("This is  the  file 'iota'.");
        writer.flush();
        writer.close();

        try
        {
            final String expectedDiffOutput = expectedDiffHeader +
                "@@ -1 +1 @@" + NL +
                "-This is the file 'iota'." + NL +
                "\\ No newline at end of file" + NL +
                "+This is  the  file 'iota'." + NL +
                "\\ No newline at end of file" + NL;

            client.diff(iotaPath, Revision.BASE, iotaPath, Revision.WORKING,
                        wcPath, new FileOutputStream(diffOutput.getPath()),
                        Depth.infinity, null,
                        false, false, false, false, false, false, null);
            assertFileContentsEquals(
                "Unexpected diff output with no options in file '" +
                diffOutput.getPath() + '\'',
                expectedDiffOutput, diffOutput);
            diffOutput.delete();
        }
        catch (ClientException e)
        {
            fail(e.getMessage());
        }

        try
        {
            final String expectedDiffOutput = "";

            client.diff(iotaPath, Revision.BASE, iotaPath, Revision.WORKING,
                        wcPath, new FileOutputStream(diffOutput.getPath()),
                        Depth.infinity, null,
                        false, false, false, false, false, false,
                        new DiffOptions(DiffOptions.Flag.IgnoreWhitespace));
            assertFileContentsEquals(
                "Unexpected diff output with Flag.IgnoreWhitespace in file '" +
                diffOutput.getPath() + '\'',
                expectedDiffOutput, diffOutput);
            diffOutput.delete();
        }
        catch (ClientException e)
        {
            fail("Using Flag.IgnoreWhitespace: "
                  + e.getMessage());
        }

        try
        {
            final String expectedDiffOutput = "";

            client.diff(iotaPath, Revision.BASE, iotaPath, Revision.WORKING,
                        wcPath, diffOutput.getPath(), Depth.infinity, null,
                        false, false, false, false, false, false,
                        new DiffOptions(DiffOptions.Flag.IgnoreSpaceChange));
            assertFileContentsEquals(
                "Unexpected diff output with Flag.IgnoreSpaceChange in file '" +
                diffOutput.getPath() + '\'',
                expectedDiffOutput, diffOutput);
            diffOutput.delete();
        }
        catch (ClientException e)
        {
            fail("Using Flag.IgnoreSpaceChange: "
                 + e.getMessage());
        }

        // make edits to iota
        writer = new PrintWriter(new FileOutputStream(iotaPath));
        writer.print("This is  the  file 'io ta'.");
        writer.flush();
        writer.close();

        try
        {
            final String expectedDiffOutput = expectedDiffHeader +
                "@@ -1 +1 @@" + NL +
                "-This is the file 'iota'." + NL +
                "\\ No newline at end of file" + NL +
                "+This is  the  file 'io ta'." + NL +
                "\\ No newline at end of file" + NL;

            client.diff(iotaPath, Revision.BASE, iotaPath, Revision.WORKING,
                        wcPath, diffOutput.getPath(), Depth.infinity, null,
                        false, false, false, false, false, false,
                        new DiffOptions(DiffOptions.Flag.IgnoreSpaceChange));
            assertFileContentsEquals(
                "Unexpected diff output with Flag.IgnoreSpaceChange in file '" +
                diffOutput.getPath() + '\'',
                expectedDiffOutput, diffOutput);
            diffOutput.delete();
        }
        catch (ClientException e)
        {
            fail("Using Flag.IgnoreSpaceChange: "
                 + e.getMessage());
        }
    }


    private void assertFileContentsEquals(String msg, String expected,
                                          File actual)
        throws IOException
    {
        FileReader reader = new FileReader(actual);
        StringBuffer buf = new StringBuffer();
        int ch;
        while ((ch = reader.read()) != -1)
        {
            buf.append((char) ch);
        }
        assertEquals(msg, expected, buf.toString());
    }

    /**
     * Test the {@link SVNClientInterface.diffSummarize()} API.
     * @since 1.5
     */
    public void testDiffSummarize()
        throws SubversionException, IOException
    {
        OneTest thisTest = new OneTest(false);
        DiffSummaries summaries = new DiffSummaries();
        // Perform a recursive diff summary, ignoring ancestry.
        client.diffSummarize(thisTest.getUrl().toString(), new Revision.Number(0),
                             thisTest.getUrl().toString(), Revision.HEAD, Depth.infinity,
                             null, false, summaries);
        assertExpectedDiffSummaries(summaries);

        summaries.clear();
        // Perform a recursive diff summary with a peg revision,
        // ignoring ancestry.
        client.diffSummarize(thisTest.getUrl().toString(), Revision.HEAD,
                             new Revision.Number(0), Revision.HEAD,
                             Depth.infinity, null, false, summaries);
        assertExpectedDiffSummaries(summaries);
    }

    private void assertExpectedDiffSummaries(DiffSummaries summaries)
    {
        assertEquals("Wrong number of diff summary descriptors", 20,
                     summaries.size());

        // Rigorously inspect one of our DiffSummary notifications.
        final String BETA_PATH = "A/B/E/beta";
        DiffSummary betaDiff = summaries.get(BETA_PATH);
        assertNotNull("No diff summary for " + BETA_PATH, betaDiff);
        assertEquals("Incorrect path for " + BETA_PATH, BETA_PATH,
                     betaDiff.getPath());
        assertTrue("Incorrect diff kind for " + BETA_PATH,
                   betaDiff.getDiffKind() == DiffSummary.DiffKind.added);
        assertEquals("Incorrect props changed notice for " + BETA_PATH,
                     false, betaDiff.propsChanged());
        assertEquals("Incorrect node kind for " + BETA_PATH, NodeKind.file,
                     betaDiff.getNodeKind());
    }

    /**
     * test the basic SVNClient.isAdminDirectory functionality
     * @throws Throwable
     * @since 1.2
     */
    public void testBasicIsAdminDirectory() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        ClientNotifyCallback notify = new ClientNotifyCallback()
        {
            public void onNotify(ClientNotifyInformation info)
            {
                client.isAdminDirectory(".svn");
            }
        };
        client.notification2(notify);
        // update the test
        assertEquals("wrong revision number from update",
                     update(thisTest), 1);
    }

    public void testBasicCancelOperation() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();
        ClientNotifyCallback notify = new ClientNotifyCallback()
        {
            public void onNotify(ClientNotifyInformation info)
            {
                try
                {
                    client.cancelOperation();
                }
                catch (ClientException e)
                {
                    fail(e.getMessage());
                }
            }
        };
        client.notification2(notify);
        // update the test to try to cancel an operation
        try
        {
            update(thisTest);
            fail("missing exception for canceled operation");
        }
        catch (ClientException e)
        {
            // this is expected
        }
    }

    private static class CountingProgressListener implements ProgressCallback
    {
        public void onProgress(ProgressEvent event)
        {
            // TODO: Examine the byte counts from "event".
            gotProgress = true;
        }
        public boolean gotProgress = false;
    }

    public void testDataTransferProgressReport() throws Throwable
    {
        // ### FIXME: This isn't working over ra_local, because
        // ### ra_local is not invoking the progress callback.
        if (SVNTests.rootUrl.startsWith("file://"))
            return;

        // build the test setup
        OneTest thisTest = new OneTest();
        CountingProgressListener listener = new CountingProgressListener();
        client.setProgressCallback(listener);

        // Perform an update to exercise the progress notification.
        update(thisTest);
        if (!listener.gotProgress)
            fail("No progress reported");
    }

    /**
     * Test the basic tree conflict functionality.
     * @throws Throwable
     */
    public void testTreeConflict() throws Throwable
    {
        // build the test setup. Used for the changes
        OneTest thisTest = new OneTest();
        WC wc = thisTest.getWc();

        // build the backup test setup. That is the one that will be updated
        OneTest tcTest = thisTest.copy(".tree-conflict");


        // Move files from A/B/E to A/B/F.
        Set<String> relPaths = new HashSet<String>(1);
        relPaths.add("alpha");
        Set<String> srcPaths = new HashSet<String>(1);
        for (String fileName : relPaths)
        {
            srcPaths.add(new File(thisTest.getWorkingCopy(),
                                   "A/B/E/" + fileName).getPath());

            wc.addItem("A/B/F/" + fileName,
                       wc.getItemContent("A/B/E/" + fileName));
            wc.setItemWorkingCopyRevision("A/B/F/" + fileName, 2);
            addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                                  "A/B/F/" + fileName, NodeKind.file,
                                  CommitItemStateFlags.Add |
                                  CommitItemStateFlags.IsCopy);

            wc.removeItem("A/B/E/" + fileName);
            addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl().toString(),
                                  "A/B/E/" + fileName, NodeKind.file,
                                  CommitItemStateFlags.Delete);
        }
        client.move(srcPaths,
                    new File(thisTest.getWorkingCopy(), "A/B/F").getPath(),
                    false, true, false, false, false, null, null, null);

        // Commit the changes, and check the state of the WC.
        checkCommitRevision(thisTest,
                            "Unexpected WC revision number after commit", 2,
                            thisTest.getWCPathSet(),
                            "Move files", Depth.infinity, false, false,
                            null, null);
        thisTest.checkStatus();

        // modify A/B/E/alpha in second working copy
        File alpha = new File(tcTest.getWorkingCopy(), "A/B/E/alpha");
        PrintWriter alphaWriter = new PrintWriter(new FileOutputStream(alpha, true));
        alphaWriter.print("appended alpha text");
        alphaWriter.close();

        // update the tc test
        assertEquals("wrong revision number from update",
                     update(tcTest), 2);

        // set the expected working copy layout for the tc test
        tcTest.getWc().addItem("A/B/F/alpha",
                tcTest.getWc().getItemContent("A/B/E/alpha"));
        tcTest.getWc().setItemWorkingCopyRevision("A/B/F/alpha", 2);
        // we expect the tree conflict to turn the existing item into
        // a scheduled-add with history.
        tcTest.getWc().setItemTextStatus("A/B/E/alpha", Status.Kind.added);
        tcTest.getWc().setItemTextStatus("A/B/F/alpha", Status.Kind.normal);

        // check the status of the working copy of the tc test
        tcTest.checkStatus();

        // get the Info2 of the tree conflict
        MyInfoCallback callback = new MyInfoCallback();
        client.info2(tcTest.getWCPath() + "/A/B/E/alpha", null,
                null, Depth.unknown, null, callback);
        Set<ConflictDescriptor> conflicts = callback.getInfo().getConflicts();
        assertNotNull("Conflict should not be null", conflicts);
        ConflictDescriptor conflict = conflicts.iterator().next();

        assertNotNull("Conflict should not be null", conflict);
        assertNotNull("Repository UUID must be set", conflict.getSrcLeftVersion().getReposUUID());

        assertEquals(conflict.getSrcLeftVersion().getNodeKind(), NodeKind.file);
        assertEquals(conflict.getSrcLeftVersion().getReposURL() + "/" +
                conflict.getSrcLeftVersion().getPathInRepos(), tcTest.getUrl() + "/A/B/E/alpha");
        assertEquals(conflict.getSrcLeftVersion().getPegRevision(), 1L);

        if (conflict.getSrcRightVersion() != null)
        {
            assertEquals(conflict.getSrcLeftVersion().getReposUUID(),
                         conflict.getSrcRightVersion().getReposUUID());
            assertEquals(conflict.getSrcRightVersion().getNodeKind(), NodeKind.none);
            assertEquals(conflict.getSrcRightVersion().getReposURL(), tcTest.getUrl().toString());
            assertEquals(conflict.getSrcRightVersion().getPegRevision(), 2L);
        }
    }

    /**
     * Test the basic SVNClient.propertySetRemote functionality.
     * @throws Throwable
     */
    public void testPropEdit() throws Throwable
    {
        final String PROP = "abc";
        final byte[] VALUE = new String("def").getBytes();
        final byte[] NEWVALUE = new String("newvalue").getBytes();
        // create the test working copy
        OneTest thisTest = new OneTest();

        Set<String> pathSet = new HashSet<String>();
        // set a property on A/D/G/rho file
        pathSet.clear();
        pathSet.add(thisTest.getWCPath()+"/A/D/G/rho");
        client.propertySetLocal(pathSet, PROP, VALUE,
                                Depth.infinity, null, false);
        thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.modified);

        // test the status of the working copy
        thisTest.checkStatus();

        // commit the changes
        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
                            thisTest.getWCPathSet(), "log msg", Depth.infinity,
                            false, false, null, null);

        thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.normal);

        // check the status of the working copy
        thisTest.checkStatus();

        // now edit the propval directly in the repository
        long baseRev = 2L;
        client.propertySetRemote(thisTest.getUrl()+"/A/D/G/rho", baseRev, PROP, NEWVALUE,
                                 new ConstMsg("edit prop"), false, null, null);

        // update the WC and verify that the property was changed
        client.update(thisTest.getWCPathSet(), Revision.HEAD, Depth.infinity, false, false,
                      false, false);
        byte[] propVal = client.propertyGet(thisTest.getWCPath()+"/A/D/G/rho", PROP, null, null);

        assertEquals(new String(propVal), new String(NEWVALUE));

    }

    /**
     * Test tolerance of unversioned obstructions when adding paths with
     * {@link org.apache.subversion.javahl.SVNClient#checkout()},
     * {@link org.apache.subversion.javahl.SVNClient#update()}, and
     * {@link org.apache.subversion.javahl.SVNClient#doSwitch()}
     * @throws IOException
     * @throws SubversionException
     */
    /*
      This is currently commented out, because we don't have an XFail method
      for JavaHL.  The resolution is pending the result of issue #3680:
      https://issues.apache.org/jira/browse/SVN-3680

    public void testObstructionTolerance()
            throws SubversionException, IOException
    {
        // build the test setup
        OneTest thisTest = new OneTest();

        File file;
        PrintWriter pw;

        // ----- TEST CHECKOUT -----
        // Use export to make unversioned obstructions for a second
        // WC checkout (deleting export target from previous tests
        // first if it exists).
        String secondWC = thisTest.getWCPath() + ".backup1";
        removeDirOrFile(new File(secondWC));
        client.doExport(thisTest.getUrl(), secondWC, null, null, false, false,
                        Depth.infinity, null);

        // Make an obstructing file that conflicts with add coming from repos
        file = new File(secondWC, "A/B/lambda");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("This is the conflicting obstructiong file 'lambda'.");
        pw.close();

        // Attempt to checkout backup WC without "--force"...
        try
        {
            // ...should fail
            client.checkout(thisTest.getUrl(), secondWC, null, null,
                            Depth.infinity, false, false);
            fail("obstructed checkout should fail by default");
        }
        catch (ClientException expected)
        {
        }

        // Attempt to checkout backup WC with "--force"
        // so obstructions are tolerated
        client.checkout(thisTest.getUrl(), secondWC, null, null,
                        Depth.infinity, false, true);

        // Check the WC status, the only status should be a text
        // mod to lambda.  All the other obstructing files were identical
        MyStatusCallback statusCallback = new MyStatusCallback();
        client.status(secondWC, Depth.unknown, false, false, false, false,
                    null, statusCallback);
        Status[] secondWCStatus = statusCallback.getStatusArray();
        if (!(secondWCStatus.length == 1 &&
            secondWCStatus[0].getPath().endsWith("A/B/lambda") &&
            secondWCStatus[0].getTextStatus() == Status.Kind.modified &&
            secondWCStatus[0].getPropStatus() == Status.Kind.none))
        {
            fail("Unexpected WC status after co with " +
                 "unversioned obstructions");
        }

        // Make a third WC to test obstruction tolerance of sw and up.
        OneTest backupTest = thisTest.copy(".backup2");

        // ----- TEST UPDATE -----
        // r2: Add a file A/D/H/nu
        file = new File(thisTest.getWorkingCopy(), "A/D/H/nu");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("This is the file 'nu'.");
        pw.close();
        client.add(file.getAbsolutePath(), Depth.empty, false, false, false);
        addExpectedCommitItem(thisTest.getWCPath(), thisTest.getUrl(),
                              "A/D/H/nu", NodeKind.file,
                              CommitItemStateFlags.TextMods +
                              CommitItemStateFlags.Add);
        assertEquals("wrong revision number from commit",
                     commit(thisTest, "log msg"), 2);
        thisTest.getWc().addItem("A/D/H/nu", "This is the file 'nu'.");
        statusCallback = new MyStatusCallback();
        client.status(thisTest.getWCPath() + "/A/D/H/nu", Depth.immediates,
                      false, true, false, false, null, statusCallback);
        Status status = statusCallback.getStatusArray()[0];

        // Add an unversioned file A/D/H/nu to the backup WC
        file = new File(backupTest.getWorkingCopy(), "A/D/H/nu");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("This is the file 'nu'.");
        pw.close();

        // Attempt to update backup WC without "--force"
        try
        {
            // obstructed update should fail
            update(backupTest);
            fail("obstructed update should fail by default");
        }
        catch (ClientException expected)
        {
        }

        // Attempt to update backup WC with "--force"
        assertEquals("wrong revision from update",
                     client.update(backupTest.getWCPathSet(),
                                   null, Depth.infinity, false, false,
                                   true)[0],
                     2);

        // ----- TEST SWITCH -----
        // Add an unversioned file A/B/E/nu to the backup WC
        // The file differs from A/D/H/nu
        file = new File(backupTest.getWorkingCopy(), "A/B/E/nu");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("This is yet another file 'nu'.");
        pw.close();

        // Add an unversioned file A/B/E/chi to the backup WC
        // The file is identical to A/D/H/chi.
        file = new File(backupTest.getWorkingCopy(), "A/B/E/chi");
        pw = new PrintWriter(new FileOutputStream(file));
        pw.print("This is the file 'chi'.");
        pw.close();

        // Attempt to switch A/B/E to A/D/H without "--force"
        try
        {
            // obstructed switch should fail
            client.doSwitch(backupTest.getWCPath() + "/A/B/E",
                            backupTest.getUrl() + "/A/D/H",
                            null, Revision.HEAD, Depth.files, false, false,
                            false);
            fail("obstructed switch should fail by default");
        }
        catch (ClientException expected)
        {
        }

        // Complete the switch using "--force" and check the status
        client.doSwitch(backupTest.getWCPath() + "/A/B/E",
                        backupTest.getUrl() + "/A/D/H",
                        Revision.HEAD, Revision.HEAD, Depth.infinity,
                        false, false, true);

        backupTest.getWc().setItemIsSwitched("A/B/E",true);
        backupTest.getWc().removeItem("A/B/E/alpha");
        backupTest.getWc().removeItem("A/B/E/beta");
        backupTest.getWc().addItem("A/B/E/nu",
                                   "This is yet another file 'nu'.");
        backupTest.getWc().setItemTextStatus("A/B/E/nu", Status.Kind.modified);
        backupTest.getWc().addItem("A/D/H/nu",
                                   "This is the file 'nu'.");
        backupTest.getWc().addItem("A/B/E/chi",
                                   backupTest.getWc().getItemContent("A/D/H/chi"));
        backupTest.getWc().addItem("A/B/E/psi",
                                   backupTest.getWc().getItemContent("A/D/H/psi"));
        backupTest.getWc().addItem("A/B/E/omega",
                                   backupTest.getWc().getItemContent("A/D/H/omega"));

        backupTest.checkStatus();
    }*/

    /**
     * Test basic blame functionality.  This test marginally tests blame
     * correctness, mainly just that the blame APIs link correctly.
     * @throws Throwable
     * @since 1.5
     */
    @SuppressWarnings("deprecation")
    public void testBasicBlame() throws Throwable
    {
        OneTest thisTest = new OneTest();
        // Test the old interface to be sure it still works
        byte[] result = collectBlameLines(thisTest.getWCPath() + "/iota",
                                          Revision.getInstance(1),
                                          Revision.getInstance(1),
                                          Revision.getInstance(1),
                                          false, false);
        assertEquals("     1    jrandom This is the file 'iota'.\n",
                     new String(result));

        // Test the current interface
        BlameCallbackImpl callback = new BlameCallbackImpl();
        client.blame(thisTest.getWCPath() + "/iota", Revision.getInstance(1),
                     Revision.getInstance(1), Revision.getInstance(1),
                     false, false, callback);
        assertEquals(1, callback.numberOfLines());
        BlameCallbackImpl.BlameLine line = callback.getBlameLine(0);
        assertNotNull(line);
        assertEquals(1, line.getRevision());
        assertEquals("jrandom", line.getAuthor());
        assertEquals("This is the file 'iota'.", line.getLine());
    }

    /**
     * Test blame with diff options.
     * @since 1.9
     */
    @SuppressWarnings("deprecation")
    public void testBlameWithDiffOptions() throws Throwable
    {
        OneTest thisTest = new OneTest();
        // Modify the file iota, making only whitespace changes.
        File iota = new File(thisTest.getWorkingCopy(), "iota");
        FileOutputStream stream = new FileOutputStream(iota, false);
        stream.write("This   is   the   file   'iota'.\t".getBytes());
        stream.close();
        Set<String> srcPaths = new HashSet<String>(1);
        srcPaths.add(thisTest.getWCPath());
        try {
            client.username("rayjandom");
            client.commit(srcPaths, Depth.infinity, false, false, null, null,
                          new ConstMsg("Whitespace-only change in /iota"), null);
        } finally {
            client.username("jrandom");
        }

        // Run blame on the result
        BlameCallbackImpl callback = new BlameCallbackImpl();
        client.blame(thisTest.getWCPath() + "/iota", Revision.HEAD,
                     Revision.getInstance(1), Revision.HEAD,
                     false, false, callback,
                     new DiffOptions(DiffOptions.Flag.IgnoreWhitespace));
        assertEquals(1, callback.numberOfLines());
        BlameCallbackImpl.BlameLine line = callback.getBlameLine(0);
        assertNotNull(line);
        assertEquals(1, line.getRevision());
        assertEquals("jrandom", line.getAuthor());
        assertEquals("This   is   the   file   'iota'.\t", line.getLine());
    }

    /**
     * Test the new 1.12 blame interface on a file with null bytes.
     * @throws Throwable
     * @since 1.12
     */
    public void testBinaryBlame() throws Throwable
    {
        final byte[] lineIn = {0x0, 0x0, 0x0, 0xa};
        final byte[] lineOut = {0x0, 0x0, 0x0};

        OneTest thisTest = new OneTest();
        // Modify the file iota, adding null bytes.
        File iota = new File(thisTest.getWorkingCopy(), "iota");
        FileOutputStream stream = new FileOutputStream(iota, false);
        stream.write(lineIn);
        stream.close();
        Set<String> srcPaths = new HashSet<String>(1);
        srcPaths.add(thisTest.getWCPath());
        try {
            client.username("rayjandom");
            client.commit(srcPaths, Depth.infinity, false, false, null, null,
                          new ConstMsg("NUL bytes written to /iota"), null);
        } finally {
            client.username("jrandom");
        }

        // Test the current interface
        BlameRangeCallbackImpl rangeCallback = new BlameRangeCallbackImpl();
        BlameLineCallbackImpl lineCallback = new BlameLineCallbackImpl();
        client.blame(thisTest.getWCPath() + "/iota", Revision.HEAD,
                     Revision.getInstance(0), Revision.HEAD,
                     false, false, null, rangeCallback, lineCallback);
        assertEquals(0, rangeCallback.startRevnum);
        assertEquals(2, rangeCallback.endRevnum);
        assertEquals(1, lineCallback.numberOfLines());

        BlameLineCallbackImpl.BlameLine line = lineCallback.getBlameLine(0);
        assertNotNull(line);
        assertEquals(2, line.getRevision());
        assertEquals("rayjandom", line.getAuthor());
        assertArrayEquals(lineOut, line.getLine());
    }

    /**
     * Test commit of arbitrary revprops.
     * @throws Throwable
     * @since 1.5
     */
    public void testCommitRevprops() throws Throwable
    {
        // build the test setup
        OneTest thisTest = new OneTest();

        // modify file A/mu
        File mu = new File(thisTest.getWorkingCopy(), "A/mu");
        PrintWriter muWriter = new PrintWriter(new FileOutputStream(mu, true));
        muWriter.print("appended mu text");
        muWriter.close();
        thisTest.getWc().setItemWorkingCopyRevision("A/mu", 2);
        thisTest.getWc().setItemContent("A/mu",
                thisTest.getWc().getItemContent("A/mu") + "appended mu text");
        addExpectedCommitItem(thisTest.getWCPath(),
                thisTest.getUrl().toString(), "A/mu",NodeKind.file,
                CommitItemStateFlags.TextMods);

        // commit the changes, with some extra revprops
        Map<String, String> revprops = new HashMap<String, String>();
        revprops.put("kfogel", "rockstar");
        revprops.put("cmpilato", "theman");
        checkCommitRevision(thisTest, "wrong revision number from commit", 2,
                            thisTest.getWCPathSet(), "log msg",
                            Depth.infinity, true, true, null, revprops);

        // check the status of the working copy
        thisTest.checkStatus();

        // Fetch our revprops from the server
        final List<Map<String, byte[]>> revpropList =
                            new ArrayList<Map<String, byte[]>>();
        Set<String> revProps = new HashSet<String>(2);
        revProps.add("kfogel");
        revProps.add("cmpilato");
        // Testing variant with allRevProps = false
        client.logMessages(thisTest.getWCPath(), Revision.getInstance(2),
                toRevisionRange(Revision.getInstance(2),
                                Revision.getInstance(2)),
                false, false, false, revProps, false, 0,
                new LogMessageCallback () {
                    public void singleMessage(Set<ChangePath> changedPaths,
                                              long revision,
                                              Map<String, byte[]> revprops,
                                              boolean hasChildren)
                  { revpropList.add(revprops); }
                });
        Map<String, byte[]> fetchedProps = revpropList.get(0);

        assertEquals("wrong number of fetched revprops", revprops.size(),
                     fetchedProps.size());
        Set<String> keys = fetchedProps.keySet();
        for (String key : keys)
          {
            assertEquals("revprops check", revprops.get(key),
                         new String(fetchedProps.get(key)));
          }
    }

    /**
     * Test an explicit expose of SVNClient.
     * (This used to cause a fatal exception in the Java Runtime)
     */
    public void testDispose() throws Throwable
    {
      SVNClient cl = new SVNClient();
      cl.dispose();
    }

    /**
     * Test RevisionRangeList.remove
     */
    public void testRevisionRangeListRemove() throws Throwable
    {
        RevisionRangeList ranges =
            new RevisionRangeList(new ArrayList<RevisionRange>());
        ranges.getRanges()
            .add(new RevisionRange(Revision.getInstance(1),
                                   Revision.getInstance(5),
                                   true));
        ranges.getRanges()
            .add(new RevisionRange(Revision.getInstance(7),
                                   Revision.getInstance(9),
                                   false));
        RevisionRangeList eraser =
            new RevisionRangeList(new ArrayList<RevisionRange>());
        eraser.getRanges()
            .add(new RevisionRange(Revision.getInstance(7),
                                   Revision.getInstance(9),
                                   true));

        List<RevisionRange> result = ranges.remove(eraser, true).getRanges();
        assertEquals(2, ranges.getRanges().size());
        assertEquals(1, eraser.getRanges().size());
        assertEquals(2, result.size());

        result = ranges.remove(eraser.getRanges(), false);
        assertEquals(2, ranges.getRanges().size());
        assertEquals(1, eraser.getRanges().size());
        assertEquals(1, result.size());
    }

    private class Tunnel extends Thread
        implements TunnelAgent, TunnelAgent.CloseTunnelCallback
    {
        public boolean checkTunnel(String name)
        {
            return name.equals("test");
        }

        public TunnelAgent.CloseTunnelCallback
            openTunnel(ReadableByteChannel request,
                       WritableByteChannel response,
                       String name, String user,
                       String hostname, int port)
        {
            this.request = request;
            this.response = response;
            start();
            return this;
        }

        public void closeTunnel()
        {
            Throwable t = null;
            try {
                request.close();
                join();
                response.close();
            } catch (Throwable ex) {
                t = ex;
            }
            assertEquals("No exception thrown", null, t);
        }

        private ReadableByteChannel request;
        private WritableByteChannel response;

        public void run()
        {

            int index = 0;
            byte[] raw_data = new byte[1024];
            ByteBuffer data = ByteBuffer.wrap(raw_data);
            while(index < commands.length && request.isOpen()) {
                try {
                    byte[] command = commands[index++];
                    response.write(ByteBuffer.wrap(command));
                } catch (IOException ex) {
                    break;
                }

                try {
                    data.clear();
                    request.read(data);
                } catch (Throwable ex) {}
            }

            try {
                response.close();
                request.close();
            } catch (Throwable t) {}
        }

        private final byte[][] commands = new byte[][]{
            // Initial capabilities negotiation
            ("( success ( 2 2 ( ) " +
             "( edit-pipeline svndiff1 absent-entries commit-revprops " +
             "depth log-revprops atomic-revprops partial-replay " +
             "inherited-props ephemeral-txnprops file-revs-reverse " +
             ") ) ) ").getBytes(),

            // Response for successful connection
            ("( success ( ( ANONYMOUS EXTERNAL ) " +
             "36:e3c8c113-03ba-4ec5-a8e6-8fc555e57b91 ) ) ").getBytes(),

            // Response to authentication request
            ("( success ( ) ) ( success ( " +
             "36:e3c8c113-03ba-4ec5-a8e6-8fc555e57b91 " +
             "24:svn+test://localhost/foo ( mergeinfo ) ) ) ").getBytes(),

            // Response to revprop request
            ("( success ( ( ) 0: ) ) ( success ( ( 4:fake ) ) ) ").getBytes()
        };
    }

    /**
     * Test tunnel handling.
     */
    public void testTunnelAgent() throws Throwable
    {
        byte[] revprop;
        SVNClient cl = new SVNClient();
        try {
            cl.notification2(new MyNotifier());
            if (DefaultAuthn.useDeprecated())
                cl.setPrompt(DefaultAuthn.getDeprecated());
            else
                cl.setPrompt(DefaultAuthn.getDefault());
            cl.username(USERNAME);
            cl.setProgressCallback(new DefaultProgressListener());
            cl.setConfigDirectory(conf.getAbsolutePath());

            cl.setTunnelAgent(new Tunnel());
            revprop = cl.revProperty("svn+test://localhost/foo", "svn:log",
                                     Revision.getInstance(0L));
        } finally {
            cl.dispose();
        }
        assertEquals("fake", new String(revprop));
    }

    public static int FLAG_ECHO          = 0x00000001;
    public static int FLAG_THROW_IN_OPEN = 0x00000002;

    public enum Actions
    {
        READ_CLIENT,    // Read a request from SVN client
        EMUL_SERVER,    // Emulate server response
        WAIT_TUNNEL,    // Wait for tunnel to be closed
    };

    public static class ScriptItem
    {
        Actions action;
        String value;

        ScriptItem(Actions action, String value)
        {
            this.action = action;
            this.value = value;
        }
    }

    private static class TestTunnelAgent extends Thread
        implements TunnelAgent
    {
        ScriptItem[] script;
        int flags;
        String error = null;
        ReadableByteChannel request;
        WritableByteChannel response;

        final CloseTunnelCallback closeTunnelCallback = () ->
        {
            if ((flags & FLAG_ECHO) != 0)
                System.out.println("TunnelAgent.CloseTunnelCallback");
        };

        TestTunnelAgent(int flags, ScriptItem[] script)
        {
            this.flags = flags;
            this.script = script;
        }

        public void joinAndTest()
        {
            try
            {
                join();
            }
            catch (InterruptedException e)
            {
                fail("InterruptedException was caught");
            }

            if (error != null)
                fail(error);
        }

        @Override
        public boolean checkTunnel(String name)
        {
            return true;
        }

        private String readClient(ByteBuffer readBuffer)
            throws IOException
        {
            readBuffer.reset();
            request.read(readBuffer);

            final int offset = readBuffer.arrayOffset();
            return new String(readBuffer.array(),
                offset,
                readBuffer.position() - offset);
        }

        private void emulateServer(String serverMessage)
            throws IOException
        {
            final byte[] responseBytes = serverMessage.getBytes();
            response.write(ByteBuffer.wrap(responseBytes));
        }

        private void doScriptItem(ScriptItem scriptItem, ByteBuffer readBuffer)
            throws Exception
        {
            switch (scriptItem.action)
            {
            case READ_CLIENT:
                final String actualLine = readClient(readBuffer);

                if ((flags & FLAG_ECHO) != 0)
                {
                    System.out.println("SERVER: " + scriptItem.value);
                    System.out.flush();
                }

                if (!actualLine.contains(scriptItem.value))
                {
                    System.err.println("Expected: " + scriptItem.value);
                    System.err.println("Actual:   " + actualLine);
                    System.err.flush();

                    // Unblock the SVN thread by emulating a server error
                    final String serverError = "( success ( ( ) 0: ) ) ( failure ( ( 160000 39:Test script received unexpected request 0: 0 ) ) ) ";
                    emulateServer(serverError);

                    fail("Unexpected client request");
                }
                break;
            case EMUL_SERVER:
                if ((flags & FLAG_ECHO) != 0)
                {
                    System.out.println("CLIENT: " + scriptItem.value);
                    System.out.flush();
                }

                emulateServer(scriptItem.value);
                break;
            case WAIT_TUNNEL:
                // The loop will end with an exception when tunnel is closed
                for (;;)
                {
                    readClient(readBuffer);
                }
            }
        }

        public void run()
        {
            final ByteBuffer readBuffer = ByteBuffer.allocate(1024 * 1024);
            readBuffer.mark();

            for (ScriptItem scriptItem : script)
            {
                try
                {
                    doScriptItem(scriptItem, readBuffer);
                }
                catch (ClosedChannelException ex)
                {
                    // Expected when closed properly
                }
                catch (IOException e)
                {
                    // IOException occurs when already-freed apr_file_t was lucky
                    // to have reasonable fields to avoid the crash. It still
                    // indicates a problem.
                    error = "IOException was caught in run()";
                    return;
                }
                catch (Throwable t)
                {
                    // No other exceptions are expected here.
                    error = "Exception was caught in run()";
                    t.printStackTrace();
                    return;
                }
            }
        }

        @Override
        public CloseTunnelCallback openTunnel(ReadableByteChannel request,
                                              WritableByteChannel response,
                                              String name,
                                              String user,
                                              String hostname,
                                              int port)
            throws Throwable
        {
            this.request = request;
            this.response = response;

            start();

            if ((flags & FLAG_THROW_IN_OPEN) != 0)
                throw ClientException.fromException(new RuntimeException("Test exception"));

            return closeTunnelCallback;
        }
    };

    /**
     * Test scenario which previously caused a JVM crash.
     * In this scenario, GC is invoked before closing tunnel.
     */
    public void testCrash_RemoteSession_nativeDispose()
    {
        final ScriptItem[] script = new ScriptItem[]
        {
            new ScriptItem(Actions.EMUL_SERVER, "( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) ) "),
            new ScriptItem(Actions.READ_CLIENT, "edit-pipeline"),
            new ScriptItem(Actions.EMUL_SERVER, "( success ( ( ANONYMOUS ) 36:0113e071-0208-4a7b-9f20-3038f9caf0f0 ) ) "),
            new ScriptItem(Actions.READ_CLIENT, "ANONYMOUS"),
            new ScriptItem(Actions.EMUL_SERVER, "( success ( ) ) ( success ( 36:00000000-0000-0000-0000-000000000000 25:svn+test://localhost/test ( mergeinfo ) ) ) "),
        };

        final TestTunnelAgent tunnelAgent = new TestTunnelAgent(0, script);
        final RemoteFactory remoteFactory = new RemoteFactory();
        remoteFactory.setTunnelAgent(tunnelAgent);

        ISVNRemote remote = null;
        try
        {
            remote = remoteFactory.openRemoteSession("svn+test://localhost/test", 1);
        }
        catch (SubversionException e)
        {
            fail("SubversionException was caught");
        }

        // Previously, 'OperationContext::openTunnel()' didn't 'NewGlobalRef()'
        // callback returned by 'TunnelAgent.openTunnel()'. This caused JVM to
        // dispose it on next GC. JavaHL calls callback in 'remote.dispose()'.
        // If the callback was disposed, this caused a JVM crash.
        System.gc();
        remote.dispose();

        tunnelAgent.joinAndTest();
    }

    /**
     * Test scenario which previously caused a JVM crash.
     * In this scenario, tunnel was not properly closed after exception in
     * 'TunnelAgent.openTunnel()'.
     */
    public void testCrash_RequestChannel_nativeRead_AfterException()
    {
        // Previously, exception caused TunnelChannel's native side to be
        // destroyed with the following abbreviated stack:
        //   TunnelChannel.nativeClose()
        //   svn_pool_destroy(sesspool)
        //   svn_ra_open5()
        // TunnelAgent was unaware and called 'RequestChannel.nativeRead()'
        // or 'ResponseChannel.nativeWrite()', causing either a crash or
        // an attempt to use a random file.
        final int flags = FLAG_THROW_IN_OPEN;

        final ScriptItem[] script = new ScriptItem[]
        {
            new ScriptItem(Actions.EMUL_SERVER, "( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) ) "),
            new ScriptItem(Actions.WAIT_TUNNEL, ""),
        };

        final TestTunnelAgent tunnelAgent = new TestTunnelAgent(flags, script);
        final SVNClient svnClient = new SVNClient();
        svnClient.setTunnelAgent(tunnelAgent);

        try
        {
            svnClient.openRemoteSession("svn+test://localhost/test");
        }
        catch (SubversionException e)
        {
            // RuntimeException("Test exception") is expected here
        }

        tunnelAgent.joinAndTest();
    }

    /**
     * Test scenario which previously caused a JVM crash.
     * In this scenario, tunnel was not properly closed after an SVN error.
     */
    public void testCrash_RequestChannel_nativeRead_AfterSvnError()
    {
        final String wcRoot = new File("tempSvnRepo").getAbsolutePath();

        final ScriptItem[] script = new ScriptItem[]
        {
            // openRemoteSession
            new ScriptItem(Actions.EMUL_SERVER, "( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) ) "),
            new ScriptItem(Actions.READ_CLIENT, "edit-pipeline"),
            new ScriptItem(Actions.EMUL_SERVER, "( success ( ( ANONYMOUS ) 36:0113e071-0208-4a7b-9f20-3038f9caf0f0 ) ) "),
            new ScriptItem(Actions.READ_CLIENT, "ANONYMOUS"),
            new ScriptItem(Actions.EMUL_SERVER, "( success ( ) ) ( success ( 36:00000000-0000-0000-0000-000000000000 25:svn+test://localhost/test ( mergeinfo ) ) ) "),
            // checkout
            new ScriptItem(Actions.READ_CLIENT, "( get-latest-rev ( ) ) "),
            // Previously, error caused a SubversionException to be created,
            // which then skipped closing the Tunnel properly due to
            // 'ExceptionOccurred()' in 'OperationContext::closeTunnel()'.
            // If TunnelAgent was unaware and called 'RequestChannel.nativeRead()',
            // it either crashed or tried to use a random file.
            new ScriptItem(Actions.EMUL_SERVER, "( success ( ( ) 0: ) ) ( failure ( ( 160006 20:This is a test error 0: 0 ) ) ) "),
            // Pretend that TunnelAgent tries to read more
            new ScriptItem(Actions.WAIT_TUNNEL, ""),
        };

        final TestTunnelAgent tunnelAgent = new TestTunnelAgent(0, script);
        final SVNClient svnClient = new SVNClient();
        svnClient.setTunnelAgent(tunnelAgent);

        try
        {
            svnClient.checkout("svn+test://localhost/test",
                               wcRoot,
                               Revision.getInstance(1),
                               null,
                               Depth.infinity,
                               true,
                               false);

            svnClient.dispose();
        }
        catch (ClientException ex)
        {
            final int SVN_ERR_FS_NO_SUCH_REVISION = 160006;
            if (SVN_ERR_FS_NO_SUCH_REVISION != ex.getAllMessages().get(0).getCode())
                ex.printStackTrace();
        }

        tunnelAgent.joinAndTest();
    }

    /**
     * @return <code>file</code> converted into a -- possibly
     * <code>canonical</code>-ized -- Subversion-internal path
     * representation.
     */
    private String fileToSVNPath(File file, boolean canonical)
    {
        // JavaHL need paths with '/' separators
        if (canonical)
        {
            try
            {
                return file.getCanonicalPath().replace('\\', '/');
            }
            catch (IOException e)
            {
                return null;
            }
        }
        else
        {
            return file.getPath().replace('\\', '/');
        }
    }

    private List<RevisionRange> toRevisionRange(Revision rev1, Revision rev2)
    {
        List<RevisionRange> ranges = new ArrayList<RevisionRange>(1);
        ranges.add(new RevisionRange(rev1, rev2));
        return ranges;
    }

    /**
     * A DiffSummaryReceiver implementation which collects all DiffSummary
     * notifications.
     */
    private static class DiffSummaries extends HashMap<String, DiffSummary>
        implements DiffSummaryCallback
    {
        // Update the serialVersionUID when there is a incompatible
        // change made to this class.
        private static final long serialVersionUID = 1L;

        public void onSummary(DiffSummary descriptor)
        {
            super.put(descriptor.getPath(), descriptor);
        }
    }

    private class MyChangelistCallback
        extends HashMap<String, Collection<String>>
        implements ChangelistCallback
    {
        private static final long serialVersionUID = 1L;

        private HashSet<String> allChangelists = new HashSet<String>();

        public void doChangelist(String path, String changelist)
        {
            if (changelist != null)
                allChangelists.add(changelist);

            path = fileToSVNPath(new File(path), true);
            if (super.containsKey(path))
            {
                // Append the changelist to the existing list
                Collection<String> changelists = super.get(path);
                changelists.add(changelist);
            }
            else
            {
                // Create a new changelist with that list
                List<String> changelistList = new ArrayList<String>();
                changelistList.add(changelist);
                super.put(path, changelistList);
            }
        }

        public Collection<String> get(String path)
        {
            return super.get(path);
        }

        public Collection<String> getChangelists()
        {
            return allChangelists;
        }
    }

    private class MyInfoCallback implements InfoCallback {
        private Info info;

        public void singleInfo(Info info) {
            this.info = info;
        }

        public Info getInfo() {
            return info;
        }
    }

    private void checkCommitRevision(OneTest thisTest, String failureMsg,
                                     long expectedRevision,
                                     Set<String> path, String message,
                                     Depth depth, boolean noUnlock,
                                     boolean keepChangelist,
                                     Collection<String> changelists,
                                     Map<String, String> revpropTable)
            throws ClientException
    {
        MyCommitCallback callback = new MyCommitCallback();

        client.commit(path, depth, noUnlock, keepChangelist,
                      changelists, revpropTable,
                      new ConstMsg(message), callback);
        assertEquals(failureMsg, callback.getRevision(), expectedRevision);
    }

    private class MyCommitCallback implements CommitCallback
    {
        private CommitInfo info = null;

        public void commitInfo(CommitInfo info) {
            this.info = info;
        }

        public long getRevision() {
            if (info != null)
                return info.getRevision();
            else
                return -1;
        }
    }

    private class MyStatusCallback implements StatusCallback
    {
        private List<Status> statuses = new ArrayList<Status>();

        public void doStatus(String path, Status status)
        {
            if (status != null)
                statuses.add(status);
        }

        public Status[] getStatusArray()
        {
            return statuses.toArray(new Status[statuses.size()]);
        }
    }

    private class ConstMsg implements CommitMessageCallback
    {
        private String message;

        ConstMsg(String message)
        {
            this.message = message;
        }

        public String getLogMessage(Set<CommitItem> items)
        {
            return message;
        }
    }

    private Map<String, byte[]> collectProperties(String path,
                                             Revision revision,
                                             Revision pegRevision, Depth depth,
                                             Collection<String> changelists)
        throws ClientException
    {
       final Map<String, Map<String, byte[]>> propMap =
            new HashMap<String, Map<String, byte[]>>();

        client.properties(path, revision, revision, depth, changelists,
                new ProplistCallback () {
            public void singlePath(String path, Map<String, byte[]> props)
            { propMap.put(path, props); }
        });

        return propMap.get(path);
    }

    private DirEntry[] collectDirEntries(String url, Revision revision,
                                         Revision pegRevision, Depth depth,
                                         int direntFields, boolean fetchLocks)
        throws ClientException
    {
        class MyListCallback implements ListCallback
        {
            private List<DirEntry> dirents = new ArrayList<DirEntry>();

            public void doEntry(DirEntry dirent, Lock lock)
            {
                // All of this is meant to retain backward compatibility with
                // the old svn_client_ls-style API.  For further information
                // about what is going on here, see the comments in
                // libsvn_client/list.c:store_dirent().

                if (dirent.getPath().length() == 0)
                {
                    if (dirent.getNodeKind() == NodeKind.file)
                    {
                        String absPath = dirent.getAbsPath();
                        int lastSeparator = absPath.lastIndexOf('/');
                        String path = absPath.substring(lastSeparator,
                                                        absPath.length());
                        dirent.setPath(path);
                    }
                    else
                    {
                        // It's the requested directory, which we don't want
                        // to add.
                        return;
                    }
                }

                dirents.add(dirent);
            }

            public DirEntry[] getDirEntryArray()
            {
                return dirents.toArray(new DirEntry[dirents.size()]);
            }
        }

        MyListCallback callback = new MyListCallback();
        client.list(url, revision, pegRevision, depth, direntFields,
                    fetchLocks, callback);
        return callback.getDirEntryArray();
    }

    private Info[] collectInfos(String pathOrUrl, Revision revision,
                                 Revision pegRevision, Depth depth,
                                 Collection<String> changelists)
        throws ClientException
    {
       final List<Info> infos = new ArrayList<Info>();

       client.info(pathOrUrl, revision, pegRevision, depth,
                   true, true, false,
                   changelists, new InfoCallback () {
            public void singleInfo(Info info)
            { infos.add(info); }
        });
        return infos.toArray(new Info[infos.size()]);
    }

    private LogMessage[] collectLogMessages(String path, Revision pegRevision,
                                            List<RevisionRange> revisionRanges,
                                            boolean stopOnCopy,
                                            boolean discoverPath,
                                            boolean includeMergedRevisions,
                                            long limit)
        throws ClientException
    {
        class MyLogMessageCallback implements LogMessageCallback
        {
            private List<LogMessage> messages = new ArrayList<LogMessage>();

            public void singleMessage(Set<ChangePath> changedPaths,
                                      long revision,
                                      Map<String, byte[]> revprops,
                                      boolean hasChildren)
            {
                String author, message;
                try {
                    author = new String(revprops.get("svn:author"), "UTF8");
                } catch (UnsupportedEncodingException e) {
                    author = new String(revprops.get("svn:author"));
                }
                try {
                    message = new String(revprops.get("svn:log"), "UTF8");
                } catch (UnsupportedEncodingException e) {
                    message = new String(revprops.get("svn:log"));
                }
                long timeMicros;

                try {
                    LogDate date = new LogDate(new String(
                                                    revprops.get("svn:date")));
                    timeMicros = date.getTimeMicros();
                } catch (ParseException ex) {
                    timeMicros = 0;
                }

                LogMessage msg = new LogMessage(changedPaths, revision,
                                                author, timeMicros, message);

                /* Filter out the SVN_INVALID_REVNUM message which pre-1.5
                   clients won't expect, nor understand. */
                if (revision != Revision.SVN_INVALID_REVNUM)
                    messages.add(msg);
            }

            public LogMessage[] getMessages()
            {
                return messages.toArray(new LogMessage[messages.size()]);
            }
        }

        MyLogMessageCallback callback = new MyLogMessageCallback();
        // Testing variant with allRevProps = true
        client.logMessages(path, pegRevision, revisionRanges, stopOnCopy,
                           discoverPath, includeMergedRevisions, null,
                           true, limit, callback);
        return callback.getMessages();
    }

    @SuppressWarnings("deprecation")
    private byte[] collectBlameLines(String path, Revision pegRevision,
                                     Revision revisionStart,
                                     Revision revisionEnd,
                                     boolean ignoreMimeType,
                                     boolean includeMergedRevisions)
        throws ClientException
    {
        BlameCallbackImpl callback = new BlameCallbackImpl();
        client.blame(path, pegRevision, revisionStart, revisionEnd,
                     ignoreMimeType, includeMergedRevisions, callback);

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < callback.numberOfLines(); i++)
        {
            BlameCallbackImpl.BlameLine line = callback.getBlameLine(i);
            if (line != null)
            {
                sb.append(line.toString());
                sb.append("\n");
            }
        }
        return sb.toString().getBytes();
    }

    protected class LogMessage
    {
        private String message;

        private long timeMicros;

        private Date date;

        private long revision;

        private String author;

        private Set<ChangePath> changedPaths;

        LogMessage(Set<ChangePath> cp, long r, String a, long t, String m)
        {
            changedPaths = cp;
            revision = r;
            author = a;
            timeMicros = t;
            date = null;
            message = m;
        }

        public String getMessage()
        {
            return message;
        }

        public long getTimeMicros()
        {
            return timeMicros;
        }

        public long getTimeMillis()
        {
            return timeMicros / 1000;
        }

        public Date getDate()
        {
            if (date == null)
               date = new Date(timeMicros / 1000);
            return date;
        }

        public long getRevisionNumber()
        {
            return revision;
        }

        public String getAuthor()
        {
            return author;
        }

        public Set<ChangePath> getChangedPaths()
        {
            return changedPaths;
        }
    }

    /* A blame callback implementation. */
    @SuppressWarnings("deprecation")
    protected class BlameCallbackImpl implements BlameCallback
    {

        /** list of blame records (lines) */
        private List<BlameLine> lines = new ArrayList<BlameLine>();

        public void singleLine(Date changed, long revision, String author,
                               String line)
        {
            addBlameLine(new BlameLine(revision, author, changed, line));
        }

        public void singleLine(Date date, long revision, String author,
                               Date merged_date, long merged_revision,
                               String merged_author, String merged_path,
                               String line)
        {
            addBlameLine(new BlameLine(getRevision(revision, merged_revision),
                                       getAuthor(author, merged_author),
                                       getDate(date, merged_date),
                                       line));
        }

        public void singleLine(long lineNum, long rev,
                               Map<String, byte[]> revProps,
                               long mergedRevision,
                               Map<String, byte[]> mergedRevProps,
                               String mergedPath, String line,
                               boolean localChange)
            throws ClientException
        {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

            try {
                singleLine(
                    df.parse(new String(revProps.get("svn:date"))),
                    rev,
                    new String(revProps.get("svn:author")),
                    mergedRevProps == null ? null
                        : df.parse(new String(mergedRevProps.get("svn:date"))),
                    mergedRevision,
                    mergedRevProps == null ? null
                        : new String(mergedRevProps.get("svn:author")),
                    mergedPath, line);
            } catch (ParseException e) {
                throw ClientException.fromException(e);
            }
        }

        private Date getDate(Date date, Date merged_date) {
            return (merged_date == null ? date : merged_date);
        }

        private String getAuthor(String author, String merged_author) {
            return (merged_author == null ? author : merged_author);
        }

        private long getRevision(long revision, long merged_revision) {
            return (merged_revision == -1 ? revision : merged_revision);
        }

        /**
         * Retrieve the number of line of blame information
         * @return number of lines of blame information
         */
        public int numberOfLines()
        {
            return this.lines.size();
        }

        /**
         * Retrieve blame information for specified line number
         * @param i the line number to retrieve blame information about
         * @return  Returns object with blame information for line
         */
        public BlameLine getBlameLine(int i)
        {
            if (i >= this.lines.size())
            {
                return null;
            }
            return this.lines.get(i);
        }

        /**
         * Append the given blame info to the list
         * @param blameLine
         */
        protected void addBlameLine(BlameLine blameLine)
        {
            this.lines.add(blameLine);
        }

        /**
         * Class represeting one line of the lines, i.e. a blame record
         *
         */
        public class BlameLine
        {

            private long revision;

            private String author;

            private Date changed;

            private String line;

            /**
             * Constructor
             *
             * @param revision
             * @param author
             * @param changed
             * @param line
             */
            public BlameLine(long revision, String author,
                             Date changed, String line)
            {
                super();
                this.revision = revision;
                this.author = author;
                this.changed = changed;
                this.line = line;
            }

            /**
             * @return Returns the author.
             */
            public String getAuthor()
            {
                return author;
            }

            /**
             * @return Returns the date changed.
             */
            public Date getChanged()
            {
                return changed;
            }

            /**
             * @return Returns the source line content.
             */
            public String getLine()
            {
                return line;
            }


            /**
             * @return Returns the revision.
             */
            public long getRevision()
            {
                return revision;
            }

            /*
             * (non-Javadoc)
             * @see java.lang.Object#toString()
             */
            public String toString()
            {
                StringBuffer sb = new StringBuffer();
                if (revision > 0)
                {
                    pad(sb, Long.toString(revision), 6);
                    sb.append(' ');
                }
                else
                {
                    sb.append("     - ");
                }

                if (author != null)
                {
                    pad(sb, author, 10);
                    sb.append(" ");
                }
                else
                {
                    sb.append("         - ");
                }

                sb.append(line);

                return sb.toString();
            }

            /**
             * Left pad the input string to a given length, to simulate
             * printf()-style output. This method appends the output to the
             * class sb member.
             * @param sb StringBuffer to append to
             * @param val the input string
             * @param len the minimum length to pad to
             */
            private void pad(StringBuffer sb, String val, int len)
            {
                int padding = len - val.length();

                for (int i = 0; i < padding; i++)
                {
                    sb.append(' ');
                }

                sb.append(val);
            }
        }
    }

    /* A blame range callback implementation. */
    protected class BlameRangeCallbackImpl implements BlameRangeCallback
    {
        public long startRevnum = -1;
        public long endRevnum = -1;
        public void setRange(long start, long end)
        {
            startRevnum = start;
            endRevnum = end;
        }
    }

    /* A blame line callback implementation. */
    protected class BlameLineCallbackImpl implements BlameLineCallback
    {

        /** list of blame records (lines) */
        private List<BlameLine> lines = new ArrayList<BlameLine>();

        public void singleLine(long lineNum, long rev,
                               Map<String, byte[]> revProps,
                               long mergedRevision,
                               Map<String, byte[]> mergedRevProps,
                               String mergedPath, boolean localChange,
                               byte[] line)
            throws ClientException
        {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

            try {
                insertLine(
                    df.parse(new String(revProps.get("svn:date"))),
                    rev,
                    new String(revProps.get("svn:author")),
                    mergedRevProps == null ? null
                        : df.parse(new String(mergedRevProps.get("svn:date"))),
                    mergedRevision,
                    mergedRevProps == null ? null
                        : new String(mergedRevProps.get("svn:author")),
                    mergedPath, line);
            } catch (ParseException e) {
                throw ClientException.fromException(e);
            }
        }

        private Date getDate(Date date, Date merged_date) {
            return (merged_date == null ? date : merged_date);
        }

        private String getAuthor(String author, String merged_author) {
            return (merged_author == null ? author : merged_author);
        }

        private long getRevision(long revision, long merged_revision) {
            return (merged_revision == -1 ? revision : merged_revision);
        }

        private void insertLine(Date date, long revision, String author,
                                Date merged_date, long merged_revision,
                                String merged_author, String merged_path,
                                byte[] line)
        {
            this.lines.add(new BlameLine(getRevision(revision, merged_revision),
                                         getAuthor(author, merged_author),
                                         getDate(date, merged_date),
                                         line));
        }

        /**
         * Retrieve the number of line of blame information
         * @return number of lines of blame information
         */
        public int numberOfLines()
        {
            return this.lines.size();
        }

        /**
         * Retrieve blame information for specified line number
         * @param i the line number to retrieve blame information about
         * @return  Returns object with blame information for line
         */
        public BlameLine getBlameLine(int i)
        {
            if (i >= this.lines.size())
            {
                return null;
            }
            return this.lines.get(i);
        }

        /**
         * Class represeting one line of the lines, i.e. a blame record
         */
        public final class BlameLine
        {
            private long revision;
            private String author;
            private Date changed;
            private byte[] line;

            /**
             * Constructor
             *
             * @param revision
             * @param author
             * @param changed
             * @param line
             */
            public BlameLine(long revision, String author,
                             Date changed, byte[] line)
            {
                this.revision = revision;
                this.author = author;
                this.changed = changed;
                this.line = line;
            }

            /**
             * @return Returns the author.
             */
            public String getAuthor()
            {
                return author;
            }

            /**
             * @return Returns the date changed.
             */
            public Date getChanged()
            {
                return changed;
            }

            /**
             * @return Returns the source line content.
             */
            public byte[] getLine()
            {
                return line;
            }

            /**
             * @return Returns the revision.
             */
            public long getRevision()
            {
                return revision;
            }
        }
    }

    /** A helper which calls update with a bunch of default args. */
    private long update(OneTest thisTest)
        throws ClientException
    {
        return client.update(thisTest.getWCPathSet(), null,
                             Depth.unknown, false, false, false, false)[0];
    }

    /** A helper which calls update with a bunch of default args. */
    private long update(OneTest thisTest, String subpath)
        throws ClientException
    {
        return client.update(thisTest.getWCPathSet(subpath), null,
                             Depth.unknown, false, false, false, false)[0];
    }

    private void setprop(String path, String name, String value)
        throws ClientException
    {
        Set<String> paths = new HashSet<String>();
        paths.add(path);

        client.propertySetLocal(paths, name,
                                value != null ? value.getBytes() : null,
                                Depth.empty, null, false);
    }

    private void setprop(String path, String name, byte[] value)
        throws ClientException
    {
        Set<String> paths = new HashSet<String>();
        paths.add(path);

        client.propertySetLocal(paths, name, value, Depth.empty,
                                null, false);
    }

    private long commit(OneTest thisTest, String msg)
        throws ClientException
    {
        MyCommitCallback commitCallback = new MyCommitCallback();

        client.commit(thisTest.getWCPathSet(), Depth.infinity,
                      false, false, null, null, new ConstMsg(msg),
                      commitCallback);
        return commitCallback.getRevision();
    }
}
