diff --git a/proof/proof/src/TProofMgr.cxx b/proof/proof/src/TProofMgr.cxx
index 5928c129b1c1d82e7927f4f656b426995ac40210..38d69da8ab81e05a75c68ad58ebc1c93c7817585 100644
--- a/proof/proof/src/TProofMgr.cxx
+++ b/proof/proof/src/TProofMgr.cxx
@@ -33,6 +33,7 @@
 #include "TProofMgrLite.h"
 #include "TSocket.h"
 #include "TROOT.h"
+#include "TMath.h"
 
 ClassImp(TProofMgr)
 
@@ -779,9 +780,15 @@ TFileCollection *TProofMgr::UploadFiles(TList *src,
    //      <d0>, <d1>, <d2>, ...         referring to the n-th sub-component
    //                                    of the src path
    //      <bn>                          basename in the source path
+   //      <bs>                          basename sans extension
+   //      <ex>                          Extension 
    //      <sn>                          serial number of file in the list
+   //      <s0>                          as <sn> but zero padded
    //      <fn>                          the full file path
    //      <us>, <gr>                    the local user and group names.
+   //      <pg>                          the users PROOF group
+   //      <pa>                          immediate parent directory
+   //      <gp>                          next-to immediate parent directory
    // So, for example, if the source filename for the 99-th file is
    //               protosrc://host//d0/d1/d2/d3/d4/d5/myfile
    // then with dest = '/pool/user/<d3>/<d4>/<d5>/<s>/<bn>' and 
@@ -828,6 +835,9 @@ TFileCollection *TProofMgr::UploadFiles(TList *src,
       }
       dirph.SetOwner(kTRUE);
    }
+   // Generate template for zero-padded serial numbers 
+   TString sForm = TString::Format("%%0%dd", 
+				   Int_t(TMath::Log10(src->GetEntries()+1)));
 
    // Now we will actually copy files and create the TList object
    ds = new TFileCollection();
@@ -874,11 +884,47 @@ TFileCollection *TProofMgr::UploadFiles(TList *src,
          // Replace filename and basename
          if (fdst.Contains("<bn>")) fdst.ReplaceAll("<bn>", gSystem->BaseName(furl->GetFile()));
          if (fdst.Contains("<fn>")) fdst.ReplaceAll("<fn>", furl->GetFile());
+	 if (fdst.Contains("<bs>")) { 
+	   // Basename sans 'extension' 
+	   TString bs(gSystem->BaseName(furl->GetFile()));
+	   Int_t idx = bs.Last('.');
+	   if (idx != kNPOS) bs.Remove(idx);
+	   fdst.ReplaceAll("<bs>", bs.Data());
+	 }
+	 if (fdst.Contains("<ex>")) { 
+	   // 'Extension' - that is the last part after the last '.'
+	   TString ex(furl->GetFile());
+	   Int_t idx = ex.Last('.');
+	   if (idx != kNPOS) ex.Remove(0, idx+1);
+	   else                       ex = "";
+	   fdst.ReplaceAll("<ex>", ex);
+	 }
+	 if (fdst.Contains("<pa>")) { 
+	   fdst.ReplaceAll("<pa>", 
+			   gSystem->BaseName(gSystem
+					     ->DirName(furl->GetFile())));
+	   
+	 }
+	 if (fdst.Contains("<gp>")) { 
+	   fdst.ReplaceAll("<gp>", 
+			   gSystem->BaseName(gSystem
+					     ->DirName(gSystem
+						       ->DirName(furl->GetFile()))));
+	   
+	 }
+	 
+
+         // Replace serial number         
+         if (fdst.Contains("<sn>")) {
+	   TString skn = TString::Format("%d", kn);
+	   fdst.ReplaceAll("<sn>", skn);
+         }
+	 if (fdst.Contains("<s0>")) { 
+	   TString skn = TString::Format(sForm.Data(), kn);
+	   fdst.ReplaceAll("<s0>", skn);
+	 }
+	 kn++;
 
-         // Replace serial number
-         TString skn = TString::Format("%d", kn++);
-         if (fdst.Contains("<sn>")) fdst.ReplaceAll("<sn>", skn);
-         
          // Replace user and group name
          UserGroup_t *pw = gSystem->GetUserInfo();
          if (pw) {
@@ -886,6 +932,8 @@ TFileCollection *TProofMgr::UploadFiles(TList *src,
             if (fdst.Contains("<gr>")) fdst.ReplaceAll("<gr>", pw->fGroup);
             delete pw;
          }
+	 if (gProof && fdst.Contains("<pg>")) 
+	   fdst.ReplaceAll("<pg>", gProof->GetGroup());
 
          // Now replace the subdirs, if required
          if (dirph.GetSize() > 0)