diff --git a/base/inc/TSystem.h b/base/inc/TSystem.h
index a3b02582d60e78ed0f61ee653beb6d5908de99c9..ae101ab46cc3b73593d111d2ffa9b796344c55de 100644
--- a/base/inc/TSystem.h
+++ b/base/inc/TSystem.h
@@ -1,4 +1,4 @@
-// @(#)root/base:$Name:  $:$Id: TSystem.h,v 1.57 2006/07/04 17:36:37 brun Exp $
+// @(#)root/base:$Name:  $:$Id: TSystem.h,v 1.58 2006/09/04 00:45:02 rdm Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -103,6 +103,7 @@ enum EFileModeMask {
    kS_IFMT   = 0170000,   // bitmask for the file type bitfields
    kS_IFSOCK = 0140000,   // socket
    kS_IFLNK  = 0120000,   // symbolic link
+   kS_IFOFF  = 0110000,   // offline file
    kS_IFREG  = 0100000,   // regular file
    kS_IFBLK  = 0060000,   // block device
    kS_IFDIR  = 0040000,   // directory
@@ -132,6 +133,7 @@ inline Bool_t R_ISREG(Int_t mode)  { return ((mode & kS_IFMT) == kS_IFREG); }
 inline Bool_t R_ISLNK(Int_t mode)  { return ((mode & kS_IFMT) == kS_IFLNK); }
 inline Bool_t R_ISFIFO(Int_t mode) { return ((mode & kS_IFMT) == kS_IFIFO); }
 inline Bool_t R_ISSOCK(Int_t mode) { return ((mode & kS_IFMT) == kS_IFSOCK); }
+inline Bool_t R_ISOFF(Int_t mode)  { return ((mode & kS_IFMT) == kS_IFOFF); }
 
 struct FileStat_t {
    Long_t   fDev;          // device id
diff --git a/netx/inc/TXNetSystem.h b/netx/inc/TXNetSystem.h
index 6f24873e8754b3677e4142d0d06231ca8c0162e2..d0b61d02ab00952b55fd32deefa48fabd953acf1 100644
--- a/netx/inc/TXNetSystem.h
+++ b/netx/inc/TXNetSystem.h
@@ -1,4 +1,4 @@
-// @(#)root/netx:$Name:  $:$Id: TXNetSystem.h,v 1.3 2006/03/16 09:08:08 rdm Exp $
+// @(#)root/netx:$Name:  $:$Id: TXNetSystem.h,v 1.4 2006/06/30 14:35:03 rdm Exp $
 // Author: Frank Winklmeier, Fabrizio Furano
 
 /*************************************************************************
@@ -37,6 +37,7 @@
 #include "XrdClient/XrdClientVector.hh"
 
 class XrdClientAdmin;
+class TXNetSystemConnectGuard;
 
 typedef XrdClientVector<XrdOucString> vecString;
 typedef XrdClientVector<bool>         vecBool;
@@ -44,18 +45,21 @@ typedef XrdClientVector<bool>         vecBool;
 
 class TXNetSystem : public TNetSystem {
 
+friend class TXNetSystemConnectGuard;
+
 private:
-   XrdClientAdmin *fClientAdmin;  // Handle to the client admin object
    Bool_t          fIsRootd;      // Nature of remote file server
    Bool_t          fIsXRootd;     // Nature of remote file server
    TString         fDir;          // Current directory
    void           *fDirp;         // Directory pointer
    vecString       fDirList;      // Buffer for directory content
    Bool_t          fDirListValid; // fDirList content valid ?
+   TString         fUrl;          // Initial url
 
    static Bool_t   fgInitDone;    // Avoid initializing more than once
    static Bool_t   fgRootdBC;     // Control rootd backward compatibility
 
+   XrdClientAdmin *Connect(const char *url); // Connect to server
    void           *GetDirPtr() const { return fDirp; }
    void            InitXrdClient();
    void            SaveEndPointUrl();
@@ -72,8 +76,27 @@ public:
    virtual Int_t       GetPathInfo(const char* path, FileStat_t &buf);
    virtual Int_t       MakeDirectory(const char* dir);
    virtual void       *OpenDirectory(const char* dir);
+   virtual int         Unlink(const char *path);
 
    ClassDef(TXNetSystem,0)   // System management class for xrootd servers
 };
 
+//
+// Simple guard class for connections
+//
+class TXNetSystemConnectGuard {
+
+private:
+   XrdClientAdmin *fClientAdmin;  // Handle to the client admin object
+
+public:
+   TXNetSystemConnectGuard(TXNetSystem *xn, const char *url);
+   ~TXNetSystemConnectGuard();
+
+   bool IsValid() const { return ((fClientAdmin) ? 1 : 0); } 
+
+   XrdClientAdmin *ClientAdmin() const { return fClientAdmin; }
+
+};
+
 #endif
diff --git a/netx/src/TXNetSystem.cxx b/netx/src/TXNetSystem.cxx
index 80db4aa0f0b502cc5d5f220aa4bab8c4e3a1f2c2..8b0fb3f1a59a50d37fdc606ac13c0875402cf0d6 100644
--- a/netx/src/TXNetSystem.cxx
+++ b/netx/src/TXNetSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/netx:$Name:  $:$Id: TXNetSystem.cxx,v 1.12 2006/06/30 14:36:02 rdm Exp $
+// @(#)root/netx:$Name:  $:$Id: TXNetSystem.cxx,v 1.13 2006/09/29 08:17:21 rdm Exp $
 // Author: Frank Winklmeier, Fabrizio Furano
 
 /*************************************************************************
@@ -48,11 +48,11 @@ TXNetSystem::TXNetSystem(Bool_t owner) : TNetSystem(owner)
    // Create system management class without connecting to server.
 
    SetTitle("(x)rootd system administration");
-   fClientAdmin = 0;
    fIsXRootd = kFALSE;
    fDir = "";
    fDirp = 0;
    fDirListValid = kFALSE;
+   fUrl = "";
 }
 
 //_____________________________________________________________________________
@@ -66,6 +66,7 @@ TXNetSystem::TXNetSystem(const char *url, Bool_t owner) : TNetSystem(owner)
    fDir = "";
    fDirp = 0;
    fDirListValid = kFALSE;
+   fUrl = url;
 
    // Set debug level
    EnvPutInt(NAME_DEBUG, gEnv->GetValue("XNet.Debug", -1));
@@ -77,25 +78,41 @@ TXNetSystem::TXNetSystem(const char *url, Bool_t owner) : TNetSystem(owner)
    // Fill in user, host, port
    TNetSystem::InitRemoteEntity(url);
 
+   TXNetSystemConnectGuard cguard(this, url);
+   if (!cguard.IsValid()) {
+      Error("TXNetSystem","fatal error: connection creation failed.");
+      gSystem->Abort();
+   }
+
+   return;
+}
+
+//_____________________________________________________________________________
+XrdClientAdmin *TXNetSystem::Connect(const char *url)
+{
+   // Init a connection to the server.
+   // Returns a pointer to the appropriate instance of XrdClientAdmin or 0
+   // in case of failure.
+
    // We need a dummy filename after the server url to connect
    TString dummy = url;
    dummy += "/dummy";
 
-   fClientAdmin = new XrdClientAdmin(dummy);
+   XrdClientAdmin *cadm = new XrdClientAdmin(dummy);
 
-   if (!fClientAdmin) {
-      Error("TXNetSystem","fatal error: new object creation failed.");
-      gSystem->Abort();
+   if (!cadm) {
+      Error("Connect","fatal error: new object creation failed.");
+      return cadm;
    }
 
    // Try to connect to the server
-   if (fClientAdmin->Connect()) {
+   if (cadm->Connect()) {
       fIsXRootd = kTRUE;
    } else {
       if (fgRootdBC) {
          Bool_t isRootd =
-            (fClientAdmin->GetClientConn()->GetServerType() == kSTRootd);
-         Int_t sd = fClientAdmin->GetClientConn()->GetOpenSockFD();
+            (cadm->GetClientConn()->GetServerType() == kSTRootd);
+         Int_t sd = cadm->GetClientConn()->GetOpenSockFD();
          if (isRootd && sd > -1) {
             //
             // Create a TSocket on the open connection
@@ -111,16 +128,17 @@ TXNetSystem::TXNetSystem(const char *url, Bool_t owner) : TNetSystem(owner)
             Int_t rproto = TXNetFile::GetRootdProtocol(s);
             if (rproto < 0) {
                Error("TXNetSystem", "getting protocol of the rootd server");
-               return;
+               delete cadm;
+               return 0;
             }
             // Finalize TSocket initialization
             s->SetRemoteProtocol(rproto);
-            TUrl uut((fClientAdmin->GetClientConn()
+            TUrl uut((cadm->GetClientConn()
                              ->GetCurrentUrl()).GetUrl().c_str());
             TString uu;
             TXNetFile::FormUrl(uut,uu);
             if (gDebug > 2)
-               Info("TXNetSystem"," url: %s",uu.Data());
+               Info("Connect"," url: %s",uu.Data());
 
             s->SetUrl(uu.Data());
             s->SetService("rootd");
@@ -142,31 +160,29 @@ TXNetSystem::TXNetSystem(const char *url, Bool_t owner) : TNetSystem(owner)
             // Type of server
             fIsRootd = kTRUE;
 
+            delete cadm;
+
          } else {
-            Error("TXNetSystem", "some severe error occurred while opening"
+            Error("Connect", "some severe error occurred while opening"
                   " the connection at %s - exit", url);
-            return;
+            delete cadm;
+            return cadm;
          }
       } else {
-         Error("TXNetSystem",
+         Error("Connect",
                "while opening the connection at %s - exit", url);
-         return;
+         delete cadm;
+         return cadm;
       }
    }
 
-   return;
+   return cadm;
 }
 
 //_____________________________________________________________________________
 TXNetSystem::~TXNetSystem()
 {
    // Destructor
-
-#ifndef WIN32 
-   // pthread locking problem on windows at exit time...
-   if (fIsXRootd && fClientAdmin)
-      delete fClientAdmin;
-#endif
 }
 
 
@@ -184,18 +200,7 @@ void TXNetSystem::InitXrdClient()
    // Print the tag, if required (only once)
    if (gEnv->GetValue("XNet.PrintTAG",0) == 1)
      Info("TXNetFile","(C) 2005 SLAC TXNetSystem (eXtended TNetSystem) %s",
-	  gROOT->GetVersion());
-}
-
-//_____________________________________________________________________________
-void TXNetSystem::SaveEndPointUrl()
-{
-   // Save the end-point user, host, port
-
-   if (fClientAdmin->GetClientConn()) {
-      XrdClientUrlInfo eurl = fClientAdmin->GetClientConn()->GetCurrentUrl();
-      TNetSystem::InitRemoteEntity(eurl.GetUrl().c_str());
-   }
+         gROOT->GetVersion());
 }
 
 //_____________________________________________________________________________
@@ -205,20 +210,22 @@ void* TXNetSystem::OpenDirectory(const char* dir)
    // purpose) in case of success, 0 in case of error.
 
    if (fIsXRootd) {
-      // Extract the directory name
-      fDir = TUrl(dir).GetFile();
-      fDirp = (void*)&fDir;     // serves as directory pointer
-
-      vecString dirs;
-      vecBool existDirs;
-      XrdOucString s(fDir.Data());
-      dirs.Push_back(s);
       // Check if the directory exists
-      fClientAdmin->ExistDirs(dirs,existDirs);
-      // Save the end-point user, host, port
-      SaveEndPointUrl();
-      if (existDirs.GetSize()>0 && existDirs[0])
-         return fDirp;
+      TXNetSystemConnectGuard cg(this, dir);
+      if (cg.IsValid()) {
+         fUrl = dir;
+         // Extract the directory name
+         fDir = TUrl(dir).GetFile();
+         fDirp = (void*)&fDir;     // serves as directory pointer
+
+         vecString dirs;
+         vecBool existDirs;
+         XrdOucString s(fDir.Data());
+         dirs.Push_back(s);
+         cg.ClientAdmin()->ExistDirs(dirs, existDirs);
+         if (existDirs.GetSize()>0 && existDirs[0])
+            return fDirp;
+      }
       return 0;
    }
 
@@ -254,14 +261,16 @@ Int_t TXNetSystem::MakeDirectory(const char* dir)
    // Create a directory. Return 0 on success, -1 otherwise.
 
    if (fIsXRootd) {
-      // use default permissions 755 to create directory
-      Bool_t ok = fClientAdmin->Mkdir(TUrl(dir).GetFile(),7,5,5);
-      // Save the end-point user, host, port
-      SaveEndPointUrl();
-      return (ok ? 0 : -1);
+      TXNetSystemConnectGuard cg(this, dir);
+      if (cg.IsValid()) {
+         // use default permissions 755 to create directory
+         Bool_t ok = cg.ClientAdmin()->Mkdir(TUrl(dir).GetFile(),7,5,5);
+         return (ok ? 0 : -1);
+      }
    }
 
-   if (gDebug > 1) Info("MakeDirectory","Calling TNetSystem::MakeDirectory");
+   if (gDebug > 1)
+      Info("MakeDirectory","Calling TNetSystem::MakeDirectory");
    return TNetSystem::MakeDirectory(dir);     // for a rootd
 }
 
@@ -279,13 +288,14 @@ const char* TXNetSystem::GetDirEntry(void *dirp)
 
       // Only request new directory listing the first time called
       if (!fDirListValid) {
-         Bool_t ok = fClientAdmin->DirList(fDir,fDirList);
-         // Save the end-point user, host, port
-         SaveEndPointUrl();
-         if (ok)
-            fDirListValid = kTRUE;
-         else
-            return 0;
+         TXNetSystemConnectGuard cg(this, fUrl);
+         if (cg.IsValid()) {
+            Bool_t ok = cg.ClientAdmin()->DirList(fDir, fDirList);
+            if (ok)
+               fDirListValid = kTRUE;
+            else
+               return 0;
+         }
       }
 
       // Return entries one by one with each call of method
@@ -309,38 +319,39 @@ Int_t TXNetSystem::GetPathInfo(const char* path, FileStat_t &buf)
 
    if (fIsXRootd) {
 
-      Long_t id;
-      Long64_t size;
-      Long_t flags;
-      Long_t modtime;
-
-      // Extract the directory name
-      TString edir = TUrl(path).GetFile();
-      Bool_t ok = fClientAdmin->Stat(edir,id,size,flags,modtime);
-
-      // Save the end-point user, host, port
-      SaveEndPointUrl();
-
-      // Count offline files as inexistent 
-      ok &= !(flags & kXR_offline);
-
-      if (ok) {
-         buf.fDev = (id >> 24);
-         buf.fIno = (id && 0x00FFFFFF);
-         buf.fUid = -1;       // not all information available in xrootd
-         buf.fGid = -1;       // not available
-         buf.fSize = size;
-         buf.fMtime = modtime;
-
-         if (flags == 0) buf.fMode = kS_IFREG;
-         if (flags & kXR_xset) buf.fMode = (kS_IFREG|kS_IXUSR|kS_IXGRP|kS_IXOTH);
-         if (flags & kXR_isDir) buf.fMode = kS_IFDIR;
-         if (flags & kXR_other) buf.fMode = kS_IFSOCK;
-         if (flags & kXR_readable) buf.fMode |= kS_IRUSR;
-         if (flags & kXR_writable) buf.fMode |= kS_IWUSR;
-
-         buf.fIsLink = 0;     // not available
-         return 0;
+      TXNetSystemConnectGuard cg(this, path);
+      if (cg.IsValid()) {
+
+         Long_t id;
+         Long64_t size;
+         Long_t flags;
+         Long_t modtime;
+
+         // Extract the directory name
+         TString edir = TUrl(path).GetFile();
+         Bool_t ok = cg.ClientAdmin()->Stat(edir.Data(),id,size,flags,modtime);
+
+         // Flag offline files
+         if (flags & kXR_offline) {
+            buf.fMode = kS_IFOFF;
+         } else if (ok) {
+            buf.fDev = (id >> 24);
+            buf.fIno = (id && 0x00FFFFFF);
+            buf.fUid = -1;       // not all information available in xrootd
+            buf.fGid = -1;       // not available
+            buf.fSize = size;
+            buf.fMtime = modtime;
+
+            if (flags == 0) buf.fMode = kS_IFREG;
+            if (flags & kXR_xset) buf.fMode = (kS_IFREG|kS_IXUSR|kS_IXGRP|kS_IXOTH);
+            if (flags & kXR_isDir) buf.fMode = kS_IFDIR;
+            if (flags & kXR_other) buf.fMode = kS_IFSOCK;
+            if (flags & kXR_readable) buf.fMode |= kS_IRUSR;
+            if (flags & kXR_writable) buf.fMode |= kS_IWUSR;
+
+            buf.fIsLink = 0;     // not available
+            return 0;
+         }
       }
       return 1;
    }
@@ -360,9 +371,6 @@ Bool_t TXNetSystem::ConsistentWith(const char *path, void *dirptr)
       Info("ConsistenWith",
            "Calling TNetSystem::ConsistenWith for path: %s, dir: %p", path, dirptr);
 
-   // Save the end-point user, host, port
-   SaveEndPointUrl();
-
    return TNetSystem::ConsistentWith(path,dirptr);    // for a rootd
 }
 
@@ -389,3 +397,66 @@ Bool_t TXNetSystem::AccessPathName(const char *path, EAccessMode mode)
       Info("AccessPathName", "calling TNetSystem::AccessPathName");
    return TNetSystem::AccessPathName(path,mode);    // for a rootd
 }
+
+//_____________________________________________________________________________
+int TXNetSystem::Unlink(const char *path)
+{
+   // Unlink 'path' on the remote server system.
+   // Returns 0 on success, -1 otherwise.
+
+   if (fIsXRootd) {
+
+      TXNetSystemConnectGuard cg(this, path);
+      if (cg.IsValid()) {
+
+         Long_t id;
+         Long64_t size;
+         Long_t flags;
+         Long_t modtime;
+
+         // Extract the directory name
+         TString edir = TUrl(path).GetFile();
+         Bool_t ok = cg.ClientAdmin()->Stat(edir.Data(), id, size, flags, modtime);
+
+         // Flag offline files
+         if (ok && !(flags & kXR_offline)) {
+            if (flags & kXR_isDir)
+               ok = cg.ClientAdmin()->Rmdir(edir.Data());
+            else
+               ok = cg.ClientAdmin()->Rm(edir.Data());
+
+            // Done
+            return ((ok) ? 0 : -1);
+         }
+      }
+   }
+
+   if (gDebug > 1)
+      Info("AccessPathName", "calling TNetSystem::AccessPathName");
+   return -1;    // not implemented for rootd
+}
+
+
+//
+// Guard methods
+//
+//_____________________________________________________________________________
+TXNetSystemConnectGuard::TXNetSystemConnectGuard(TXNetSystem *xn, const char *url)
+                        : fClientAdmin(0)
+{
+   // Construct a guard object
+
+    if (xn)
+       // Connect
+       fClientAdmin = xn->Connect(url);
+}
+
+//_____________________________________________________________________________
+TXNetSystemConnectGuard::~TXNetSystemConnectGuard()
+{
+   // Destructor: close the connection
+
+   if (fClientAdmin)
+      delete fClientAdmin;
+}
+
diff --git a/unix/src/TUnixSystem.cxx b/unix/src/TUnixSystem.cxx
index bdcd63c3b749df14f95f82e2167c9d82019ba7c2..d0e110a9672c81a9eb8cb3865348464dab85badf 100644
--- a/unix/src/TUnixSystem.cxx
+++ b/unix/src/TUnixSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/unix:$Name:  $:$Id: TUnixSystem.cxx,v 1.157 2006/09/04 00:45:03 rdm Exp $
+// @(#)root/unix:$Name:  $:$Id: TUnixSystem.cxx,v 1.158 2006/10/03 13:29:25 rdm Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -1332,6 +1332,10 @@ int TUnixSystem::Unlink(const char *name)
    // Unlink, i.e. remove, a file or directory. Returns 0 when succesfull,
    // -1 in case of failure.
 
+   TSystem *helper = FindHelper(name);
+   if (helper)
+      return helper->Unlink(name);
+
    struct stat finfo;
    if (lstat(name, &finfo) < 0)
       return -1;
diff --git a/winnt/src/TWinNTSystem.cxx b/winnt/src/TWinNTSystem.cxx
index 17395aaa8e4da87b1325acfdec2264bafc768175..cdf2d3feeeffe7c5343a5703a39fa0ff22cef255 100644
--- a/winnt/src/TWinNTSystem.cxx
+++ b/winnt/src/TWinNTSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/winnt:$Name:  $:$Id: TWinNTSystem.cxx,v 1.146 2006/09/04 00:45:03 rdm Exp $
+// @(#)root/winnt:$Name:  $:$Id: TWinNTSystem.cxx,v 1.147 2006/09/28 11:37:26 rdm Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -2245,6 +2245,10 @@ int TWinNTSystem::Unlink(const char *name)
 {
    // Unlink, i.e. remove, a file or directory.
 
+   TSystem *helper = FindHelper(name);
+   if (helper)
+      return helper->Unlink(name);
+
    struct _stati64 finfo;
 
    if (_stati64(name, &finfo) < 0) {