Index: src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamLabel.java
===================================================================
--- src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamLabel.java	(revision 750390)
+++ src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamLabel.java	(working copy)
@@ -1,11 +1,10 @@
 /*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
+ * Copyright  2001-2004 The Apache Software Foundation
  *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
@@ -38,8 +37,7 @@
  * starteamurl="server:port/project/view"/&gt;
  * </pre>
  *
-  * @see <a href="http://www.borland.com/us/products/starteam/index.html"
-  * >borland StarTeam Web Site</a>
+ * @see <A HREF="http://www.starbase.com/">StarBase Web Site</A>
  *
  * @ant.task name="stlabel" category="scm"
  */
@@ -79,16 +77,14 @@
 
 
     /**
-     * The name to be given to the label; required.
-     * @param label the name to be used
-     */
+    * The name to be given to the label; required.
+    */
     public void setLabel(String label) {
         this.labelName = label;
     }
 
     /**
      * Description of the label to be stored in the StarTeam project.
-     * @param description the description to be used
      */
     public void setDescription(String description) {
         this.description = description;
@@ -121,8 +117,6 @@
     /**
      * The timestamp of the build that will be stored with the label; required.
      * Must be formatted <code>yyyyMMddHHmmss</code>
-     * @param lastbuild the timestamp of the last build
-     * @throws BuildException on error
      */
     public void setLastBuild(String lastbuild) throws BuildException {
         try {
@@ -137,7 +131,7 @@
     /**
      * This method does the work of creating the new view and checking it into
      * Starteam.
-     * @throws BuildException on error
+     *
      */
     public void execute() throws BuildException {
 
@@ -166,6 +160,7 @@
                 log("Created View Label ("
                     + (this.buildlabel ? "" : "non-") + "build) " + this.labelName);
             }
+            snapshot.close(); //Free up server resources
         } catch (Exception e) {
             throw new BuildException(e);
         } finally {
Index: src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java
===================================================================
--- src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java	(revision 750390)
+++ src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java	(working copy)
@@ -17,12 +17,7 @@
  */
 package org.apache.tools.ant.taskdefs.optional.starteam;
 
-import com.starbase.starteam.Folder;
-import com.starbase.starteam.Label;
-import com.starbase.starteam.PropertyNames;
-import com.starbase.starteam.StarTeamFinder;
-import com.starbase.starteam.View;
-import com.starbase.starteam.ViewConfiguration;
+import com.starbase.starteam.*;
 import com.starbase.util.OLEDate;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -137,7 +132,9 @@
      */
     private String asOfDateFormat = null;
 
+	private String promotionState;
 
+	private PromotionState promotionStateInUse;
 
     ///////////////////////////////////////////////////////////////
     // GET/SET methods.
@@ -286,6 +283,21 @@
         }
     }
 
+    /**
+     * protected function to allow subclasses to set the promotion state (or not).
+     * sets the StarTeam promotion state
+     *
+     * @param label name of the StarTeam label to be set
+     */
+    protected void _setPromotionState(String promotionState) {
+        if (null != promotionState) {
+            promotionState = promotionState.trim();
+            if (promotionState.length() > 0) {
+                this.promotionState = promotionState;
+            }
+        }
+    }
+    
     // CheckStyle:MethodNameCheck OFF - bc
 
     /**
@@ -401,6 +413,15 @@
     protected String getLabel() {
         return this.label;
     }
+    
+    /**
+     * return the promotion state passed to the task by the user as a string
+     *
+     * @return the promotion state passed to the task by the user as a string
+     */
+    protected String getPromotionState() {
+        return this.promotionState;
+    }    
 
     /**
      * Get the value of recursive.
@@ -468,6 +489,15 @@
     }
 
     /**
+     *  returns true if a valid promotionState has been specified
+     *
+     * @return  true if a valid promotionState has been specified
+     */
+    protected boolean isUsingPromotionState() {
+        return null != this.promotionStateInUse;
+    }
+    
+    /**
      *  returns true if a label has been specified and it is a revision label.
      *
      * @return  true if a label has been specified and it is a revision label
@@ -486,6 +516,15 @@
     }
 
     /**
+     * returns the promotionState being used
+     *
+     * @return the promotionState being used
+     */
+    protected PromotionState getPromotionStateInUse() {
+        return this.promotionStateInUse;
+    }
+    
+    /**
      * show the label in the log and its type.
      */
     protected void logLabel() {
@@ -497,6 +536,15 @@
     }
 
     /**
+     * show the promotion state in the log
+     */
+    protected void logPromotionState() {
+        if (this.isUsingPromotionState()) {
+            log("  Using promotion state " + getPromotionState());
+        }
+    }
+    
+    /**
      * show the asofDate in the log
      * @since Ant 1.6
      */
@@ -675,6 +723,8 @@
 
             // Inspect everything in the root folder and then recursively
             visit(starteamrootfolder, localrootfolder);
+            
+            starteamrootfolder.getView().close(); //Free up server resources
 
         } catch (Exception e) {
             throw new BuildException(e);
@@ -684,26 +734,13 @@
     }
 
     private void findLabel(View v) throws BuildException {
-        Label[] allLabels = v.getLabels();
-        for (int i = 0; i < allLabels.length; i++) {
-            Label stLabel = allLabels[i];
-            log("checking label " + stLabel.getName(), Project.MSG_DEBUG);
-            if (stLabel != null && !stLabel.isDeleted() && stLabel.getName().equals(this.label)) {
-                if (!stLabel.isRevisionLabel() && !stLabel.isViewLabel()) {
-                    throw new BuildException("Unexpected label type.");
-                }
-                log("using label " + stLabel.getName(), Project.MSG_VERBOSE);
-                this.labelInUse = stLabel;
-                return;
-            }
-        }
-        throw new BuildException("Error: label "
-                + this.label
-                + " does not exist in view "
-                + v.getFullName());
+        this.labelInUse = findLabel(v, this.label);
+    }
 
+	private void findPromotionState(View v) throws BuildException {
+        this.promotionStateInUse = findPromotionState(v, this.promotionState); 
     }
-
+	
     /**
      * Helper method calls on the StarTeam API to retrieve an ID number
      * for the specified view, corresponding to this.label.
@@ -722,6 +759,23 @@
     }
 
     /**
+     * Helper method calls on the StarTeam API to retrieve an ID number
+     * for the specified view, corresponding to this.promotionState.
+     * @param v the <code>View</code> in which to search for <code>this.promotionState</code>
+     * @return the ID number corresponding to <code>this.promotionState</code> or -1 if
+     *         no promotionState was provided.
+     * @exception BuildException if <code>this.promotionState</code> does not correspond
+     *                           to any promotionState in the supplied view
+     */
+    protected int getPromotionStateID(View v) throws BuildException {
+        if (null != this.promotionState) {
+            findPromotionState(v);
+            return this.promotionStateInUse.getID();
+        }
+        return -1;
+    }    
+    
+    /**
      * Get the id of the label in use.
      * @return id of the label in use, if labelinuse is present,
      *         otherwise return null
Index: src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamTask.java
===================================================================
--- src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamTask.java	(revision 750390)
+++ src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamTask.java	(working copy)
@@ -17,12 +17,13 @@
  */
 package org.apache.tools.ant.taskdefs.optional.starteam;
 
-import com.starbase.starteam.BuildNumber;
-import com.starbase.starteam.Server;
-import com.starbase.starteam.StarTeamFinder;
-import com.starbase.starteam.TypeNames;
-import com.starbase.starteam.User;
-import com.starbase.starteam.View;
+import com.starbase.starteam.*;
+import com.starbase.starteam.vts.comm.EncryptionAlgorithm;
+import com.starbase.starteam.vts.comm.NetMonitor;
+import com.starbase.starteam.vts.comm.ServerCommandAdapter;
+import com.starbase.starteam.vts.comm.ServerCommandEvent;
+
+
 import java.util.StringTokenizer;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
@@ -53,6 +54,12 @@
     private String password;
 
     /**
+     * The passwordFile that contains the encrypted password for the username
+     * @see username
+     */
+    private String passwordFile = null;
+
+    /**
      * name of Starteam server to connect to
      */
     private String servername;
@@ -77,6 +84,28 @@
      */
     private Server server = null;
 
+	/**
+	 * Attempt to check-out files using a StarteamMPX Cache Agent
+	 * Valid options are hostName:portNumber or autolocate 
+	 */
+	protected boolean useCA;
+
+	protected String cacheAgentHost = null;
+
+	protected int cacheAgentPort = 0;
+
+	protected EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.NULL;
+
+	protected boolean useCompression = false;
+
+	protected boolean optimizeForSlowConnections = false;
+	
+//	private boolean autoLogOn = false;
+	
+	private String logOnProvider = "org.apache.tools.ant.taskdefs.optional.starteam.StarTeamDefaultLogOn";
+	
+	private boolean useNetMonitor = false;
+
     private void logStarteamVersion() {
         log("StarTeam version: "
             + BuildNumber.getDisplayString(), Project.MSG_VERBOSE);
@@ -270,6 +299,25 @@
     }
 
     /**
+     * set the password to be used for login; required.
+     *
+     * @param password the password to be used for login
+     */
+    public final void setPasswordFile(String passwordFile) {
+        this.passwordFile = passwordFile;
+    }
+
+    /**
+     * returns the password used for login
+     *
+     * @return the password used for login
+     */
+    public final String getPasswordFile() {
+        return this.passwordFile;
+    }
+    
+    
+    /**
      * returns a reference to the server which may be used for informational
      * purposes by subclasses.
      *
@@ -280,11 +328,24 @@
     }
 
     /**
+     * sets a reference to the server which may be used for informational
+     * purposes by subclasses.
+     *
+     * @return a reference to the server
+     */
+    protected final void setServer(Server server) {
+        this.server = server;
+    }
+    
+    /**
      * disconnects from the StarTeam server.  Should be called from the
      * finally clause of every StarTeamTask-based execute method.
      */
     protected final void disconnectFromServer() {
         if (null != this.server) {
+        	if (getUseNetMonitor()) {
+        		NetMonitor.kill();
+        	}
             this.server.disconnect();
             log("successful disconnect from StarTeam Server " + servername,
                 Project.MSG_VERBOSE);
@@ -310,6 +371,8 @@
     protected abstract View createSnapshotView(View rawview)
     throws BuildException;
 
+
+    
     /**
      * All subclasses will call on this method to open the view needed for
      * processing.  This method also saves a reference to the
@@ -319,32 +382,158 @@
      * @return the <code>View</code> that will be used for processing.
      * @see #createSnapshotView(View)
      * @see #getServer()
+     * @see #setServer(Server)
      * @throws BuildException on error
      */
     protected View openView() throws BuildException {
 
-        logStarteamVersion();
-        View view = null;
-        try {
-            view = StarTeamFinder.openView(getViewURL());
-        } catch (Exception e) {
-            throw new BuildException(
-                "Failed to connect to " + getURL(), e);
+    	ClientApplication.setName("Ant " + org.apache.tools.ant.Main.getAntVersion());
+    	
+    	log("StarTeam version: "
+                + BuildNumber.getDisplayString(), Project.MSG_VERBOSE);
+    	
+        ServerInfo serverInfo = new ServerInfo();
+        serverInfo.setHost(getServername());
+        serverInfo.setPort(Integer.parseInt(getServerport()));
+        serverInfo.setEncryption(encryptionAlgorithm);
+        serverInfo.setCompression(useCompression);
+        
+        if (useCA) {
+        	if (cacheAgentPort > 0) {
+        		serverInfo.setMPXCacheAgentAddress(cacheAgentHost);
+        		serverInfo.setMPXCacheAgentPort(cacheAgentPort);
+        	} else {
+        		serverInfo.setAutoLocateCacheAgent(true);
+        	}
+        	serverInfo.setEnableCacheAgentForFileContent(true);
         }
+        Server server = new Server(serverInfo);
+        
+        if (getUseNetMonitor()) {
+        	NetMonitor.addServerCommandListener(
+        		new ServerCommandAdapter() {
+		            public void end(ServerCommandEvent event) {
+		                NetMonitor.println("[NetMonitor] Server Command " + event.getCommandName() + " took " + event.getCommandTime() + " msec and sent " + event.getBytesSent() + " bytes and received " + event.getBytesReceived() + " bytes");
+		            }
+		            public void start(ServerCommandEvent e) {
+		            	// do nothing
+		            }
+		            public void error(ServerCommandEvent e) {
+		            	NetMonitor.println("[NetMonitor] FAILED Server Command " + e.getCommandName() + " took " + e.getCommandTime() + " msec and sent " + e.getBytesSent() + " bytes and received " + e.getBytesReceived() + " bytes");
+		            }
+            }); 
+        	NetMonitor.onConsole();
+        }
+        
+        StarTeamLogOnProvider provider;
+		try {
+			provider = (StarTeamLogOnProvider) Class.forName( logOnProvider ).newInstance();
+		} catch (InstantiationException e1) {
+			throw new BuildException("Unable to Instantiate class " + logOnProvider);
+		} catch (IllegalAccessException e1) {
+			throw new BuildException("Illegal Access to class " + logOnProvider);
+		} catch (ClassNotFoundException e1) {
+			throw new BuildException("Class " + logOnProvider + " not found.");
+		}
+        
+        provider.LogOn(this, server);
+        
+        if (! server.isLoggedOn() ) throw new BuildException("Unable to log onto server " + getServername() + " at port " + getServerport());
 
-        if (null == view) {
-            throw new BuildException("Cannot find view" + getURL()
-                + " in repository()");
+        if (useCA) {
+        	try {
+				server.enableMPX();
+				if (getUseNetMonitor()) {
+					com.starbase.starteam.vts.comm.NetMonitor.addCacheAgentListener(new CacheAgentAdapter(){
+						public void itemMissed(CacheAgentEvent e) {
+							NetMonitor.println("[NetMonitor] MISSED Cache Agent  the " + e.getType().getName() + " with the item id of " + e.getItemID() + ". Bytes recieved " + e.getBytesReceived() + ".  Execution took " + e.getExecutionTime() + " msec");
+						}
+						public void itemReceived(CacheAgentEvent e) {
+							NetMonitor.println("[NetMonitor] Cache Agent Recieved the " + e.getType().getName() + " with the item id of " + e.getItemID() + ". Bytes recieved " + e.getBytesReceived() + ".  Execution took " + e.getExecutionTime() + " msec");
+						}
+					});
+				}
+			} catch (MPXException e) {
+				log("unable to enable Starteam MPX.");
+			}
         }
+        
+        com.starbase.starteam.Project[] projects = server.getProjects();
+        com.starbase.starteam.Project project = null;
+        for (int i = 0; i < projects.length; i++ ) {
+        	if (projects[i].getName().equalsIgnoreCase(getProjectname())) {
+        		project = projects[i];
+        		break;
+        	}
+        }
+        
+        projects = null;
+        
+        if (project == null ) throw new BuildException("Unable to find project " + getProjectname() + " on server.");
 
+        View view = null;
+        if (getViewname() != null) {
+	        View[] views = project.getAccessibleViews();
+	        for (int i = 0; i < views.length; i++) {
+	        	if (views[i].getName().equalsIgnoreCase(getViewname())) {
+	        		view = views[i];
+	        		break;
+	        	}
+	        }
+	        
+	        views = null;
+        } else {
+        	view = project.getDefaultView();
+        }
+        if (view == null ) throw new BuildException("Unable to find view " + getViewname() + " in project "+ getProjectname() );
+        
         View snapshot = createSnapshotView(view);
         log("Connected to StarTeam view " + getURL(),
             Project.MSG_VERBOSE);
-        this.server = snapshot.getServer();
-        return snapshot;
+        setServer(server);
+        return snapshot;  
+        
     }
 
-    /**
+    public final void setUseCA(String useCA) {
+		if (useCA.equalsIgnoreCase("autolocate")){
+			this.useCA = true;
+		} else {
+			try {
+		    	int pos = useCA.indexOf(":");
+		        if (pos > 0) {
+		            this.cacheAgentHost = useCA.substring(0, pos);
+		            this.cacheAgentPort = Integer.valueOf(useCA.substring(pos + 1)).intValue();
+		            this.useCA = true;
+		        }
+			} catch (Exception e) {
+				this.useCA = false;
+			}
+		}
+	}
+
+
+	/**
+	 * returns the hostName:portNumber of the StarTeamMPX Cache Agent to use
+	 *
+	 * @return the hostName:portNumber of the StarTeamMPX Cache Agent
+	 */
+	public final String getUseCA() {
+	    return cacheAgentPort > 0 ? cacheAgentHost + ":" + cacheAgentPort : "autolocate";
+	}
+
+
+	/**
+	 * show the cache agent in the log
+	 */
+	protected void logUseCacheAgent() {
+	    if (this.useCA) {
+	    		log("  Using StarTeam MPX Cache Agent at " + getUseCA());
+	    }
+	}
+
+
+	/**
      * Returns the name of the user with the supplied ID or a blank string
      * if user not found.
      *
@@ -358,5 +547,206 @@
         }
         return u.getName();
     }
+    
+    /**
+     * Specified the class name for logOnProvider to be used.
+     * Current providers are StarTeamDefaultLogOn, StarTeamAutoLogOn and StarTeamEncyptedFileLogOn 
+     * @param value = class name (class must exist on ANT's class path)
+     */
+    public void setLogOnProvider(String value) {
+    	logOnProvider = value;
+    }
+    
+    /**
+     * @see setLogOnProvider
+     * @return logOnProvider
+     */
+    public String getLogOnProvider() {
+    	return logOnProvider;
+    }
+    
+	/**
+	 * returns Encryption Algorithm to be used during checkout operations
+	 *
+	 * @return the EncryptionAlgorithm being used
+	 */
+	public EncryptionAlgorithm getEncryptionAlgorithm() {
+		return encryptionAlgorithm;
+	}
 
-}
+
+	/**
+	 * sets the EncryptionAlgorithm member.
+	 *
+	 * @param encryptionName
+	 *				Can be any of the following values:               
+	 *              RC2_CBC, RC2_CFB, RC2_ECB, RC4, NULL 
+	 *               
+	 */
+	public void setEncryptionAlgorithm(String encryptionName) {
+		if (encryptionName.equalsIgnoreCase("RC2_CBC")) {
+			encryptionAlgorithm = EncryptionAlgorithm.RC2_CBC;
+		} else if (encryptionName.equalsIgnoreCase("RC2_CFB")) {
+			encryptionAlgorithm = EncryptionAlgorithm.RC2_CFB;
+		} else if (encryptionName.equalsIgnoreCase("RC2_ECB")) {
+			encryptionAlgorithm = EncryptionAlgorithm.RC2_ECB;
+		} else if (encryptionName.equalsIgnoreCase("RC4")) {
+			encryptionAlgorithm = EncryptionAlgorithm.RC4;
+		} else {
+			encryptionAlgorithm = EncryptionAlgorithm.NULL;
+		}
+	}
+
+
+	/**
+	 * show the Encryption Algorithm being used in the log
+	 */
+	protected void logEncryptionAlgorithm() {
+	    if (! encryptionAlgorithm.equals(EncryptionAlgorithm.NULL)) {
+	    		log("  Connecting to StarTeam using " + encryptionAlgorithm.getName() + " encryption");
+	    }
+	}
+	
+	/**
+	 * returns whether UseNetMonitor is enabled.
+	 *
+	 * @return whether UseNetMonitor is enabled
+	 */
+	public boolean getUseNetMonitor() {
+		return useNetMonitor;
+	}
+
+
+	/**
+	 * sets the UseNetMonitor member.
+	 *
+	 * @param useNetMonitor {true|false}
+	 *               
+	 */
+	public void setUseNetMonitor(String useNetMonitor) {
+		this.useNetMonitor = useNetMonitor.equalsIgnoreCase("true");
+	}
+
+
+	/**
+	 * show whether net monitor is enabled in the log
+	 */
+	protected void logUseNetMonitor() {
+	    if (!useNetMonitor) {
+	    		log("  Net Monitor is enabled.");
+	    }
+	}	
+
+
+	protected PromotionState findPromotionState(View v, String strPromotionState) {
+	    PromotionModel model = v.getPromotionModel();
+	    if (model != null)
+	    {
+	    	PromotionState[] promotionStates = model.getPromotionStates();
+	    	if (promotionStates != null)
+	    	{
+		        for (int i = 0; i < promotionStates.length; i++) {
+		            PromotionState ps = promotionStates[i];
+		            log("checking promotion state " + ps.getName(), Project.MSG_DEBUG);
+		            if (ps != null && ps.getName().equals(strPromotionState)) {
+		                log("using promotion state " + ps.getName(), Project.MSG_VERBOSE);
+		                return ps;
+		            }
+		        }
+	    	}
+	    }
+	    throw new BuildException("Error: promotion state "
+	            + strPromotionState
+	            + " does not exist in view "
+	            + v.getFullName());
+	}
+
+
+	/**
+	 * sets the useCompression member.
+	 *
+	 * @param value ("true" or "false")
+	 */
+	public void setUseCompression(String value) {
+		useCompression = value.equalsIgnoreCase("true");
+	}
+
+
+	/**
+	 * returns the value of useCompression to be used during checkout operations
+	 *
+	 * @return boolean useCompression
+	 */
+	public boolean getUseCompression() {
+		return useCompression;
+	}
+
+
+	/**
+	 * show if compression is being used in the log
+	 */
+	protected void logUseCompression() {
+	    if (useCompression) {
+	    		log("  StarTeam compression is turned on ");
+	    }
+	}
+
+
+	protected Label findLabel(View v, String strLabel) {
+		Label stLabel = null;
+	    Label[] allLabels = v.getLabels();
+		for (int i = 0; i < allLabels.length; i++) {
+	        stLabel = allLabels[i];
+	        log("checking label " + stLabel.getName(), Project.MSG_DEBUG);
+	        if (stLabel != null && !stLabel.isDeleted() && stLabel.getName().equals(strLabel)) {
+	            if (!stLabel.isRevisionLabel() && !stLabel.isViewLabel()) {
+	                throw new BuildException("Unexpected label type.");
+	            }
+	            log("using label " + stLabel.getName(), Project.MSG_VERBOSE);
+	            return stLabel;
+	        }
+	    }
+	    throw new BuildException("Error: label "
+	            + strLabel
+	            + " does not exist in view "
+	            + v.getFullName());
+	}
+
+
+	/**
+	 * sets the OptimizeForSlowConnections member.
+	 *
+	 * @param value ("true" or "false")
+	 */
+	public void setOptimizeForSlowConnections(String value) {
+		optimizeForSlowConnections = value.equalsIgnoreCase("true");
+	}
+
+
+	/**
+	 * returns the value of OptimizeForSlowConnections to be used during checkout operations
+	 *
+	 * @return boolean OptimizeForSlowConnections
+	 */
+	public boolean getOptimizeForSlowConnections() {
+		return optimizeForSlowConnections;
+	}
+
+
+	/**
+	 * show if delta checkouts are being used in the log
+	 */
+	protected void logOptimizeForSlowConnections() {
+	    if (optimizeForSlowConnections) {
+	    		log("  StarTeam delta checkout is turned on ");
+	    }
+	}
+
+	/**
+	 * show if compression is being used in the log
+	 */
+	protected void logLogOnProvider() {
+	    log("  StarTeam Log On provider being used is " + logOnProvider);
+	}
+	
+}
\ No newline at end of file
Index: src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckin.java
===================================================================
--- src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckin.java	(revision 750390)
+++ src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckin.java	(working copy)
@@ -1,11 +1,10 @@
 /*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
+ * Copyright  2002-2004 The Apache Software Foundation
  *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
@@ -359,3 +358,5 @@
     }
 
 }
+
+
Index: src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckout.java
===================================================================
--- src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckout.java	(revision 750390)
+++ src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckout.java	(working copy)
@@ -17,15 +17,9 @@
  */
 package org.apache.tools.ant.taskdefs.optional.starteam;
 
-import com.starbase.starteam.Folder;
-import com.starbase.starteam.Item;
-import com.starbase.starteam.Status;
-import com.starbase.starteam.View;
-import com.starbase.starteam.ViewConfiguration;
+import com.starbase.starteam.*;
+
 import java.io.IOException;
-import java.io.File;
-import java.util.Enumeration;
-import java.util.Hashtable;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 
@@ -69,8 +63,14 @@
      */
     private boolean convertEOL = true;
 
-
     /**
+     * Set the hostName:portNumber of the StarteamMPX Cache Agent to use;
+     * @param useCA a <code>String</code> value
+     */
+    
+    private CheckoutManager checkoutManager;
+    
+    /**
      * flag (defaults to true) to create all directories
      * that are in the Starteam repository even if they are empty.
      *
@@ -109,6 +109,15 @@
     }
 
     /**
+     * Sets the promotion state StarTeam is to use for checkout; defaults to the most recent file.
+     * The promotion state must exist in starteam or an exception will be thrown.
+     * @param promotionState the promotionState to be used
+     */
+    public void setPromotionState(String promotionState) {
+        _setPromotionState(promotionState);
+    }
+    
+    /**
      * This attribute tells whether to do a locked checkout, an unlocked
      * checkout or to leave the checkout status alone (default).  A locked
      * checkout locks all other users out from making changes.  An unlocked
@@ -180,7 +189,31 @@
         return this.useRepositoryTimeStamp;
     }
 
+    private String markUnlockedFilesReadOnly = "project";
+
     /**
+     * sets the MarkUnlockedFilesReadOnly member.
+     *
+     * @param MarkUnlockedFilesReadOnly
+     *               true means checked out files that are unlocked will be marked as read only.
+     *               false means the checked out files will be marked as read/write.
+     *               project means the checkout manager will use the option set in the Projects properties.
+     */
+    public void setMarkUnlockedFilesReadOnly(String markUnlockedFilesReadOnly) {
+        this.markUnlockedFilesReadOnly = markUnlockedFilesReadOnly;
+    }
+
+    /**
+     * returns the value of the MarkUnlockedFilesReadOnly member
+     *
+     * @return the value of the MarkUnlockedFilesReadOnly member
+     */
+    public String getMarkUnlockedFilesReadOnly() {
+        return this.markUnlockedFilesReadOnly;
+    }
+    
+    
+    /**
      * List files, dates, and statuses as of this date; optional.
      * If not specified, the most recent version of each file will be listed.
      *
@@ -190,7 +223,7 @@
     public void setAsOfDate(String asOfDateParam) {
         _setAsOfDate(asOfDateParam);
     }
-
+    
     /**
      * Date Format with which asOfDate parameter to be parsed; optional.
      * Must be a SimpleDateFormat compatible string.
@@ -203,7 +236,7 @@
     public void setAsOfDateFormat(String asOfDateFormat) {
         _setAsOfDateFormat(asOfDateFormat);
     }
-
+    
     /**
      * Override of base-class abstract function creates an
      * appropriately configured view for checkouts - either
@@ -217,16 +250,18 @@
      */
     protected View createSnapshotView(View raw) throws BuildException {
 
-        int labelID = getLabelID(raw);
-
         // if a label has been supplied and it is a view label, use it
         // to configure the view
+    	int labelID = getLabelID(raw);    	
         if (this.isUsingViewLabel()) {
             return new View(raw, ViewConfiguration.createFromLabel(labelID));
         // if a label has been supplied and it is a revision label, use the raw
         // the view as the snapshot
         } else if (this.isUsingRevisionLabel()) {
             return raw;
+        } else if (this.isUsingPromotionState()) {
+            int promotionStateID = getPromotionStateID(raw);
+			return new View(raw, ViewConfiguration.createFromPromotionState(promotionStateID));
         }
         // if a date has been supplied use a view configured to the date.
         View view = getViewConfiguredByDate(raw);
@@ -272,14 +307,21 @@
                     + " when checking out a non-current version.");
             }
         }
-        if (null != getLabel() && null != getAsOfDate()) {
+        
+        int numConfigOptions = 0;
+        if (null != getLabel()) numConfigOptions++;
+        if (null != getAsOfDate()) numConfigOptions++;
+        if (null != getPromotionState()) numConfigOptions++;
+        
+        if (numConfigOptions > 1) {
             throw new BuildException(
-                "Both label and asOfDate specified.  "
+                "Multiple configuration options specified.  " +
+                "Only one of the following configuration options may be used: [asOfDate | label | promotionState].  "
                 + "Unable to process request.");
         }
 
     }
-
+    
     /**
      * extenders should emit to the log an entry describing the parameters
      * that will be used by this operation.
@@ -300,12 +342,26 @@
             + (null == getRootLocalFolder() ? "(default): " : ": ")
             + targetrootFolder.getAbsolutePath());
 
-
+        logLogOnProvider();
+        logUseCacheAgent();
+        logEncryptionAlgorithm();
+        logUseCompression();
+        logOptimizeForSlowConnections();
+        logPromotionState();
         logLabel();
         logAsOfDate();
         logIncludes();
         logExcludes();
+        
+        if (this.getMarkUnlockedFilesReadOnly().equalsIgnoreCase("true")) {
+        	log("  Unlocked Files will be marked as Read only.");
+        } else if (this.getMarkUnlockedFilesReadOnly().equalsIgnoreCase("false")) {
+        	log("  Unlocked Files will not be marked as Read only.");
+        } else if (this.getMarkUnlockedFilesReadOnly().equalsIgnoreCase("project")) {
+        	log("  Unlocked Files will be marked as Read Only if this option has been checked in the Project properties.");
+        }
 
+
         if (this.lockStatus == Item.LockType.EXCLUSIVE) {
             log("  Items will be checked out with Exclusive locks.");
         } else if (this.lockStatus == Item.LockType.UNLOCKED) {
@@ -345,89 +401,127 @@
     protected void visit(Folder starteamFolder, java.io.File targetFolder)
             throws BuildException {
         try {
+    		View tempView = starteamFolder.getView();
 
+        	if (checkoutManager == null) {
+        		
+        		// Create checkout Options
+        		CheckoutOptions checkoutOptions = new CheckoutOptions(tempView);
+        		        		
+        		checkoutOptions.setEOLConversionEnabled(convertEOL);
+        		checkoutOptions.setLockType(lockStatus);
+        		checkoutOptions.setForceCheckout(isForced());
+        		checkoutOptions.setTimeStampNow(!useRepositoryTimeStamp);
+        		checkoutOptions.setOptimizeForSlowConnections(optimizeForSlowConnections);
+        		
+        		// if using Revision Label, then use the checkout options to force checkout by label.
+        		if (this.isUsingRevisionLabel()) {
+        			checkoutOptions.setCheckoutLabelID(this.getIDofLabelInUse());
+        		}
+        		
+        		if (this.getMarkUnlockedFilesReadOnly().equalsIgnoreCase("true")) {
+        			checkoutOptions.setMarkUnlockedFilesReadOnly(true);
+        		} else if (this.getMarkUnlockedFilesReadOnly().equalsIgnoreCase("project")) {
+        			Integer mufro = (Integer) tempView.getProject().get(tempView.getProject().getPropertyNames().PROJECT_MARK_UNLOCKED_FILES_READ_ONLY);
+        			checkoutOptions.setMarkUnlockedFilesReadOnly(  mufro.intValue() > 0 );
+        		} else if (this.getMarkUnlockedFilesReadOnly().equalsIgnoreCase("false")) {
+        			checkoutOptions.setMarkUnlockedFilesReadOnly(false);
+        		}
+        		
+        		// Build Checkout Manager 
+        		checkoutManager = tempView.createCheckoutManager(checkoutOptions);
+        		
+        		// add a checkout listener to log is finished events.
+        		checkoutManager.addCheckoutListener(new CheckoutListener() {
+        			public void onNotifyProgress(CheckoutEvent event) {
+        				if (event.isFinished()) {
+        					if (event.isSuccessful()) {
+        						log("Checked out " + describeCheckout(event.getCurrentFile(), event.getCurrentWorkingFile()));
+        					} else {
+        						if (event.getError() != null) {
+        							log("FAILED to Checked out " + describeCheckout(event.getCurrentFile(), event.getCurrentWorkingFile()));
+        						} else {
+        							log("SKIP Checked out of " + describeCheckout(event.getCurrentFile(), event.getCurrentWorkingFile()));
+        						}
+        					}
+        				}
+        			}
+        			public void onStartFile(CheckoutEvent event) {
+        				
+        			}
+        		});
+        		
+        	}
 
             if (null != getRootLocalFolder()) {
                 starteamFolder.setAlternatePathFragment(
                     targetFolder.getAbsolutePath());
             }
 
-            if (!targetFolder.exists()) {
-                if (!this.isUsingRevisionLabel()) {
-                    if (this.createDirs) {
-                        if (targetFolder.mkdirs()) {
-                            log("Creating folder: " + targetFolder);
-                        } else {
-                            throw new BuildException(
-                                "Failed to create local folder " + targetFolder);
-                        }
-                    }
-                }
-            }
+            FolderListManager folderListMgr = new FolderListManager(tempView);
+            
+            folderListMgr.includeFolders(starteamFolder, Filter.CONTEXT_LOCAL_AND_SERVER, -1);
+			
+			folderListMgr.refresh();
+					
+			Type fileType = tempView.getServer().typeForName("File");
+			
+			Filter filter = new Filter(fileType, "all_files", Filter.CONTEXT_LOCAL_AND_SERVER, false);
+			
+			ItemListManager itemListMgr = new ItemListManager(fileType, folderListMgr);
 
+			itemListMgr.setFilter(filter);
+			
+			itemListMgr.refresh();
 
-            Folder[] foldersList = starteamFolder.getSubFolders();
-            Item[] filesList = starteamFolder.getItems(getTypeNames().FILE);
+			// get a file list from the List Managers
+			Items filesList = itemListMgr.getItems();
 
-            if (this.isUsingRevisionLabel()) {
-
-                // prune away any files not belonging to the revision label
-                // this is one ugly API from Starteam SDK
-
-                Hashtable labelItems = new Hashtable(filesList.length);
-                int s = filesList.length;
-                int[] ids = new int[s];
-                for (int i = 0; i < s; i++) {
-                    ids[i] = filesList[i].getItemID();
-                    labelItems.put(new Integer(ids[i]), new Integer(i));
-                }
-                int[] foundIds = getLabelInUse().getLabeledItemIDs(ids);
-                s = foundIds.length;
-                Item[] labeledFiles = new Item[s];
-                for (int i = 0; i < s; i++) {
-                    Integer id = new Integer(foundIds[i]);
-                    labeledFiles[i] =
-                        filesList[((Integer) labelItems.get(id)).intValue()];
-                }
-                filesList = labeledFiles;
-            }
-
-
             // note, it's important to scan the items BEFORE we make the
             // Unmatched file map because that creates a bunch of NEW
             // folders and files (unattached to repository) and we
             // don't want to include those in our traversal.
 
-            UnmatchedFileMap ufm =
-                new CheckoutMap().
-                    init(targetFolder.getAbsoluteFile(), starteamFolder);
+            ItemList items = new ItemList();
+            // add files to item list to be bulk processed by checkout manager.
+            for (int i = 0; i < filesList.size(); i++) {
+            	com.starbase.starteam.File stFile = (com.starbase.starteam.File) filesList.getAt(i);
+            	
+            	if (deleteUncontrolled &&  (stFile.getSmartStatus() == Status.NEW)) {
+            		java.io.File file = new java.io.File(stFile.getLocalPath() + System.getProperty("file.separator") + stFile.getLocalName());
+            		file.delete();
+            	} else if (this.shouldProcess(stFile.getName())) {
+            		items.addItem(stFile);
+            	}
+            }
 
-
-
-            for (int i = 0; i < foldersList.length; i++) {
-                Folder stFolder = foldersList[i];
-
-                java.io.File subfolder =
-                     new java.io.File(targetFolder, stFolder.getName());
-
-                 ufm.removeControlledItem(subfolder);
-
-                 if (isRecursive()) {
-                         visit(stFolder, subfolder);
-                     }
-                 }
-
-            for (int i = 0; i < filesList.length; i++) {
-                com.starbase.starteam.File stFile =
-                    (com.starbase.starteam.File) filesList[i];
-                processFile(stFile, targetFolder);
-
-                ufm.removeControlledItem(
-                    new java.io.File(targetFolder, stFile.getName()));
+            filesList = null;            
+            
+            checkoutManager.checkout(items);
+            
+            while (checkoutManager.isRunning()) {
+            	
+            	try {
+					wait(100);
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
             }
-            if (this.deleteUncontrolled) {
-                ufm.processUncontrolledItems();
-            }
+            
+            CheckoutProgress checkoutProgress = checkoutManager.getProgress();
+
+            log("Total files checked out by SDK: " + (checkoutProgress.getTotalFilesCheckedOutByMPXCacheAgent() - checkoutProgress.getTotalFilesCheckedOut()));
+            log("Total files checked out by Cache Agent: " + checkoutProgress.getTotalFilesCheckedOutByMPXCacheAgent());
+            log("Total files checked out: " + checkoutProgress.getTotalFilesCheckedOut());
+            log("Total bytes checked out by SDK: " + (checkoutProgress.getTotalBytesCheckedOutByMPXCacheAgent() - checkoutProgress.getTotalBytesCheckedOut()));
+            log("Total bytes checked out by Cache Agent: " + checkoutProgress.getTotalBytesCheckedOutByMPXCacheAgent());
+            log("Total bytes checked out: " + checkoutProgress.getTotalBytesCheckedOut());
+            
+            items = null;
+            itemListMgr = null;
+            folderListMgr = null;
+            checkoutManager = null;
+            
         } catch (IOException e) {
             throw new BuildException(e);
         }
@@ -445,7 +539,17 @@
                                     java.io.File localFile) {
         StringBuffer sb = new StringBuffer();
         sb.append(getFullRepositoryPath(remotefile))
-          .append(" --> ");
+          .append(" ");
+
+        Item labelItem = remotefile.getFromHistoryByLabelID(this.getIDofLabelInUse());
+    	if (labelItem != null) {
+    		sb.append(labelItem.getDotNotation());
+    	} else {
+    		sb.append(remotefile.getDotNotation());
+    	}
+        
+        sb.append(" --> ");
+        
         if (null == localFile) {
             sb.append(remotefile.getFullName());
         } else {
@@ -453,191 +557,5 @@
         }
         return sb.toString();
     }
-    private String describeCheckout(com.starbase.starteam.File remotefile) {
-        return describeCheckout(remotefile, null);
-    }
-    /**
-     * Processes (checks out) <code>stFiles</code>files from StarTeam folder.
-     *
-     * @param eachFile repository file to process
-     * @param targetFolder a java.io.File (Folder) to work
-     * @throws IOException when StarTeam API fails to work with files
-     */
-    private void processFile(com.starbase.starteam.File eachFile,
-                             File targetFolder)
-    throws IOException {
-        String filename = eachFile.getName();
 
-        java.io.File localFile = new java.io.File(targetFolder, filename);
-
-        // If the file doesn't pass the include/exclude tests, skip it.
-        if (!shouldProcess(filename)) {
-            log("Excluding " + getFullRepositoryPath(eachFile),
-                Project.MSG_INFO);
-                return;
-        }
-
-        if (this.isUsingRevisionLabel()) {
-            if (!targetFolder.exists()) {
-                if (targetFolder.mkdirs()) {
-                    log("Creating folder: " + targetFolder);
-                } else {
-                    throw new BuildException(
-                        "Failed to create local folder " + targetFolder);
-                }
-            }
-            boolean success = eachFile.checkoutByLabelID(
-                localFile,
-                getIDofLabelInUse(),
-                this.lockStatus,
-                !this.useRepositoryTimeStamp,
-                true,
-                false);
-            if (success) {
-                log("Checked out " + describeCheckout(eachFile, localFile));
-            }
-        } else {
-            boolean checkout = true;
-
-            // Just a note: StarTeam has a status for NEW which implies
-            // that there is an item  on your local machine that is not
-            // in the repository.  These are the items that show up as
-            // NOT IN VIEW in the Starteam GUI.
-            // One would think that we would want to perhaps checkin the
-            // NEW items (not in all cases! - Steve Cohen 15 Dec 2001)
-            // Unfortunately, the sdk doesn't really work, and we can't
-            // actually see  anything with a status of NEW. That is why
-            // we can just check out  everything here without worrying
-            // about losing anything.
-
-            int fileStatus = (eachFile.getStatus());
-
-            // We try to update the status once to give StarTeam
-            // another chance.
-
-            if (fileStatus == Status.MERGE
-                || fileStatus == Status.UNKNOWN) {
-                eachFile.updateStatus(true, true);
-                fileStatus = (eachFile.getStatus());
-            }
-
-            log(eachFile.toString() + " has status of "
-                + Status.name(fileStatus), Project.MSG_DEBUG);
-
-
-            switch (fileStatus) {
-            case Status.OUTOFDATE:
-            case Status.MISSING:
-                log("Checking out: " + describeCheckout(eachFile));
-                break;
-            default:
-                if (isForced() && fileStatus != Status.CURRENT) {
-                    log("Forced checkout of "
-                        + describeCheckout(eachFile)
-                        + " over status " + Status.name(fileStatus));
-                } else {
-                    log("Skipping: " + getFullRepositoryPath(eachFile)
-                        + " - status: " + Status.name(fileStatus));
-                    checkout = false;
-                }
-            }
-
-            if (checkout) {
-                if (!targetFolder.exists()) {
-                    if (targetFolder.mkdirs()) {
-                        log("Creating folder: " + targetFolder);
-                    } else {
-                        throw new BuildException(
-                            "Failed to create local folder " + targetFolder);
-                    }
-                }
-                eachFile.checkout(this.lockStatus,
-                                 !this.useRepositoryTimeStamp, this.convertEOL, false);
-            }
-        }
-    }
-    /**
-     * handles the deletion of uncontrolled items
-     */
-    private class CheckoutMap extends UnmatchedFileMap {
-        protected boolean isActive() {
-            return StarTeamCheckout.this.deleteUncontrolled;
-        }
-
-        /**
-         * override of the base class init.  It can be much simpler, since
-         * the action to be taken is simply to delete the local files.  No
-         * further interaction with the repository is necessary.
-         *
-         * @param localFolder
-         *        the local folder from which the mappings will be made.
-         * @param remoteFolder
-         *        not used in this implementation
-         */
-        UnmatchedFileMap init(java.io.File localFolder, Folder remoteFolder) {
-            if (!localFolder.exists()) {
-                return this;
-            }
-
-            String[] localFiles = localFolder.list();
-            // PR 31965 says that it can return null
-            if (localFiles == null) {
-                return this;
-            }
-            for (int i = 0; i < localFiles.length; i++) {
-                java.io.File localFile =
-                    new java.io.File(localFolder, localFiles[i]).getAbsoluteFile();
-
-                log("adding " + localFile + " to UnmatchedFileMap",
-                    Project.MSG_DEBUG);
-
-                if (localFile.isDirectory()) {
-                    this.put(localFile, "");
-                } else {
-                    this.put(localFile, "");
-                }
-            }
-            return this;
-        }
-
-
-
-        /**
-         * deletes uncontrolled items from the local tree.  It is assumed
-         * that this method will not be called until all the items in the
-         * corresponding folder have been processed, and that the internal map
-         * will contain only uncontrolled items.
-         */
-        void processUncontrolledItems() throws BuildException {
-            if (this.isActive()) {
-                Enumeration e = this.keys();
-                while (e.hasMoreElements()) {
-                    java.io.File local = (java.io.File) e.nextElement();
-                    delete(local);
-                }
-            }
-        }
-
-        /**
-         * deletes all files and if the file is a folder recursively deletes
-         * everything in it.
-         *
-         * @param local  The local file or folder to be deleted.
-         */
-        void delete(java.io.File local) {
-            // once we find a folder that isn't in the repository,
-            // anything below it can be deleted.
-            if (local.isDirectory() && isRecursive()) {
-                String[] contents = local.list();
-                for (int i = 0; i < contents.length; i++) {
-                    java.io.File file = new java.io.File(local, contents[i]);
-                    delete(file);
-                }
-            }
-            local.delete();
-            log("Deleted uncontrolled item " + local.getAbsolutePath());
-        }
-    }
-
-
-}
+}
\ No newline at end of file
Index: src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java
===================================================================
--- src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java	(revision 750390)
+++ src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java	(working copy)
@@ -1,11 +1,10 @@
 /*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
+ * Copyright  2002-2004 The Apache Software Foundation
  *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
@@ -99,8 +98,9 @@
         View view = getViewConfiguredByDate(raw);
         if (view != null) {
             return view;
+        }
         // otherwise, use this view configured as the tip.
-        } else {
+        else {
             return new View(raw, ViewConfiguration.createTip());
         }
     }
@@ -151,7 +151,6 @@
      * @param starteamFolder the StarTeam folder from which files to be
      *                       checked out
      * @param targetFolder the local mapping of rootStarteamFolder
-     * @throws BuildException on error
      */
     protected void visit(Folder starteamFolder, java.io.File targetFolder)
             throws BuildException {
@@ -216,12 +215,6 @@
     private static final SimpleDateFormat SDF =
         new SimpleDateFormat("yyyy-MM-dd hh:mm:ss zzz");
 
-    /**
-     * Log a repositary file and it's corresponding local file.
-     * @param reposFile the repositary file to log
-     * @param localFile the corresponding local file
-     * @throws IOException on error getting information from files
-     */
     protected void list(File reposFile, java.io.File localFile)
             throws IOException {
         StringBuffer b = new StringBuffer();
@@ -243,7 +236,7 @@
         log(b.toString());
     }
 
-    private static final String BLANK_STRING = blanks(30);
+    private static final String blankstr = blanks(30);
 
     private static String blanks(int len) {
         StringBuffer b = new StringBuffer();
@@ -253,24 +246,12 @@
         return b.toString();
     }
 
-    /**
-     * Return a padded string.
-     * @param s the string to pad
-     * @param padlen the size of the padded string
-     * @return the padded string
-     */
     protected static String pad(String s, int padlen) {
-        return (s + BLANK_STRING).substring(0, padlen);
+        return (s + blankstr).substring(0, padlen);
     }
 
-    /**
-     * Return a right padded string.
-     * @param s the string to pad
-     * @param padlen the size of the padded string
-     * @return the padded string
-     */
     protected static String rpad(String s, int padlen) {
-        s = BLANK_STRING + s;
+        s = blankstr + s;
         return s.substring(s.length() - padlen);
     }
 
