Index: branches/pap/Nebulous/Changes
===================================================================
--- branches/pap/Nebulous/Changes	(revision 23948)
+++ branches/pap/Nebulous/Changes	(revision 25027)
@@ -1,3 +1,12 @@
 Revision history for Nebulous
+
+0.17
+    - add chmod() API
+    - change neb-ls to always output in --long format
+    - add neb-rm --force flag
+    - change neb-locate's output seperator to \n
+    - add Nebulous::Client->prune() method
+    - add Nebulous::Client->there_can_be_only_one() method
+    - add neb-cull --one_only flag
 
 0.10
@@ -9,4 +18,5 @@
     - add neb-swap
     - add nebclient:nebSetXattr()
+    - add neb-rm --move flag
 
 0.09 Wed Jul  9 16:36:27 HST 2008
Index: branches/pap/Nebulous/MANIFEST
===================================================================
--- branches/pap/Nebulous/MANIFEST	(revision 23948)
+++ branches/pap/Nebulous/MANIFEST	(revision 25027)
@@ -79,6 +79,6 @@
 t/00_distribution.t 
 t/01_load.t
-t/50_client_new.t
-t/51_client_create.t
+t/49_client_new.t
+t/50_client_create.t
 t/51_client_open_create.t
 t/52_client_replicate.t
@@ -98,5 +98,9 @@
 t/66_client_xattr.t
 t/67_client_swap.t
+t/68_client_chmod.t
+t/69_client_prune.t
 t/70_neb-ls.t
+t/71_client_there_can_be_only_one.t
+t/72_neb-cull.t
 t/90_nebclient.t
 t/TEST.PL
Index: branches/pap/Nebulous/bin/neb-cull
===================================================================
--- branches/pap/Nebulous/bin/neb-cull	(revision 23948)
+++ branches/pap/Nebulous/bin/neb-cull	(revision 25027)
@@ -16,5 +16,5 @@
 use Pod::Usage qw( pod2usage );
 
-my ($server, $volume);
+my ($server, $volume, $one_only);
 
 $server = $ENV{'NEB_SERVER'} unless $server;
@@ -23,4 +23,5 @@
     'server|s=s'    => \$server,
     'volume|v=s'    => \$volume,
+    'one_only|o'    => \$one_only,
 ) || pod2usage( 2 );
 
@@ -40,10 +41,24 @@
     unless defined $neb;
 
+my @cull_args;    
+push @cull_args, $key;
 if (defined $volume) {
-    $neb->cull($key, $volume)
-        or die "failed to replicate Nebulous key: $key";
+    push @cull_args, $volume;
+}
+
+if ($one_only) {
+    my $status = $neb->there_can_be_only_one(@cull_args);
+    if ($status == 0) {
+        die "not enough instances of Nebulous key: $key";
+    }
+    if (not defined $status or $status < 1) {
+        die "failed to cull Nebulous key: $key - " . $neb->err
+            if defined $neb->err;
+        die "failed to cull Nebulous key: $key";
+    }
 } else {
-    $neb->cull($key)
-        or die "failed to replicate Nebulous key: $key";
+    unless (defined $neb->cull(@cull_args)) {
+        die "failed to cull Nebulous key: $key - " . $neb->err;
+    }
 }
 
@@ -58,5 +73,5 @@
 =head1 SYNOPSIS
 
-    neb-cull [--server <URL>] [--volume <volume name>] <key>
+    neb-cull [--server <URL>] [--volume <volume name>] [--one_only] <key>
 
 =head1 DESCRIPTION
@@ -77,4 +92,12 @@
 
 Symbolic name of the volume to create the new instance on.
+
+Optional.
+
+=item * --one_only|-o
+
+Removes all but one instances of an object.  Any inaccessible instances are
+removed.  If C<--volume> is specified, and an instance exists on that volume,
+all instances but the one on that volume are removed.
 
 Optional.
@@ -110,5 +133,5 @@
 =head1 COPYRIGHT
 
-Copyright (C) 2007-2008  Joshua Hoblitt.  All rights reserved.
+Copyright (C) 2007-2009  Joshua Hoblitt.  All rights reserved.
 
 This program is free software; you can redistribute it and/or modify it under
Index: branches/pap/Nebulous/bin/neb-locate
===================================================================
--- branches/pap/Nebulous/bin/neb-locate	(revision 23948)
+++ branches/pap/Nebulous/bin/neb-locate	(revision 25027)
@@ -41,4 +41,6 @@
     unless defined $neb;
 
+$volume = 'any' if defined $all;
+
 my $uris;
 if (defined $volume) {
@@ -70,5 +72,5 @@
 }
 
-print join(" ", @files), "\n";
+print join("\n", @files), "\n";
 
 __END__
Index: branches/pap/Nebulous/bin/neb-ls
===================================================================
--- branches/pap/Nebulous/bin/neb-ls	(revision 23948)
+++ branches/pap/Nebulous/bin/neb-ls	(revision 25027)
@@ -21,4 +21,7 @@
 
 $server = $ENV{'NEB_SERVER'} unless $server;
+
+# make --long the default
+$long = 1;
 
 GetOptions(
Index: branches/pap/Nebulous/bin/neb-replicate
===================================================================
--- branches/pap/Nebulous/bin/neb-replicate	(revision 23948)
+++ branches/pap/Nebulous/bin/neb-replicate	(revision 25027)
@@ -16,5 +16,5 @@
 use Pod::Usage qw( pod2usage );
 
-my ($server, $volume, $copies);
+my ($server, $volume, $copies, $set_copies);
 $copies = 1;  # default to making just one copy
 
Index: branches/pap/Nebulous/bin/neb-rm
===================================================================
--- branches/pap/Nebulous/bin/neb-rm	(revision 23948)
+++ branches/pap/Nebulous/bin/neb-rm	(revision 25027)
@@ -16,9 +16,15 @@
 use Pod::Usage qw( pod2usage );
 
-my ($server);
+my (
+    $force,
+    $move,
+    $server,
+);
 
 $server = $ENV{'NEB_SERVER'} unless $server;
 
 GetOptions(
+    'force|f'       => \$force,
+    'move|m'        => \$move,
     'server|s=s'    => \$server,
 ) || pod2usage( 2 );
@@ -35,5 +41,9 @@
 
 foreach my $key (@ARGV) {
-    $neb->delete($key) or warn "failed to delete key: $key";
+    unless (defined $move) {
+        $neb->delete($key, $force) or warn "failed to delete key: $key";
+    } else {
+        $neb->move($key, "${key}.rm") or warn "failed to move key: $key";
+    }
 }
 
@@ -48,5 +58,5 @@
 =head1 SYNOPSIS
 
-    neb-rm [--server <URL>] <key...>
+    neb-rm [--server <URL>] [--force] [--move] <key...>
 
 =head1 DESCRIPTION
@@ -58,4 +68,18 @@
 
 =over 4
+
+=item * --force|-f
+
+When set, C<<key>> will be removed from the nebulous database even if the on
+disk file(s) are missing.
+
+Optional.
+
+=item * --move|-m
+
+When set, this flag causes C<<key>> to be renamed to C<<key>.rm> instead of
+being deleted.
+
+Optional.
 
 =item * --server|-s <URL>
Index: branches/pap/Nebulous/bin/neb-stat
===================================================================
--- branches/pap/Nebulous/bin/neb-stat	(revision 23948)
+++ branches/pap/Nebulous/bin/neb-stat	(revision 25027)
@@ -41,16 +41,17 @@
 my $stat = $neb->stat($key);
 die "nebulous key: $key not found" unless $stat;   
-my $instances = $neb->find_instances($key, ':any');
+my $instances = $neb->find_instances($key, 'any');
 die "no instances found" unless $instances;   
 
 no warnings qw(uninitialized);
 print
-    "object id:     ", @$stat[0], "\n",
-    "key:           ", @$stat[1], "\n",
-    "read lock:     ", @$stat[2], "\n",
-    "write lock:    ", @$stat[3], "\n",
-    "epoch:         ", @$stat[4], "\n",
-    "mtime:         ", @$stat[5], "\n",
-    "n instances:   ", @$stat[6], "\n",
+    "object id:             ", @$stat[0], "\n",
+    "key:                   ", @$stat[1], "\n",
+    "read lock:             ", @$stat[2], "\n",
+    "write lock:            ", @$stat[3], "\n",
+    "epoch:                 ", @$stat[4], "\n",
+    "mtime:                 ", @$stat[5], "\n",
+    "available instances:   ", @$stat[6], "\n",
+    "total instances:       ", @$stat[7], "\n",
     "instance location:\n", " " x 4,
     join("\n" . " " x 4, @$instances), "\n";
Index: branches/pap/Nebulous/lib/Nebulous/Client.pm
===================================================================
--- branches/pap/Nebulous/lib/Nebulous/Client.pm	(revision 23948)
+++ branches/pap/Nebulous/lib/Nebulous/Client.pm	(revision 25027)
@@ -9,5 +9,5 @@
 no warnings qw( uninitialized );
 
-our $VERSION = '0.09';
+our $VERSION = '0.17';
 
 use Digest::MD5;
@@ -16,5 +16,5 @@
 use Nebulous::Client::Log;
 use Nebulous::Util qw( :standard );
-use Params::Validate qw( validate validate_pos SCALAR UNDEF );
+use Params::Validate qw( validate validate_pos SCALAR UNDEF BOOLEAN );
 #use SOAP::Lite +trace => [qw( debug )];
 use SOAP::Lite;
@@ -297,5 +297,5 @@
         my $instances = $stats[6];
         if (defined $instances and $instances < 2) {
-            $log->debug("can not cull - not enough instances");
+            $self->set_err("can not cull - not enough instances");
             $log->debug("leaving");
 
@@ -305,5 +305,5 @@
         $locations = $self->find_instances($key, $vol_name);
         unless (defined $locations) {
-            $log->debug( "no instances" );
+            $self->set_err( "no instances" );
             $log->debug( "leaving" );
 
@@ -313,5 +313,5 @@
         $locations = $self->find_instances($key);
         unless ($locations) {
-            $log->debug("no instances");
+            $self->set_err( "no instances" );
             $log->debug("leaving");
 
@@ -320,5 +320,5 @@
 
         if (scalar @{ $locations } < 2) {
-            $log->debug("can not cull - not enough instances");
+            $self->set_err("can not cull - not enough instances");
             $log->debug("leaving");
 
@@ -329,7 +329,85 @@
     my $uri = $self->delete_instance($key, @$locations[0]);
 
+    eval {
+        _nuke_file(_get_file_path(@$locations[0]));
+    };
+    if ($@) {
+        $log->logdie($@);
+    }
+
     $log->debug("leaving");
 
     return $uri;
+}
+
+
+sub there_can_be_only_one
+{
+    my $self = shift;
+
+    my ($key, $vol_name) = validate_pos(@_,
+        {
+            type => SCALAR,
+        },
+        {
+            # volume
+            type        => SCALAR,
+            optional    => 1,
+        },
+    );
+
+    $log->debug( "entered - @_" );
+
+    my $locations;
+    my $removed = 0;
+    eval {
+        # first - strip off any inaccesible instances
+        if (not defined $self->prune($key)) {
+            # use the prune() method to also determine if $key is valid
+            die "invalid key: $key";
+        }
+
+        # check to see if there is an instance on $vol_name that should be the
+        # sole survivor
+        if (defined $vol_name) {
+            $locations = $self->find_instances($key, $vol_name);
+        }
+
+        if (defined $locations) {
+            my $instances = $self->find_instances($key);
+            if (scalar @$instances < 2) {
+                die "not enough instances";
+            }
+            foreach my $victim (@$instances) {
+                next if $victim eq $locations->[0];
+                $self->delete_instance($key, $victim);
+                $removed++;
+            }
+        } else {
+            # nuke whatever
+            my $stats = $self->stat($key);
+            # start at one so cull() is called one less time then the # of
+            # instances
+            if ($stats->[6] < 2) {
+                die "not enough instances";
+            }
+            for (my $i = 1; $i < $stats->[6]; $i++) {
+                $self->cull($key);
+                $removed++;
+            }
+        }
+
+    };
+    if ($@) {
+        if ($@ =~ qr/invalid key/) {
+            $self->set_err($@);
+            return;
+        }
+        $log->logdie($@);
+    }
+
+    $log->debug("leaving");
+
+    return $removed;
 }
 
@@ -803,7 +881,17 @@
     my $self = shift;
 
-    my ( $key ) = validate_pos( @_,
-        {
-            type => SCALAR,
+    my ($key, $force) = validate_pos( @_,
+        {
+            type        => SCALAR,
+        },
+        {
+            type        => BOOLEAN,
+            optional    => 1,
+            default     => undef,
+            callbacks   => {
+                'is boolean' => sub {
+                    $_[0] == 0 or $_[0] == 1 or $_[0] == undef;
+                },
+            },
         },
     );
@@ -817,5 +905,32 @@
     # a lock is implicitly removed when the last storage object is deleted
     foreach my $uri ( @$locations ) {
+        # it is being assumed here that it is better to have files on disk and
+        # not in the database then the inverse.
+        my $path;
+        eval {
+            $path = _get_file_path( $uri );
+        };
+        if ($@) {
+            if ($force) {
+                $log->warn($@);
+                $log->warn("exception ignored because force is in effect");
+            } else {
+                $log->logdie($@);
+            }
+        }
+
         $self->delete_instance($key, $uri) or return undef;
+
+        eval {
+            _nuke_file( $path );
+        };
+        if ($@) {
+            if ($force) {
+                $log->warn($@);
+                $log->warn("exception ignored because force is in effect");
+            } else {
+                $log->logdie($@);
+            }
+        }
     }
 
@@ -959,13 +1074,4 @@
     $log->debug( "entered - @_" );
 
-    # it is being assumed here that it is better to have files on disk and not in
-    # the database then the inverse.
-
-    my $path;
-    eval {
-        $path = _get_file_path( $uri );
-    };
-    $log->logdie( $@ ) if $@;
-
     my $response = $self->{ 'server' }->delete_instance($key, $uri);
     if ( $response->fault ) {
@@ -982,9 +1088,4 @@
     $log->debug( "server deleted instance" );
 
-    eval {
-        _nuke_file( $path );
-    };
-    $log->logdie( $@ ) if $@;
-
     $log->debug( "leaving" );
 
@@ -1045,4 +1146,76 @@
 
     return $stats;
+}
+
+
+sub chmod
+{
+    my $self = shift;
+
+    my ($key, $mode) = validate_pos( @_,
+        {
+            type => SCALAR,
+        },
+        {
+            type => SCALAR,
+            regex       => qr/\d{3,4}/,
+        },
+    );
+
+    $log->debug( "entered - @_" );
+
+    my $response = $self->{ 'server' }->chmod_object($key, $mode);
+    if ( $response->fault ) {
+        $self->set_err($response->faultstring);
+        if ($response->faultstring =~ /is valid object key/) {
+            $log->debug( "leaving" );
+            return;
+        }
+        if ($response->faultstring =~ /is allowable mode/) {
+            $log->debug( "leaving" );
+            return;
+        }
+
+        $log->logdie("unhandled fault - ", $self->err);
+    }
+
+    my $response_mode = $response->result;
+
+    $log->debug( "leaving" );
+
+    return $response_mode;
+}
+
+
+sub prune
+{
+    my $self = shift;
+
+    my ( $key ) = validate_pos( @_,
+        {
+            type => SCALAR,
+        },
+    );
+
+    $log->debug( "entered - @_" );
+
+    my $response = $self->{ 'server' }->prune_object( $key );
+    if ( $response->fault ) {
+        $self->set_err($response->faultstring);
+        if ($response->faultstring =~ /is valid object key/) {
+            $log->debug( "leaving" );
+            return;
+        }
+
+        $log->logdie("unhandled fault - ", $self->err);
+    }
+
+    $log->debug( "server returned a stat" );
+
+    my $n_removed = $response->result;
+
+    $log->debug( "leaving" );
+
+    return $n_removed;
 }
 
Index: branches/pap/Nebulous/lib/Nebulous/Client.pod
===================================================================
--- branches/pap/Nebulous/lib/Nebulous/Client.pod	(revision 23948)
+++ branches/pap/Nebulous/lib/Nebulous/Client.pod	(revision 25027)
@@ -13,10 +13,10 @@
     );
 
-    my $uri = $neb->create( "key", "node01" );
-    my $fh = $neb->open_create( "key", "node01" );
-    $neb->replicate( "key", "node01" );
-    $neb->cull( "key", "node01" );
-    $neb->lock( "key", 'write' );
-    $neb->unlock( "key", 'write' );
+    my $uri = $neb->create( $key, $vol );
+    my $fh = $neb->open_create( $key, $vol );
+    $neb->replicate( $key, $vol );
+    $neb->cull( $key, $vol );
+    $neb->lock( $key, 'write' );
+    $neb->unlock( $key, 'write' );
     $neb->setxattr( $key, $name, $value, $flags );
     $neb->getxattr( $key, $name );
@@ -24,14 +24,17 @@
     $neb->removexattr( $key, $name );
     my $uris = $neb->find_objects( $pattern );
-    my $uris = $neb->find_instances( "key", "node01" );
-    my $path = $neb->find( "key" );
-    my $fh = $neb->open( "key", 'read' );
-    $neb->delete( "key" );
-    $neb->copy( "key", "new_key", "node01" );
-    $neb->move( "key", "new_key" );
-    $neb->swap( "key1", "key2" );
+    my $uris = $neb->find_instances( $key, $vol );
+    my $path = $neb->find( $key );
+    my $fh = $neb->open( $key, 'read' );
+    $neb->delete( $key );
+    $neb->copy( $key, $new_key, $vol );
+    $neb->move( $key, $new_key );
+    $neb->swap( $key1, $key2 );
     $neb->delete_instance( $uri );
-    my $stats = $neb->stat( "key" );
+    my $stats = $neb->stat( $key );
     my $mounts = $neb->mounts();
+    my $mode = $neb->chmod( $key, $mode );
+    my $n_dead = $neb->prune( $key );
+    my $n_dead = $neb->there_can_be_only_one( $key, $vol );
 
 =head1 DESCRIPTION
@@ -404,4 +407,38 @@
 
 Returns an arrayref of scalars.
+
+=item * prune($key)
+
+Removes all of the inaccessible instances from an object.
+
+=over 4
+
+=item * key
+
+The storage object key (name).
+
+=back
+
+The number of instances removed.
+
+=item * there_can_be_only_one($key, $vol)
+
+Removes all but one instance of an object and automatically removes any
+inaccessible instances.
+
+=over 4
+
+=item * key
+
+The storage object key (name).
+
+=item * vol
+
+If specified, the only remaining instance will be left on this volume (if an
+instance already exists there).
+
+=back
+
+The number of avaiable instances removed.
 
 =item * mounts()
@@ -425,4 +462,11 @@
     ]
 
+=item * chmod( $key, $mode );
+
+Accepts 2 parameters, both mandatory.  C<$key> is the nebulous key to operate
+on and C<$mode> are the POSIX like file permissions to set on all instances of
+C<$key>.  C<$mode> must be specified in oct.  Returns C<$mode> or sucess or an
+exception on failure.
+
 =back
 
@@ -456,5 +500,5 @@
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008  Joshua Hoblitt.  All rights reserved.
+Copyright (C) 2004-2009  Joshua Hoblitt.  All rights reserved.
 
 This program is free software; you can redistribute it and/or modify it under
Index: branches/pap/Nebulous/nebclient/configure.ac
===================================================================
--- branches/pap/Nebulous/nebclient/configure.ac	(revision 23948)
+++ branches/pap/Nebulous/nebclient/configure.ac	(revision 25027)
@@ -5,5 +5,5 @@
 AC_PREREQ(2.61)
 
-AC_INIT([nebclient], [0.08], [jhoblitt@cpan.org])
+AC_INIT([nebclient], [0.17], [jhoblitt@cpan.org])
 AC_CONFIG_SRCDIR([nebulous.wsdl])
 
Index: branches/pap/Nebulous/nebclient/nebulous.wsdl
===================================================================
--- branches/pap/Nebulous/nebclient/nebulous.wsdl	(revision 23948)
+++ branches/pap/Nebulous/nebclient/nebulous.wsdl	(revision 25027)
@@ -140,4 +140,21 @@
     </message>
 
+    <message name="chmod_objectRequest">
+        <part name="key" type="xsd:string" />
+        <part name="mode" type="xsd:int" />
+    </message>
+    <message name="chmod_objectResponse">
+        <!-- fixme -->
+        <part name="result" type="xsd:int" />
+    </message>
+
+    <message name="prune_objectRequest">
+        <part name="key" type="xsd:string" />
+    </message>
+    <message name="prune_objectResponse">
+        <!-- fixme -->
+        <part name="result" type="xsd:int" />
+    </message>
+
 
     <portType name="Nebulous/Server/SOAPPort">
@@ -240,4 +257,18 @@
             -->
         </operation>
+        <operation name="chmod_object">
+            <input  message="tns:chmod_objectRequest" />
+            <output message="tns:chmod_objectResponse" />
+            <!--
+                <fault name="" message="" />
+            -->
+        </operation>
+        <operation name="prune_object">
+            <input  message="tns:prune_objectRequest" />
+            <output message="tns:prune_objectResponse" />
+            <!--
+                <fault name="" message="" />
+            -->
+        </operation>
     </portType>
 
@@ -390,4 +421,26 @@
         <operation name="stat_object">
             <soap:operation soapAction="urn:Nebulous/Server/SOAP#stat_object" />
+            <input>
+                <soap:body use="encoded" namespace="urn:Nebulous/Server/SOAP"
+                    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body use="encoded" namespace="urn:Nebulous/Server/SOAP"
+                    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="chmod_object">
+            <soap:operation soapAction="urn:Nebulous/Server/SOAP#chmod_object" />
+            <input>
+                <soap:body use="encoded" namespace="urn:Nebulous/Server/SOAP"
+                    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body use="encoded" namespace="urn:Nebulous/Server/SOAP"
+                    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="prune_object">
+            <soap:operation soapAction="urn:Nebulous/Server/SOAP#prune_object" />
             <input>
                 <soap:body use="encoded" namespace="urn:Nebulous/Server/SOAP"
Index: branches/pap/Nebulous/nebclient/src/nebclient.c
===================================================================
--- branches/pap/Nebulous/nebclient/src/nebclient.c	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/nebclient.c	(revision 25027)
@@ -51,9 +51,8 @@
 static char *nullstrncpy(char *dest, const char *src, size_t n);
 
+
 nebServer *nebServerAlloc(const char *endpoint)
 {
-    nebServer       *server;
-
-    server          = xmalloc(sizeof(nebServer));
+    nebServer *server = xmalloc(sizeof(nebServer));
 
     if (endpoint) {
@@ -77,4 +76,5 @@
 }
 
+
 void nebServerFree(nebServer *server)
 {
@@ -92,17 +92,16 @@
 }
 
+
 char *nebCreate(nebServer *server, const char *key, const char *volume, char **URI)
 {
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return NULL;
+    }
+
     struct ns1__create_USCOREobjectResponse response;
-    char            *filename;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return NULL;
-    }
-
     if (soap_call_ns1__create_USCOREobject(server->soap, server->endpoint, NULL,
             (char *)key, (char *)volume, (char **)&response) != SOAP_OK) {
@@ -117,6 +116,9 @@
     }
 
+    char *filename;
     if (!nebParseURI(server, (char *)response.result, &filename)) {
         nebSetErr(server, "can not parse URI");
+        nebFree(filename);
+
         return NULL;
     }
@@ -131,20 +133,21 @@
 }
 
+
 int nebOpenCreate(nebServer *server, const char *key, const char *volume, char **URI)
 {
-    char            *filename;
-    int             file;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return -1;
-    }
-
-    filename = nebCreate(server, key, volume, URI);
-
-    file = open(filename, O_RDWR|O_TRUNC, 0660);
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return -1;
+    }
+
+    char *filename = nebCreate(server, key, volume, URI);
+    if (!filename) {
+        return -1;
+    }
+
+    int file = open(filename, O_RDWR|O_TRUNC, 0660);
     if (file == -1) {
         nebSetErr(server, "can not open %s: %s", filename, strerror(errno));
@@ -159,10 +162,7 @@
 }
 
+
 bool nebReplicate(nebServer *server, const char *key, const char *volume, char **URI)
 {
-    struct ns1__replicate_USCOREobjectResponse response;
-    char            *filename;
-    int             sourceFH, destFH;
-
     REQUIRE_SERVER;
 
@@ -177,8 +177,7 @@
     // we don't do this, it's possible that open will find & open the new
     // instance that we're in the process of creating
-    sourceFH = nebOpen(server, (char *)key, NEB_READ);
+    int sourceFH = nebOpen(server, (char *)key, NEB_READ);
     if (sourceFH == -1) {
         nebSetErr(server, "can not open key %s", key);
-        nebFree(filename);
 
         return false;
@@ -186,4 +185,5 @@
 
     // ask the server for a new instance attached to our key
+    struct ns1__replicate_USCOREobjectResponse response;
     if (soap_call_ns1__replicate_USCOREobject(server->soap, server->endpoint,
             NULL, (char *)key, (char *)volume, (char **)&response) != SOAP_OK) {
@@ -193,4 +193,5 @@
     }
 
+    char *filename = NULL;
     if (!nebParseURI(server, (char *)response.result, &filename)) {
         nebSetErr(server, "can not parse URI");
@@ -199,5 +200,5 @@
     }
 
-    destFH = open(filename, O_RDWR|O_TRUNC, 0660);
+    int destFH = open(filename, O_RDWR|O_TRUNC, 0660);
     if (destFH == -1) {
         nebSetErr(server, "can not open %s: %s\n", filename, strerror(errno));
@@ -234,19 +235,21 @@
 }
 
+
 bool nebCull(nebServer *server, const char *key)
 {
-    nebObjectInstances *locations;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return false;
-    }
-
-    locations = nebFindInstances(server, key, NULL);
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return false;
+    }
+
+    nebObjectInstances *locations = nebFindInstances(server, key, NULL);
     if (!locations || locations->n <= 1) {
         nebSetErr(server, "can not cull - not enough instances");
+        if (locations) {
+            nebObjectInstancesFree(locations);
+        }
 
         return false;
@@ -264,23 +267,21 @@
 }
 
+
 bool nebLock(nebServer *server, const char *key, nebRW flag)
 {
-    time_t          endtime;
-    char            *type;
-    int             response;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return false;
-    }
-
-    type = flag == NEB_READ ? "read" : "write";
-
-    endtime = time(NULL) + LOCK_TIMEOUT;
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return false;
+    }
+
+    char *type = flag == NEB_READ ? "read" : "write";
+
+    time_t endtime = time(NULL) + LOCK_TIMEOUT;
 
     while (time(NULL) < endtime) {
+        int response;
         if (soap_call_ns1__lock_USCOREobject(server->soap, server->endpoint,
             NULL, (char *)key, type, &response) != SOAP_OK) {
@@ -302,19 +303,18 @@
 }
 
+
 bool nebUnlock(nebServer *server, const char *key, nebRW flag)
 {
-    char            *type;
-    int             response;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return false;
-    }
-
-    type = flag == NEB_READ ? "read" : "write";
-
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return false;
+    }
+
+    char *type = flag == NEB_READ ? "read" : "write";
+
+    int response;
     if (soap_call_ns1__unlock_USCOREobject(server->soap, server->endpoint,
         NULL, (char *)key, type, &response) != SOAP_OK) {
@@ -466,17 +466,13 @@
 nebObjectInstances *nebFindInstances(nebServer *server, const char *key, const char *volume)
 {
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return NULL;
+    }
+
     struct ns1__find_USCOREinstancesResponse response;
-    int             resultElements = 0;
-    char            **resultArray;
-    nebObjectInstances *locations = NULL;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return NULL;
-    }
-
     // FIXME is this leaking memory when response goes out of scope?  the gsoap
     // manual seems to 'suggest' that this is temporary data that gets cleaed
@@ -488,11 +484,12 @@
     }
 
-    resultElements = response.result->__size;
-
+    int resultElements = response.result->__size;
+
+    nebObjectInstances *locations = NULL;
     if (resultElements) {
         locations = xmalloc(sizeof(nebObjectInstances));
         locations->n = resultElements;
         
-        resultArray    = response.result->__ptr;
+        char **resultArray = response.result->__ptr;
 
         locations->URI = xmalloc(sizeof(char*) * resultElements);
@@ -508,4 +505,5 @@
 }
 
+
 void nebObjectInstancesFree(nebObjectInstances *locations)
 {
@@ -521,9 +519,7 @@
 }
 
+
 char *nebFind(nebServer *server, const char *key)
 {
-    nebObjectInstances *locations;
-    char            *filename;
-
     REQUIRE_SERVER;
 
@@ -534,5 +530,5 @@
     }
     
-    locations = nebFindInstances(server, key, NULL);
+    nebObjectInstances *locations = nebFindInstances(server, key, NULL);
     if (!locations) {
         if (!strstr(nebErr(server), "no instances on storage volume")) {
@@ -548,4 +544,5 @@
     }
 
+    char *filename;
     if (!nebParseURI(server, locations->URI[0], &filename)) {
         nebSetErr(server, "can not parse URI");
@@ -560,19 +557,16 @@
 }
 
+
 int nebOpen(nebServer *server, const char *key, nebRW flag)
 {
-    nebObjectInstances *locations;
-    char            *filename;
-    int             fh;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return -1;
-    }
-
-    locations = nebFindInstances(server, key, NULL);
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return -1;
+    }
+
+    nebObjectInstances *locations = nebFindInstances(server, key, NULL);
     if (!locations) {
         nebSetErr(server, "no instances found");
@@ -581,4 +575,5 @@
     }
 
+    char *filename;
     if (!nebParseURI(server, locations->URI[0], &filename)) {
         nebSetErr(server, "can not parse URI");
@@ -588,4 +583,5 @@
     }
 
+    int fh = 0;
     if (flag == NEB_WRITE) {
         if (locations->n > 1) {
@@ -613,17 +609,16 @@
 }
 
+
 bool nebDelete(nebServer *server, const char *key)
 {
-    nebObjectInstances *locations;
-
-    REQUIRE_SERVER;
-
-    if (!key) {
-        nebSetErr(server, "parameter 'key' may not be NULL");
-
-        return false;
-    }
-
-    locations = nebFindInstances(server, key, "any");
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return false;
+    }
+
+    nebObjectInstances *locations = nebFindInstances(server, key, "any");
     if (!locations) {
         nebSetErr(server, "no instances found");
@@ -646,9 +641,7 @@
 }
 
+
 bool nebCopy(nebServer *server, const char *key, const char *newKey)
 {
-    int             sourceFH;
-    int             destFH;
-
     REQUIRE_SERVER;
 
@@ -665,5 +658,5 @@
     }
 
-    sourceFH = nebOpen(server, (char *)key, NEB_READ);
+    int sourceFH = nebOpen(server, (char *)key, NEB_READ);
     if (sourceFH < 0) {
         // propigate nebOpen() error
@@ -672,5 +665,5 @@
     }
 
-    destFH = nebOpenCreate(server, newKey, NULL, NULL);
+    int destFH = nebOpenCreate(server, newKey, NULL, NULL);
     if (destFH < 0) {
         // propigate nebCreate() error
@@ -696,4 +689,5 @@
 }
 
+
 bool nebMove(nebServer *server, const char *key, const char *newKey)
 {
@@ -723,8 +717,7 @@
 }
 
+
 bool nebSwap(nebServer *server, const char *key1, const char *key2)
 {
-    struct ns1__create_USCOREobjectResponse response;
-
     REQUIRE_SERVER;
 
@@ -741,4 +734,5 @@
     }
 
+    struct ns1__create_USCOREobjectResponse response;
     if (soap_call_ns1__swap_USCOREobjects(server->soap, server->endpoint,
             NULL, (char *)key1, (char *)key2, (char **)&response) != SOAP_OK) {
@@ -749,10 +743,7 @@
 }
 
+
 bool nebDeleteInstance(nebServer *server, const char *key, const char *URI)
 {
-    int             response;
-    char            *filename;
-    bool            status;
-
     REQUIRE_SERVER;
 
@@ -763,4 +754,5 @@
     }
 
+    char *filename;
     if (!nebParseURI(server, URI, &filename)) {
         nebSetErr(server, "can not parse URI");
@@ -769,4 +761,5 @@
     }
 
+    int response;
     if (soap_call_ns1__delete_USCOREinstance(server->soap, server->endpoint,
         NULL, (char *)key, (char *)URI, &response) != SOAP_OK) {
@@ -776,4 +769,5 @@
     }
 
+    bool status;
     if (response > 0) {
         status = nebNukeFile(server, filename);
@@ -787,11 +781,7 @@
 }
 
+
 nebObjectStat *nebStat(nebServer *server, const char *key)
 {
-    struct ns1__stat_USCOREobjectResponse response;
-    nebObjectStat   *stat;
-    int             resultElements = 0;
-    char            **resultArray = NULL;
-
     REQUIRE_SERVER;
 
@@ -802,9 +792,10 @@
     }
 
-    stat = xmalloc(sizeof(nebObjectStat));
+    nebObjectStat *stat = xmalloc(sizeof(nebObjectStat));
 
     // FIXME is this leaking memory when response goes out of scope?  the gsoap
     // manual seems to 'suggest' that this is temporary data that gets cleaed
     // up on the next soap function call
+    struct ns1__stat_USCOREobjectResponse response;
     if (soap_call_ns1__stat_USCOREobject(server->soap, server->endpoint,
             NULL, (char *)key, &response) != SOAP_OK) {
@@ -813,23 +804,147 @@
     }
 
-    resultElements = response.result->__size;
-    resultArray    = response.result->__ptr;
-
-    if (resultElements != 7) {
+    int resultElements = response.result->__size;
+    char **resultArray    = response.result->__ptr;
+
+    if (resultElements != 8) {
         nebSetErr(server, "server didn't return the proper number of stat elements");
         return NULL;
     }
 
-    nullstrncpy(stat->so_id, resultArray[0], 256);
-    nullstrncpy(stat->ext_id, resultArray[1], 256);
-    nullstrncpy(stat->read_lock, resultArray[2], 256);
+    stat->so_id     = atol(resultArray[0]);
+    stat->ext_id    = atol(resultArray[1]);
+    stat->read_lock = atoi(resultArray[2]);
     nullstrncpy(stat->write_lock, resultArray[3], 256);
     nullstrncpy(stat->epoch, resultArray[4], 256);
     nullstrncpy(stat->mtime, resultArray[5], 256);
-    stat->instances = atoi(resultArray[6]);
+    stat->available = atoi(resultArray[6]);
+    stat->instances = atoi(resultArray[7]);
 
     return stat;
 }
 
+
+void nebObjectStatFree(nebObjectStat *stat)
+{
+    if (!stat) {
+        return;
+    }
+
+    nebFree(stat);
+}
+
+
+int nebChmod(nebServer *server, const char *key, mode_t mode)
+{
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return -1;
+    }
+
+    // FIXME is this leaking memory when response goes out of scope?  the gsoap
+    // manual seems to 'suggest' that this is temporary data that gets cleaed
+    // up on the next soap function call
+    int response;
+    if (soap_call_ns1__chmod_USCOREobject(server->soap, server->endpoint,
+            NULL, (char *)key, mode, &response) != SOAP_OK) {
+        nebSetServerErr(server);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+int nebPrune(nebServer *server, const char *key)
+{
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return -1;
+    }
+
+    // FIXME is this leaking memory when response goes out of scope?  the gsoap
+    // manual seems to 'suggest' that this is temporary data that gets cleaed
+    // up on the next soap function call
+    int response;
+    if (soap_call_ns1__prune_USCOREobject(server->soap, server->endpoint,
+            NULL, (char *)key, &response) != SOAP_OK) {
+        nebSetServerErr(server);
+        return -1;
+    }
+
+    return response;
+}
+
+
+int nebThereCanBeOnlyOne(nebServer *server, const char *key, const char *volume)
+{
+    REQUIRE_SERVER;
+
+    if (!key) {
+        nebSetErr(server, "parameter 'key' may not be NULL");
+
+        return -1;
+    }
+
+    // first - strip off any inaccesible instances
+    if (nebPrune(server, key) < 0 ) {
+        // use the prune() method to also determine if $key is valid
+        return -1;
+    }
+
+    // check to see if there is an instance on $vol_name that should be the
+    // sole survivor
+    nebObjectInstances *locations = NULL;
+    if (volume) {
+        locations = nebFindInstances(server, key, NULL);
+    }
+
+    long removed = 0;
+    if (locations && locations->n) {
+        nebObjectInstances *instances = nebFindInstances(server, key, NULL);
+        for (long i = 0; i < instances->n; i++) {
+            if (strcmp(locations->URI[0], instances->URI[i]) == 0) {
+                continue;
+            }
+            if (!nebDeleteInstance(server, key, instances->URI[i])) {
+                nebObjectInstancesFree(instances);
+                nebObjectInstancesFree(locations);
+                return -1;
+            }
+            removed++;
+        }
+        nebObjectInstancesFree(instances);
+        nebObjectInstancesFree(locations);
+    } else {
+        nebObjectInstancesFree(locations);
+        // nuke whatever
+        nebObjectStat *stat = nebStat(server, key);
+        if (!stat) {
+            return -1;
+        }
+
+        int available = stat->available;
+        nebObjectStatFree(stat);
+
+        // start at one so cull() is called one less time then the # of
+        // instances
+        for (long i = 1; i < available; i++) {
+            if (!nebCull(server, key)) {
+                return -1;
+            }
+            removed++;
+        }
+    }
+
+    return removed;
+}
+
+
 char *nebErr(nebServer *server)
 {
@@ -837,5 +952,7 @@
 }
 
+
 void nebFree(void *ptr) {
+    if (!ptr) { return; }
     xfree(ptr);
 }
@@ -844,10 +961,6 @@
 static void p_nebSetErr(const char * filename, unsigned long lineno, const char *function, nebServer *server, const char *format, ...)
 {
-    va_list         args;
-    size_t          err_size;
-    char            err_location[ERRBUF_SIZE];
-    size_t          err_location_size; 
-
-    err_location_size = snprintf(err_location, ERRBUF_SIZE, "%s:%lu %s() - ",
+    char err_location[ERRBUF_SIZE];
+    size_t err_location_size = snprintf(err_location, ERRBUF_SIZE, "%s:%lu %s() - ",
             filename, lineno, function);
 
@@ -862,7 +975,8 @@
 
     while (1) {
+        va_list args;
         va_start(args, format);
         // append error string after error location info
-        err_size = vsnprintf(
+        size_t err_size = vsnprintf(
                 server->err_buf + err_location_size,
                 server->err_buf_size - err_location_size,
@@ -888,27 +1002,22 @@
 }
 
+
 static void nebSetServerErr(nebServer *server)
 {
-    const char      **code;
-    const char      **string;
-
-    REQUIRE_SERVER;
-
-    code   = soap_faultcode(server->soap);
-    string = soap_faultstring(server->soap);
+    REQUIRE_SERVER;
+
+    const char **code   = soap_faultcode(server->soap);
+    const char **string = soap_faultstring(server->soap);
 
     nebSetErr(server, "%s - %s", *code, *string);
 }
+
 
 #if NEBCOPYFILE
 static off_t nebCopyFile(nebServer *server, const char *source, const char *dest)
 {
-    int             sourceFH;
-    int             destFH; 
-    off_t           bytesCopied;
-
-    REQUIRE_SERVER;
-
-    sourceFH = open(source, O_RDONLY);
+    REQUIRE_SERVER;
+
+    int sourceFH = open(source, O_RDONLY);
     if (sourceFH == -1) {
         nebSetErr(server, "can not open %s: %s", source, strerror(errno));
@@ -917,5 +1026,5 @@
     }
 
-    destFH = open(dest, O_WRONLY|O_CREAT|O_CREAT, 0600);
+    int destFH = open(dest, O_WRONLY|O_CREAT|O_CREAT, 0600);
     if (destFH == -1) {
         nebSetErr(server, "can not open %s: %s", dest, strerror(errno));
@@ -924,5 +1033,5 @@
     }
 
-    bytesCopied = nebCopyFilehandle(server, sourceFH, destFH);
+    off_t bytesCopied = nebCopyFilehandle(server, sourceFH, destFH);
     if (bytesCopied < 0) {
         return -1;
@@ -945,14 +1054,10 @@
 #endif
 
+
 static off_t nebCopyFilehandle(nebServer *server, int sourceFH, int destFH)
 {
-    off_t           bytesTotal;
-    off_t           bytesRemaining;
-    off_t           writeSize;
-    char            writeBuf[64 * 1024];
+    REQUIRE_SERVER;
+
     struct stat     sourceStat;
-
-    REQUIRE_SERVER;
-
     if(fstat(sourceFH, &sourceStat)) {
         nebSetErr(server, "can not stat filehandles: %s", strerror(errno));
@@ -962,5 +1067,5 @@
 
     // the size of the file to copied
-    bytesTotal = sourceStat.st_size;
+    off_t bytesTotal = sourceStat.st_size;
 
     /*
@@ -970,7 +1075,9 @@
     */
 
-    bytesRemaining = bytesTotal;
+    off_t bytesRemaining = bytesTotal;
 
     while (bytesRemaining) {
+        off_t writeSize;
+        char writeBuf[64 * 1024];
         if (bytesRemaining <= sizeof(writeBuf)) {
             writeSize = bytesRemaining;
@@ -997,15 +1104,7 @@
 }
 
+
 static size_t nebParseURI(nebServer *server, const char *URI, char **filename)
 {
-    regex_t         myregex;
-    regmatch_t      mymatch[2];
-    char            errbuf[ERRBUF_SIZE];
-    char            *pattern = "^file://(.*)$";
-    int             status;
-    size_t          matchStart, matchEnd;
-    size_t          matchLength;
-    size_t          filename_size;
-
     REQUIRE_SERVER;
 
@@ -1022,5 +1121,10 @@
     }
 
-    status = regcomp(&myregex, pattern, REG_EXTENDED);
+    regex_t myregex;
+    regmatch_t mymatch[2];
+    char *pattern = "^file://(.*)$";
+    char errbuf[ERRBUF_SIZE];
+
+    int status = regcomp(&myregex, pattern, REG_EXTENDED);
     if (status != 0) {
         regerror(status, &myregex, errbuf, ERRBUF_SIZE);
@@ -1040,7 +1144,7 @@
     regfree(&myregex);
 
-    matchStart = (size_t)mymatch[1].rm_so;
-    matchEnd   = (size_t)mymatch[1].rm_eo;
-    matchLength = matchEnd - matchStart;
+    size_t matchStart = (size_t)mymatch[1].rm_so;
+    size_t matchEnd   = (size_t)mymatch[1].rm_eo;
+    size_t matchLength = matchEnd - matchStart;
 
     if (matchStart == -1) {
@@ -1048,5 +1152,5 @@
     }
 
-    filename_size = matchLength + 1;
+    size_t filename_size = matchLength + 1;
     *filename = xmalloc(filename_size);
 
@@ -1055,4 +1159,5 @@
     return strlen(*filename);
 }
+
 
 static bool nebNukeFile(nebServer *server, const char *filename)
@@ -1074,4 +1179,5 @@
     return true;
 }
+
 
 static char *nullstrncpy(char *dest, const char *src, size_t n) {
@@ -1081,4 +1187,8 @@
     }
 
+    if (!dest) {
+        dest = xmalloc(n + 1);
+    }
+
     return strncpy(dest, src, n);
 }
Index: branches/pap/Nebulous/nebclient/src/nebclient.h
===================================================================
--- branches/pap/Nebulous/nebclient/src/nebclient.h	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/nebclient.h	(revision 25027)
@@ -11,4 +11,6 @@
 #ifndef NEBCLIENT_H
 #define NEBCLIENT_H 1
+
+// #include <sys/stat.h>
 
 #ifdef __cplusplus
@@ -36,11 +38,12 @@
 
 typedef struct {
-    char            so_id[256];         ///< storage object ID
-    char            ext_id[256];        ///< storage object key (name)
-    char            read_lock[256];     ///< read lock value
+    long            so_id;              ///< storage object ID
+    long            ext_id;             ///< storage object key (name)
+    int             read_lock;          ///< read lock value
     char            write_lock[256];    ///< write lock value
     char            epoch[256];         ///< creation time stamp
     char            mtime[256];         ///< modification time stamp
-    int             instances;          ///< number of instances
+    int             available;          ///< number of available instances
+    int             instances;          ///< total number of instances
 } nebObjectStat;
 
@@ -293,5 +296,47 @@
 nebObjectStat *nebStat(
     nebServer *server,                  ///< nebServer object
-    const char *key                     /// storage object key (name)
+    const char *key                     ///< storage object key (name)
+);
+
+
+/** Deallocates a stat object
+ */
+void nebObjectStatFree(
+    nebObjectStat *stat                 ///< nebObjectStat object
+);
+
+/** Change permissions of a storage objects
+ *
+ * This function will change the file permissions of all currently on disk
+ * instances of a storage object.
+ *
+ * @return the new mode or NULL on failure.
+ */
+
+int nebChmod(
+    nebServer *server,                  ///< nebServer object
+    const char *key,                    ///< storage object key (name)
+    mode_t mode                         ///< chmod(2) compatible mode (mode_t)
+);
+
+/** Removes all of the inaccessible instances from an object
+ *
+ * @return the number of inaccessible instances removed
+ */
+
+int nebPrune(
+    nebServer *server,                  ///< nebServer object
+    const char *key                     ///< storage object key (name)
+);
+
+/** Removes all but one instances of an object
+ *
+ * @return the number of available instances removed
+ */
+
+int nebThereCanBeOnlyOne(
+    nebServer *server,                  ///< nebServer object
+    const char *key,                    ///< storage object key (name)
+    const char *volume                  ///< leave remain instance on this volume
 );
 
Index: branches/pap/Nebulous/nebclient/src/nebulous.h
===================================================================
--- branches/pap/Nebulous/nebclient/src/nebulous.h	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/nebulous.h	(revision 25027)
@@ -1,5 +1,5 @@
 /* src/nebulous.h
    Generated by wsdl2h 1.2.12 from nebulous.wsdl and typemap.dat
-   2009-04-20 22:15:21 GMT
+   2009-07-25 01:30:29 GMT
    Copyright (C) 2001-2008 Robert van Engelen, Genivia Inc. All Rights Reserved.
    This part of the software is released under one of the following licenses:
@@ -119,4 +119,6 @@
   - @ref ns1__delete_USCOREinstance
   - @ref ns1__stat_USCOREobject
+  - @ref ns1__chmod_USCOREobject
+  - @ref ns1__prune_USCOREobject
 
 @section SOAP_ports Endpoints of Binding  "SOAP"
@@ -893,3 +895,106 @@
 );
 
+/******************************************************************************\
+ *                                                                            *
+ * ns1__chmod_USCOREobject                                                    *
+ *                                                                            *
+\******************************************************************************/
+
+
+/// Operation "ns1__chmod_USCOREobject" of service binding "SOAP"
+
+/**
+
+Operation details:
+
+  - SOAP RPC encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
+  - SOAP action="urn:Nebulous/Server/SOAP#chmod_object"
+
+C stub function (defined in soapClient.c[pp] generated by soapcpp2):
+@code
+  int soap_call_ns1__chmod_USCOREobject(
+    struct soap *soap,
+    NULL, // char *endpoint = NULL selects default endpoint for this operation
+    NULL, // char *action = NULL selects default action for this operation
+    // request parameters:
+    char*                               key,
+    int                                 mode,
+    // response parameters:
+    int                                *result
+  );
+@endcode
+
+C server function (called from the service dispatcher defined in soapServer.c[pp]):
+@code
+  int ns1__chmod_USCOREobject(
+    struct soap *soap,
+    // request parameters:
+    char*                               key,
+    int                                 mode,
+    // response parameters:
+    int                                *result
+  );
+@endcode
+
+*/
+
+//gsoap ns1  service method-style:	chmod_USCOREobject rpc
+//gsoap ns1  service method-encoding:	chmod_USCOREobject http://schemas.xmlsoap.org/soap/encoding/
+//gsoap ns1  service method-action:	chmod_USCOREobject urn:Nebulous/Server/SOAP#chmod_object
+int ns1__chmod_USCOREobject(
+    char*                               key,	///< Request parameter
+    int                                 mode,	///< Request parameter
+    int                                *result	///< Response parameter
+);
+
+/******************************************************************************\
+ *                                                                            *
+ * ns1__prune_USCOREobject                                                    *
+ *                                                                            *
+\******************************************************************************/
+
+
+/// Operation "ns1__prune_USCOREobject" of service binding "SOAP"
+
+/**
+
+Operation details:
+
+  - SOAP RPC encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
+  - SOAP action="urn:Nebulous/Server/SOAP#prune_object"
+
+C stub function (defined in soapClient.c[pp] generated by soapcpp2):
+@code
+  int soap_call_ns1__prune_USCOREobject(
+    struct soap *soap,
+    NULL, // char *endpoint = NULL selects default endpoint for this operation
+    NULL, // char *action = NULL selects default action for this operation
+    // request parameters:
+    char*                               key,
+    // response parameters:
+    int                                *result
+  );
+@endcode
+
+C server function (called from the service dispatcher defined in soapServer.c[pp]):
+@code
+  int ns1__prune_USCOREobject(
+    struct soap *soap,
+    // request parameters:
+    char*                               key,
+    // response parameters:
+    int                                *result
+  );
+@endcode
+
+*/
+
+//gsoap ns1  service method-style:	prune_USCOREobject rpc
+//gsoap ns1  service method-encoding:	prune_USCOREobject http://schemas.xmlsoap.org/soap/encoding/
+//gsoap ns1  service method-action:	prune_USCOREobject urn:Nebulous/Server/SOAP#prune_object
+int ns1__prune_USCOREobject(
+    char*                               key,	///< Request parameter
+    int                                *result	///< Response parameter
+);
+
 /* End of src/nebulous.h */
Index: branches/pap/Nebulous/nebclient/src/soapC.c
===================================================================
--- branches/pap/Nebulous/nebclient/src/soapC.c	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/soapC.c	(revision 25027)
@@ -12,5 +12,5 @@
 #endif
 
-SOAP_SOURCE_STAMP("@(#) soapC.c ver 2.7.12 2009-04-20 22:15:22 GMT")
+SOAP_SOURCE_STAMP("@(#) soapC.c ver 2.7.12 2009-07-25 01:30:29 GMT")
 
 
@@ -161,4 +161,12 @@
 	case SOAP_TYPE_int:
 		return soap_in_int(soap, NULL, NULL, "xsd:int");
+	case SOAP_TYPE_ns1__prune_USCOREobject:
+		return soap_in_ns1__prune_USCOREobject(soap, NULL, NULL, "ns1:prune_object");
+	case SOAP_TYPE_ns1__prune_USCOREobjectResponse:
+		return soap_in_ns1__prune_USCOREobjectResponse(soap, NULL, NULL, "ns1:prune_objectResponse");
+	case SOAP_TYPE_ns1__chmod_USCOREobject:
+		return soap_in_ns1__chmod_USCOREobject(soap, NULL, NULL, "ns1:chmod_object");
+	case SOAP_TYPE_ns1__chmod_USCOREobjectResponse:
+		return soap_in_ns1__chmod_USCOREobjectResponse(soap, NULL, NULL, "ns1:chmod_objectResponse");
 	case SOAP_TYPE_ns1__stat_USCOREobject:
 		return soap_in_ns1__stat_USCOREobject(soap, NULL, NULL, "ns1:stat_object");
@@ -250,4 +258,20 @@
 			return soap_in_int(soap, NULL, NULL, NULL);
 		}
+		if (!soap_match_tag(soap, t, "ns1:prune_object"))
+		{	*type = SOAP_TYPE_ns1__prune_USCOREobject;
+			return soap_in_ns1__prune_USCOREobject(soap, NULL, NULL, NULL);
+		}
+		if (!soap_match_tag(soap, t, "ns1:prune_objectResponse"))
+		{	*type = SOAP_TYPE_ns1__prune_USCOREobjectResponse;
+			return soap_in_ns1__prune_USCOREobjectResponse(soap, NULL, NULL, NULL);
+		}
+		if (!soap_match_tag(soap, t, "ns1:chmod_object"))
+		{	*type = SOAP_TYPE_ns1__chmod_USCOREobject;
+			return soap_in_ns1__chmod_USCOREobject(soap, NULL, NULL, NULL);
+		}
+		if (!soap_match_tag(soap, t, "ns1:chmod_objectResponse"))
+		{	*type = SOAP_TYPE_ns1__chmod_USCOREobjectResponse;
+			return soap_in_ns1__chmod_USCOREobjectResponse(soap, NULL, NULL, NULL);
+		}
 		if (!soap_match_tag(soap, t, "ns1:stat_object"))
 		{	*type = SOAP_TYPE_ns1__stat_USCOREobject;
@@ -440,4 +464,12 @@
 	case SOAP_TYPE_int:
 		return soap_out_int(soap, tag, id, (const int *)ptr, "xsd:int");
+	case SOAP_TYPE_ns1__prune_USCOREobject:
+		return soap_out_ns1__prune_USCOREobject(soap, tag, id, (const struct ns1__prune_USCOREobject *)ptr, "ns1:prune_object");
+	case SOAP_TYPE_ns1__prune_USCOREobjectResponse:
+		return soap_out_ns1__prune_USCOREobjectResponse(soap, tag, id, (const struct ns1__prune_USCOREobjectResponse *)ptr, "ns1:prune_objectResponse");
+	case SOAP_TYPE_ns1__chmod_USCOREobject:
+		return soap_out_ns1__chmod_USCOREobject(soap, tag, id, (const struct ns1__chmod_USCOREobject *)ptr, "ns1:chmod_object");
+	case SOAP_TYPE_ns1__chmod_USCOREobjectResponse:
+		return soap_out_ns1__chmod_USCOREobjectResponse(soap, tag, id, (const struct ns1__chmod_USCOREobjectResponse *)ptr, "ns1:chmod_objectResponse");
 	case SOAP_TYPE_ns1__stat_USCOREobject:
 		return soap_out_ns1__stat_USCOREobject(soap, tag, id, (const struct ns1__stat_USCOREobject *)ptr, "ns1:stat_object");
@@ -527,4 +559,16 @@
 	switch (type)
 	{
+	case SOAP_TYPE_ns1__prune_USCOREobject:
+		soap_serialize_ns1__prune_USCOREobject(soap, (const struct ns1__prune_USCOREobject *)ptr);
+		break;
+	case SOAP_TYPE_ns1__prune_USCOREobjectResponse:
+		soap_serialize_ns1__prune_USCOREobjectResponse(soap, (const struct ns1__prune_USCOREobjectResponse *)ptr);
+		break;
+	case SOAP_TYPE_ns1__chmod_USCOREobject:
+		soap_serialize_ns1__chmod_USCOREobject(soap, (const struct ns1__chmod_USCOREobject *)ptr);
+		break;
+	case SOAP_TYPE_ns1__chmod_USCOREobjectResponse:
+		soap_serialize_ns1__chmod_USCOREobjectResponse(soap, (const struct ns1__chmod_USCOREobjectResponse *)ptr);
+		break;
 	case SOAP_TYPE_ns1__stat_USCOREobject:
 		soap_serialize_ns1__stat_USCOREobject(soap, (const struct ns1__stat_USCOREobject *)ptr);
@@ -1195,4 +1239,310 @@
 #endif
 
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__prune_USCOREobject(struct soap *soap, struct ns1__prune_USCOREobject *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_default_string(soap, &a->key);
+}
+
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__prune_USCOREobject(struct soap *soap, const struct ns1__prune_USCOREobject *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_serialize_string(soap, &a->key);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__prune_USCOREobject(struct soap *soap, const struct ns1__prune_USCOREobject *a, const char *tag, const char *type)
+{
+	register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__prune_USCOREobject);
+	if (soap_out_ns1__prune_USCOREobject(soap, tag, id, a, type))
+		return soap->error;
+	return soap_putindependent(soap);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__prune_USCOREobject(struct soap *soap, const char *tag, int id, const struct ns1__prune_USCOREobject *a, const char *type)
+{
+	if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__prune_USCOREobject), type))
+		return soap->error;
+	if (soap_out_string(soap, "key", -1, &a->key, ""))
+		return soap->error;
+	return soap_element_end_out(soap, tag);
+}
+
+SOAP_FMAC3 struct ns1__prune_USCOREobject * SOAP_FMAC4 soap_get_ns1__prune_USCOREobject(struct soap *soap, struct ns1__prune_USCOREobject *p, const char *tag, const char *type)
+{
+	if ((p = soap_in_ns1__prune_USCOREobject(soap, tag, p, type)))
+		if (soap_getindependent(soap))
+			return NULL;
+	return p;
+}
+
+SOAP_FMAC3 struct ns1__prune_USCOREobject * SOAP_FMAC4 soap_in_ns1__prune_USCOREobject(struct soap *soap, const char *tag, struct ns1__prune_USCOREobject *a, const char *type)
+{
+	size_t soap_flag_key = 1;
+	if (soap_element_begin_in(soap, tag, 0, type))
+		return NULL;
+	a = (struct ns1__prune_USCOREobject *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__prune_USCOREobject, sizeof(struct ns1__prune_USCOREobject), 0, NULL, NULL, NULL);
+	if (!a)
+		return NULL;
+	soap_default_ns1__prune_USCOREobject(soap, a);
+	if (soap->body && !*soap->href)
+	{
+		for (;;)
+		{	soap->error = SOAP_TAG_MISMATCH;
+			if (soap_flag_key && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))
+				if (soap_in_string(soap, "key", &a->key, "xsd:string"))
+				{	soap_flag_key--;
+					continue;
+				}
+			if (soap->error == SOAP_TAG_MISMATCH)
+				soap->error = soap_ignore_element(soap);
+			if (soap->error == SOAP_NO_TAG)
+				break;
+			if (soap->error)
+				return NULL;
+		}
+		if (soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	else
+	{	a = (struct ns1__prune_USCOREobject *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__prune_USCOREobject, 0, sizeof(struct ns1__prune_USCOREobject), 0, NULL);
+		if (soap->body && soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	return a;
+}
+
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__prune_USCOREobjectResponse(struct soap *soap, struct ns1__prune_USCOREobjectResponse *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	a->result = NULL;
+}
+
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__prune_USCOREobjectResponse(struct soap *soap, const struct ns1__prune_USCOREobjectResponse *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_serialize_PointerToint(soap, &a->result);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__prune_USCOREobjectResponse(struct soap *soap, const struct ns1__prune_USCOREobjectResponse *a, const char *tag, const char *type)
+{
+	register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__prune_USCOREobjectResponse);
+	if (soap_out_ns1__prune_USCOREobjectResponse(soap, tag, id, a, type))
+		return soap->error;
+	return soap_putindependent(soap);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__prune_USCOREobjectResponse(struct soap *soap, const char *tag, int id, const struct ns1__prune_USCOREobjectResponse *a, const char *type)
+{
+	if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__prune_USCOREobjectResponse), type))
+		return soap->error;
+	if (soap_out_PointerToint(soap, "result", -1, &a->result, ""))
+		return soap->error;
+	return soap_element_end_out(soap, tag);
+}
+
+SOAP_FMAC3 struct ns1__prune_USCOREobjectResponse * SOAP_FMAC4 soap_get_ns1__prune_USCOREobjectResponse(struct soap *soap, struct ns1__prune_USCOREobjectResponse *p, const char *tag, const char *type)
+{
+	if ((p = soap_in_ns1__prune_USCOREobjectResponse(soap, tag, p, type)))
+		if (soap_getindependent(soap))
+			return NULL;
+	return p;
+}
+
+SOAP_FMAC3 struct ns1__prune_USCOREobjectResponse * SOAP_FMAC4 soap_in_ns1__prune_USCOREobjectResponse(struct soap *soap, const char *tag, struct ns1__prune_USCOREobjectResponse *a, const char *type)
+{
+	size_t soap_flag_result = 1;
+	if (soap_element_begin_in(soap, tag, 0, type))
+		return NULL;
+	a = (struct ns1__prune_USCOREobjectResponse *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__prune_USCOREobjectResponse, sizeof(struct ns1__prune_USCOREobjectResponse), 0, NULL, NULL, NULL);
+	if (!a)
+		return NULL;
+	soap_default_ns1__prune_USCOREobjectResponse(soap, a);
+	if (soap->body && !*soap->href)
+	{
+		for (;;)
+		{	soap->error = SOAP_TAG_MISMATCH;
+			if (soap_flag_result && soap->error == SOAP_TAG_MISMATCH)
+				if (soap_in_PointerToint(soap, "result", &a->result, "xsd:int"))
+				{	soap_flag_result--;
+					continue;
+				}
+			if (soap->error == SOAP_TAG_MISMATCH)
+				soap->error = soap_ignore_element(soap);
+			if (soap->error == SOAP_NO_TAG)
+				break;
+			if (soap->error)
+				return NULL;
+		}
+		if (soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	else
+	{	a = (struct ns1__prune_USCOREobjectResponse *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__prune_USCOREobjectResponse, 0, sizeof(struct ns1__prune_USCOREobjectResponse), 0, NULL);
+		if (soap->body && soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	return a;
+}
+
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__chmod_USCOREobject(struct soap *soap, struct ns1__chmod_USCOREobject *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_default_string(soap, &a->key);
+	soap_default_int(soap, &a->mode);
+}
+
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__chmod_USCOREobject(struct soap *soap, const struct ns1__chmod_USCOREobject *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_serialize_string(soap, &a->key);
+	soap_embedded(soap, &a->mode, SOAP_TYPE_int);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__chmod_USCOREobject(struct soap *soap, const struct ns1__chmod_USCOREobject *a, const char *tag, const char *type)
+{
+	register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__chmod_USCOREobject);
+	if (soap_out_ns1__chmod_USCOREobject(soap, tag, id, a, type))
+		return soap->error;
+	return soap_putindependent(soap);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__chmod_USCOREobject(struct soap *soap, const char *tag, int id, const struct ns1__chmod_USCOREobject *a, const char *type)
+{
+	if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__chmod_USCOREobject), type))
+		return soap->error;
+	if (soap_out_string(soap, "key", -1, &a->key, ""))
+		return soap->error;
+	if (soap_out_int(soap, "mode", -1, &a->mode, ""))
+		return soap->error;
+	return soap_element_end_out(soap, tag);
+}
+
+SOAP_FMAC3 struct ns1__chmod_USCOREobject * SOAP_FMAC4 soap_get_ns1__chmod_USCOREobject(struct soap *soap, struct ns1__chmod_USCOREobject *p, const char *tag, const char *type)
+{
+	if ((p = soap_in_ns1__chmod_USCOREobject(soap, tag, p, type)))
+		if (soap_getindependent(soap))
+			return NULL;
+	return p;
+}
+
+SOAP_FMAC3 struct ns1__chmod_USCOREobject * SOAP_FMAC4 soap_in_ns1__chmod_USCOREobject(struct soap *soap, const char *tag, struct ns1__chmod_USCOREobject *a, const char *type)
+{
+	size_t soap_flag_key = 1;
+	size_t soap_flag_mode = 1;
+	if (soap_element_begin_in(soap, tag, 0, type))
+		return NULL;
+	a = (struct ns1__chmod_USCOREobject *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__chmod_USCOREobject, sizeof(struct ns1__chmod_USCOREobject), 0, NULL, NULL, NULL);
+	if (!a)
+		return NULL;
+	soap_default_ns1__chmod_USCOREobject(soap, a);
+	if (soap->body && !*soap->href)
+	{
+		for (;;)
+		{	soap->error = SOAP_TAG_MISMATCH;
+			if (soap_flag_key && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG))
+				if (soap_in_string(soap, "key", &a->key, "xsd:string"))
+				{	soap_flag_key--;
+					continue;
+				}
+			if (soap_flag_mode && soap->error == SOAP_TAG_MISMATCH)
+				if (soap_in_int(soap, "mode", &a->mode, "xsd:int"))
+				{	soap_flag_mode--;
+					continue;
+				}
+			if (soap->error == SOAP_TAG_MISMATCH)
+				soap->error = soap_ignore_element(soap);
+			if (soap->error == SOAP_NO_TAG)
+				break;
+			if (soap->error)
+				return NULL;
+		}
+		if (soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	else
+	{	a = (struct ns1__chmod_USCOREobject *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__chmod_USCOREobject, 0, sizeof(struct ns1__chmod_USCOREobject), 0, NULL);
+		if (soap->body && soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	if ((soap->mode & SOAP_XML_STRICT) && (soap_flag_mode > 0))
+	{	soap->error = SOAP_OCCURS;
+		return NULL;
+	}
+	return a;
+}
+
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__chmod_USCOREobjectResponse(struct soap *soap, struct ns1__chmod_USCOREobjectResponse *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	a->result = NULL;
+}
+
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__chmod_USCOREobjectResponse(struct soap *soap, const struct ns1__chmod_USCOREobjectResponse *a)
+{
+	(void)soap; (void)a; /* appease -Wall -Werror */
+	soap_serialize_PointerToint(soap, &a->result);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__chmod_USCOREobjectResponse(struct soap *soap, const struct ns1__chmod_USCOREobjectResponse *a, const char *tag, const char *type)
+{
+	register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ns1__chmod_USCOREobjectResponse);
+	if (soap_out_ns1__chmod_USCOREobjectResponse(soap, tag, id, a, type))
+		return soap->error;
+	return soap_putindependent(soap);
+}
+
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__chmod_USCOREobjectResponse(struct soap *soap, const char *tag, int id, const struct ns1__chmod_USCOREobjectResponse *a, const char *type)
+{
+	if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_ns1__chmod_USCOREobjectResponse), type))
+		return soap->error;
+	if (soap_out_PointerToint(soap, "result", -1, &a->result, ""))
+		return soap->error;
+	return soap_element_end_out(soap, tag);
+}
+
+SOAP_FMAC3 struct ns1__chmod_USCOREobjectResponse * SOAP_FMAC4 soap_get_ns1__chmod_USCOREobjectResponse(struct soap *soap, struct ns1__chmod_USCOREobjectResponse *p, const char *tag, const char *type)
+{
+	if ((p = soap_in_ns1__chmod_USCOREobjectResponse(soap, tag, p, type)))
+		if (soap_getindependent(soap))
+			return NULL;
+	return p;
+}
+
+SOAP_FMAC3 struct ns1__chmod_USCOREobjectResponse * SOAP_FMAC4 soap_in_ns1__chmod_USCOREobjectResponse(struct soap *soap, const char *tag, struct ns1__chmod_USCOREobjectResponse *a, const char *type)
+{
+	size_t soap_flag_result = 1;
+	if (soap_element_begin_in(soap, tag, 0, type))
+		return NULL;
+	a = (struct ns1__chmod_USCOREobjectResponse *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_ns1__chmod_USCOREobjectResponse, sizeof(struct ns1__chmod_USCOREobjectResponse), 0, NULL, NULL, NULL);
+	if (!a)
+		return NULL;
+	soap_default_ns1__chmod_USCOREobjectResponse(soap, a);
+	if (soap->body && !*soap->href)
+	{
+		for (;;)
+		{	soap->error = SOAP_TAG_MISMATCH;
+			if (soap_flag_result && soap->error == SOAP_TAG_MISMATCH)
+				if (soap_in_PointerToint(soap, "result", &a->result, "xsd:int"))
+				{	soap_flag_result--;
+					continue;
+				}
+			if (soap->error == SOAP_TAG_MISMATCH)
+				soap->error = soap_ignore_element(soap);
+			if (soap->error == SOAP_NO_TAG)
+				break;
+			if (soap->error)
+				return NULL;
+		}
+		if (soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	else
+	{	a = (struct ns1__chmod_USCOREobjectResponse *)soap_id_forward(soap, soap->href, (void*)a, 0, SOAP_TYPE_ns1__chmod_USCOREobjectResponse, 0, sizeof(struct ns1__chmod_USCOREobjectResponse), 0, NULL);
+		if (soap->body && soap_element_end_in(soap, tag))
+			return NULL;
+	}
+	return a;
+}
+
 SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__stat_USCOREobject(struct soap *soap, struct ns1__stat_USCOREobject *a)
 {
Index: branches/pap/Nebulous/nebclient/src/soapClient.c
===================================================================
--- branches/pap/Nebulous/nebclient/src/soapClient.c	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/soapClient.c	(revision 25027)
@@ -10,5 +10,5 @@
 #endif
 
-SOAP_SOURCE_STAMP("@(#) soapClient.c ver 2.7.12 2009-04-20 22:15:21 GMT")
+SOAP_SOURCE_STAMP("@(#) soapClient.c ver 2.7.12 2009-07-25 01:30:29 GMT")
 
 
@@ -812,4 +812,119 @@
 }
 
+SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__chmod_USCOREobject(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, int mode, int *result)
+{	struct ns1__chmod_USCOREobject soap_tmp_ns1__chmod_USCOREobject;
+	struct ns1__chmod_USCOREobjectResponse *soap_tmp_ns1__chmod_USCOREobjectResponse;
+	if (!soap_endpoint)
+		soap_endpoint = "http://localhost:80/nebulous";
+	if (!soap_action)
+		soap_action = "urn:Nebulous/Server/SOAP#chmod_object";
+	soap->encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/";
+	soap_tmp_ns1__chmod_USCOREobject.key = key;
+	soap_tmp_ns1__chmod_USCOREobject.mode = mode;
+	soap_begin(soap);
+	soap_serializeheader(soap);
+	soap_serialize_ns1__chmod_USCOREobject(soap, &soap_tmp_ns1__chmod_USCOREobject);
+	if (soap_begin_count(soap))
+		return soap->error;
+	if (soap->mode & SOAP_IO_LENGTH)
+	{	if (soap_envelope_begin_out(soap)
+		 || soap_putheader(soap)
+		 || soap_body_begin_out(soap)
+		 || soap_put_ns1__chmod_USCOREobject(soap, &soap_tmp_ns1__chmod_USCOREobject, "ns1:chmod_object", "")
+		 || soap_body_end_out(soap)
+		 || soap_envelope_end_out(soap))
+			 return soap->error;
+	}
+	if (soap_end_count(soap))
+		return soap->error;
+	if (soap_connect(soap, soap_endpoint, soap_action)
+	 || soap_envelope_begin_out(soap)
+	 || soap_putheader(soap)
+	 || soap_body_begin_out(soap)
+	 || soap_put_ns1__chmod_USCOREobject(soap, &soap_tmp_ns1__chmod_USCOREobject, "ns1:chmod_object", "")
+	 || soap_body_end_out(soap)
+	 || soap_envelope_end_out(soap)
+	 || soap_end_send(soap))
+		return soap_closesock(soap);
+	if (!result)
+		return soap_closesock(soap);
+	soap_default_int(soap, result);
+	if (soap_begin_recv(soap)
+	 || soap_envelope_begin_in(soap)
+	 || soap_recv_header(soap)
+	 || soap_body_begin_in(soap))
+		return soap_closesock(soap);
+	soap_tmp_ns1__chmod_USCOREobjectResponse = soap_get_ns1__chmod_USCOREobjectResponse(soap, NULL, "ns1:chmod_objectResponse", "");
+	if (soap->error)
+	{	if (soap->error == SOAP_TAG_MISMATCH && soap->level == 2)
+			return soap_recv_fault(soap);
+		return soap_closesock(soap);
+	}
+	if (soap_body_end_in(soap)
+	 || soap_envelope_end_in(soap)
+	 || soap_end_recv(soap))
+		return soap_closesock(soap);
+	if (result && soap_tmp_ns1__chmod_USCOREobjectResponse->result)
+		*result = *soap_tmp_ns1__chmod_USCOREobjectResponse->result;
+	return soap_closesock(soap);
+}
+
+SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__prune_USCOREobject(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, int *result)
+{	struct ns1__prune_USCOREobject soap_tmp_ns1__prune_USCOREobject;
+	struct ns1__prune_USCOREobjectResponse *soap_tmp_ns1__prune_USCOREobjectResponse;
+	if (!soap_endpoint)
+		soap_endpoint = "http://localhost:80/nebulous";
+	if (!soap_action)
+		soap_action = "urn:Nebulous/Server/SOAP#prune_object";
+	soap->encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/";
+	soap_tmp_ns1__prune_USCOREobject.key = key;
+	soap_begin(soap);
+	soap_serializeheader(soap);
+	soap_serialize_ns1__prune_USCOREobject(soap, &soap_tmp_ns1__prune_USCOREobject);
+	if (soap_begin_count(soap))
+		return soap->error;
+	if (soap->mode & SOAP_IO_LENGTH)
+	{	if (soap_envelope_begin_out(soap)
+		 || soap_putheader(soap)
+		 || soap_body_begin_out(soap)
+		 || soap_put_ns1__prune_USCOREobject(soap, &soap_tmp_ns1__prune_USCOREobject, "ns1:prune_object", "")
+		 || soap_body_end_out(soap)
+		 || soap_envelope_end_out(soap))
+			 return soap->error;
+	}
+	if (soap_end_count(soap))
+		return soap->error;
+	if (soap_connect(soap, soap_endpoint, soap_action)
+	 || soap_envelope_begin_out(soap)
+	 || soap_putheader(soap)
+	 || soap_body_begin_out(soap)
+	 || soap_put_ns1__prune_USCOREobject(soap, &soap_tmp_ns1__prune_USCOREobject, "ns1:prune_object", "")
+	 || soap_body_end_out(soap)
+	 || soap_envelope_end_out(soap)
+	 || soap_end_send(soap))
+		return soap_closesock(soap);
+	if (!result)
+		return soap_closesock(soap);
+	soap_default_int(soap, result);
+	if (soap_begin_recv(soap)
+	 || soap_envelope_begin_in(soap)
+	 || soap_recv_header(soap)
+	 || soap_body_begin_in(soap))
+		return soap_closesock(soap);
+	soap_tmp_ns1__prune_USCOREobjectResponse = soap_get_ns1__prune_USCOREobjectResponse(soap, NULL, "ns1:prune_objectResponse", "");
+	if (soap->error)
+	{	if (soap->error == SOAP_TAG_MISMATCH && soap->level == 2)
+			return soap_recv_fault(soap);
+		return soap_closesock(soap);
+	}
+	if (soap_body_end_in(soap)
+	 || soap_envelope_end_in(soap)
+	 || soap_end_recv(soap))
+		return soap_closesock(soap);
+	if (result && soap_tmp_ns1__prune_USCOREobjectResponse->result)
+		*result = *soap_tmp_ns1__prune_USCOREobjectResponse->result;
+	return soap_closesock(soap);
+}
+
 #ifdef __cplusplus
 }
Index: branches/pap/Nebulous/nebclient/src/soapH.h
===================================================================
--- branches/pap/Nebulous/nebclient/src/soapH.h	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/soapH.h	(revision 25027)
@@ -42,5 +42,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Fault
-#define SOAP_TYPE_SOAP_ENV__Fault (64)
+#define SOAP_TYPE_SOAP_ENV__Fault (70)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Fault(struct soap*, struct SOAP_ENV__Fault *);
@@ -56,5 +56,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Reason
-#define SOAP_TYPE_SOAP_ENV__Reason (63)
+#define SOAP_TYPE_SOAP_ENV__Reason (69)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Reason(struct soap*, struct SOAP_ENV__Reason *);
@@ -70,5 +70,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Detail
-#define SOAP_TYPE_SOAP_ENV__Detail (60)
+#define SOAP_TYPE_SOAP_ENV__Detail (66)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Detail(struct soap*, struct SOAP_ENV__Detail *);
@@ -84,5 +84,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Code
-#define SOAP_TYPE_SOAP_ENV__Code (58)
+#define SOAP_TYPE_SOAP_ENV__Code (64)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Code(struct soap*, struct SOAP_ENV__Code *);
@@ -98,5 +98,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Header
-#define SOAP_TYPE_SOAP_ENV__Header (57)
+#define SOAP_TYPE_SOAP_ENV__Header (63)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_default_SOAP_ENV__Header(struct soap*, struct SOAP_ENV__Header *);
@@ -109,4 +109,44 @@
 #endif
 
+#ifndef SOAP_TYPE_ns1__prune_USCOREobject
+#define SOAP_TYPE_ns1__prune_USCOREobject (62)
+#endif
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__prune_USCOREobject(struct soap*, struct ns1__prune_USCOREobject *);
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__prune_USCOREobject(struct soap*, const struct ns1__prune_USCOREobject *);
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__prune_USCOREobject(struct soap*, const struct ns1__prune_USCOREobject *, const char*, const char*);
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__prune_USCOREobject(struct soap*, const char*, int, const struct ns1__prune_USCOREobject *, const char*);
+SOAP_FMAC3 struct ns1__prune_USCOREobject * SOAP_FMAC4 soap_get_ns1__prune_USCOREobject(struct soap*, struct ns1__prune_USCOREobject *, const char*, const char*);
+SOAP_FMAC3 struct ns1__prune_USCOREobject * SOAP_FMAC4 soap_in_ns1__prune_USCOREobject(struct soap*, const char*, struct ns1__prune_USCOREobject *, const char*);
+
+#ifndef SOAP_TYPE_ns1__prune_USCOREobjectResponse
+#define SOAP_TYPE_ns1__prune_USCOREobjectResponse (61)
+#endif
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__prune_USCOREobjectResponse(struct soap*, struct ns1__prune_USCOREobjectResponse *);
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__prune_USCOREobjectResponse(struct soap*, const struct ns1__prune_USCOREobjectResponse *);
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__prune_USCOREobjectResponse(struct soap*, const struct ns1__prune_USCOREobjectResponse *, const char*, const char*);
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__prune_USCOREobjectResponse(struct soap*, const char*, int, const struct ns1__prune_USCOREobjectResponse *, const char*);
+SOAP_FMAC3 struct ns1__prune_USCOREobjectResponse * SOAP_FMAC4 soap_get_ns1__prune_USCOREobjectResponse(struct soap*, struct ns1__prune_USCOREobjectResponse *, const char*, const char*);
+SOAP_FMAC3 struct ns1__prune_USCOREobjectResponse * SOAP_FMAC4 soap_in_ns1__prune_USCOREobjectResponse(struct soap*, const char*, struct ns1__prune_USCOREobjectResponse *, const char*);
+
+#ifndef SOAP_TYPE_ns1__chmod_USCOREobject
+#define SOAP_TYPE_ns1__chmod_USCOREobject (59)
+#endif
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__chmod_USCOREobject(struct soap*, struct ns1__chmod_USCOREobject *);
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__chmod_USCOREobject(struct soap*, const struct ns1__chmod_USCOREobject *);
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__chmod_USCOREobject(struct soap*, const struct ns1__chmod_USCOREobject *, const char*, const char*);
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__chmod_USCOREobject(struct soap*, const char*, int, const struct ns1__chmod_USCOREobject *, const char*);
+SOAP_FMAC3 struct ns1__chmod_USCOREobject * SOAP_FMAC4 soap_get_ns1__chmod_USCOREobject(struct soap*, struct ns1__chmod_USCOREobject *, const char*, const char*);
+SOAP_FMAC3 struct ns1__chmod_USCOREobject * SOAP_FMAC4 soap_in_ns1__chmod_USCOREobject(struct soap*, const char*, struct ns1__chmod_USCOREobject *, const char*);
+
+#ifndef SOAP_TYPE_ns1__chmod_USCOREobjectResponse
+#define SOAP_TYPE_ns1__chmod_USCOREobjectResponse (58)
+#endif
+SOAP_FMAC3 void SOAP_FMAC4 soap_default_ns1__chmod_USCOREobjectResponse(struct soap*, struct ns1__chmod_USCOREobjectResponse *);
+SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_ns1__chmod_USCOREobjectResponse(struct soap*, const struct ns1__chmod_USCOREobjectResponse *);
+SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__chmod_USCOREobjectResponse(struct soap*, const struct ns1__chmod_USCOREobjectResponse *, const char*, const char*);
+SOAP_FMAC3 int SOAP_FMAC4 soap_out_ns1__chmod_USCOREobjectResponse(struct soap*, const char*, int, const struct ns1__chmod_USCOREobjectResponse *, const char*);
+SOAP_FMAC3 struct ns1__chmod_USCOREobjectResponse * SOAP_FMAC4 soap_get_ns1__chmod_USCOREobjectResponse(struct soap*, struct ns1__chmod_USCOREobjectResponse *, const char*, const char*);
+SOAP_FMAC3 struct ns1__chmod_USCOREobjectResponse * SOAP_FMAC4 soap_in_ns1__chmod_USCOREobjectResponse(struct soap*, const char*, struct ns1__chmod_USCOREobjectResponse *, const char*);
+
 #ifndef SOAP_TYPE_ns1__stat_USCOREobject
 #define SOAP_TYPE_ns1__stat_USCOREobject (56)
@@ -402,5 +442,5 @@
 
 #ifndef SOAP_TYPE_PointerToSOAP_ENV__Reason
-#define SOAP_TYPE_PointerToSOAP_ENV__Reason (66)
+#define SOAP_TYPE_PointerToSOAP_ENV__Reason (72)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Reason(struct soap*, struct SOAP_ENV__Reason *const*);
@@ -415,5 +455,5 @@
 
 #ifndef SOAP_TYPE_PointerToSOAP_ENV__Detail
-#define SOAP_TYPE_PointerToSOAP_ENV__Detail (65)
+#define SOAP_TYPE_PointerToSOAP_ENV__Detail (71)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Detail(struct soap*, struct SOAP_ENV__Detail *const*);
@@ -428,5 +468,5 @@
 
 #ifndef SOAP_TYPE_PointerToSOAP_ENV__Code
-#define SOAP_TYPE_PointerToSOAP_ENV__Code (59)
+#define SOAP_TYPE_PointerToSOAP_ENV__Code (65)
 #endif
 SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerToSOAP_ENV__Code(struct soap*, struct SOAP_ENV__Code *const*);
Index: branches/pap/Nebulous/nebclient/src/soapServer.c
===================================================================
--- branches/pap/Nebulous/nebclient/src/soapServer.c	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/soapServer.c	(revision 25027)
@@ -10,5 +10,5 @@
 #endif
 
-SOAP_SOURCE_STAMP("@(#) soapServer.c ver 2.7.12 2009-04-20 22:15:21 GMT")
+SOAP_SOURCE_STAMP("@(#) soapServer.c ver 2.7.12 2009-07-25 01:30:29 GMT")
 
 
@@ -105,4 +105,8 @@
 	if (!soap_match_tag(soap, soap->tag, "ns1:stat_object"))
 		return soap_serve_ns1__stat_USCOREobject(soap);
+	if (!soap_match_tag(soap, soap->tag, "ns1:chmod_object"))
+		return soap_serve_ns1__chmod_USCOREobject(soap);
+	if (!soap_match_tag(soap, soap->tag, "ns1:prune_object"))
+		return soap_serve_ns1__prune_USCOREobject(soap);
 	return soap->error = SOAP_NO_METHOD;
 }
@@ -713,4 +717,92 @@
 }
 
+SOAP_FMAC5 int SOAP_FMAC6 soap_serve_ns1__chmod_USCOREobject(struct soap *soap)
+{	struct ns1__chmod_USCOREobject soap_tmp_ns1__chmod_USCOREobject;
+	struct ns1__chmod_USCOREobjectResponse soap_tmp_ns1__chmod_USCOREobjectResponse;
+	int soap_tmp_int;
+	soap_default_ns1__chmod_USCOREobjectResponse(soap, &soap_tmp_ns1__chmod_USCOREobjectResponse);
+	soap_default_int(soap, &soap_tmp_int);
+	soap_tmp_ns1__chmod_USCOREobjectResponse.result = &soap_tmp_int;
+	soap_default_ns1__chmod_USCOREobject(soap, &soap_tmp_ns1__chmod_USCOREobject);
+	soap->encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/";
+	if (!soap_get_ns1__chmod_USCOREobject(soap, &soap_tmp_ns1__chmod_USCOREobject, "ns1:chmod_object", NULL))
+		return soap->error;
+	if (soap_body_end_in(soap)
+	 || soap_envelope_end_in(soap)
+	 || soap_end_recv(soap))
+		return soap->error;
+	soap->error = ns1__chmod_USCOREobject(soap, soap_tmp_ns1__chmod_USCOREobject.key, soap_tmp_ns1__chmod_USCOREobject.mode, &soap_tmp_int);
+	if (soap->error)
+		return soap->error;
+	soap_serializeheader(soap);
+	soap_serialize_ns1__chmod_USCOREobjectResponse(soap, &soap_tmp_ns1__chmod_USCOREobjectResponse);
+	if (soap_begin_count(soap))
+		return soap->error;
+	if (soap->mode & SOAP_IO_LENGTH)
+	{	if (soap_envelope_begin_out(soap)
+		 || soap_putheader(soap)
+		 || soap_body_begin_out(soap)
+		 || soap_put_ns1__chmod_USCOREobjectResponse(soap, &soap_tmp_ns1__chmod_USCOREobjectResponse, "ns1:chmod_objectResponse", "")
+		 || soap_body_end_out(soap)
+		 || soap_envelope_end_out(soap))
+			 return soap->error;
+	};
+	if (soap_end_count(soap)
+	 || soap_response(soap, SOAP_OK)
+	 || soap_envelope_begin_out(soap)
+	 || soap_putheader(soap)
+	 || soap_body_begin_out(soap)
+	 || soap_put_ns1__chmod_USCOREobjectResponse(soap, &soap_tmp_ns1__chmod_USCOREobjectResponse, "ns1:chmod_objectResponse", "")
+	 || soap_body_end_out(soap)
+	 || soap_envelope_end_out(soap)
+	 || soap_end_send(soap))
+		return soap->error;
+	return soap_closesock(soap);
+}
+
+SOAP_FMAC5 int SOAP_FMAC6 soap_serve_ns1__prune_USCOREobject(struct soap *soap)
+{	struct ns1__prune_USCOREobject soap_tmp_ns1__prune_USCOREobject;
+	struct ns1__prune_USCOREobjectResponse soap_tmp_ns1__prune_USCOREobjectResponse;
+	int soap_tmp_int;
+	soap_default_ns1__prune_USCOREobjectResponse(soap, &soap_tmp_ns1__prune_USCOREobjectResponse);
+	soap_default_int(soap, &soap_tmp_int);
+	soap_tmp_ns1__prune_USCOREobjectResponse.result = &soap_tmp_int;
+	soap_default_ns1__prune_USCOREobject(soap, &soap_tmp_ns1__prune_USCOREobject);
+	soap->encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/";
+	if (!soap_get_ns1__prune_USCOREobject(soap, &soap_tmp_ns1__prune_USCOREobject, "ns1:prune_object", NULL))
+		return soap->error;
+	if (soap_body_end_in(soap)
+	 || soap_envelope_end_in(soap)
+	 || soap_end_recv(soap))
+		return soap->error;
+	soap->error = ns1__prune_USCOREobject(soap, soap_tmp_ns1__prune_USCOREobject.key, &soap_tmp_int);
+	if (soap->error)
+		return soap->error;
+	soap_serializeheader(soap);
+	soap_serialize_ns1__prune_USCOREobjectResponse(soap, &soap_tmp_ns1__prune_USCOREobjectResponse);
+	if (soap_begin_count(soap))
+		return soap->error;
+	if (soap->mode & SOAP_IO_LENGTH)
+	{	if (soap_envelope_begin_out(soap)
+		 || soap_putheader(soap)
+		 || soap_body_begin_out(soap)
+		 || soap_put_ns1__prune_USCOREobjectResponse(soap, &soap_tmp_ns1__prune_USCOREobjectResponse, "ns1:prune_objectResponse", "")
+		 || soap_body_end_out(soap)
+		 || soap_envelope_end_out(soap))
+			 return soap->error;
+	};
+	if (soap_end_count(soap)
+	 || soap_response(soap, SOAP_OK)
+	 || soap_envelope_begin_out(soap)
+	 || soap_putheader(soap)
+	 || soap_body_begin_out(soap)
+	 || soap_put_ns1__prune_USCOREobjectResponse(soap, &soap_tmp_ns1__prune_USCOREobjectResponse, "ns1:prune_objectResponse", "")
+	 || soap_body_end_out(soap)
+	 || soap_envelope_end_out(soap)
+	 || soap_end_send(soap))
+		return soap->error;
+	return soap_closesock(soap);
+}
+
 #ifdef __cplusplus
 }
Index: branches/pap/Nebulous/nebclient/src/soapStub.h
===================================================================
--- branches/pap/Nebulous/nebclient/src/soapStub.h	(revision 23948)
+++ branches/pap/Nebulous/nebclient/src/soapStub.h	(revision 25027)
@@ -306,6 +306,43 @@
 #endif
 
+#ifndef SOAP_TYPE_ns1__chmod_USCOREobjectResponse
+#define SOAP_TYPE_ns1__chmod_USCOREobjectResponse (58)
+/* ns1:chmod_objectResponse */
+struct ns1__chmod_USCOREobjectResponse
+{
+	int *result;	/* SOAP 1.2 RPC return element (when namespace qualified) */	/* optional element of type xsd:int */
+};
+#endif
+
+#ifndef SOAP_TYPE_ns1__chmod_USCOREobject
+#define SOAP_TYPE_ns1__chmod_USCOREobject (59)
+/* ns1:chmod_object */
+struct ns1__chmod_USCOREobject
+{
+	char *key;	/* optional element of type xsd:string */
+	int mode;	/* required element of type xsd:int */
+};
+#endif
+
+#ifndef SOAP_TYPE_ns1__prune_USCOREobjectResponse
+#define SOAP_TYPE_ns1__prune_USCOREobjectResponse (61)
+/* ns1:prune_objectResponse */
+struct ns1__prune_USCOREobjectResponse
+{
+	int *result;	/* SOAP 1.2 RPC return element (when namespace qualified) */	/* optional element of type xsd:int */
+};
+#endif
+
+#ifndef SOAP_TYPE_ns1__prune_USCOREobject
+#define SOAP_TYPE_ns1__prune_USCOREobject (62)
+/* ns1:prune_object */
+struct ns1__prune_USCOREobject
+{
+	char *key;	/* optional element of type xsd:string */
+};
+#endif
+
 #ifndef SOAP_TYPE_SOAP_ENV__Header
-#define SOAP_TYPE_SOAP_ENV__Header (57)
+#define SOAP_TYPE_SOAP_ENV__Header (63)
 /* SOAP Header: */
 struct SOAP_ENV__Header
@@ -318,5 +355,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Code
-#define SOAP_TYPE_SOAP_ENV__Code (58)
+#define SOAP_TYPE_SOAP_ENV__Code (64)
 /* SOAP Fault Code: */
 struct SOAP_ENV__Code
@@ -328,5 +365,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Detail
-#define SOAP_TYPE_SOAP_ENV__Detail (60)
+#define SOAP_TYPE_SOAP_ENV__Detail (66)
 /* SOAP-ENV:Detail */
 struct SOAP_ENV__Detail
@@ -339,5 +376,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Reason
-#define SOAP_TYPE_SOAP_ENV__Reason (63)
+#define SOAP_TYPE_SOAP_ENV__Reason (69)
 /* SOAP-ENV:Reason */
 struct SOAP_ENV__Reason
@@ -348,5 +385,5 @@
 
 #ifndef SOAP_TYPE_SOAP_ENV__Fault
-#define SOAP_TYPE_SOAP_ENV__Fault (64)
+#define SOAP_TYPE_SOAP_ENV__Fault (70)
 /* SOAP Fault: */
 struct SOAP_ENV__Fault
@@ -437,4 +474,8 @@
 SOAP_FMAC5 int SOAP_FMAC6 ns1__stat_USCOREobject(struct soap*, char *key, struct ns1__stat_USCOREobjectResponse *_param_4);
 
+SOAP_FMAC5 int SOAP_FMAC6 ns1__chmod_USCOREobject(struct soap*, char *key, int mode, int *result);
+
+SOAP_FMAC5 int SOAP_FMAC6 ns1__prune_USCOREobject(struct soap*, char *key, int *result);
+
 /******************************************************************************\
  *                                                                            *
@@ -472,4 +513,8 @@
 SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__stat_USCOREobject(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, struct ns1__stat_USCOREobjectResponse *_param_4);
 
+SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__chmod_USCOREobject(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, int mode, int *result);
+
+SOAP_FMAC5 int SOAP_FMAC6 soap_call_ns1__prune_USCOREobject(struct soap *soap, const char *soap_endpoint, const char *soap_action, char *key, int *result);
+
 /******************************************************************************\
  *                                                                            *
@@ -509,4 +554,8 @@
 
 SOAP_FMAC5 int SOAP_FMAC6 soap_serve_ns1__stat_USCOREobject(struct soap*);
+
+SOAP_FMAC5 int SOAP_FMAC6 soap_serve_ns1__chmod_USCOREobject(struct soap*);
+
+SOAP_FMAC5 int SOAP_FMAC6 soap_serve_ns1__prune_USCOREobject(struct soap*);
 
 #ifdef __cplusplus
Index: branches/pap/Nebulous/nebclient/tests/tests.c
===================================================================
--- branches/pap/Nebulous/nebclient/tests/tests.c	(revision 23948)
+++ branches/pap/Nebulous/nebclient/tests/tests.c	(revision 25027)
@@ -20,5 +20,5 @@
     char            *key = "foobarbaz";
 
-    plan_tests(28);
+    plan_tests(31);
 
     if (getenv("NEB_SERVER")) {
@@ -98,10 +98,9 @@
 
     char *copies = nebGetXattr(server, key, "user.copies");
-    neb_ok(server, strcmp(copies, "2") == 0, "get user.copies xattr");
+    neb_ok(server, copies != NULL && strcmp(copies, "2") == 0, "get user.copies xattr");
     char **xattrs = NULL;
     int n_xattrs = nebListXattr(server, key, &xattrs);
-    printf("# %s\n\n", xattrs[0]);
-    neb_ok(server, n_xattrs == 1, "count of xattrs");
-    neb_ok(server, strcmp(xattrs[0], "user.copies") == 0, "user.copies xattr exists");
+    neb_ok(server, xattrs != NULL && n_xattrs == 1, "count of xattrs");
+    neb_ok(server, xattrs != NULL && strcmp(xattrs[0], "user.copies") == 0, "user.copies xattr exists");
     neb_ok(server, nebRemoveXattr(server, key, "user.copies"), "remove user.copies xattr");
 
@@ -136,4 +135,12 @@
     neb_ok(server, nebMove(server, "copyiedfile", "movedfile"), "move object");
 
+    neb_ok(server, nebChmod(server, "movedfile", 0440) == 0, "chmod object");
+
+    // no dead instances to remove
+    neb_ok(server, nebPrune(server, "movedfile") == 0, "prune object");
+
+    nebReplicate(server, key, NULL, NULL);
+    neb_ok(server, nebThereCanBeOnlyOne(server, "movedfile", NULL) == 0, "reduce instances to only 1");
+
     if (!nebDelete(server, "movedfile")) {
         diag( "cleanup failed %s\n", nebErr(server));
Index: branches/pap/Nebulous/t/49_client_new.t
===================================================================
--- branches/pap/Nebulous/t/49_client_new.t	(revision 25027)
+++ branches/pap/Nebulous/t/49_client_new.t	(revision 25027)
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2004-2005  Joshua Hoblitt
+#
+# $Id: 50_client_new.t,v 1.1 2005-12-03 02:52:31 jhoblitt Exp $
+
+use strict;
+use warnings FATAL => qw( all );
+
+use Apache::Test qw( -withtestmore );
+
+plan tests => 4;
+
+use lib qw( ./t ./lib );
+
+use Nebulous::Client;
+use Nebulous::Util qw( :standard );
+use Test::Nebulous;
+
+my $hostport = Apache::Test->config->{ 'hostport' };
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    isa_ok( $neb, "Nebulous::Client" );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+        uri   => "http://example.com/PS/IPP/Nebulous/Client",
+    );
+
+    isa_ok( $neb, "Nebulous::Client" );
+}
+
+Test::Nebulous->setup;
+
+eval {
+    Nebulous::Client->new;
+};
+like( $@, qr/Mandatory parameter/, "no proxy" );
+
+Test::Nebulous->setup;
+
+eval {
+    Nebulous::Client->new(
+        proxy => "foo",
+        dog => "do"
+    );
+};
+like( $@, qr/not listed in the validation options/, "bad param" );
+
+Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/50_client_create.t
===================================================================
--- branches/pap/Nebulous/t/50_client_create.t	(revision 25027)
+++ branches/pap/Nebulous/t/50_client_create.t	(revision 25027)
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2004-2005  Joshua Hoblitt
+#
+# $Id: 51_client_create.t,v 1.6 2008-05-15 03:24:58 jhoblitt Exp $
+
+use strict;
+use warnings FATAL => qw( all );
+
+use Apache::Test qw( -withtestmore );
+
+plan tests => 9;
+
+use lib qw( ./t ./lib );
+
+use Nebulous::Client;
+use Test::Nebulous;
+use Test::URI;
+use URI::Split qw( uri_split );
+
+my $hostport = Apache::Test->config->{ 'hostport' };
+
+Test::Nebulous->setup;
+
+{
+    # key
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    my $uri = $neb->create("foo");
+    my ($scheme, $auth, $path, $query, $frag) = uri_split($uri);
+    ok(-e $path, "good filename");
+    uri_scheme_ok($uri, 'file');
+}
+
+Test::Nebulous->setup;
+
+{
+    # key, volume
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    my $uri = $neb->create("foo", "node01");
+
+    my ($scheme, $auth, $path, $query, $frag) = uri_split($uri);
+    ok(-e $path, "good filename");
+    uri_scheme_ok($uri, 'file');
+}
+
+Test::Nebulous->setup;
+
+{
+    # key, volume == undef
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    my $uri = $neb->create("foo", undef);
+
+    my ($scheme, $auth, $path, $query, $frag) = uri_split($uri);
+    ok(-e $path, "good filename");
+    uri_scheme_ok($uri, 'file');
+}
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    $neb->create("foo");
+    is($neb->create("foo"), undef, "object already exists");
+}
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    $neb->create();
+};
+like($@, qr/1 - 2 were expected/, "no params");
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    $neb->create(1, 2, 3);
+};
+like($@, qr/1 - 2 were expected/, "too many params");
+
+Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/50_client_new.t
===================================================================
--- branches/pap/Nebulous/t/50_client_new.t	(revision 23948)
+++ 	(revision )
@@ -1,60 +1,0 @@
-#!/usr/bin/perl
-
-# Copryight (C) 2004-2005  Joshua Hoblitt
-#
-# $Id: 50_client_new.t,v 1.1 2005-12-03 02:52:31 jhoblitt Exp $
-
-use strict;
-use warnings FATAL => qw( all );
-
-use Apache::Test qw( -withtestmore );
-
-plan tests => 4;
-
-use lib qw( ./t ./lib );
-
-use Nebulous::Client;
-use Nebulous::Util qw( :standard );
-use Test::Nebulous;
-
-my $hostport = Apache::Test->config->{ 'hostport' };
-
-Test::Nebulous->setup;
-
-{
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    isa_ok( $neb, "Nebulous::Client" );
-}
-
-Test::Nebulous->setup;
-
-{
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-        uri   => "http://example.com/PS/IPP/Nebulous/Client",
-    );
-
-    isa_ok( $neb, "Nebulous::Client" );
-}
-
-Test::Nebulous->setup;
-
-eval {
-    Nebulous::Client->new;
-};
-like( $@, qr/Mandatory parameter/, "no proxy" );
-
-Test::Nebulous->setup;
-
-eval {
-    Nebulous::Client->new(
-        proxy => "foo",
-        dog => "do"
-    );
-};
-like( $@, qr/not listed in the validation options/, "bad param" );
-
-Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/51_client_create.t
===================================================================
--- branches/pap/Nebulous/t/51_client_create.t	(revision 23948)
+++ 	(revision )
@@ -1,100 +1,0 @@
-#!/usr/bin/perl
-
-# Copryight (C) 2004-2005  Joshua Hoblitt
-#
-# $Id: 51_client_create.t,v 1.6 2008-05-15 03:24:58 jhoblitt Exp $
-
-use strict;
-use warnings FATAL => qw( all );
-
-use Apache::Test qw( -withtestmore );
-
-plan tests => 9;
-
-use lib qw( ./t ./lib );
-
-use Nebulous::Client;
-use Test::Nebulous;
-use Test::URI;
-use URI::Split qw( uri_split );
-
-my $hostport = Apache::Test->config->{ 'hostport' };
-
-Test::Nebulous->setup;
-
-{
-    # key
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    my $uri = $neb->create("foo");
-    my ($scheme, $auth, $path, $query, $frag) = uri_split($uri);
-    ok(-e $path, "good filename");
-    uri_scheme_ok($uri, 'file');
-}
-
-Test::Nebulous->setup;
-
-{
-    # key, volume
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    my $uri = $neb->create("foo", "node01");
-
-    my ($scheme, $auth, $path, $query, $frag) = uri_split($uri);
-    ok(-e $path, "good filename");
-    uri_scheme_ok($uri, 'file');
-}
-
-Test::Nebulous->setup;
-
-{
-    # key, volume == undef
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    my $uri = $neb->create("foo", undef);
-
-    my ($scheme, $auth, $path, $query, $frag) = uri_split($uri);
-    ok(-e $path, "good filename");
-    uri_scheme_ok($uri, 'file');
-}
-
-Test::Nebulous->setup;
-
-{
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create("foo");
-    is($neb->create("foo"), undef, "object already exists");
-}
-
-Test::Nebulous->setup;
-
-eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create();
-};
-like($@, qr/1 - 2 were expected/, "no params");
-
-Test::Nebulous->setup;
-
-eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create(1, 2, 3);
-};
-like($@, qr/1 - 2 were expected/, "too many params");
-
-Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/59_client_delete.t
===================================================================
--- branches/pap/Nebulous/t/59_client_delete.t	(revision 23948)
+++ branches/pap/Nebulous/t/59_client_delete.t	(revision 25027)
@@ -10,5 +10,5 @@
 use Apache::Test qw( -withtestmore );
 
-plan tests => 9;
+plan tests => 13;
 
 use lib qw( ./t ./lib );
@@ -26,7 +26,9 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->create( "foo" );
+    my $uri = $neb->create( "foo" );
 
     ok( $neb->delete( "foo" ), "delete object" );
+
+    ok( ! -e _get_file_path($uri), "deleted file" );
 
     my $locations = $neb->find_instances( "foo" );
@@ -76,4 +78,27 @@
 }
 
+# force flag
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->create( "foo" );
+
+    is( $neb->delete("foo", undef), 1, "force flag false" );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->create( "foo" );
+
+    is( $neb->delete("foo", 1), 1, "force flag false" );
+}
+
 Test::Nebulous->setup;
 
@@ -84,5 +109,5 @@
     $neb->delete();
 };
-like( $@, qr/1 was expected/, "no params" );
+like( $@, qr/1 - 2 were expected/, "no params" );
 
 Test::Nebulous->setup;
@@ -92,7 +117,17 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->delete( "foo", 2 );
+    $neb->delete( "foo", 3);
 };
-like( $@, qr/1 was expected/, "too many params" );
+like( $@, qr/is boolean/, "force flag not boolean" );
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->delete( "foo", 0, 2 );
+};
+like( $@, qr/1 - 2 were expected/, "too many params" );
 
 Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/62_client_delete_instance.t
===================================================================
--- branches/pap/Nebulous/t/62_client_delete_instance.t	(revision 23948)
+++ branches/pap/Nebulous/t/62_client_delete_instance.t	(revision 25027)
@@ -10,5 +10,5 @@
 use Apache::Test qw( -withtestmore );
 
-plan tests => 11;
+plan tests => 10;
 
 use lib qw( ./t ./lib );
@@ -35,6 +35,4 @@
 
     is( $uri, @$locations[0], "delete instance" );
-
-    ok( ! -e _get_file_path( @$locations[0] ), "deleted file" );
 }
 
Index: branches/pap/Nebulous/t/63_client_stat.t
===================================================================
--- branches/pap/Nebulous/t/63_client_stat.t	(revision 23948)
+++ branches/pap/Nebulous/t/63_client_stat.t	(revision 25027)
@@ -10,5 +10,5 @@
 use Apache::Test qw( -withtestmore );
 
-plan tests => 12;
+plan tests => 13;
 
 use lib qw( ./t ./lib );
@@ -30,5 +30,5 @@
     my $info = $neb->stat( "foo" );
 
-    is( scalar @$info, 7, "number of columns" );
+    is( scalar @$info, 8, "number of columns" );
 }
 
@@ -43,5 +43,5 @@
     my $info = $neb->stat( "foo" );
 
-    is( scalar @$info, 7,                       "number of columns" );
+    is( scalar @$info, 8,                       "number of columns" );
     is( @$info[0], 1,                           "so_id" );
     is( @$info[1], "foo",                       "ext_id" );
@@ -50,5 +50,6 @@
     like( @$info[4], qr/....-..-.. ..:..:../,   "epoch" );
     like( @$info[5], qr/....-..-.. ..:..:../,   "mtime" );
-    is( @$info[6], 1,                           "instances" );
+    is( @$info[6], 1,                           "available instances" );
+    is( @$info[7], 1,                           "total instances" );
 }
 
Index: branches/pap/Nebulous/t/66_client_xattr.t
===================================================================
--- branches/pap/Nebulous/t/66_client_xattr.t	(revision 23948)
+++ branches/pap/Nebulous/t/66_client_xattr.t	(revision 25027)
@@ -1,7 +1,5 @@
 #!/usr/bin/perl
 
-# Copryight (C) 2007-2008  Joshua Hoblitt
-#
-# $Id: 66_client_xattr.t,v 1.1 2008-05-20 00:54:30 jhoblitt Exp $
+# Copryight (C) 2007-2009  Joshua Hoblitt
 
 use strict;
@@ -9,6 +7,5 @@
 
 use Apache::Test qw( -withtestmore );
-plan tests => 32;
-
+plan tests => 44;
 
 use lib qw( ./t ./lib );
@@ -20,4 +17,8 @@
 my $hostport = Apache::Test->config->{ 'hostport' };
 
+my $neb = Nebulous::Client->new(
+    proxy => "http://$hostport/nebulous",
+);
+
 # 1 key / xattr
 
@@ -25,21 +26,17 @@
 
 {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
     my $uri = $neb->create('foo');
 
-    ok($neb->setxattr('foo', 'bar', 'baz', 'create'), 'set object xattr');
+    ok($neb->setxattr('foo', 'user.bar', 'baz', 'create'), 'set object xattr');
     {
         my $xattrs = $neb->listxattr('foo');
         is(scalar @$xattrs, 1, 'number of xattrs');
-        is(@$xattrs[0], 'bar', 'xattr name');
-    }
-
-    my $value = $neb->getxattr('foo', 'bar');
+        is(@$xattrs[0], 'user.bar', 'xattr name');
+    }
+
+    my $value = $neb->getxattr('foo', 'user.bar');
     is($value, 'baz', 'xattr value');
 
-    ok($neb->removexattr('foo', 'bar'), "remove object xattr");
+    ok($neb->removexattr('foo', 'user.bar'), "remove object xattr");
     {
         my $xattrs = $neb->listxattr('foo');
@@ -53,27 +50,23 @@
 
 {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
     my $uri = $neb->create('foo');
 
-    ok($neb->setxattr('foo', 'bar', 'baz', 'create'), 'set object xattr');
-    ok($neb->setxattr('foo', 'bonk', 'quix', 'create'), 'set object xattr');
+    ok($neb->setxattr('foo', 'user.bar', 'baz', 'create'), 'set object xattr');
+    ok($neb->setxattr('foo', 'user.bonk', 'quix', 'create'), 'set object xattr');
     
     {
         my $xattrs = $neb->listxattr('foo');
         is(scalar @$xattrs, 2, 'number of xattrs');
-        is(@$xattrs[0], 'bar', 'xattr name');
-        is(@$xattrs[1], 'bonk', 'xattr name');
-    }
-
-    my $value = $neb->getxattr('foo', 'bar');
+        is(@$xattrs[0], 'user.bar', 'xattr name');
+        is(@$xattrs[1], 'user.bonk', 'xattr name');
+    }
+
+    my $value = $neb->getxattr('foo', 'user.bar');
     is($value, 'baz', 'xattr value');
-    $value = $neb->getxattr('foo', 'bonk');
+    $value = $neb->getxattr('foo', 'user.bonk');
     is($value, 'quix', 'xattr value');
 
-    ok($neb->removexattr('foo', 'bar'), "remove object xattr");
-    ok($neb->removexattr('foo', 'bonk'), "remove object xattr");
+    ok($neb->removexattr('foo', 'user.bar'), "remove object xattr");
+    ok($neb->removexattr('foo', 'user.bonk'), "remove object xattr");
     {
         my $xattrs = $neb->listxattr('foo');
@@ -87,23 +80,19 @@
 
 {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
     my $uri = $neb->create('foo');
 
-    ok($neb->setxattr('foo', 'bar', 'baz', 'create'), 'set object xattr');
-    ok($neb->setxattr('foo', 'bar', 'quix', 'replace'), 're-set object xattr');
+    ok($neb->setxattr('foo', 'user.bar', 'baz', 'create'), 'set object xattr');
+    ok($neb->setxattr('foo', 'user.bar', 'quix', 'replace'), 're-set object xattr');
     
     {
         my $xattrs = $neb->listxattr('foo');
         is(scalar @$xattrs, 1, 'number of xattrs');
-        is(@$xattrs[0], 'bar', 'xattr name');
-    }
-
-    my $value = $neb->getxattr('foo', 'bar');
+        is(@$xattrs[0], 'user.bar', 'xattr name');
+    }
+
+    my $value = $neb->getxattr('foo', 'user.bar');
     is($value, 'quix', 'xattr value');
 
-    ok($neb->removexattr('foo', 'bar'), "remove object xattr");
+    ok($neb->removexattr('foo', 'user.bar'), "remove object xattr");
     {
         my $xattrs = $neb->listxattr('foo');
@@ -117,8 +106,27 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
+    $neb->setxattr('foo', 'user.bar', 'baz', 'create');
+};
+like($@, qr/is valid object key/, "create xattr on non-existant key");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create('foo');
+
+    $neb->setxattr('foo', 'luser.bar', 'baz', 'create');
+};
+like($@, qr/xattr is in user. namespace/, "user. namspace");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->setxattr('foo', 'user.bar', 'baz', 'replace');
+};
+like($@, qr/is valid object key/, "replace xattr on non-existant key");
+
+Test::Nebulous->setup;
+
+eval {
     $neb->setxattr();
 };
@@ -128,11 +136,7 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create('foo');
-
-    $neb->setxattr('foo', 'bar');
+    $neb->create('foo');
+
+    $neb->setxattr('foo', 'user.bar');
 };
 like($@, qr/4 were expected/, "too few params");
@@ -141,11 +145,7 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create('foo');
-
-    $neb->setxattr('foo', 'bar', 'baz');
+    $neb->create('foo');
+
+    $neb->setxattr('foo', 'user.bar', 'baz');
 };
 like($@, qr/4 were expected/, "too few params");
@@ -154,14 +154,62 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create('foo');
-
-    $neb->setxattr('foo', 'bar', 'baz', 'create', 'quix');
+    $neb->create('foo');
+
+    $neb->setxattr('foo', 'user.bar', 'baz', 'create', 'quix');
 };
 like($@, qr/4 were expected/, "too many params");
 
+# getxattr
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->getxattr('foo', 'bar');
+};
+like($@, qr/is valid object key/, "get xattr from non-existant nebulous key");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create('foo');
+
+    $neb->getxattr('foo', 'luser.bar');
+};
+like($@, qr/xattr is in user. namespace/, "user. namespace");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create('foo');
+    $neb->getxattr('foo', 'user.bar');
+};
+like($@, qr|xattr neb:///foo:user.bar does not exist|,
+    "get xattr from non-existant xattr key");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->getxattr();
+};
+like($@, qr/2 were expected/, "no params");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create('foo');
+
+    $neb->getxattr('foo');
+};
+like($@, qr/2 were expected/, "too few params");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create('foo');
+
+    $neb->getxattr('foo', 'user.bar', 'baz');
+};
+like($@, qr/2 were expected/, "too many params");
+
 # listxattr
 
@@ -169,8 +217,4 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
     $neb->create('foo');
 
@@ -182,8 +226,4 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
     $neb->create('foo');
 
@@ -192,14 +232,35 @@
 like($@, qr/1 was expected/, "too many params");
 
-# getxattr
-
-Test::Nebulous->setup;
-
-eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->getxattr();
+# removexattr
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->removexattr('foo', 'user.bar');
+};
+like($@, qr/is valid object key/, "remove xattr from non-existant nebulous key");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create('foo');
+
+    $neb->getxattr('foo', 'luser.bar');
+};
+like($@, qr/xattr is in user. namespace/, "user. namespace");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create('foo');
+    $neb->removexattr('foo', 'user.bar');
+};
+like($@, qr|xattr neb:///foo:user.bar does not exist|,
+    "remove xattr from non-existant xattr key");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->removexattr();
 };
 like($@, qr/2 were expected/, "no params");
@@ -208,11 +269,7 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create('foo');
-
-    $neb->getxattr('foo');
+    $neb->create('foo');
+
+    $neb->removexattr('foo');
 };
 like($@, qr/2 were expected/, "too few params");
@@ -221,11 +278,7 @@
 
 eval {
-    my $neb = Nebulous::Client->new(
-        proxy => "http://$hostport/nebulous",
-    );
-
-    $neb->create('foo');
-
-    $neb->getxattr('foo', 'bar', 'baz');
+    $neb->create('foo');
+
+    $neb->removexattr('foo', 'user.bar', 'baz');
 };
 like($@, qr/2 were expected/, "too many params");
Index: branches/pap/Nebulous/t/68_client_chmod.t
===================================================================
--- branches/pap/Nebulous/t/68_client_chmod.t	(revision 25027)
+++ branches/pap/Nebulous/t/68_client_chmod.t	(revision 25027)
@@ -0,0 +1,117 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2009  Joshua Hoblitt
+
+use strict;
+use warnings FATAL => qw( all );
+
+use Apache::Test qw( -withtestmore );
+
+plan tests => 13;
+
+use lib qw( ./t ./lib );
+
+use Nebulous::Client;
+use Nebulous::Util qw( :standard );
+use Test::URI;
+use Test::Nebulous;
+use URI;
+use File::stat;
+
+my $hostport = Apache::Test->config->{ 'hostport' };
+
+my $neb = Nebulous::Client->new(
+    proxy => "http://$hostport/nebulous",
+);
+
+Test::Nebulous->setup;
+
+# object with one instance
+{
+    my $key = "foo";
+    my $uri = $neb->create($key);
+
+    my $path = URI->new($uri)->path;
+    my $st1 = stat($path);
+
+    my $mode = $neb->chmod($key, 0440);
+    my $st2 = stat($path);
+
+    is($st2->mode &07777, 0440, "chmod() single instance");
+    is($mode, 0440, "returned mode");
+    is($neb->getxattr($key, 'user.mode'), 0440, "xattr user.mode");
+}
+
+Test::Nebulous->setup;
+
+# object with two instances
+{
+    my $key = "foo";
+    my $uri1 = $neb->create($key);
+    my $uri2 = $neb->replicate($key);
+
+    my $mode = $neb->chmod($key, 0440);
+
+    my $st1 = stat(URI->new($uri1)->path);
+    my $st2 = stat(URI->new($uri2)->path);
+
+    is($st1->mode &07777, 0440, "chmod() first instance");
+    is($st2->mode &07777, 0440, "chmod() second instance");
+    is($mode, 0440, "returned mode");
+    is($neb->getxattr($key, 'user.mode'), 0440, "xattr user.mode");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $mode = $neb->chmod("foo", 0644);
+
+    is($mode, undef, "object does not exist");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create("foo");
+
+    my $mode = $neb->chmod("foo", 0640);
+
+    is($mode, undef, "mode is not 0440");
+}
+
+Test::Nebulous->setup;
+
+{
+    $neb->create("foo");
+
+    my $mode = $neb->chmod("foo", 999);
+
+    is($mode, undef, "bad mode");
+}
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->chmod();
+};
+like($@, qr/2 were expected/, "no params");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create("foo");
+
+    $neb->chmod("foo");
+};
+like($@, qr/2 were expected/, "one param");
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->create("foo");
+
+    $neb->chmod("foo", 0440, 2);
+};
+like($@, qr/2 were expected/, "three params");
+
+Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/69_client_prune.t
===================================================================
--- branches/pap/Nebulous/t/69_client_prune.t	(revision 25027)
+++ branches/pap/Nebulous/t/69_client_prune.t	(revision 25027)
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2004-2009  Joshua Hoblitt
+
+use strict;
+use warnings FATAL => qw( all );
+
+use Apache::Test qw( -withtestmore );
+
+plan tests => 5;
+
+use lib qw( ./t ./lib );
+
+
+use Nebulous::Client;
+use Nebulous::Util qw( :standard );
+use Test::Nebulous;
+
+my $hostport = Apache::Test->config->{ 'hostport' };
+
+my $neb = Nebulous::Client->new(
+    proxy => "http://$hostport/nebulous",
+);
+
+# note: Test::DBUnit::expected_dataset_ok() does not seem to work under
+# Apache::Test for some reason
+#
+use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS;
+
+Test::Nebulous->setup;
+
+{
+    my $key = "foo";
+    my $uri1 = $neb->create($key, 'node01');
+    my $uri2 = $neb->replicate($key, 'node02');
+
+    # make one of the instances unavailable
+    my $dbh = test_dbh();
+    $dbh->do("UPDATE mountedvol SET available = 0 WHERE name = 'node01'");
+
+    ok($neb->prune($key), "prune object");
+
+    is(scalar @{$neb->find_instances($key)}, 1, "# of instances");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = "foo";
+    my $uri1 = $neb->create($key);
+
+    is($neb->prune($key), 0, "no dead instances to remove");
+}
+
+Test::Nebulous->setup;
+
+eval {
+    $neb->prune();
+};
+like($@, qr/1 was expected/, "no params");
+
+Test::Nebulous->setup;
+
+eval {
+    my $key = "foo";
+    my $uri1 = $neb->create($key);
+
+    $neb->prune("foo", 2);
+};
+like($@, qr/1 was expected/, "too many params");
+
+Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/70_neb-ls.t
===================================================================
--- branches/pap/Nebulous/t/70_neb-ls.t	(revision 23948)
+++ branches/pap/Nebulous/t/70_neb-ls.t	(revision 25027)
@@ -38,4 +38,5 @@
 
 # NEB_SERVER env var not set
+undef $ENV{'NEB_SERVER'} if defined $ENV{'NEB_SERVER'};
 Test::Nebulous->setup;
 
@@ -82,5 +83,5 @@
 
     is($? >> 8, 0, "exit code");
-    like($test->stdout, qr/^foo bar$/,  "stdout");
+    like($test->stdout, qr/^bar\nfoo$/,  "stdout");
     like($test->stderr, qr/^$/,         "stderr");
 }
@@ -98,5 +99,5 @@
 
     is($? >> 8, 0, "exit code");
-    like($test->stdout, qr/^foo\nbar\n$/,   "stdout");
+    like($test->stdout, qr/^bar\nfoo\n$/,   "stdout");
     like($test->stderr, qr/^$/,             "stderr");
 }
@@ -114,5 +115,5 @@
 
     is($? >> 8, 0, "exit code");
-    like($test->stdout, qr/^foo\nbar\n$/,   "stdout");
+    like($test->stdout, qr/^bar\nfoo\n$/,   "stdout");
     like($test->stderr, qr/^$/,             "stderr");
 }
@@ -160,5 +161,5 @@
 
     is($? >> 8, 0, "exit code");
-    like($test->stdout, qr|^a/foo a/bar$|,  "stdout");
+    like($test->stdout, qr|^a/bar\na/foo$|,  "stdout");
     like($test->stderr, qr/^$/,             "stderr");
 }
@@ -192,5 +193,5 @@
 
     is($? >> 8, 0, "exit code");
-    like($test->stdout, qr|^a/foo$|,        "stdout");
+    like($test->stdout, qr|^a/b/\na/foo$|,        "stdout");
     like($test->stderr, qr/^$/,             "stderr");
 }
Index: branches/pap/Nebulous/t/71_client_there_can_be_only_one.t
===================================================================
--- branches/pap/Nebulous/t/71_client_there_can_be_only_one.t	(revision 25027)
+++ branches/pap/Nebulous/t/71_client_there_can_be_only_one.t	(revision 25027)
@@ -0,0 +1,89 @@
+#!/usr/bin/perl
+
+# Copryight (C) 2004-2005  Joshua Hoblitt
+#
+# $Id: 56_client_find_instances.t,v 1.5 2008-09-10 23:50:26 bills Exp $
+
+use strict;
+use warnings FATAL => qw( all );
+
+use Apache::Test qw( -withtestmore );
+
+plan tests => 8;
+
+use lib qw( ./t ./lib );
+
+use Nebulous::Client;
+use Nebulous::Util qw( :standard );
+use Test::Nebulous;
+
+my $hostport = Apache::Test->config->{ 'hostport' };
+
+Test::Nebulous->setup;
+
+{
+    my $key = "foo";
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->create($key);
+    $neb->replicate($key,);
+
+    is($neb->there_can_be_only_one($key), 1, "there can be only one!");
+
+    my $locations = $neb->find_instances( "foo" );
+
+    is( scalar @$locations, 1, "found 1" );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = "foo";
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->create($key, "node01");
+    my $uri = $neb->replicate($key, "node02");
+
+    is($neb->there_can_be_only_one($key, "node02"), 1, "there can be only one!");
+
+    my $locations = $neb->find_instances( "foo" );
+
+    is( scalar @$locations, 1, "found 1" );
+    is($locations->[0], $uri, "instance on correct volume" );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    is( $neb->there_can_be_only_one( "foo" ), undef, "storage object does not exist" );
+}
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    $neb->there_can_be_only_one();
+};
+like( $@, qr/1 - 2 were expected/, "no params" );
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+
+    $neb->there_can_be_only_one( "foo", 'read', 3 );
+};
+like( $@, qr/1 - 2 were expected/, "too many params" );
+
+Test::Nebulous->cleanup;
Index: branches/pap/Nebulous/t/72_neb-cull.t
===================================================================
--- branches/pap/Nebulous/t/72_neb-cull.t	(revision 25027)
+++ branches/pap/Nebulous/t/72_neb-cull.t	(revision 25027)
@@ -0,0 +1,181 @@
+#!/usr/bin/env perl
+
+# Copyright (C) 2009  Joshua Hoblitt
+
+=head1 NAME
+
+t/72_neb-cull.t - tests neb-cull
+
+=head1 SYNOPSIS
+    
+    prove t/72_neb-cull.t
+
+=cut
+
+use strict;
+use warnings;
+
+use Apache::Test qw( -withtestmore );
+plan tests => 29;
+
+use lib qw( ./lib ./t );
+
+use Test::Cmd;
+use Nebulous::Client;
+use Test::Nebulous;
+
+my $hostport = Apache::Test->config->{ 'hostport' };
+my $neb_url  = "http://$hostport/nebulous";
+
+
+my $cmd = 'bin/neb-cull';
+
+# last ditch effort to make sure $cmd executable
+chmod 0755, $cmd;
+
+my $test = Test::Cmd->new(prog => $cmd, workdir => '');
+isa_ok($test, 'Test::Cmd');
+
+# NEB_SERVER env var not set
+undef $ENV{'NEB_SERVER'} if defined $ENV{'NEB_SERVER'};
+Test::Nebulous->setup;
+
+{
+    $test->run(args => '');
+    missing_args(2, "Required options: --server");
+}
+
+# NEB_SERVER set
+Test::Nebulous->setup;
+
+{
+    $ENV{NEB_SERVER} = $neb_url;
+
+    $test->run(args => '');
+    missing_args(2, "missing key operand");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = 'foo';
+
+    my $neb = Nebulous::Client->new(
+        proxy => $neb_url,
+    );
+    $neb->create($key);
+
+    $test->run(args => $key);
+
+    is($neb->stat($key)->[6], 1, "correct # of instances");
+    is($? >> 8, 255, "exit code");
+    like($test->stdout, qr/^$/, "stdout");
+    like($test->stderr, qr/not enough instances/, "stderr");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = 'foo';
+
+    my $neb = Nebulous::Client->new(
+        proxy => $neb_url,
+    );
+    $neb->create($key);
+    $neb->replicate($key);
+
+    $test->run(args => $key);
+
+    is($neb->stat($key)->[6], 1, "correct # of instances");
+    is($? >> 8, 0, "exit code");
+    like($test->stdout, qr/^$/, "stdout");
+    like($test->stderr, qr/^$/, "stderr");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = 'foo';
+
+    my $neb = Nebulous::Client->new(
+        proxy => $neb_url,
+    );
+    $neb->create($key);
+    $neb->replicate($key);
+    $neb->replicate($key);
+
+    $test->run(args => $key);
+
+    is($neb->stat($key)->[6], 2, "correct # of instances");
+    is($? >> 8, 0, "exit code");
+    like($test->stdout, qr/^$/, "stdout");
+    like($test->stderr, qr/^$/, "stderr");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = 'foo';
+
+    my $neb = Nebulous::Client->new(
+        proxy => $neb_url,
+    );
+    $neb->create($key);
+
+    $test->run(args => "--one_only " . $key);
+
+    is($neb->stat($key)->[6], 1, "correct # of instances");
+    is($? >> 8, 255, "exit code");
+    like($test->stdout, qr/^$/, "stdout");
+    like($test->stderr, qr/not enough instances/, "stderr");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = 'foo';
+
+    my $neb = Nebulous::Client->new(
+        proxy => $neb_url,
+    );
+    $neb->create($key);
+    $neb->replicate($key);
+
+    $test->run(args => "--one_only " . $key);
+
+    is($neb->stat($key)->[6], 1, "correct # of instances");
+    is($? >> 8, 0, "exit code");
+    like($test->stdout, qr/^$/, "stdout");
+    like($test->stderr, qr/^$/, "stderr");
+}
+
+Test::Nebulous->setup;
+
+{
+    my $key = 'foo';
+
+    my $neb = Nebulous::Client->new(
+        proxy => $neb_url,
+    );
+    $neb->create($key);
+    $neb->replicate($key);
+    $neb->replicate($key);
+
+    $test->run(args => "--one_only " . $key);
+
+    is($neb->stat($key)->[6], 1, "correct # of instances");
+    is($? >> 8, 0, "exit code");
+    like($test->stdout, qr/^$/, "stdout");
+    like($test->stderr, qr/^$/, "stderr");
+}
+
+
+Test::Nebulous->cleanup;
+
+sub missing_args
+{
+    my ($exit, $errstr) = @_;
+
+    is($? >> 8, $exit, "error code is: $exit");
+    like($test->stderr, qr/$errstr/, "error string is: $errstr");
+}
Index: branches/pap/Nebulous/t/conf/startup.pl.in
===================================================================
--- branches/pap/Nebulous/t/conf/startup.pl.in	(revision 23948)
+++ branches/pap/Nebulous/t/conf/startup.pl.in	(revision 25027)
@@ -18,4 +18,5 @@
 my $config = Nebulous::Server::Config->new(
     trace       => 'all',
+    memcached_servers => ['127.0.0.1:11211'],
 );
 $config->add_db(
