Index: subversion/bindings/swig/swigutil_pl.c
===================================================================
--- subversion/bindings/swig/swigutil_pl.c	(revision 8041)
+++ subversion/bindings/swig/swigutil_pl.c	(working copy)
@@ -232,7 +232,7 @@
 
 typedef enum perl_func_invoker {
     CALL_METHOD,
-    CALL_SV,
+    CALL_SV
 } perl_func_invoker_t;
 
 /* put the va_arg in stack and invoke caller_func with func.
@@ -322,7 +322,6 @@
     return SVN_NO_ERROR;
 }
 
-
 /*** Editor Wrapping ***/
 
 /* this could be more perlish */
@@ -848,6 +847,152 @@
     return SVN_NO_ERROR;
 }
 
+svn_error_t *svn_swig_pl_thunk_simple_prompt(svn_auth_cred_simple_t **cred,
+                                             void *baton,
+                                             const char *realm,
+                                             const char *username,
+                                             svn_boolean_t may_save,
+                                             apr_pool_t *pool)
+{
+    SV *result;
+    swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *");
+    swig_type_info *credinfo = SWIG_TypeQuery ("svn_auth_cred_simple_t *");
+
+    /* Be nice and allocate the memory for the cred structure before passing it
+     * off to the perl space */
+    *cred = apr_pcalloc (pool, sizeof (**cred));
+    if (!*cred) {
+        croak ("Could not allocate memory for cred structure");
+    }
+    perl_callback_thunk (CALL_SV,
+                         baton, &result,
+                         "SssiS", *cred, credinfo,
+                         realm, username, may_save, pool, poolinfo);
+
+    return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_username_prompt(svn_auth_cred_username_t **cred,
+                                               void *baton,
+                                               const char *realm,
+                                               svn_boolean_t may_save,
+                                               apr_pool_t *pool)
+{
+    SV *result;
+    swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *");
+    swig_type_info *credinfo = SWIG_TypeQuery ("svn_auth_cred_username_t *");
+
+    /* Be nice and allocate the memory for the cred structure before passing it
+     * off to the perl space */
+    *cred = apr_pcalloc (pool, sizeof (**cred));
+    if (!*cred) {
+        croak ("Could not allocate memory for cred structure");
+    }
+    
+    perl_callback_thunk (CALL_SV,
+                         baton, &result,
+                         "SsiS", *cred, credinfo,
+                         realm, may_save, pool, poolinfo);
+
+    return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_ssl_server_trust_prompt(
+                              svn_auth_cred_ssl_server_trust_t **cred,
+                              void *baton,
+                              const char *realm,
+                              apr_uint32_t failures,
+                              const svn_auth_ssl_server_cert_info_t *cert_info,
+                              svn_boolean_t may_save,
+                              apr_pool_t *pool)
+{
+    SV *result;
+    swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *");
+    swig_type_info *credinfo = SWIG_TypeQuery (
+                                 "svn_auth_cred_ssl_server_trust_t *");
+    swig_type_info *cert_info_info = SWIG_TypeQuery (
+                                 "svn_auth_ssl_server_cert_info_t *");
+
+    /* Be nice and allocate the memory for the cred structure before passing it
+     * off to the perl space */
+    *cred = apr_pcalloc (pool, sizeof (**cred));
+    if (!*cred) {
+        croak ("Could not allocate memory for cred structure");
+    }
+   
+    perl_callback_thunk (CALL_SV,
+                         baton, &result,
+                         "SsiSiS", *cred, credinfo,
+                         realm, failures, 
+                         cert_info, cert_info_info,
+                         may_save, pool, poolinfo);
+
+    /* Allow the perl callback to indicate failure by setting all vars to 0 
+     * or by simply doing nothing.  While still allowing them to indicate
+     * failure by setting the cred strucutre's pointer to 0 via $$cred = 0 */
+    if (*cred) {
+        if ((*cred)->may_save == 0 && (*cred)->accepted_failures == 0) {
+            *cred = NULL;
+        }
+    }
+    
+    return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_prompt(
+                svn_auth_cred_ssl_client_cert_t **cred,
+                void *baton,
+                const char * realm,
+                svn_boolean_t may_save,
+                apr_pool_t *pool)
+{
+    SV *result;
+    swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *");
+    swig_type_info *credinfo = SWIG_TypeQuery (
+                                 "svn_auth_cred_ssl_client_cert_t *");
+    
+    /* Be nice and allocate the memory for the cred structure before passing it
+     * off to the perl space */
+    *cred = apr_pcalloc (pool, sizeof (**cred));
+    if (!*cred) {
+        croak ("Could not allocate memory for cred structure");
+    }
+    
+    perl_callback_thunk (CALL_SV,
+                         baton, &result,
+                         "SsiS", *cred, credinfo,
+                         realm, may_save, pool, poolinfo);
+
+    return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt(
+                                     svn_auth_cred_ssl_client_cert_pw_t **cred,
+                                     void *baton,
+                                     const char *realm,
+                                     svn_boolean_t may_save,
+                                     apr_pool_t *pool)
+{
+    SV *result;
+    swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *");
+    swig_type_info *credinfo = SWIG_TypeQuery (
+                                 "svn_auth_cred_ssl_client_cert_pw_t *");
+
+    /* Be nice and allocate the memory for the cred structure before passing it
+     * off to the perl space */
+    *cred = apr_pcalloc (pool, sizeof (**cred));
+    if (!*cred) {
+        croak ("Could not allocate memory for cred structure");
+    }
+    
+    perl_callback_thunk (CALL_SV,
+                         baton, &result,
+                         "SsiS", *cred, credinfo,
+                         realm, may_save, pool, poolinfo);
+
+    return SVN_NO_ERROR;
+}
+
 /* default pool support */
 apr_pool_t *current_pool;
 
Index: subversion/bindings/swig/swigutil_pl.h
===================================================================
--- subversion/bindings/swig/swigutil_pl.h	(revision 8041)
+++ subversion/bindings/swig/swigutil_pl.h	(working copy)
@@ -123,7 +123,47 @@
 				   SV *perl_callbacks,
 				   apr_pool_t *pool);
 
+/* thunked simple_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_simple_prompt (svn_auth_cred_simple_t **cred,
+                                              void *baton,
+                                              const char *realm,
+                                              const char *username,
+                                              svn_boolean_t may_save,
+                                              apr_pool_t *pool);
 
+/* thunked username_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_username_prompt (svn_auth_cred_username_t **cred,
+                                                void *baton,
+                                                const char *realm,
+                                                svn_boolean_t may_save,
+                                                apr_pool_t *pool);
+
+/* thunked ssl_server_trust_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_ssl_server_trust_prompt(
+                              svn_auth_cred_ssl_server_trust_t **cred,
+                              void *baton,
+                              const char *realm,
+                              apr_uint32_t failures,
+                              const svn_auth_ssl_server_cert_info_t *cert_info,
+                              svn_boolean_t may_save,
+                              apr_pool_t *pool);
+
+/* thunked ssl_client_cert callback function */
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_prompt (
+                                        svn_auth_cred_ssl_client_cert_t **cred,
+                                        void *baton,
+                                        const char *realm,
+                                        svn_boolean_t may_save,
+                                        apr_pool_t *pool);
+
+/* thunked ssl_client_cert_pw callback function */
+svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt (
+                                     svn_auth_cred_ssl_client_cert_pw_t **cred,
+                                     void *baton,
+                                     const char *realm,
+                                     svn_boolean_t may_save,
+                                     apr_pool_t *pool);
+
 /* thunked callback for svn_ra_get_wc_prop_func_t */
 svn_error_t *thunk_get_wc_prop (void *baton,
                                 const char *relpath,
Index: subversion/bindings/swig/svn_client.i
===================================================================
--- subversion/bindings/swig/svn_client.i	(revision 8041)
+++ subversion/bindings/swig/svn_client.i	(working copy)
@@ -235,9 +235,73 @@
    any API, but svn_client_ls returns a hash of pointers to dirents. */
 %types(svn_dirent_t *);
 
+/* -----------------------------------------------------------------------
+  thunk the various authentication prompt functions and store
+  the inputed SV in _global_callback for use in the later argout
+  typemap
+*/
+%typemap(perl5, in) (svn_auth_simple_prompt_func_t prompt_func,
+                     void *prompt_baton) {
+    $1 = svn_swig_pl_thunk_simple_prompt;
+    _global_callback = $input;
+    $2 = (void *) _global_callback;
+}
+
+%typemap(perl5, in) (svn_auth_username_prompt_func_t prompt_func,
+                     void *prompt_baton) {
+    $1 = svn_swig_pl_thunk_username_prompt;
+    _global_callback = $input;
+    $2 = (void *) _global_callback;
+}
+
+%typemap(perl5, in) (svn_auth_ssl_server_trust_prompt_func_t prompt_func,
+                     void *prompt_baton) {
+    $1 = svn_swig_pl_thunk_ssl_server_trust_prompt;
+    _global_callback = $input;
+    $2 = (void *) _global_callback;
+}
+
+%typemap(perl5, in) (svn_auth_ssl_client_cert_prompt_func_t prompt_func,
+                      void *prompt_baton) {
+    $1 = svn_swig_pl_thunk_ssl_client_cert_prompt;
+    _global_callback = $input;
+    $2 = (void *) _global_callback;
+}
+
+%typemap(perl5, in) (svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func,
+                      void *prompt_baton) {
+    $1 = svn_swig_pl_thunk_ssl_client_cert_pw_prompt;
+    _global_callback = $input;
+    $2 = (void *) _global_callback;
+}
+
+/* For all the prompt functions create a reference for the baton
+ * (which in this case is an SV pointing to the prompt callback)
+ * and make that a second return from the prompt function.  The
+ * auth_open_helper can then split these values up so they
+ * can be stored and the callback can stay valid until the 
+ * auth_baton is freed. */
+%typemap(perl5, argout) void *prompt_baton (SV * _global_callback) {
+  $result = sv_2mortal (newRV_inc (_global_callback));
+  argvi++;
+}
+
 /* ----------------------------------------------------------------------- */
 
+/* Convert perl hashes back into apr_hash_t * for setting the config
+ * member of the svn_client_ctx_t.   This is an ugly hack, it will
+ * always allocate the new apr_hash_t out of the global current_pool
+ * It would be better to make apr_hash_t's into magic variables in
+ * perl that are tied to the apr_hash_t interface.  This would
+ * remove the need to convert to and from perl hashs all the time.
+ */
+%typemap(perl5, in) apr_hash_t *config {
+  $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *",
+                                         svn_swig_pl_make_pool (NULL));
+}
 
+/* ----------------------------------------------------------------------- */
+
 %typemap(java, in) svn_stream_t *out %{
     $1 = svn_swig_java_outputstream_to_stream(jenv, $input, _global_pool);
 %}
Index: subversion/bindings/swig/perl/t/3client.t
===================================================================
--- subversion/bindings/swig/perl/t/3client.t	(revision 0)
+++ subversion/bindings/swig/perl/t/3client.t	(revision 0)
@@ -0,0 +1,30 @@
+#!/usr/bin/perl -w
+
+use Test::More qw(no_plan);
+use strict;
+
+require SVN::Core;
+require SVN::Repos;
+require SVN::Client;
+
+my $repospath = "/tmp/svn-$$";
+my $reposurl = "file://$repospath";
+my $wcpath = "/tmp/svn-wc-$$";
+
+# This is ugly to create the test repo with SVN::Repos, but
+# it seems to be the most reliable way.
+ok(SVN::Repos::create("$repospath", undef, undef, undef, undef),
+   "create repository at $repospath");
+
+my $ctx = SVN::Client->new;
+isa_ok($ctx,'SVN::Client','Client Object');
+
+my $ci_dir1 = $ctx->mkdir(["$reposurl/dir1"]);
+isa_ok($ci_dir1,'_p_svn_client_commit_info_t');
+is($ci_dir1->revision,1,'commit info revision equals 1');
+
+END {
+diag "cleanup";
+`rm -rf $repospath`;
+#`rm -rf $wcpath`;
+}
Index: subversion/bindings/swig/perl/Core.pm
===================================================================
--- subversion/bindings/swig/perl/Core.pm	(revision 8041)
+++ subversion/bindings/swig/perl/Core.pm	(working copy)
@@ -37,6 +37,10 @@
 SVN::Core implements higher level functions of fundamental subversion
 functions.
 
+=head1 FUNCTIONS
+
+=over 4
+
 =cut
 
 BEGIN {
@@ -48,6 +52,45 @@
     SVN::_Core::apr_terminate;
 }
 
+=item SVN::Core::auth_open([auth provider array]);
+
+Takes a reference to an array of authentication providers
+and returns an auth_baton.  If you use prompt providers
+you can not use this function, but need to use the 
+auth_open_helper.
+
+=item SVN::Core::auth_open_helper([auth provider array);
+
+Prompt providers return two values instead of one.  The
+2nd paramaeter is a reference to whatever was passed into
+them as the callback.  auth_open_helper splits up these
+arguments, passing the provider objects into auth_open
+which gives it an auth_baton and putting the other
+ones in an array.  The first return value of this
+function is the auth_baton, the second is a reference
+to an array containing the references to the callbacks.
+
+These callback arrays should be stored in the object
+the auth_baton is attached to.  
+
+=cut
+
+sub auth_open_helper {
+    my $args = shift;
+    my (@auth_providers,@auth_callbacks);
+    
+    foreach my $arg (@{$args}) {
+        if (ref($arg) eq '_p_svn_auth_provider_object_t') {
+            push @auth_providers, $arg;
+        } else {
+            push @auth_callbacks, $arg;
+            
+        }
+    }
+    my $auth_baton = SVN::Core::auth_open(\@auth_providers);
+    return ($auth_baton,\@auth_callbacks);
+}
+
 package _p_svn_stream_t;
 use SVN::Base qw(Core svn_stream_);
 
@@ -55,6 +98,10 @@
 use IO::Handle;
 our @ISA = qw(IO::Handle);
 
+=head1 OTHER OBJECTS
+
+=over 4
+
 =head2 svn_stream_t - SVN::Stream
 
 You can use native perl io handles (including io globs) as
@@ -219,6 +266,10 @@
 package SVN::Pool;
 use SVN::Base qw/Core svn_pool_/;
 
+=back
+
+=over 4
+
 =head2 svn_pool_t - SVN::Pool
 
 The perl bindings significantly simplify the usage of pools, without
Index: subversion/bindings/swig/perl/Base.pm
===================================================================
--- subversion/bindings/swig/perl/Base.pm	(revision 8041)
+++ subversion/bindings/swig/perl/Base.pm	(working copy)
@@ -38,6 +38,11 @@
 over the symbols provided in that module, it them puts the function
 with prefix trimmed in the namespace of the caller for this import.
 
+The 3rd through the last parameter is a list of symbol endings that
+you wish for SVN::Base not to import into your namespace.  This is useful
+for cases where you may want to import certaion symbols differently than
+normally.
+
 =head1 CAVEATS
 
 SVN::Base consider a function as structure member accessor if it is
@@ -47,7 +52,7 @@
 =cut
 
 sub import {
-    my (undef, $pkg, $prefix) = @_;
+    my (undef, $pkg, $prefix, @ignore) = @_;
     no warnings 'uninitialized';
     unless (${"SVN::_${pkg}::ISA"}[0] eq 'DynaLoader') {
 	@{"SVN::_${pkg}::ISA"} = qw(DynaLoader);
@@ -61,9 +66,12 @@
 
     my $caller = caller(0);
 
-    for (keys %{"SVN::_${pkg}::"}) {
+    SYMBOL: for (keys %{"SVN::_${pkg}::"}) {
 	my $name = $_;
 	next unless s/^$prefix//i;
+    foreach my $ignored_symbol (@ignore) {
+        next SYMBOL if ("$prefix$ignored_symbol" eq $name);
+    }
 
 	# insert the accessor
 	if (m/(.*)_get$/) {
Index: subversion/bindings/swig/perl/Client.pm
===================================================================
--- subversion/bindings/swig/perl/Client.pm	(revision 8041)
+++ subversion/bindings/swig/perl/Client.pm	(working copy)
@@ -1,5 +1,10 @@
+use SVN::Core;
+
 package SVN::Client;
-use SVN::Base qw(Client svn_client_);
+use SVN::Base(qw(Client svn_client_ checkout update switch add mkdir delete
+                 commit status log blame diff merge cleanup relocate
+                 revert resolved copy move revprop_set propset
+                 proplist revvprop_list export ls cat import)); 
 
 =head1 NAME
 
@@ -7,31 +12,411 @@
 
 =head1 SYNOPSIS
 
-    require SVN::Core;
-    require SVN::Client;
-    my $ctx = SVN::_Client::new_svn_client_ctx_t ();
+    use SVN::Client;
+    my $ctx = new SVN::Client(
+              auth => [SVN::Client::get_simple_provider(),
+              SVN::Client::get_simple_prompt_provider(\&simple_prompt,2),
+              SVN::Client::get_username_provider()]
+              );
 
-    $ctx->auth_baton (SVN::Core::auth_open
-          ([SVN::Client::get_simple_provider(),
-            SVN::Client::get_username_provider()]));
+    $ctx->cat (\*STDOUT, 'http://svn.collab.net/repos/svn/trunk/README', 
+               'HEAD');
 
-    SVN::Client::cat (\*STDOUT,
-                      'http://svn.collab.net/repos/svn/trunk/README',
-                      'HEAD', $ctx);
+    sub simple_prompt {                                                        
+      my $cred = shift;                                                        
+      my $realm = shift;                                                       
+      my $default_username = shift;                                            
+      my $may_save = shift;
+      my $pool = shift;                                                        
+                                                                               
+      print "Enter authentication info for realm: $realm\n";                   
+      print "Username: ";                                                      
+      my $username = <>;                                                       
+      chop($username);                                                         
+      $cred->username($username);                                              
+      print "Password: ";                                                      
+      my $password = <>;                                                       
+      chomp($password);                                                        
+      $cred->password($password);                                              
+    }                                                                          
+                                                                               
 
 =head1 DESCRIPTION
 
 SVN::Client wraps the highest level of functions provided by
-subversion to accomplish specific tasks. Consult the svn_client.h
-section in the Subversion API. the svn_client_ctx_t object could be
-obtained as showed above in SYNOPSIS.
+subversion to accomplish specific tasks in an object oriented API.
+Methods are similar to the functions provided by the C API and
+as such the documentation for it may be helpful in understanding
+this interface.
 
-The author does not have much incentive to support SVN::Client, since
-the behavior is really just like what you can get from the
-command-line client - svn.
+There are a few notable differences from the C API.  Most C function
+calls take a svn_client_ctx_t pointer as the next to last parameter.
+The perl method calls take a SVN::Client object as the first parameter.
+This allows method call invocation of the methods to be possible.
 
+Many of the C API calls also take a apr_pool_t pointer as their last
+argument.  The Perl bindings generally deal with this for you and
+you do not need to pass a pool parameter.  However, you may still
+pass a pool parameter as the last parameter to override the automatic
+handling of this for you.
+
+Users of this interface should not directly manipulate the underlying hash
+values but should use the respective attribute methods.  Many of these
+attribute methods do other things, especially when setting an attribute,
+besides simply manipulating the value in the hash.
+
+=head1 METHODS
+
+The following methods are available:
+
+=over 4
+
+=item $ctx = SVN::Client->new( %options );
+
+This class method constructs a new C<SVN::Client> object and returns
+a reference to it.
+
+Key/value pair arguments may be provided to set up the initial state
+of the user agent.  The following methods correspond to attribute
+methods described below:
+
+    KEY                    DEFAULT
+    ----------             ----------------------------------------
+    config                 Hash containing the config from the 
+                           default subversion config file location.
+
+    auth                   auth_baton intiated to provide the
+                           provider that read cached authentication
+                           options from the subversion config only.
+
+    pool                   A new pool is created for the context.
+
+=cut 
+
+sub new
+{
+    my $class = shift;
+    my $self = bless {}, $class;
+    my %args = @_;
+
+    $self->{'ctx'} = SVN::_Client::new_svn_client_ctx_t ();
+
+    if (defined($args{'auth'}))
+    {
+        $self->auth($args{'auth'});
+    } else {
+        $self->auth([SVN::Client::get_username_provider(),
+                     SVN::Client::get_simple_provider(),
+                     SVN::Client::get_ssl_server_trust_file_provider(),
+                     SVN::Client::get_ssl_client_cert_file_provider(),
+                     SVN::Client::get_ssl_client_cert_pw_file_provider(),
+                    ]);
+    }
+
+    {
+        my $pool_type = ref($args{'pool'});
+        if ($pool_type eq 'SVN::Pool' ||
+            $pool_type eq '_p_apr_pool_t') 
+        {
+            $self->{'pool'} = $args{'pool'};
+        } else {
+            $self->{'pool'} = new SVN::Pool();
+        }
+    }
+
+    # If we're passed a config use it, otherwise get the default
+    # config.
+    if (defined($args{'config'}))
+    {
+        if (ref($args{'config'}) eq 'HASH')
+        {
+            $self->config($args{'config'});
+        }
+    } else {
+        $self->config(SVN::Core::config_get_config(undef));
+    }
+    return $self;
+} 
+
+=item $ctx->cat(\*FILEHANDLE, path_or_url, revision, pool);
+
+Outputs the content of the file identified by path_or_url and revision to the
+FILEHANDLE.  FILEHANLDE is a reference to a filehandle.  revision should be a
+number or 'HEAD'.  pool is an optional parameter.
+
+=cut 
+
+# import methods into our name space and wrap them in a closure
+# to support method calling style $ctx->log()
+foreach my $function (qw(checkout update switch add mkdir delete commit
+                       status log blame diff merge cleanup relocate
+                       revert resolved copy move revprop_set propset
+                       proplist revvprop_list export ls cat import))
+{
+
+    my $real_function = \&{"SVN::_Client::svn_client_$function"};
+    *{"SVN::Client::$function"} = sub
+    {
+        # Allows import to work while not breaking use SVN::Client.
+        if ($function eq 'import')
+        {
+            if (ref($_[$[]) ne 'SVN::Client')
+            {
+                return;
+            }
+        }
+    
+        my $self = shift;
+        my @args;
+
+        if (ref($_[$#_]) eq '_p_apr_pool_t')
+        {
+            # if we got a pool pased to us we need to
+            # leave it off until we add the ctx first
+            # so we push only the first arg to the next
+            # to last arg.
+            push @args, @_[$[ .. ($#_ - 1)];
+            unless ($function eq 'propset')
+            {
+                # propset doesn't take a ctx argument
+                push @args, $self->{'ctx'};
+            }
+            push @args, $_[$#_];
+        } else {
+            push @args, @_;
+            unless ($function eq 'propset')
+            {
+                push @args,$self->{'ctx'};
+            }
+            if (defined($self->{'pool'}) && 
+                ref($self->{'pool'}) eq '_p_apr_pool_t')
+            {
+                # allow the pool entry in the SVN::Client
+                # object to override the default pool.
+                push @args, $self->{'pool'};
+            }       
+        } 
+        return $real_function->(@args);
+    }
+}
+
+=head1 ATTRIBUTE METHODS
+
+The following attribute methods are provided that allow you to set various
+configuration or retrieve it.  They all take value(s) to set the attribute and
+return the new value of the attribute or no paremeters which reuturns the
+current value.
+
+=item $ctx->auth(SVN::Client::get_username_provider());
+
+Provides access the auth_baton in the svn_client_ctx_t attached to the
+SVN::Client object.
+
+This method will accept an array or array ref of values returned from the
+authentication provider functions see L</"AUTHENTICATION PROVIDERS">.  Which it
+will convert to an auth_baton for you.  This is the preferred method of setting
+the auth_baton.
+
+It will also accept a scalar that references a _p_svn_auth_baton_t such as
+those returned from SVN::Core::auth_open and SVN::Core::auth_open_helper.
+
 =cut
 
+sub auth
+{
+    my $self = shift;
+    my $args;
+    if (scalar(@_) == 0)
+    {
+        return $self->{'ctx'}->auth_baton();
+    } elsif (scalar(@_) > 1) {
+        $args = \@_;
+    } else {
+        $args = shift;
+        if (ref($args) eq '_p_svn_auth_baton_t')
+        {
+            # 1 arg as an auth_baton so just set
+            # the baton.
+            $self->{'ctx'}->auth_baton($args);
+            return $self->{'ctx'}->auth_baton();
+        }
+    }
+    
+    my ($auth_baton,$callbacks) = SVN::Core::auth_open_helper($args);
+    $self->{'auth_provider_callbacks'} = $callbacks;
+    $self->{'ctx'}->auth_baton($auth_baton);
+    return $self->{'ctx'}->auth_baton();
+}
+
+=item $ctx->pool(new SVN::Pool);
+
+Method that sets or gets the pool that is passed to method calls requiring a
+pool but that you didn't pass one.
+
+See L<SVN::Core> for more information about how pools are managed
+in this interface.
+
+=cut
+sub pool
+{
+    my $self = shift;
+  
+    if (scalar(@_) == 0)
+    {
+        $self->{'pool'};
+    } else {
+        return $self->{'pool'} = shift;
+    }
+}
+
+=item $ctx->config(SVN::Core::config_get_config(undef));
+
+Method that allows access to the config member of the svn_client_ctx_t.
+Accepts a perl hash to set, which is what functions like
+SVN::Core:config_get_config() will return.
+
+It will return a _p_arp_hash_t scalar.  THis is a temporary
+situation.  The return value is not particular useful.  In
+the future, this value will be tied to the actual hash used
+by the C API.
+
+=cut
+sub config
+{
+    my $self = shift;
+    if (scalar(@_) == 0) {
+        return $self->{'ctx'}->config();
+    } else {
+        $self->{'ctx'}->config(shift);
+        return $self->{'ctx'}->config();
+    }
+}
+
+
+=head1 AUTHENTICATION PROVIDERS
+
+The following functions get authentication providers for you.
+They come in two forms.  Standard or File versions, which look
+for authentication information in the subversion configuration
+directory that was previously cached, or Prompt versions which
+call a subroutine to allow you to prompt the user for the
+information.
+
+The functions that return the provider objects for prompt style providers
+take a reference to a perl subroutine to use for the callback.  The first
+parameter each of these subroutines receive is a credential object.  The
+subroutines return the response by setting members of that object.  Members
+may be set like so: $cred->username("breser");  These functions and credential
+objects always have a may_save member which specifies if the authentication
+data will be cached.
+
+The providers are as follows:
+
+        NAME                WHAT IT HANDLES
+        ----------------    ----------------------------------------
+        simple              username and password pairs
+
+        username            username only
+
+        ssl_server_trust    server certificates and failures
+                            authenticating them
+
+        ssl_client_cert     client side certificate files
+
+        ssl_client_cert_pw  password for a client side certificate file.
+
+
+=over 4
+
+=item SVN::Client::get_simple_provider
+
+Returns a simple provider that returns information from previously cached
+sessions.  Takes no parameters or one pool parameter.
+
+=item SVN::Client::get_simple_prompt_provider
+
+Returns a simple provider that prompts the user via a callback. Takes two or
+three parameters, the first is the callback subroutine, the 2nd is the number
+of retries to allow, the 3rd is optionally a pool.  The subroutine gets called
+with the following parameters.  A svn_auth_cred_simple object, a realm string,
+a default username, may_save, and a pool.  The svn_auth_cred_simple has the
+following members: username, password, and may_save.
+
+=item SVN::Client::get_username_provider
+
+Returns a username provider that returns information from a previously cached
+sessions.  Takes no parameters or one pool parameter.
+
+=item SVN::Client::get_username_prompt_provider
+
+Returns a username provider that prompts the user via a callback. Takes two or
+three parameters, the first is the callback subroutine, the 2nd is the number
+of retries to allow, the 3rd is optionally a pool.  The subroutine gets called
+with the following parameters.  A svn_auth_cred_username object, a realm
+string, a default username, may_save, and a pool.  The svn_auth_cred_username
+has the following members: username and may_save.
+
+=item SVN::Client::get_ssl_server_trust_file_provider
+
+Returns a server trust provider that returns infromation from previously
+cached sessions.  Takes no parameters or optionally a pool parameter.
+
+=item SVN::Client::get_ssl_server_trust_prompt_provider
+
+Returns a server trust  provider that prompts the user via a callback. Takes
+one or two parameters the callback subroutine and optionally a pool parameter.
+The subroutine gets called with the following parameters.  A
+svn_auth_cred_ssl_server_trust object, a realm string, an integer specifiying
+how the certificate failed authentication, a cert info object, may_save, and a
+pool.  The svn_auth_cred_ssl_server_trust object has the following members:
+may_save and accepted_failures.  The svn_ssl_cert_info object has the following
+members (and behaves just like cred objects though you can't modify it):
+hostname, fingerprint, valid_from, valid_until, issuer_dname, ascii_cert.
+
+The masks used for determaning the failures are in SVN::_Core and are named:
+
+$SVN::_Core::SVN_AUTH_SSL_NOTYETVALID
+$SVN::_Core::SVN_AUTH_SSL_EXPIRED
+$SVN::_Core::SVN_AUTH_SSL_CNMISMATCH
+$SVN::_Core::SVN_AUTH_SSL_UNKNOWNCA
+$SVN::_Core::SVN_AUTH_SSL_OTHER
+
+You reply by setting the accepted_failures of the cred object with an integer 
+of the values for what you want to accept bitwise anded together.
+
+=item SVN::Client::get_ssl_cert_file_provider
+
+Returns a client certificate provider that returns infromation from previously
+cached sessions.  Takes no parameters or optionally a pool parameter.
+
+=item SVN::Client::get_ssl_cert_prompt_provider
+
+Returns a client certificate provider that prompts the user via a callback.
+Takes two or three parameters, the first is the callback subroutine, the 2nd is
+the number of retries to allow, the 3rd is optionally a pool parameter.  The
+subroutine gets called with the following parameters.  A
+svn_auth_cred_ssl_client_cert object, a realm string, may_save, and a pool.
+The svn_auth_cred_ssl_client_cert the following members: cert_file and
+may_save.
+
+=item SVN::Client::get_ssl_cert_pw_file_provider
+
+Returns a client certificate password provider that returns infromation from
+previously cached sessions.  Takes no parameters or optionally a pool
+paramater.
+
+=item SVN::Client::get_ssl_cert_pw_prompt_provider
+
+Returns a client certificate passowrd provider that prompts the user via a
+callback. Takes two or three parameters, the first is the callback subroutine,
+the 2nd is the number of retries to allow, the 3rd is optionally a pool
+parameter.  The subroutine gets called with the following parameters.  A
+svn_auth_cred_ssl_client_cert_pw object, a realm string, may_save, and a pool.
+The svn_auth_cred_ssl_client_cert_pw has the following members: password and
+may_save.
+
+=cut
+
 package _p_svn_client_commit_info_t;                                           
 use SVN::Base qw(Client svn_client_commit_info_t_);                            
                                                                                
@@ -44,6 +429,18 @@
 package _p_svn_client_proplist_item_t;                                         
 use SVN::Base qw(Client svn_client_proplist_item_t_);
 
+=head1 TODO
+
+* Complete documentation 
+
+* Support for the notify callback.
+
+* Support for the log_msg callback.
+
+* Better support for the config.
+
+* More unit tests.
+
 =head1 AUTHORS
 
 Chia-liang Kao E<lt>clkao@clkao.orgE<gt>
Index: subversion/bindings/swig/perl/Ra.pm
===================================================================
--- subversion/bindings/swig/perl/Ra.pm	(revision 8041)
+++ subversion/bindings/swig/perl/Ra.pm	(working copy)
@@ -90,8 +90,21 @@
     my $self = bless {}, $class;
     %$self = $#_ ? @_ : (url => $_[0]);
 
-    $self->{auth} ||= SVN::Core::auth_open
-	([ SVN::Client::get_username_provider() ]);
+    if (defined($self->{auth})) {
+        if (ref($self->{auth}) ne '_p_svn_auth_baton_t') {
+            # If the auth is already set to a auth_baton ignore it
+            # otherwise make an auth_baton and store the callbacks
+            my ($auth_baton,$auth_callbacks) = 
+                                SVN::Core::auth_open_helper($self->{auth});
+            $self->{auth} = $auth_baton;
+            $self->{auth_provider_callbacks} = $auth_callbacks;
+        }
+    } else {
+        # no callback to worry about with a username provider so just call
+        # auth_open directly
+        $self->{auth} = SVN::Core::auth_open(
+                             [SVN::Client::get_username_provider()]);
+    }
 
     my $pool = $self->{pool} ||= SVN::Core::pool_create(undef);
 


