[jboss-cvs] repository.jboss.com/apache-slide/2.1-brew/src ...

Vivek Lakshmanan vivekl at redhat.com
Fri Feb 23 01:04:33 EST 2007


  User: vivekl  
  Date: 07/02/23 01:04:33

  Added:       apache-slide/2.1-brew/src   
                        jakarta-slide-webdavclient-2.2-WebdavResource.java
                        jakarta-slide-webdavclient-3.0-compat.patch
                        jakarta-slide-webdavclient-src-2.1.tar.gz
  Log:
  - Address the following JIRA tasks:
    JBAS-3994
    JBAS-4132
    JBAS-4137
    JBAS-4138
    JBAS-4139
    JBAS-4141
  - Add brew-built binaries for thirdparty dependencies for AS 4.2
  
  Revision  Changes    Path
  1.1      date: 2007/02/23 06:04:33;  author: vivekl;  state: Exp;repository.jboss.com/apache-slide/2.1-brew/src/jakarta-slide-webdavclient-2.2-WebdavResource.java
  
  Index: jakarta-slide-webdavclient-2.2-WebdavResource.java
  ===================================================================
  /*
   * $Header: /cvsroot/jboss/repository.jboss.com/apache-slide/2.1-brew/src/jakarta-slide-webdavclient-2.2-WebdavResource.java,v 1.1 2007/02/23 06:04:33 vivekl Exp $
   * $Revision: 1.1 $
   * $Date: 2007/02/23 06:04:33 $
   *
   * ====================================================================
   *
   * Copyright 1999-2002 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
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   *
   */
  
  package org.apache.webdav.lib;
  
  import java.io.ByteArrayInputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  import java.text.DateFormat;
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.*;
  
  import org.apache.commons.httpclient.Credentials;
  import org.apache.commons.httpclient.HostConfiguration;
  import org.apache.commons.httpclient.HttpClient;
  import org.apache.commons.httpclient.HttpException;
  import org.apache.commons.httpclient.HttpMethod;
  import org.apache.commons.httpclient.HttpStatus;
  import org.apache.commons.httpclient.HttpURL;
  import org.apache.commons.httpclient.HttpsURL;
  import org.apache.commons.httpclient.URIException;
  import org.apache.commons.httpclient.UsernamePasswordCredentials;
  import org.apache.commons.httpclient.methods.GetMethod;
  import org.apache.commons.httpclient.methods.HeadMethod;
  import org.apache.commons.httpclient.methods.PutMethod;
  import org.apache.commons.httpclient.util.URIUtil;
  
  import org.apache.webdav.lib.methods.*;
  import org.apache.webdav.lib.properties.AclProperty;
  import org.apache.webdav.lib.properties.LockDiscoveryProperty;
  import org.apache.webdav.lib.properties.PrincipalCollectionSetProperty;
  import org.apache.webdav.lib.properties.ResourceTypeProperty;
  import org.apache.webdav.lib.util.DOMUtils;
  import org.apache.webdav.lib.util.WebdavStatus;
  
  /**
   * The class <code>WebdavResource</code> is an abstract representation
   * for WebDAV resource.<p>
   *
   * <pre>
   * A functional comparison of WebdavResource and JDK(It's different a lot).
   * ----------------------------------+-------------------------------------
   *   File class (JDK 1.3.x)          |  WebdavResource class
   * ----------------------------------+-------------------------------------
   *   File(String)                    |  WebdavResource(HttpURL)
   *   File(String, String)            |  X (need to escape)
   *   File(File, String)              |  WebdavResource(HttpURL, String)
   *   getName()                       |  getName()
   *   getParent()                     |  *see getHttpURL() and HttpURL
   *   getParentFile()                 |  X (not yet)
   *   getPath()                       |  getPath()
   *   isAbsolute()                    |  X
   *   getAbsolutePath()               |
   *   getAbsoluteFile()               |  X
   *   getCanonicalPath()              |
   *   getCanonicalFile()              |  X
   *   toURL()                         |  *see HttpURL
   *   canRead()                       |
   *   !canWrite()                     |  !isLocked()
   *   exists()                        |  exists()
   *   isDirectory()                   |  isCollection()
   *   isFile()                        |  !isCollection()
   *   isHidden()                      |  getIsHidden()
   *   lastModified()                  |  getGetLastModified()
   *   length()                        |  getGetContentLength()
   *   createNewFile()                 |  putMethod(String)
   *   delete()                        |  deleteMethod()
   *   deleteOnExit()                  |  X
   *   list()                          |  list()
   *   list(FilenameFilter)            |  X
   *   listFiles()                     |  listWebdavResources()
   *   listFiles(FilenameFilter)       |  X
   *   listFiles(FileFilter)           |  X
   *   mkdir()                         |  mkcolMethod()
   *   mkdirs()                        |  mkcolMethod()
   *   renameTo(File)                  |  moveMethod(String)
   *   setLastModified()               |  X
   *   setReadOnly()                   |  setOverwrite(boolean)
   *   listRoots()                     |  *see WebdavSession
   *   generateFile()                  |
   *   createTempFile(...)             |  setGetTempDir(String)
   *   compareTo(Object)               |  compareTo(Object)
   *   equals(Object)                  |  equals(Object)
   *   hashCode()                      |  X
   * ----------------------------------+-------------------------------------
   *   URL class (JDK 1.3.x)           |  Webdavresource and HttpURL classes
   * ----------------------------------+-------------------------------------
   *   getQuery()                      |  getQuery()
   *   getPath()                       |  getPath()
   *   getUserInfo()                   |  getUserInfo()
   *   getAuthority()                  |  getAuthority()
   *   getPort()                       |  getPort()
   *   getProtocol()                   |  getScheme()
   *   getHost()                       |  getHost()
   *   getFile()                       |  getPath()
   *   getRef()                        |  getFragmenet()
   *   hashCode()                      |  X
   *   sameFile()                      |
   *   toExternalForm()                |  toExternalForm()
   *   openConnection()                |
   *   openStream()                    |
   *   getContent()                    |  getMethodDataAsString()
   * ----------------------------------+-------------------------------------
   *   URLConnection class (JDK 1.3.x) |  HttpClient Library and more
   * ----------------------------------+-------------------------------------
   *   getFileNameMap()                |  X
   *   setFileNameMap()                |  X
   *   connect()                       |
   *   getURL()                        |  HttpURL#getURL()
   *   getContenetLength()()           |
   *   getContentType()                |
   *   getContentEncoding()            |
   *   getExpiration()                 |
   *   getDate()                       |
   *   getLastModified()               |
   *   getHeaderField()                |
   *   getHeaderFieldInt()             |  X
   *   getHeaderFielDate()             |  X
   *   getHeaderFieldKey()             |  X
   *   getHeaderFiled(int)             |  X
   *   getContenet()                   |
   *   getInputStream()                |  WebdavResource#getMethodData()
   *   getOutputStream()               |  WebdavResource#putMethod(...)
   *   setDoInput()                    |  X
   *   getDoInput()                    |  X
   *   setAllowUserInteraction()       |  *see WebdavException and WebdavStatus
   *   getAllowUserInteraction()       |  *see WebdavException and WebdavStatus
   *   setUseCaches()                  |
   *   getUseCaches()                  |
   *   getIfModifiedSince()            |  X
   *   setIfModifiedSince(boolean)     |  X
   *   setRequestProperty(...)         |  X
   *   getRequestProperty(...)         |  X
   *   guessContentTypeFromStream(...) |  X
   * ----------------------------------+-------------------------------------
   * </pre>
   *
   */
  public class WebdavResource extends WebdavSession {
  
  
      // -------------------------------------------------------  Constructors
  
      /**
       * The default constructor.
       */
      protected WebdavResource() {
      }
  
  
      /**
       * The constructor.
       */
      protected WebdavResource(HttpClient client) {
          super();
          this.client = client;
      }
  
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param credentials The credentials to use for authentication.
       * @param action The action to set properties of this resource.
       * @param depth The depth to find properties.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, Credentials credentials, int action,
                            int depth)
          throws HttpException, IOException {
  
          setCredentials(credentials);
          setHttpURL(httpURL, action, depth);
      }
  
  
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param action The action to set properties of this resource.
       * @param depth The depth to find properties.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, int action, int depth)
          throws HttpException, IOException {
  
          setHttpURL(httpURL, action, depth);
      }
  
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param action The action to set properties of this resource.
       * @param depth The depth to find properties.
       * @param followRedirects shall redirects from the server be accepted
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, int action, int depth,
               boolean followRedirects)
         throws HttpException, IOException {
         
         setFollowRedirects(this.followRedirects);
         setHttpURL(httpURL, action, depth);
      }
  
  
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param depth The depth to find properties.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, int depth)
          throws HttpException, IOException {
  
          setHttpURL(httpURL, defaultAction, depth);
  
      }
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param depth The depth to find properties.
       * @param followRedirects Shall redirects be followed automatically.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, int depth, boolean followRedirects)
         throws HttpException, IOException {
         
         setFollowRedirects(followRedirects);
         setHttpURL(httpURL, defaultAction, depth);
      }
  
  
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL)
          throws HttpException, IOException {
  
          setHttpURL(httpURL);
      }
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param followRedirects shall redirects from the server be accepted
       */
      public WebdavResource(HttpURL httpURL, boolean followRedirects)
          throws HttpException, IOException {
          
          setFollowRedirects(followRedirects);
          setHttpURL(httpURL);
      }
  
  
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param proxyHost The hostname of the proxy to use.
       * @param proxyPort The port number of the proxy to use.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, String proxyHost, int proxyPort)
          throws HttpException, IOException {
  
          setProxy(proxyHost, proxyPort);
          setHttpURL(httpURL);
      }
      public WebdavResource(HttpURL httpURL, String proxyHost, int proxyPort, boolean followRedirects)
         throws HttpException, IOException {
         
         setFollowRedirects(followRedirects);
         setProxy(proxyHost, proxyPort);
         setHttpURL(httpURL);
      }
  
  
      /**
       * The constructor.
       *
       * @param httpURL The specified http URL.
       * @param proxyHost The hostname of the proxy to use.
       * @param proxyPort The port number of the proxy to use.
       * @param proxyCredentials Credentials to use for proxy authentication.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, String proxyHost, int proxyPort,
                            Credentials proxyCredentials)
          throws HttpException, IOException {
  
          setProxy(proxyHost, proxyPort);
          setProxyCredentials(proxyCredentials);
          setHttpURL(httpURL);
      }
      
      public WebdavResource(HttpURL httpURL, String proxyHost, int proxyPort,
            Credentials proxyCredentials, boolean followRedirects)
          throws HttpException, IOException {
         
          setFollowRedirects(followRedirects);
          setProxy(proxyHost, proxyPort);
          setProxyCredentials(proxyCredentials);
          setHttpURL(httpURL);
      }
  
      /**
       * The constructor.
       * It must be put an escaped http URL as an argument.
       *
       * @param escapedHttpURL The escaped http URL string.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(String escapedHttpURL)
          throws HttpException, IOException {
  
          setHttpURL(escapedHttpURL);
      }
      public WebdavResource(String escapedHttpURL, boolean followRedirects)
         throws HttpException, IOException {
         
         setFollowRedirects(followRedirects);
         setHttpURL(escapedHttpURL);
      }
  
  
      /**
       * The constructor.
       * It must be put an escaped http URL as an argument.
       *
       * @param escapedHttpURL The escaped http URL string.
       * @param credentials The credentials used for Authentication.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(String escapedHttpURL, Credentials credentials)
          throws HttpException, IOException {
  
          setCredentials(credentials);
          setHttpURL(escapedHttpURL);
      }
      
      public WebdavResource(String escapedHttpURL, Credentials credentials,
            boolean followRedirects)
         throws HttpException, IOException {
         
         setFollowRedirects(followRedirects);
         setCredentials(credentials);
         setHttpURL(escapedHttpURL);
      }
  
  
      /**
       * The constructor.
       * It must be put an escaped http URL as an argument.
       *
       * @param escapedHttpURL The escaped http URL string.
       * @param proxyHost The hostname of the proxy to use.
       * @param proxyPort The port number of the proxy to use.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(String escapedHttpURL, String proxyHost,
                            int proxyPort) throws HttpException, IOException {
  
          setProxy(proxyHost, proxyPort);
          setHttpURL(escapedHttpURL);
      }
  
      /**
       * The constructor.
       * It must be put an escaped http URL as an argument.
       *
       * @param escapedHttpURL The escaped http URL string.
       * @param proxyHost The hostname of the proxy to use.
       * @param proxyPort The port number of the proxy to use.
       * @param proxyCredentials Credentials to use for proxy authentication.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(String escapedHttpURL, String proxyHost,
                            int proxyPort, Credentials proxyCredentials)
          throws HttpException, IOException {
  
          setProxy(proxyHost, proxyPort);
          setProxyCredentials(proxyCredentials);
          setHttpURL(escapedHttpURL);
      }
  
  
      /**
       * The constructor.
       *
       * @param httpURL The http URL.
       * @param additionalPath The added relative path.
       * @exception HttpException
       * @exception IOException
       * @see #setDefaultAction(int)
       */
      public WebdavResource(HttpURL httpURL, String additionalPath)
          throws HttpException, IOException {
  
          setHttpURL(httpURL, additionalPath);
      }
  
      /**
       * The constructor.
       *
       * @param httpURL The http URL.
       * @param additionalPath The added relative path.
       * @param followRedirects shall redirects be accepted
       */
      public WebdavResource(HttpURL httpURL, String additionalPath, boolean followRedirects)
         throws HttpException, IOException {
     
         setFollowRedirects(followRedirects);
         setHttpURL(httpURL, additionalPath);
      }
  
  
      // -------------------------------------- Constants for WebDAV properties.
  
  
      /**
       * The displayname property.
       */
      public static final String DISPLAYNAME = "displayname";
  
  
      /**
       * The getcontentlanguage property.
       */
      public static final String GETCONTENTLANGUAGE = "getcontentlanguage";
  
  
      /**
       * The getcontentlength property.
       */
      public static final String GETCONTENTLENGTH = "getcontentlength";
  
  
      /**
       * The getlastmodifed property.
       */
      public static final String GETLASTMODIFIED = "getlastmodified";
  
  
      /**
       * The creationdate property.
       */
      public static final String CREATIONDATE = "creationdate";
  
  
      /**
       * The resourcetype property.
       */
      public static final String RESOURCETYPE = "resourcetype";
  
  
      /**
       * The source property.
       */
      public static final String SOURCE = "source";
  
  
      /**
       * The getcontenttype property.
       */
      public static final String GETCONTENTTYPE = "getcontenttype";
  
  
      /**
       * The getetag property.
       */
      public static final String GETETAG = "getetag";
  
  
      /**
       * The ishidden property.
       */
      public static final String ISHIDDEN = "ishidden";
  
  
      /**
       * The iscollection property.
       */
      public static final String ISCOLLECTION = "iscollection";
  
  
      /**
       * The supportedlock property.
       */
      public static final String SUPPORTEDLOCK = "supportedlock";
  
  
      /**
       * The lockdiscovery property.
       */
      public static final String LOCKDISCOVERY = "lockdiscovery";
  
  
      // ------------------------------------------------------------ Constants
  
  
      /**
       * No action to find properties for this resource.
       */
      public static final int NOACTION = 1;
  
  
      /**
       * The action setting only the displayname for this resource.
       */
      public static final int NAME = 2;
  
  
      /**
       * The action setting the basic properties for this resource.
       */
      public static final int BASIC = 3;
  
  
      /**
       * The action setting the default DAV properties for this resource.
       */
      public static final int DEFAULT = 4;
  
  
      /**
       * The action setting the all properties for this resource.
       */
      public static final int ALL = 5;
  
  
      /**
       *
       */
      public static final int OPTIONS_WORKSPACE = 8;
  
      /**
       *
       */
      public static final int OPTIONS_VERSION_HISTORY = 9;
  
      public static final int LABEL_SET = 10;
      public static final int LABEL_REMOVE = 11;
      public static final int LABEL_ADD = 12;
  
  
      /**
       * Owner information for locking and unlocking.
       */
      public static final String defaultOwner = "Slide";
  
  
      /**
       * The true constant string.
       */
      public static final String TRUE = "1";
  
  
      /**
       * The false constant string.
       */
      public static final String FALSE = "0";
  
  
      /**
       * Date formats using for Date parsing.
       */
      public static final SimpleDateFormat formats[] = {
          new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
              new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
              new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
              new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US),
              new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
              new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US)
      };
  
  
      /**
       * GMT timezone.
       */
      protected final static TimeZone gmtZone = TimeZone.getTimeZone("GMT");
  
  
      static {
          for (int i = 0; i < formats.length; i++) {
              formats[i].setTimeZone(gmtZone);
          }
      }
  
  
      // --------------------------------------------------- Instance Variables
  
  
      /**
       * The HttpURL to represent a WebDAV resource.
       */
      protected HttpURL httpURL;
  
  
      /**
       * Table of the hrefs gotten in a collection.
       */
      protected WebdavResources childResources = new WebdavResources();
  
  
      /**
       * The default action to find properties.
       */
      protected static int defaultAction = BASIC;
  
  
      /**
       * The default depth for WebDAV methods.
       */
      protected static int defaultDepth = DepthSupport.DEPTH_0;
  
  
      /**
       * The default temporary directory for the GET method.
       * @deprecated The client is responsible for disk I/O.
       */
      protected static String tempDirForGet;
  
  
      /**
       * The flag setter to use the disk for the GET method.
       * @deprecated The client is responsible for disk I/O.
       */
      protected static boolean useDiskForGet = true;
  
  
      /**
       * The flag to set the status code by propfind.
       */
      protected boolean thisResource;
  
  
      /**
       * The allowed HTTP methods.
       */
      protected Enumeration allowedMethods;
  
  
      /**
       * The capabilities of the WebDAV server.
       */
      protected Enumeration davCapabilities;
  
  
      /**
       * An WebdavResource flag to check its existence;
       */
      protected boolean exists;
  
  
      /**
       * An WebdavResource flag to check overwriting;
       */
      protected boolean overwrite;
  
  
      /**
       * An status code performed by HTTP methods at the most recent.
       */
      protected int latestStatusCode;
  
  
      /**
       * An status message performed by HTTP methods at the most recent.
       */
      protected String latestStatusMessage = "";
  
  
      /**
       * An WebDAV property, displayname.
       */
      protected String displayName = "";
  
  
      /**
       * An WebDAV property, getcontentlength.
       */
      protected long getContentLength;
  
  
      /**
       * An WebDAV property, getcontenttype.
       */
      protected String getContentType = "";
  
  
      /**
       * An WebDAV property, resourcetype.
       */
      protected ResourceTypeProperty resourceType;
  
  
      /**
       * An WebDAV property, getlastmodified.
       */
      protected long getLastModified;
  
  
      /**
       * An WebDAV property, creationdate.
       */
      protected long creationDate;
  
  
      /**
       * An WebDAV property, getetag.
       */
      protected String getEtag = "";
  
      /**
       * Owner information for locking and unlocking.
       */
      protected String owner = null;
  
  
      /**
       * An WebDAV property, ishidden.
       */
      protected boolean isHidden;
  
  
      /**
       * An WebDAV property, iscollection.
       */
      protected boolean isCollection;
  
  
      /**
       * An WebDAV property, supportedlock.
       */
      protected String supportedLock = "";
  
  
      /**
       * An WebDAV property, lockdiscovery.
       */
      protected LockDiscoveryProperty lockDiscovery;
  
      protected boolean followRedirects = false;
  
      /**
       * Map of additional headers
       */
      protected Map headers = new HashMap();
  
      // --------------------------------------------------------- Basic settings
  
      /**
       * Generates and adds the "Transaction" header if this method is part of
       * an externally controlled transaction.
       */
      protected void generateTransactionHeader(HttpMethod method) {
          if (client == null || method == null) return;
  
          WebdavState state = (WebdavState) client.getState();
          String txHandle = state.getTransactionHandle();
          if (txHandle != null) {
              method.setRequestHeader("Transaction", "<" + txHandle + ">");
          }
      }
      
      /**
       * Generate and add the If header to the specified HTTP method.
       */
      protected void generateIfHeader(HttpMethod method) {
  
          if (client == null) return;
          if (method == null) return;
  
          WebdavState state = (WebdavState) client.getState();
          String[] lockTokens = state.getAllLocks(method.getPath());
  
          if (lockTokens.length == 0) return;
  
          StringBuffer ifHeaderValue = new StringBuffer();
  
          for (int i = 0; i < lockTokens.length; i++) {
              ifHeaderValue.append("(<").append(lockTokens[i]).append(">) ");
          }
  
          method.setRequestHeader("If", ifHeaderValue.toString());
  
      }
  
      /**
       * Add all additionals headers that have been previously registered
       * with addRequestHeader to the method
       */
      protected void generateAdditionalHeaders(HttpMethod method) {
          for (Iterator iterator = headers.keySet().iterator(); iterator.hasNext();) {
              String header = (String) iterator.next();
              method.setRequestHeader(header, (String) headers.get(header));
          }
      }
  
      /**
       * Parse the <code>java.util.Date</code> string for HTTP-date.
       *
       * @return The parsed date.
       */
      protected Date parseDate(String dateValue) {
          // TODO: move to the common util package related to http.
          Date date = null;
          for (int i = 0; (date == null) && (i < formats.length); i++) {
              try {
                  synchronized (formats[i]) {
                      date = formats[i].parse(dateValue);
                  }
              } catch (ParseException e) {
              }
          }
  
          return date;
      }
  
  
      /**
       * Set only the displayname property for this resource.
       *
       * @param depth The depth to find properties.
       */
      protected void setNameProperties(int depth)
          throws HttpException, IOException {
  
          Vector properties = new Vector();
          properties.addElement(DISPLAYNAME);
  
          setNamedProp(depth, properties);
      }
  
  
      /**
       * Sets the basic properties on a resource by indirectly issuing a PROPFIND
       * on the resource.
       *
       * <p>Properties retrieved include:
       *
       * <ul>
       *  <li>displayname</li>
       *  <li>getcontentlength</li>
       *  <li>getcontenttype</li>
       *  <li>resourcetype</li>
       *  <li>getlastmodified</li>
       *  <li>lockdiscovery</li>
       * </ul>
       *
       * @param depth The depth to find properties.
       */
      protected void setBasicProperties(int depth)
          throws HttpException, IOException {
  
          Vector properties = new Vector();
          properties.addElement(DISPLAYNAME);
          properties.addElement(GETCONTENTLENGTH);
          properties.addElement(GETCONTENTTYPE);
          properties.addElement(RESOURCETYPE);
          properties.addElement(GETLASTMODIFIED);
          properties.addElement(LOCKDISCOVERY);
  
          setNamedProp(depth, properties);
      }
  
  
      /**
       * Set the default properties on the resource by indirectly issuing a PROPFIND request
       * for a default set of properties.
       *
       * <p>Properties retrieved include:
       *
       * <ul>
       *  <li>creationdate</li>
       *  <li>displayname</li>
       *  <li>getcontentlanguage</li>
       *  <li>getcontentlength</li>
       *  <li>getcontenttype</li>
       *  <li>getetag</li>
       *  <li>getlastmodified</li>
       *  <li>lockdiscovery</li>
       *  <li>resourcetype</li>
       *  <li>source</li>
       *  <li>supportedlock</li>
       * </ul>
       *
       * @param depth The depth to find properties.
       */
      protected void setDefaultProperties(int depth)
          throws HttpException, IOException {
  
          Vector properties = new Vector();
          properties.addElement(CREATIONDATE);
          properties.addElement(DISPLAYNAME);
          properties.addElement(GETCONTENTLANGUAGE);
          properties.addElement(GETCONTENTLENGTH);
          properties.addElement(GETCONTENTTYPE);
          properties.addElement(GETETAG);
          properties.addElement(GETLASTMODIFIED);
          properties.addElement(LOCKDISCOVERY);
          properties.addElement(RESOURCETYPE);
          properties.addElement(SOURCE);
          properties.addElement(SUPPORTEDLOCK);
  
          setNamedProp(depth, properties);
      }
  
  
      /**
       * Set the named properties for this resource.
       *
       * @param depth The depth.
       * @param propertyNames The property-names.
       */
      protected void setNamedProp(int depth, Vector propertyNames)
          throws HttpException, IOException {
  
          Enumeration responses = propfindMethod(depth, propertyNames);
          setWebdavProperties(responses);
      }
  
  
      /**
       * Set all properties for this resource.
       *
       * @param depth The depth
       */
      protected void setAllProp(int depth)
          throws HttpException, IOException {
  
          Enumeration responses = propfindMethod(depth);
          setWebdavProperties(responses);
      }
  
  
      /**
       * Set WebDAV properties following to the given http URL.
       * This method is fundamental for getting information of a collection.
       *
       * @param responses An enumeration over {@link ResponseEntity} items, one
       * for each resource for which information was returned via PROPFIND.
       *
       * @exception HttpException
       * @exception IOException The socket error with a server.
       */
      protected void setWebdavProperties(Enumeration responses)
          throws HttpException, IOException {
      
          // Make the resources in the collection empty.
          childResources.removeAll();
          while (responses.hasMoreElements()) {
      
              ResponseEntity response =
                  (ResponseEntity) responses.nextElement();
      
              boolean itself = false;
              String href = response.getHref();
              if (!href.startsWith("/"))
                  href = URIUtil.getPath(href);
              href = decodeMarks(href);
  
              /*
               * Decode URIs to common (unescaped) format for comparison 
               * as HttpClient.URI.setPath() doesn't escape $ and : chars.
               */
              String httpURLPath = httpURL.getPath();
              String escapedHref = URIUtil.decode(href);
              
              // Normalize them to both have trailing slashes if they differ by one in length.
              int lenDiff = escapedHref.length() - httpURLPath.length();
              int compareLen = 0;
              
              if ( lenDiff == -1 && !escapedHref.endsWith("/")) {
                  compareLen = escapedHref.length();
                  lenDiff = 0;
              }
              else
              if ( lenDiff == 1 && !httpURLPath.endsWith("/")) {
                  compareLen = httpURLPath.length();
                  lenDiff = 0;
              }
  
              // if they are the same length then compare them.
              if (lenDiff == 0) {
                  if ((compareLen == 0 && httpURLPath.equals(escapedHref))
                      || httpURLPath.regionMatches(0, escapedHref, 0, compareLen))
                  {
                      // escaped href and http path are the same
                      // Set the status code for this resource.
                      if (response.getStatusCode() > 0)
                          setStatusCode(response.getStatusCode());
                      setExistence(true);
                      itself = true;
                  }
              }
      
              // Get to know each resource.
              WebdavResource workingResource = null;
              if (itself) {
                  workingResource = this;
              }
              else {
                  workingResource = createWebdavResource(client);
                  workingResource.setDebug(debug);
              }
      
              // clear the current lock set
              workingResource.setLockDiscovery(null);
      
              // Process the resource's properties
              Enumeration properties = response.getProperties();
              while (properties.hasMoreElements()) {
      
                  Property property = (Property) properties.nextElement();
      
                  // ------------------------------  Checking WebDAV properties
                  workingResource.processProperty(property);
              }
      
              String displayName = workingResource.getDisplayName();
      
              if (displayName == null || displayName.trim().equals("")) {
                  displayName = getName(href, true);
              }
              if (!itself) {
                  String myURI = httpURL.getEscapedURI();
                  char[] childURI = (myURI + (myURI.endsWith("/") ? "" : "/")
                                     + getName(href, false)).toCharArray();
                  HttpURL childURL = httpURL instanceof HttpsURL
                                     ? new HttpsURL(childURI)
                                     : new HttpURL(childURI);
                  childURL.setRawAuthority(httpURL.getRawAuthority());
                  workingResource.setHttpURL(childURL, NOACTION, defaultDepth);
                  workingResource.setExistence(true);
                  workingResource.setOverwrite(getOverwrite());
              }
              workingResource.setDisplayName(displayName);
      
              if (!itself)
                  childResources.addResource(workingResource);
          }
      }
  
  
      // ------------------------------------------------------------ Properties
  
  
      /**
       * Set the default action for this resource.
       * The default action is set as 'BASIC' for the first time.
       *
       * ex)
       *  WebdavResource.NOACTION
       *  WebdavResource.NAME
       *  WebdavResource.BASIC
       *  WebdavResource.DEFAULT
       *  WebdavResource.ALL
       *
       * @param action The action type.
       * @see #NOACTION
       * @see #NAME
       * @see #BASIC
       * @see #DEFAULT
       * @see #ALL
       */
      public static void setDefaultAction(int action) {
          defaultAction = action;
      }
  
  
      /**
       * Get the default action.
       *
       * @return The action type.
       */
      public static int getDefaultAction() {
          return defaultAction;
      }
  
  
      /**
       * Set the default action for this resource.
       *
       * ex)
       *   DepthSupport.DEPTH_0
       *   DepthSupport.DEPTH_1
       *   DepthSupport.DEPTH_INFINITY
       *
       * @param depth The depth.
       */
      public static void setDefaultDepth(int depth) {
          defaultDepth = depth;
      }
  
  
      /**
       * Get the default action.
       *
       * @return The depth.
       */
      public static int getDefaultDepth() {
          return defaultDepth;
      }
  
  
      /**
       * Get the default temporary directory for the GET method.
       *
       * @param tempDir The temporary directory.
       * @deprecated The given directory will not be used.
       */
      public static void setGetTempDir(String tempDir) {
          tempDirForGet = tempDir;
      }
  
  
      /**
       * Get the default temporary directory for the GET method.
       * The default temporary directory is "temp/".
       *
       * @return The temporary directory path.
       *         It's set by default, if it returns null.
       * @deprecated The returned directory is not used by the GET method.
       */
      public static String getGetTempDir() {
          return tempDirForGet;
      }
  
  
  
      /**
       * Set the use disk flag for the GET method.
       *
       * @param useDisk The use disk flag.
       * @deprecated This method has no effect.
       */
      public static void setGetUseDisk(boolean useDisk) {
          //useDiskForGet = useDisk;
      }
  
  
      /**
       * Get the use disk flag for the GET method.
       *
       * @return The current flag of the use disk.
       *         By default, it's true.
       * @deprecated This method always returns false.
       */
      public static boolean getGetUseDisk() {
          return false;
      }
  
      /**
       * Sets a flag indicating that redirect responses from
       * the server shall be followed.
       */
      public void setFollowRedirects(boolean value) {
         this.followRedirects = value;
      }
      /**
       * Returns the current "follow redirects" flag.
       * @see #setFollowRedirects(boolean)
       */
      public boolean getFollowRedirects() {
         return this.followRedirects;
      }
  
  
      /**
       * Test that the httpURL is the same with the client.
       *
       * @return true if the given httpURL is the client for this resource.
       */
      protected synchronized boolean isTheClient() throws URIException {
          HostConfiguration hostConfig = client.getHostConfiguration();
          Credentials creds =
              client.getState().getCredentials(null, hostConfig.getHost());
          String userName = null;
          String password = null;
  
          if (creds instanceof UsernamePasswordCredentials) {
              UsernamePasswordCredentials upc = (UsernamePasswordCredentials) creds;
              userName = upc.getUserName();
              password = upc.getPassword();
          }
          String ref = httpURL.getUser();
          boolean userMatches = userName != null ? userName.equals(ref)
                                                 : ref == null;
          if (userMatches) {
              ref = httpURL.getPassword();
              userMatches = password != null ? password.equals(ref)
                                             : ref == null;
          } else {
              return false;
          }
          if (userMatches) {
              return httpURL.getHost().equalsIgnoreCase(hostConfig.getHost())
                  && httpURL.getPort()
                  == hostConfig.getProtocol().resolvePort(hostConfig.getPort());
          }
          return false;
      }
  
  
      /**
       * Set the client for this resource.
       *
       * @exception IOException
       */
      protected void setClient() throws IOException {
          setClient(httpURL);
      }
  
  
      /**
       * Set the client for this resource and the given http URL.
       *
       * @param httpURL The http URL.
       * @exception IOException
       */
      protected synchronized void setClient(HttpURL httpURL) throws IOException {
  
          if (client == null) {
              client = getSessionInstance(httpURL);
          } else if (!isTheClient()) {
              closeSession();
              client = getSessionInstance(httpURL);
          }
      }
  
  
      /**
       * Set the HttpURL for this WebdavResource.
       *
       * @param httpURL the specified HttpURL.
       * @param action The action to decide, which properties to find.
       * @param depth The depth to find properties.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(java.lang.String)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       * @see #setPath(java.lang.String)
       * @see #setDefaultAction(int)
       */
      public void setHttpURL(HttpURL httpURL, int action, int depth)
          throws HttpException, IOException {
  
          this.httpURL = httpURL;
          setClient(httpURL);
          // make its existence false
          setExistence(false);
  
          try {
              setProperties(action, depth);
          } catch (Exception e) {
              // Ignore the exception if default properties cannot be loaded 
          }
      }
  
  
      /**
       * Set the HttpURL for this WebdavResource.
       *
       * @param httpURL the specified HttpURL.
       * @param depth The depth to find properties.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(java.lang.String)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       * @see #setPath(java.lang.String)
       */
      public void setHttpURL(HttpURL httpURL, int depth)
          throws HttpException, IOException {
  
          // Follow the default action.
          setHttpURL(httpURL, defaultAction, depth);
      }
  
  
      /**
       * Set the HttpURL for this WebdavResource.
       * It must be put an escaped path part of the http URL as an argument.
       *
       * @param httpURL The specified HttpURL.
       * @param additionalPath The added relative path.
       * @param action The action to decide, which properties to find.
       * @param depth The depth.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(java.lang.String)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       * @see #setPath(java.lang.String)
       * @see #setDefaultAction(int)
       */
      public void setHttpURL
          (HttpURL httpURL, String additionalPath, int action, int depth)
          throws HttpException, IOException {
  
          setHttpURL(httpURL instanceof HttpsURL
                     ? new HttpsURL((HttpsURL) httpURL, additionalPath)
                     : new HttpURL(httpURL, additionalPath), action, depth);
      }
  
  
      /**
       * Set the HttpURL for this WebdavResource.
       * It must be put an escaped path part of the http URL as an argument.
       *
       * @param httpURL The specified HttpURL.
       * @param additionalPath The added relative path.
       * @param action The action to decide, which properties to find.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(java.lang.String)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       * @see #setPath(java.lang.String)
       * @see #setDefaultAction(int)
       */
      public void setHttpURL
          (HttpURL httpURL, String additionalPath, int action)
          throws HttpException, IOException {
  
          setHttpURL(httpURL instanceof HttpsURL
                     ? new HttpsURL((HttpsURL) httpURL, additionalPath)
                     : new HttpURL(httpURL, additionalPath),
                     action, defaultDepth);
      }
  
  
      /**
       * Set the HttpURL for this WebdavResource.
       *
       * @param httpURL The specified HttpURL.
       * @param additionalPath The added relative path.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(java.lang.String)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       * @see #setPath(java.lang.String)
       */
      public void setHttpURL(HttpURL httpURL, String additionalPath)
          throws HttpException, IOException {
  
          setHttpURL(httpURL instanceof HttpsURL
                     ? new HttpsURL((HttpsURL) httpURL, additionalPath)
                     : new HttpURL(httpURL, additionalPath),
                     defaultAction, defaultDepth);
      }
  
  
      /**
       * Set the HttpURL for this WebdavResource.
       *
       * @param httpURL the specified HttpURL.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(java.lang.String)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       * @see #setPath(java.lang.String)
       */
      public void setHttpURL(HttpURL httpURL)
          throws HttpException, IOException {
  
          setHttpURL(httpURL, defaultDepth);
      }
  
  
      /**
       * Set the HttpURL of this WebdavResource.
       * It must be put an escaped http URL as an argument.
       *
       * @param escapedHttpURL The escaped http URL string.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(HttpURL)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       * @see #setPath(java.lang.String)
       */
      public void setHttpURL(String escapedHttpURL)
          throws HttpException, IOException {
  
          setHttpURL(escapedHttpURL.startsWith("https")
                     ? new HttpsURL(escapedHttpURL)
                     : new HttpURL(escapedHttpURL));
      }
  
  
      /**
       * Get the HttpURL of this WebdavResource.
       *
       * @return httpURL the http URL.
       */
      public HttpURL getHttpURL() {
          return httpURL;
      }
  
  
      /**
       * Get the HttpURL except for userinfo.
       *
       * @return httpURL the http URL.
       */
      public HttpURL getHttpURLExceptForUserInfo()
          throws URIException {
  
          return httpURL instanceof HttpsURL ? new HttpsURL(httpURL.getRawURI())
                                             : new HttpURL(httpURL.getRawURI());
      }
  
  
      /**
       * Set the path part of this WebdavResource.
       *
       * @param path the specified path.
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(HttpURL)
       * @see #setHttpURL(java.lang.String)
       * @see #setUserInfo(java.lang.String, java.lang.String)
       */
      public void setPath(String path)
          throws HttpException, IOException {
  
          httpURL.setPath(path);
          setHttpURL(httpURL);
      }
  
  
      /**
       * Get the path part of this WebdavResource.
       * If the decoding of the path fails, this method will not throw an
       * exception but return the escaped path instead.
       *
       * @return the path for this WebdavResource.
       * @see org.apache.commons.httpclient.HttpURL#getPath()
       * @see #setPath(java.lang.String)
       */
      public String getPath() {
          try {
              return httpURL.getPath();
          } catch (URIException e) {
              return httpURL.getEscapedPath();
          }
      }
  
  
      /**
       * Get the name of this WebdavResource.
       * If the decoding of the name fails, this method will not throw an
       * exception but return the escaped name instead.
       *
       * @return the name of this WebdavResource.
       * @see org.apache.commons.httpclient.HttpURL#getName()
       */
      public String getName() {
          return getName(httpURL.getEscapedPath(), true);
      }
  
  
      /**
       * Get the hostname of this WebdavResource.
       *
       * @return the hostname.
       * @exception URIException
       */
      public String getHost() throws URIException {
          return httpURL.getHost();
      }
  
  
      /**
       * Set the userinfo part of this WebdavResource.
       *
       * @exception HttpException
       * @exception IOException
       * @see #setHttpURL(HttpURL)
       * @see #setHttpURL(java.lang.String)
       * @see #setPath(java.lang.String)
       */
      public void setUserInfo(String userName, String password)
          throws HttpException, IOException {
  
          httpURL.setUserinfo(userName, password);
          setHttpURL(httpURL);
      }
  
  
      /**
       * Add a header in the request sent to the webdav server
       *
       * @param header Header name
       * @param value Value
       */
      public void addRequestHeader(String header, String value) {
          headers.put(header, value);
      }
  
  
  
      // ------------------------------------------------ DAV properties checking
  
  
      /**
       * Get the value of DAV property, displayname.
       *
       * @return The displayname string.
       */
      public String getDisplayName() {
          return displayName;
      }
  
  
      /**
       * Set the value of DAV property, displayname.
       *
       * @param displayName The displayname string.
       */
      protected void setDisplayName(String displayName) {
          this.displayName = displayName;
      }
  
  
      /**
       * Get the value of DAV property, getcontentlength.
       *
       * @return The getcontentlength value.
       */
      public long getGetContentLength() {
          return getContentLength;
      }
  
  
      /**
       * Set the value of DAV property, getcontentlength.
       *
       * @param getContentLength The getcontentlength value.
       */
      protected void setGetContentLength(long getContentLength) {
          this.getContentLength = getContentLength;
      }
  
  
      /**
       * Set the value of DAV property, getcontentlength.
       *
       * @param getContentLength The getcontentlength value.
       */
      protected void setGetContentLength(String getContentLength) {
          try {
              this.getContentLength = Long.parseLong(getContentLength);
          } catch (NumberFormatException nfe) {
              // it's ok to ignore this error.
          }
      }
  
  
      /**
       * Get the value of DAV property, resourcetype.
       *
       * @return The resourcetype property.
       * @see #isCollection()
       */
      public ResourceTypeProperty getResourceType() {
          return resourceType;
      }
  
  
      /**
       * Set the value of DAV property, resourcetype.
       *
       * @param resourceType The resourcetype property.
       */
      protected void setResourceType(ResourceTypeProperty resourceType) {
          this.resourceType = resourceType;
      }
  
  
      /**
       * Get the value of DAV property, resourcetype
       *
       * @return The resourcetype string.
       * @see #getResourceType()
       * @see #getIsCollection()
       */
      public boolean isCollection() {
          if (getResourceType() == null) return false;
          return getResourceType().isCollection();
      }
  
  
      /**
       * Get the value of DAV property, getcontenttype.
       *
       * @return The getcontenttype string.
       */
      public String getGetContentType() {
          return getContentType;
      }
  
  
      /**
       * Set the value of DAV property, getcontenttype.
       *
       * @param getContentType The getcontenttype string.
       */
      protected void setGetContentType(String getContentType) {
          this.getContentType = getContentType;
      }
  
      /**
       * Set the content-type to use for this resource, for PUTs.
       * @param contentType The content-type string.
       */
      public void setContentType(String contentType) {
          this.getContentType = contentType;
      }
  
      /**
       * Get the value of DAV property, getlastmodified.
       *
       * @return The getlastmodified value.
       */
      public long getGetLastModified() {
          return getLastModified;
      }
  
  
      /**
       * Set the value of DAV property, getlastmodified.
       *
       * @param getLastModified The getlastmodified value.
       * @see #setGetLastModified(java.lang.String)
       */
      protected void setGetLastModified(long getLastModified) {
          this.getLastModified = getLastModified;
      }
  
  
      /**
       * Set the value of DAV property, getlastmodified.
       *
       * @param getLastModified The getlastmodified value.
       * @see #setGetLastModified(long)
       */
      protected void setGetLastModified(String getLastModified) {
          Date date = parseDate(getLastModified);
          if (date != null)
              this.getLastModified = date.getTime();
      }
  
  
      /**
       * Get the value of DAV property, creationdate.
       *
       * @return The creationdate string.
       */
      public long getCreationDate() {
          return creationDate;
      }
  
  
      /**
       * Set the value of DAV property, creationdate.
       *
       * @param creationDate The creationdate string.
       */
      protected void setCreationDate(long creationDate) {
          this.creationDate = creationDate;
      }
  
  
      /**
       * Set the value of DAV property, creationdate.
       *
       * @param creationDate The creationdate string.
       */
      protected void setCreationDate(String creationDate) {
          Date date = parseDate(creationDate);
          if (date != null)
              this.creationDate = date.getTime();
      }
  
  
      /**
       * Get the value of DAV property, getetag.
       *
       * @return The getetag string.
       */
      public String getGetEtag() {
          return getEtag;
      }
  
  
      /**
       * Set the value of DAV property, getetag.
       *
       * @param getEtag The getetag string.
       */
      protected void setGetEtag(String getEtag) {
          this.getEtag = getEtag;
      }
  
      /**
       * Get the owner string, as used for locking purposes.
       */
      public String getOwner() {
          return owner;
      }
  
      /**
       * Get the value of DAV property, supportedlock.
       *
       * @return The supportedlock string.
       */
      public String getSupportedLock() {
          return supportedLock;
      }
  
  
      /**
       * Set the value of DAV property, supportedlock.
       *
       * @param supportedLock The supportedlock string.
       */
      protected void setSupportedLock(String supportedLock) {
          this.supportedLock = supportedLock;
      }
  
  
      /**
       * Get the value of DAV property, lockdiscovery.
       *
       * @return The lockdiscovery property.
       */
      public LockDiscoveryProperty getLockDiscovery() {
          return lockDiscovery;
      }
  
      /**
       * Set the value of DAV property, lockdiscovery.
       *
       * @param lockDiscovery The lockdiscovery property.
       */
      protected void setLockDiscovery(LockDiscoveryProperty lockDiscovery) {
          this.lockDiscovery = lockDiscovery;
      }
  
  
      /**
       * Get the activelock owners for this resource.
       *
       * @return An enumeration of owners.
       */
      public Enumeration getActiveLockOwners() {
          if (lockDiscovery == null) return null;
          Lock[] activeLocks = lockDiscovery.getActiveLocks();
          if (activeLocks == null) return null;
          Vector buff = new Vector();
          int count = activeLocks.length;
          for (int i = 0; i < count; i++) {
              buff.addElement(activeLocks[i].getOwner());
          }
          return buff.elements();
      }
  
  
      /**
       * Test that this resource is locked.
       *
       * @return true if it's locked.
       */
      public boolean isLocked() {
          if (lockDiscovery == null) return false;
          Lock[] activeLocks = lockDiscovery.getActiveLocks();
          if (activeLocks == null) return false;
          for (int i = 0; i < activeLocks.length; i++) {
              if (activeLocks[i].getLockType() == Lock.TYPE_WRITE) return true;
          }
          return false;
      }
  
  
      /**
       * Get the value of DAV property, ishidden.
       *
       * @return true if it is hidden, otherwise false.
       */
      public boolean getIsHidden() {
          return isHidden;
      }
  
  
      /**
       * Set the value of DAV property, ishidden.
       *
       * @param isHidden
       */
      protected void setIsHidden(boolean isHidden) {
          this.isHidden = isHidden;
      }
  
  
      /**
       * Set the value of DAV property, ishidden.
       *
       * @param isHidden
       */
      protected void setIsHidden(String isHidden) {
          this.isHidden = isHidden.equals(TRUE) ? true : false;
      }
  
  
      /**
       * Get the value of DAV property, iscollection
       *
       * @return true if it is collection, otherwise false.
       * @see #isCollection()
       */
      public boolean getIsCollection() {
          return isCollection;
      }
  
  
      /**
       * Set the value of DAV property, iscollection
       *
       * @param isCollection
       */
      protected void setIsCollection(boolean isCollection) {
          this.isCollection = isCollection;
      }
  
  
      /**
       * Set the value of DAV property, iscollection
       *
       * @param isCollection
       */
      protected void setIsCollection(String isCollection) {
          this.isCollection = isCollection.equals(TRUE) ? true : false;
      }
  
  
      // --------------------------------------- WebDAV Resource Public Methods
  
  
      /**
       * Set the properties for this resource.
       *
       * @param action The action to find properties for this resource.
       * @param depth the depth to which properties shall be found
       * @see #setDefaultAction(int)
       */
      public void setProperties(int action, int depth)
          throws HttpException, IOException {
  
          switch (action) {
              case NAME:
                  setNameProperties(depth);
                  break;
              case BASIC:
                  setBasicProperties(depth);
                  break;
              case DEFAULT:
                  setDefaultProperties(depth);
                  break;
              case ALL:
                  setAllProp(depth);
                  break;
              case NOACTION:
              default:
                  break;
          }
      }
  
  
      /**
       * Set the properties for this resource.
       *
       * @param depth the depth to which properties shall be found
       */
      public void setProperties(int depth)
          throws HttpException, IOException {
  
          setProperties(defaultAction, depth);
      }
  
      /**
       * Refresh the properties of this resource
       * without changing the status of the previous command
       */
      protected void refresh() throws HttpException, IOException {
          int latestStatusCode = this.latestStatusCode;
          String latestStatusMessage = this.latestStatusMessage;
          setProperties(DepthSupport.DEPTH_0);
          this.latestStatusCode = latestStatusCode;
          this.latestStatusMessage = latestStatusMessage;
      }
  
      /**
       * Returns the last known information about the existence of this resource.
       * This is a wrapper method for getExistence.
       *
       * A previous call to the method setProperties might be necessary to update
       * that information.
       *  
       * @return true if the resource is known to exist<br>
       *         false if the resource is known not to exist or its status is unknown.
       * @see #getExistence()
       * @see #setProperties(int, int)
       */
      public boolean exists() {
          return getExistence();
      }
  
  
      /**
       * Set its existence.
       *
       * @param exists The boolean value to be set for its existence.
       */
      protected void setExistence(boolean exists) {
          this.exists = exists;
      }
  
  
      /**
       * Returns the last known information about the existence of this resource.
       *
       * A previous call to the method setProperties might be necessary to update that
       * information.
       *  
       * @return true if the resource is known to exist<br>
       *         false if the resource is known not to exist or its status is unknown.
       * @see #setProperties(int, int)
       */
      public boolean getExistence() {
          return exists;
      }
  
  
      /**
       * Set the overwrite flag for COPY, MOVE, BIND and REBIND.
       * Should be set before the method is executed.
       *
       * @param overwrite the overwrite flag
       * @see #getOverwrite()
       */
      public void setOverwrite(boolean overwrite) {
          this.overwrite = overwrite;
      }
  
  
      /**
       * Get the current value of the overwrite flag for COPY, MOVE, BIND and
       * REBIND.
       *
       * @return true if the current flag is overwriting.
       * @see #setOverwrite(boolean)
       */
      public boolean getOverwrite() {
          return overwrite;
      }
  
  
      /**
       * Close the session of this client
       */
      public void close() throws IOException {
          closeSession();
      }
  
  
      /**
       * Get the lastest value of the status message by HTTP methods.
       *
       * @return The http status string.
       */
      public String getStatusMessage() {
          return latestStatusMessage;
      }
  
  
      /**
       * Get the lastest value of the status code by HTTP methods.
       *
       * @return The http status code.
       */
      public int getStatusCode() {
          return latestStatusCode;
      }
  
  
      /**
       * Set the lastest value of the status code by HTTP methods.
       *
       * @param statusCode the HTTP status code.
       */
      protected void setStatusCode(int statusCode) {
          setStatusCode(statusCode, null);
      }
  
  
      /**
       * Set the lastest value of the status code by HTTP methods.
       *
       * @param statusCode the HTTP status code.
       * @param message the additional message.
       */
      protected void setStatusCode(int statusCode, String message) {
  
          latestStatusCode = statusCode;
          latestStatusMessage = WebdavStatus.getStatusText(statusCode) +
              " (" + statusCode + ")" + ((message == null) ? "" : message);
      }
  
  
      /**
       * Get the allowed methods, checked by HTTP OPTIONS.
       *
       * @return the allowed HTTP methods.
       * @see #optionsMethod(java.lang.String)
       */
      public Enumeration getAllowedMethods() {
          return allowedMethods;
      }
  
  
      /**
       * Get the WebDAV capabilities, checked by HTTP OPTIONS.
       *
       * @return the WebDAV capabilities.
       * @see #optionsMethod(java.lang.String)
       */
      public Enumeration getDavCapabilities() {
          return davCapabilities;
      }
  
  
      /**
       * Get all resources in this collection with the depth 1.
       *
       * @return resources in this collection with the depth 1.
       * @exception HttpException
       * @exception IOException
       */
      public WebdavResources getChildResources()
          throws HttpException, IOException {
  
          setProperties(DepthSupport.DEPTH_1);
  
          return childResources;
      }
  
  
      /**
       * Get an array of resources denoting the WebDAV child resources in the
       * collection of this resources.
       *
       * @return An array of child resources in this resource.
       * @exception HttpException
       * @exception IOException
       */
      public WebdavResource[] listWebdavResources()
          throws HttpException, IOException {
  
          return getChildResources().listResources();
      }
  
  
      /**
       * Get an array of pathnames denoting the WebDAV resources in the
       * collection denoted by this pathname.
       *
       * @return An array of pathnames denoting the resources, null if an
       *         IOException occurs.
       */
      public String[] list() {
  
          try {
              setNameProperties(DepthSupport.DEPTH_1);
          } catch (IOException e) {
              return null;
          }
          Enumeration hrefs = childResources.getResourceNames();
  
          // To be atomic.
          Vector hrefList = new Vector();
          while (hrefs.hasMoreElements()) {
              hrefList.addElement((String) hrefs.nextElement());
          }
          // Calculate the size of the string array.
          int num = hrefList.size();
          String[] pathnames = new String[num];
          for (int i = 0; i < num; i++) {
              pathnames[i] = (String) hrefList.elementAt(i);
          }
  
          return pathnames;
      }
  
  
      /**
       * Get an array of pathnames and basic information denoting the WebDAV
       * resources in the denoted by this pathname.
       *
       * array 0: displayname
       * array 1: getcontentlength
       * array 2: iscollection or getcontentype
       * array 3: getlastmodifieddate
       * array 4: name
       *
       * @return An array of pathnames and more denoting the resources.
       * @exception HttpException
       * @exception IOException
       */
      public Vector listBasic()
          throws HttpException, IOException {
  
          setBasicProperties(DepthSupport.DEPTH_1);
          Enumeration hrefs = childResources.getResourceNames();
  
          Vector hrefList = new Vector();
          while (hrefs.hasMoreElements()) {
              try {
                  String resourceName = (String) hrefs.nextElement();
                  WebdavResource currentResource =
                      childResources.getResource(resourceName);
  
                  String[] longFormat = new String[5];
                  // displayname.
                  longFormat[0] = currentResource.getDisplayName();
  
  
                  long length = currentResource.getGetContentLength();
                  // getcontentlength
                  longFormat[1] = new Long(length).toString();
                  // resourcetype
                  ResourceTypeProperty resourceTypeProperty =
                      currentResource.getResourceType();
                  // getcontenttype
                  String getContentType =
                      currentResource.getGetContentType();
                  longFormat[2] = resourceTypeProperty.isCollection() ?
                      "COLLECTION" : getContentType ;
                  Date date = new Date(currentResource.getGetLastModified());
                  // getlastmodified
                  // Save the dummy what if failed.
                  longFormat[3] = (date == null) ? "-- -- ----" :
                      // Print the local fancy date format.
                      DateFormat.getDateTimeInstance().format(date);
                  hrefList.addElement(longFormat);
  
                  // real name of componente
                  longFormat[4] = currentResource.getName();
  
  
              } catch (Exception e) {
                  // FIXME: After if's gotten an exception, any solution?
                  if (debug > 0)
                      e.printStackTrace();
                  //log.error(e,e);
              }
          }
  
          return hrefList;
      }
  
  
      /**
       * Set the URL encoding flag for this http URL.
       *
       * @param encodeURLs true if it is encoded.
       * @exception MalformedURLException
       * @exception IOException
       *
       * @deprecated  No longer has any effect.
       */
      public void setEncodeURLs(boolean encodeURLs) {
  
      }
  
  
      // -------------------------- General accessor to use http request methods.
  
  
      /**
       * Retrieve the current http client for this resource.
       *
       * @return The http client.
       * @see #executeHttpRequestMethod(HttpClient, HttpMethod)
       */
      public HttpClient retrieveSessionInstance()
          throws IOException {
  
          setClient();
          return client;
      }
  
  
      /**
       * Execute the http request method.  And get its status code.
       *
       * @param client The http client.
       * @param method The http method.
       * @return The status code.
       * @see #retrieveSessionInstance()
       */
      public int executeHttpRequestMethod(HttpClient client, HttpMethod method)
          throws IOException, HttpException {
  
          client.executeMethod(method);
          return method.getStatusCode();
      }
  
  
      // --------------------------------- WebDAV Request-method Public Methods
  
      /**
       * Updates the resource with a new set of aces.
       *
       * @param path the server relative path of the resource to which the given
       *        ACEs shall be applied
       * @param aces the ACEs to apply
       * @return true if the method succeeded
       */
      public boolean aclMethod(String path, Ace[] aces)
          throws HttpException, IOException {
  
          setClient();
  
          AclMethod method = new AclMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          for (int i=0; i<aces.length ; i++) {
              Ace ace = aces[i];
              method.addAce(ace);
          }
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Return the <code>AclProperty</code> for the current resource
       *
       * @return acl property, null if the server doesn't respond with
       * <code>AclProperty</code>
       */
      public AclProperty aclfindMethod() throws HttpException, IOException {
          thisResource = true;
          return aclfindMethod(httpURL.getPath());
      }
  
  
      /**
       * Return the <code>AclProperty</code> for the resource at the given path
       *
       * @param path the server relative path of the resource to request
       * @return acl property, null if the server doesn't respond with
       * <code>AclProperty</code>
       */
      public AclProperty aclfindMethod(String path)
          throws HttpException, IOException {
  
          setClient();
  
          AclProperty acl = null;
  
          Vector properties = new Vector();
          properties.addElement(AclProperty.TAG_NAME);
  
          // Default depth=0, type=by_name
          PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                     DepthSupport.DEPTH_0,
                                                     properties.elements());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Enumeration responses = method.getResponses();
          if (responses.hasMoreElements()) {
              ResponseEntity response =
                  (ResponseEntity) responses.nextElement();
              String href = response.getHref();
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              Enumeration responseProperties =
                  method.getResponseProperties(href);
              while (responseProperties.hasMoreElements()) {
                  Property property =
                      (Property) responseProperties.nextElement();
                  if (property instanceof AclProperty) {
                      acl = (AclProperty)property;
                  }
  
              }
          }
  
          return acl;
      }
  
  
      /**
       * Get the <code>PrincipalCollectionSetProperty</code> for the current
       * resource.
       *
       * @return principal collection set Property, null if the server doesn't
       * respond with a <code>PrincipalCollectionSetProperty</code>
       */
      public PrincipalCollectionSetProperty principalCollectionSetFindMethod()
          throws HttpException, IOException {
          thisResource = true;
          return principalCollectionSetFindMethod(httpURL.getPath());
      }
  
      /**
       * Get the <code>PrincipalCollectionSetProperty</code> for the resource.
       *
       * @param path the server relative path of the resource to request
       * @return principal collection set Property, null if the server doesn't
       * respond with a <code>PrincipalCollectionSetProperty</code>
       */
      public PrincipalCollectionSetProperty principalCollectionSetFindMethod(
          String path) throws HttpException, IOException {
  
          setClient();
  
          PrincipalCollectionSetProperty set = null;
  
          Vector properties = new Vector();
          properties.addElement(PrincipalCollectionSetProperty.TAG_NAME);
  
          // Default depth=0, type=by_name
          PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                     DepthSupport.DEPTH_0,
                                                     properties.elements());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Enumeration responses = method.getResponses();
          if (responses.hasMoreElements()) {
              ResponseEntity response =
                  (ResponseEntity) responses.nextElement();
              String href = response.getHref();
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              Enumeration responseProperties =
                  method.getResponseProperties(href);
              while (responseProperties.hasMoreElements()) {
                  Property property =
                      (Property) responseProperties.nextElement();
                  if (property instanceof PrincipalCollectionSetProperty) {
                      set = (PrincipalCollectionSetProperty)property;
                  }
  
              }
          }
  
          return set;
      }
  
  
      /**
       * Return the LockDiscoveryProperty for the current resource
       *
       * @return null if the server doesn't respond with a LockDiscoveryProperty
       */
      public LockDiscoveryProperty lockDiscoveryPropertyFindMethod()
          throws HttpException, IOException {
          thisResource = true;
          return lockDiscoveryPropertyFindMethod(httpURL.getPath());
      }
  
  
      /**
       * Return the LockDiscoveryProperty for the resource at the given path
       *
       * @param path the server relative path of the resource to request
       * @return null if the server doesn't respond with a LockDiscoveryProperty
       */
      public LockDiscoveryProperty lockDiscoveryPropertyFindMethod(String path)
          throws HttpException, IOException {
  
          setClient();
  
          LockDiscoveryProperty set = null;
  
          Vector properties = new Vector();
          properties.addElement(LockDiscoveryProperty.TAG_NAME);
  
          // Default depth=0, type=by_name
          PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                     DepthSupport.DEPTH_0,
                                                     properties.elements());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Enumeration responses = method.getResponses();
          if (responses.hasMoreElements()) {
              ResponseEntity response =
                  (ResponseEntity) responses.nextElement();
              String href = response.getHref();
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              Enumeration responseProperties =
                  method.getResponseProperties(href);
              while (responseProperties.hasMoreElements()) {
                  Property property =
                      (Property) responseProperties.nextElement();
                  if (property instanceof LockDiscoveryProperty) {
                      set = (LockDiscoveryProperty)property;
                  }
  
              }
          }
  
          return set;
      }
  
  
      /**
       * Get InputStream for the GET method.
       *
       * @return InputStream
       * @exception HttpException
       * @exception IOException
       */
      public InputStream getMethodData()
          throws HttpException, IOException {
  
          return getMethodData(httpURL.getPathQuery());
      }
  
  
      /**
       * Get InputStream for the GET method for the given path.
       *
       * @param path the server relative path of the resource to get
       * @return InputStream
       * @exception HttpException
       * @exception IOException
       */
      public InputStream getMethodData(String path)
          throws HttpException, IOException {
  
          setClient();
  
          GetMethod method = new GetMethod(URIUtil.encodePathQuery(path));
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          int statusCode = method.getStatusLine().getStatusCode();
          setStatusCode(statusCode);
  
          if(statusCode >= 200 && statusCode < 300)
              return method.getResponseBodyAsStream();
          else
              throw new IOException("Couldn't get file");
      }
  
  
      /**
       * Get data as a String for the GET method.
       *
       * @return the contents of this resource as a string
       * @exception HttpException
       * @exception IOException
       */
      public String getMethodDataAsString()
          throws HttpException, IOException {
  
          return getMethodDataAsString(httpURL.getPathQuery());
      }
  
  
      /**
       * Get data as a String for the GET method for the given path.
       *
       * @param path the server relative path of the resource to get
       * @return the contents of the given resource as a string
       * @exception HttpException
       * @exception IOException
       */
      public String getMethodDataAsString(String path)
          throws HttpException, IOException {
  
          setClient();
          GetMethod method = new GetMethod(URIUtil.encodePathQuery(path));
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return method.getResponseBodyAsString();
      }
  
  
      /**
       * Execute the GET method for this WebdavResource path.
       *
       * @param file The local file.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean getMethod(File file)
          throws HttpException, IOException {
  
          return getMethod(httpURL.getPathQuery(), file);
      }
  
  
      /**
       * Execute the GET method for the given path.
       *
       * @param path the server relative path of the resource to get
       * @param file The local file.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean getMethod(String path, File file)
          throws HttpException, IOException {
  
          setClient();
          GetMethod method = new GetMethod(URIUtil.encodePathQuery(path));
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          // get the file only if status is any kind of OK
          if (statusCode >= 200 && statusCode < 300) {
  
              // Do a simple little loop to read the response back into the passed
              // file parameter.
              InputStream inStream = method.getResponseBodyAsStream();
  
              FileOutputStream fos = new FileOutputStream(file);
              byte buffer[] = new byte[65535];
              int bytesRead;
              while ((bytesRead = inStream.read(buffer)) >= 0) {
                  fos.write(buffer, 0, bytesRead);
              }
              inStream.close();
              fos.close();
  
              return true;
  
          } else {
              return false;
  
          }
  
  
     }
  
  
      /**
       * Execute the PUT method for this resource.
       *
       * @param data The byte array.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(byte[] data)
          throws HttpException, IOException {
  
          boolean result = putMethod(httpURL.getPathQuery(), data);
          if (result) refresh();
          return result;
      }
  
  
      /**
       * Execute the PUT method for the given path.
       *
       * @param path the server relative path to put the data
       * @param data The byte array.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(String path, byte[] data)
          throws HttpException, IOException {
  
          setClient();
          PutMethod method = new PutMethod(URIUtil.encodePathQuery(path));
          generateIfHeader(method);
          if (getGetContentType() != null && !getGetContentType().equals(""))
              method.setRequestHeader("Content-Type", getGetContentType());
  
          method.setRequestHeader("Content-Length", String.valueOf(data.length));
          method.setRequestBody(new ByteArrayInputStream(data));
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the PUT method for this resource.
       *
       * @param is The input stream.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(InputStream is)
          throws HttpException, IOException {
  
          return putMethod(httpURL.getPathQuery(), is);
      }
  
  
      /**
       * Execute the PUT method for the given path.
       *
       * @param path the server relative path to put the data
       * @param is The input stream.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(String path, InputStream is)
          throws HttpException, IOException {
  
          setClient();
          PutMethod method = new PutMethod(URIUtil.encodePathQuery(path));
          generateIfHeader(method);
          if (getGetContentType() != null && !getGetContentType().equals(""))
              method.setRequestHeader("Content-Type", getGetContentType());
          method.setRequestContentLength(PutMethod.CONTENT_LENGTH_CHUNKED);
          method.setRequestBody(is);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the PUT method for this WebdavResource.
       *
       * @param data String</cdoe> data to send.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(String data)
          throws HttpException, IOException {
  
          boolean result = putMethod(httpURL.getPathQuery(), data);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the PUT method for the given path.
       *
       * @param path the server relative path to put the data
       * @param data String to send.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(String path, String data)
          throws HttpException, IOException {
  
          setClient();
          PutMethod method = new PutMethod(URIUtil.encodePathQuery(path));
          generateIfHeader(method);
          if (getGetContentType() != null && !getGetContentType().equals(""))
              method.setRequestHeader("Content-Type", getGetContentType());
          method.setRequestBody(data);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the PUT method for this WebdavResource.
       *
       * @param file the filename to get on local.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(File file)
          throws HttpException, IOException {
  
          boolean result = putMethod(httpURL.getPathQuery(), file);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the PUT method for the given path.
       *
       * @param path the server relative path to put the given file
       * @param file the filename to get on local.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(String path, File file)
          throws HttpException, IOException {
  
          setClient();
          PutMethod method = new PutMethod(URIUtil.encodePathQuery(path));
          generateIfHeader(method);
          if (getGetContentType() != null && !getGetContentType().equals(""))
              method.setRequestHeader("Content-Type", getGetContentType());
          long fileLength = file.length();
          method.setRequestContentLength(fileLength <= Integer.MAX_VALUE
                                         ? (int) fileLength
                                         : PutMethod.CONTENT_LENGTH_CHUNKED);
          method.setRequestBody(new FileInputStream(file));
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
  
      /**
       * Execute the PUT method for this resource from the given url.
       * It's like a streaming copy about a resource of the specified remote url
       * to another remote url of this resource.
       *
       * @param url The URL to get a resource.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(URL url)
          throws HttpException, IOException {
  
          boolean result = putMethod(httpURL.getPathQuery(), url);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the PUT method for the given path from the given url.
       *
       * @param path the server relative path to put the data
       * @param url The URL to get a resource.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean putMethod(String path, URL url)
          throws HttpException, IOException {
  
          setClient();
          PutMethod method = new PutMethod(URIUtil.encodePathQuery(path));
          generateIfHeader(method);
          if (getGetContentType() != null && !getGetContentType().equals(""))
              method.setRequestHeader("Content-Type", getGetContentType());
          method.setRequestBody(url.openStream());
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute OPTIONS method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean optionsMethod()
          throws HttpException, IOException {
  
          return optionsMethod(httpURL.getPath());
      }
  
  
      /**
       * Execute OPTIONS method for the given path.
       *
       * @param path the server relative path of the resource to request
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @see #getAllowedMethods()
       */
      public boolean optionsMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          OptionsMethod method;
          if (path.trim().equals("*"))
              method = new OptionsMethod("*");
          else
              method = new OptionsMethod(URIUtil.encodePath(path));
  
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          if  (statusCode >= 200 && statusCode < 300) {
              // check if the specific method is possbile
              allowedMethods = method.getAllowedMethods();
              // check WebDAV capabilities.
              davCapabilities = method.getDavCapabilities();
              return true;
          }
  
          return false;
      }
  
  
      /**
       * Execute OPTIONS method for the given path.
       *
       * @param path the server relative path to send the request
       * @param aMethod a method to check it's supported.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean optionsMethod(String path, String aMethod)
          throws HttpException, IOException {
  
          if (aMethod != null && optionsMethod(path)) {
              while (allowedMethods.hasMoreElements()) {
                  if (aMethod.equalsIgnoreCase((String)
                                                   allowedMethods.nextElement()))
                      return true;
              }
          }
  
          return false;
      }
  
  
      /**
       * Execute OPTIONS method for the given http URL.
       *
       * @param httpURL the http URL.
       * @return the allowed methods and capabilities.
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration optionsMethod(HttpURL httpURL)
          throws HttpException, IOException {
  
          HttpClient client = getSessionInstance(httpURL, true);
  
          OptionsMethod method = new OptionsMethod(httpURL.getEscapedPath());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Vector options = new Vector();
          int statusCode = method.getStatusLine().getStatusCode();
          if (statusCode >= 200 && statusCode < 300) {
              // check if the specific method is possbile
              Enumeration allowedMethods = method.getAllowedMethods();
              while (allowedMethods.hasMoreElements()) {
                  options.addElement(allowedMethods.nextElement());
              }
              // check WebDAV capabilities.
              Enumeration davCapabilities = method.getDavCapabilities();
              while (davCapabilities.hasMoreElements()) {
                  options.addElement(davCapabilities.nextElement());
              }
              Enumeration responses = method.getResponses();
              if (responses.hasMoreElements()) {
                  ResponseEntity response =
                      (ResponseEntity) responses.nextElement();
                  Enumeration workspaces = response.getWorkspaces();
                  String sResult="";
                  while (workspaces.hasMoreElements()){
                      sResult += workspaces.nextElement().toString();
                  }
                  Enumeration histories = response.getHistories();
                  while (histories.hasMoreElements()){
                      sResult += histories.nextElement().toString();
                  }
                  // Set status code for this resource.
                  if ((thisResource == true) && (response.getStatusCode() > 0))
                      setStatusCode(response.getStatusCode());
                  thisResource = false;
                  options.addElement(sResult);
              }
          }
  
          return options.elements();
      }
  
  
      /**
       * Execute OPTIONS method for the given http URL, DELTAV
       *
       * @param httpURL the http URL.
       * @return the allowed methods and capabilities.
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration optionsMethod(HttpURL httpURL, int type)
          throws HttpException, IOException {
  
          HttpClient client = getSessionInstance(httpURL, true);
  
          OptionsMethod method = new OptionsMethod(httpURL.getEscapedPath(),
                                                   type);
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Vector options = new Vector();
          int statusCode = method.getStatusLine().getStatusCode();
          if  (statusCode >= 200 && statusCode < 300) {
              Enumeration responses = method.getResponses();
              if (responses.hasMoreElements()) {
                  ResponseEntity response =
                      (ResponseEntity) responses.nextElement();
                  // String sResult="";
                  if (type == OPTIONS_WORKSPACE){
                      Enumeration workspaces = response.getWorkspaces();
                      while (workspaces.hasMoreElements()){
                          options.add(workspaces.nextElement().toString());
                      }
                  } else if (type == OPTIONS_VERSION_HISTORY){
                      Enumeration histories = response.getHistories();
                      while (histories.hasMoreElements()){
                          options.add(histories.nextElement().toString());
                      }
                  }
  
                  // Set status code for this resource.
                  if ((thisResource == true) && (response.getStatusCode() > 0))
                      setStatusCode(response.getStatusCode());
                  thisResource = false;
                  // options.addElement(sResult);
              }
          }
  
          return options.elements();
      }
  
  
      /**
       * Execute OPTIONS method for the given path.
       *
       * @param path the server relative path of the resource to request
       * @return the allowed methods and capabilities.
       * @exception HttpException
       * @exception IOException
       * @see #getAllowedMethods()
       */
      public Enumeration optionsMethod(String path, int type)
          throws HttpException, IOException {
  
          setClient();
  
          OptionsMethod method = new OptionsMethod(URIUtil.encodePath(path),
                                                   type);
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Vector options = new Vector();
          int statusCode = method.getStatusLine().getStatusCode();
          if  (statusCode >= 200 && statusCode < 300) {
              Enumeration responses = method.getResponses();
              if (responses.hasMoreElements()) {
                  ResponseEntity response =
                      (ResponseEntity) responses.nextElement();
                  // String sResult="";
                  if (type == OPTIONS_WORKSPACE){
                      Enumeration workspaces = response.getWorkspaces();
                      while (workspaces.hasMoreElements()){
                          options.add(workspaces.nextElement().toString());
                      }
                  } else if (type == OPTIONS_VERSION_HISTORY){
                      Enumeration histories = response.getHistories();
                      while (histories.hasMoreElements()){
                          options.add(histories.nextElement().toString());
                      }
                  }
  
                  // Set status code for this resource.
                  if ((thisResource == true) && (response.getStatusCode() > 0))
                      setStatusCode(response.getStatusCode());
                  thisResource = false;
                  // options.addElement(sResult);
              }
          }
  
          return options.elements();
      }
  
      /**
       * Execute a LABEL method on the current path, setting the given label
       *
       * @param labelname the label to set
       * @param type the type of action. One of:
       *        <ul>
       *        <li> LABEL_ADD
       *        <li> LABEL_REMOVE
       *        <li> LABEL_SET
       *        </ul>
       * @return true if the method succeeded
       */
      public boolean labelMethod(String labelname, int type)
          throws HttpException, IOException {
          return labelMethod(httpURL.getPath(), labelname, type);
      }
  
      /**
       * Execute a LABEL method on the given path, setting the given label
       *
       * @param path the server relative path of the resource to act on
       * @param labelname the label to set
       * @param type the type of action. One of:
       *        <ul>
       *        <li> LABEL_ADD
       *        <li> LABEL_REMOVE
       *        <li> LABEL_SET
       *        </ul>
       * @return true if the method succeeded
       */
      public boolean labelMethod(String path, String labelname, int type)
          throws HttpException, IOException {
          int labeltype=0;
  
          switch(type) {
              case LABEL_SET:
                  labeltype = LabelMethod.LABEL_SET;
                  break;
              case LABEL_REMOVE:
                  labeltype = LabelMethod.LABEL_REMOVE;
                  break;
              case LABEL_ADD:
                  labeltype = LabelMethod.LABEL_ADD;
                  break;
          }
  
          setClient();
          LabelMethod method = new LabelMethod(URIUtil.encodePath(path),
                                               labeltype, labelname);
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
      /**
       * Execute the REPORT method.
       */
      public Enumeration reportMethod(HttpURL httpURL, int depth)
  
          throws HttpException, IOException {
          setClient();
          // Default depth=0, type=by_name
          ReportMethod method = new ReportMethod(httpURL.getEscapedPath(),
                                                 depth);
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Vector results = new Vector();
  
          Enumeration responses = method.getResponses();
          while (responses.hasMoreElements()) {
              ResponseEntity response = (ResponseEntity) responses.nextElement();
              String href = response.getHref();
              String sResult = href;
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              Enumeration responseProperties = method.getResponseProperties(href);
              while (responseProperties.hasMoreElements()) {
                  Property property = (Property) responseProperties.nextElement();
                  sResult += "\n" + property.getName() + ":\t" +
                      DOMUtils.getTextValue(property.getElement());
  
              }
              results.addElement(sResult);
          }
  
          return results.elements();
      }
  
      public Enumeration reportMethod(HttpURL httpURL, Vector properties)
  
          throws HttpException, IOException {
          setClient();
          // Default depth=0, type=by_name
          ReportMethod method =
              new ReportMethod(httpURL.getEscapedPath(), DepthSupport.DEPTH_0,
                               properties.elements());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          return method.getResponses();
      }
  
      public Enumeration reportMethod(HttpURL httpURL, Vector properties,
                                      int depth)
  
          throws HttpException, IOException {
          setClient();
          // Default depth=0, type=by_name
          ReportMethod method = new ReportMethod(httpURL.getEscapedPath(), depth,
                                                 properties.elements());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          /*first draft, does work anyhow
           Enumeration results = method.getAllResponseURLs();
  
           return results;*/
          /*  Enumeration responses = method.getResponses();
           ResponseEntity response = (ResponseEntity) responses.nextElement();
           String href = (String) response.getHref();
           Enumeration results = method.getResponseProperties(href);
  
           return results;*/
  
          Vector results = new Vector();
  
          Enumeration responses = method.getResponses();
          while (responses.hasMoreElements()) {
              ResponseEntity response = (ResponseEntity) responses.nextElement();
              String href = response.getHref();
              String sResult = href;
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              Enumeration responseProperties = method.getResponseProperties(href);
              while (responseProperties.hasMoreElements()) {
                  Property property = (Property) responseProperties.nextElement();
                  sResult += "\n" + property.getName() + ":\t" +
                      DOMUtils.getTextValue(property.getElement());
                  // results.addElement(DOMUtils.getTextValue(property.getElement()));
              }
              results.addElement(sResult);
          }
  
          return results.elements();
      }
  
  
      // locate-by-history Report
      public Enumeration reportMethod(HttpURL httpURL, Vector properties,
                                      Vector histUri, int depth)
  
          throws HttpException, IOException {
          setClient();
          // Default depth=0, type=by_name
          ReportMethod method = new ReportMethod(httpURL.getEscapedPath(), depth,
                                                 properties.elements(),
                                                 histUri.elements());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Vector results = new Vector();
  
          Enumeration responses = method.getResponses();
          while (responses.hasMoreElements()) {
              ResponseEntity response = (ResponseEntity) responses.nextElement();
              String href = response.getHref();
              String sResult = href;
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              Enumeration responseProperties = method.getResponseProperties(href);
              while (responseProperties.hasMoreElements()) {
                  Property property = (Property) responseProperties.nextElement();
                  sResult += "\n" + property.getName() + ":\t" +
                      DOMUtils.getTextValue(property.getElement());
              }
              results.addElement(sResult);
          }
  
          return results.elements();
      }
      // expand-property Report
      public Enumeration reportMethod(HttpURL httpURL, String sQuery, int depth)
  
          throws HttpException, IOException {
          setClient();
          // Default depth=0, type=by_name
          ReportMethod method = new ReportMethod(httpURL.getEscapedPath(), depth,
                                                 sQuery);
  
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          client.executeMethod(method);
  
          Vector results = new Vector();
  
          Enumeration responses = method.getResponses();
          while (responses.hasMoreElements()) {
              ResponseEntity response = (ResponseEntity) responses.nextElement();
              //String href = (String) response.getHref();
              String sResult; //= href;
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              sResult = response.toString();
              /*while (responseProperties.hasMoreElements()) {
               Property property = (Property) responseProperties.nextElement();
               sResult += "\t" + DOMUtils.getTextValue(property.getElement());
  
               }*/
              results.addElement(sResult);
          }
  
          return results.elements();
      }
  
  
      /**
       * Execute PROPFIND method with allprop for this WebdavResource.
       * Get list of all WebDAV properties on this WebDAV resource.
       *
       * <p>Once used this method, the the status code in the 207
       * reponse is need to be set for the method of WebdavResource.
       *
       * <p>The values of DepthSupport.DEPTH_0, DepthSupport.DEPTH_1,
       * DepthSupport.DEPTH_INFINITY is possbile for the depth.
       *
       * @param depth
       * @return an enumeration of <code>ResponseEntity</code>
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(int depth)
          throws HttpException, IOException {
  
          thisResource = true;
          return propfindMethod(httpURL.getPath(), depth);
      }
  
  
      /**
       * Execute PROPFIND method with allprop for the given path.
       * Get list of all WebDAV properties on the given resource.
       *
       * <p>Once used this method, the the status code in the 207
       * reponse is need to be set for the method of WebdavResource.
       *
       * <p>The values of DepthSupport.DEPTH_0, DepthSupport.DEPTH_1,
       * DepthSupport.DEPTH_INFINITY is possbile for the depth.
       *
       * @param path the server relative path of the resource to request
       * @param depth
       * @return an enumeration of <code>ResponseEntity</code>
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(String path, int depth)
          throws HttpException, IOException {
  
          setClient();
          // Change the depth for allprop
          PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                     depth);
  
          method.setDebug(debug);
  
          // Default depth=infinity, type=allprop
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int status = client.executeMethod(method);
  
          // Set status code for this resource.
          if (thisResource == true) {
              setStatusCode(status);
          }
          // Also accept OK sent by buggy servers.
          if (status != HttpStatus.SC_MULTI_STATUS
              && status != HttpStatus.SC_OK) {
              HttpException ex = new HttpException();
              ex.setReasonCode(status);
              throw ex;
          }
          thisResource = false;
  
          return method.getResponses();
      }
  
  
  
      /**
       * Execute PROPFIND method with by propname for this resource.
       * Get list of named WebDAV properties on this resource.
       *
       * <p>Once used this method, the the status code in the 207
       * reponse is need to be set for the method of WebdavResource.
       *
       * <p>The values of DepthSupport.DEPTH_0, DepthSupport.DEPTH_1
       * DepthSupport.DEPTH_INFINITY is possbile for the depth.
       *
       * @param depth The depth.
       * @param properties The named properties.
       * @return an enumeration of <code>ResponseEntity</code>
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(int depth, Vector properties)
          throws HttpException, IOException {
  
          thisResource = true;
          return propfindMethod(httpURL.getPath(), depth, properties);
      }
  
  
      /**
       * Execute PROPFIND method with by propname for the given path.
       * Get list of named WebDAV properties on the given resource.
       *
       * <p>Once used this method, the the status code in the 207
       * reponse is need to be set for the method of WebdavResource.
       *
       * <p>The values of DepthSupport.DEPTH_0, DepthSupport.DEPTH_1
       * DepthSupport.DEPTH_INFINITY is possbile for the depth.
       *
       * @param path the server relative path of the resource to request
       * @param depth The depth.
       * @param properties The named properties.
       * @return an enumeration of <code>ResponseEntity</code>
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(String path, int depth,
                                        Vector properties)
          throws HttpException, IOException {
  
          setClient();
          // Change the depth for prop
          PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                     depth,
                                                     properties.elements());
  
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int status = client.executeMethod(method);
  
          // Set status code for this resource.
          if (thisResource == true) {
              // Set the status code.
              setStatusCode(method.getStatusLine().getStatusCode());
          }
          // Also accept OK sent by buggy servers.
          if (status != HttpStatus.SC_MULTI_STATUS
              && status != HttpStatus.SC_OK) {
              HttpException ex = new HttpException();
              ex.setReasonCode(status);
              throw ex;
          }
          thisResource = false;
  
          return method.getResponses();
      }
  
  
      /**
       * Execute PROPFIND method for this WebdavResource.
       * Get list of given WebDAV properties on this WebDAV resource.
       *
       * @param propertyName the WebDAV property to find.
       * @return Enumeration list of WebDAV properties on a resource.
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(String propertyName)
          throws HttpException, IOException {
  
          Vector property = new Vector();
          property.addElement(propertyName);
  
          thisResource = true;
          return propfindMethod(httpURL.getPath(), property);
      }
  
  
      /**
       * Execute PROPFIND method for the given WebdavResource path.
       * Get list of given WebDAV properties on this WebDAV resource.
       *
       * @param path the server relative path of the resource to request
       * @param propertyName the WebDAV property to find.
       * @return Enumeration list of WebDAV properties on a resource.
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(String path, String propertyName)
          throws HttpException, IOException {
  
          Vector property = new Vector();
          property.addElement(propertyName);
  
          thisResource = false;
          return propfindMethod(path, property);
      }
  
  
      /**
       * Execute PROPFIND method for this WebdavResource.
       * Get list of given WebDAV properties on this WebDAV resource.
       *
       * @param properties the WebDAV properties to find.
       * @return Enumeration list of WebDAV properties on a resource.
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(Vector properties)
          throws HttpException, IOException {
  
          thisResource = true;
          return propfindMethod(httpURL.getPath(), properties);
      }
  
  
      /**
       * Execute PROPFIND method for the given path and properties.
       * Get list of given WebDAV properties on the given resource.
       *
       * @param path the server relative path of the resource to request
       * @param properties the WebDAV properties to find.
       * @return Enumeration list of WebDAV properties on a resource.
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration propfindMethod(String path, Vector properties)
          throws HttpException, IOException {
  
          setClient();
          // Default depth=0, type=by_name
          PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                     DepthSupport.DEPTH_0,
                                                     properties.elements());
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int status = client.executeMethod(method);
  
          // Also accept OK sent by buggy servers.
          if (status != HttpStatus.SC_MULTI_STATUS
              && status != HttpStatus.SC_OK) {
              HttpException ex = new HttpException();
              ex.setReasonCode(status);
              throw ex;
          }
  
          // It contains the results.
          Vector results = new Vector();
  
          Enumeration responses = method.getResponses();
          if (responses.hasMoreElements()) {
              ResponseEntity response =
                  (ResponseEntity) responses.nextElement();
              String href = response.getHref();
  
              // Set status code for this resource.
              if ((thisResource == true) && (response.getStatusCode() > 0))
                  setStatusCode(response.getStatusCode());
              thisResource = false;
  
              Enumeration responseProperties =
                  method.getResponseProperties(href);
              while (responseProperties.hasMoreElements()) {
                  Property property =
                      (Property) responseProperties.nextElement();
                  results.addElement(property.getPropertyAsString());
              }
          }
  
          return results.elements();
      }
  
  
      /**
       * Execute PROPATCH method for this WebdavResource.
       *
       * @param propertyName the name of the property to set
       * @param propertyValue the value of the property to set
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @deprecated it could be removed after the major version changes
       */
      public boolean proppatchMethod(String propertyName, String propertyValue)
          throws HttpException, IOException {
  
          boolean result = proppatchMethod(httpURL.getPath(),
                                           propertyName, propertyValue, true);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute PROPATCH method for this resource with the given property.
       *
       * @param propertyName the property name string (in "DAV:" namespace)
       * @param propertyValue the property value string
       * If the proppatch action is being removed, the value is null or any.
       * @param action true if it's being set, false if it's being removed
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean proppatchMethod(String propertyName, String propertyValue,
                                     boolean action) throws HttpException, IOException {
  
          boolean result = proppatchMethod(httpURL.getPath(),
                                           propertyName, propertyValue, action);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute PROPATCH method for this WebdavResource.
       *
       * @param propertyName the name of the property to set
       * @param propertyValue the value of the property to set
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @deprecated it could be removed after the major version changes
       */
      public boolean proppatchMethod(PropertyName propertyName,
                                     String propertyValue)
          throws HttpException, IOException {
  
          boolean result = proppatchMethod(httpURL.getPath(),
                                           propertyName, propertyValue, true);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute PROPATCH method for this resource with the given property.
       *
       * @param propertyName the name of the property to set
       * @param propertyValue the value of the property to set
       * If the proppatch action is being removed, the value is null or any.
       * @param action true if it's being set, false if it's being removed
       * @return true if the method is succeeded
       * @exception HttpException
       * @exception IOException
       */
      public boolean proppatchMethod(PropertyName propertyName,
                                     String propertyValue, boolean action)
          throws HttpException, IOException {
  
          boolean result = proppatchMethod(httpURL.getPath(),
                                           propertyName, propertyValue, action);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute PROPATCH method for the given WebdavResource.
       *
       * @param path the server relative path of the resource to act on
       * @param propertyName the property name in "DAV:" namespace
       * @param propertyValue the property value string
       * @return true if the method is succeeded
       * @exception HttpException
       * @exception IOException
       * @deprecated it could be removed after the major version changes
       */
      public boolean proppatchMethod(String path, String propertyName,
                                     String propertyValue) throws HttpException, IOException {
  
          Hashtable property = new Hashtable();
          property.put(propertyName, propertyValue);
          return proppatchMethod(path, property, true);
      }
  
  
      /**
       * Execute PROPATCH method for the specified resource with the given
       * property.
       *
       * @param path the server relative path of the resource to act on
       * @param propertyName the property name string (in "DAV:" namespace)
       * @param propertyValue the property value string
       * If the proppatch action is being removed, the value is null or any.
       * @param action true if it's to be set, false if it's to be removed
       * @return true if the method is succeeded
       * @exception HttpException
       * @exception IOException
       */
      public boolean proppatchMethod(String path, String propertyName,
                                     String propertyValue, boolean action)
          throws HttpException, IOException {
  
          Hashtable property = new Hashtable();
          property.put(propertyName, propertyValue);
          return proppatchMethod(path, property, action);
      }
  
  
      /**
       * Execute PROPATCH method for the given WebdavResource.
       *
       * @param path the server relative path of the resource to act on
       * @param propertyName the property name.
       * @param propertyValue the property value.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @deprecated it could be removed after the major version changes
       */
      public boolean proppatchMethod(String path, PropertyName propertyName,
                                     String propertyValue) throws HttpException, IOException {
  
          Hashtable property = new Hashtable();
          property.put(propertyName, propertyValue);
  
          return proppatchMethod(path, property, true);
      }
  
  
      /**
       * Execute PROPATCH method for the given resource with the given
       * properties.
       *
       * @param path the server relative path of the resource to act on
       * @param propertyName the property name
       * @param propertyValue the property value string
       * If the proppatch action is being removed, the value is null or any.
       * @param action true if it's to be set, false if it's to be removed
       * @return true if the method is succeeded
       * @exception HttpException
       * @exception IOException
       */
      public boolean proppatchMethod(String path, PropertyName propertyName,
                                     String propertyValue, boolean action)
          throws HttpException, IOException {
  
          Hashtable property = new Hashtable();
          property.put(propertyName, propertyValue);
          return proppatchMethod(path, property, action);
      }
  
  
      /**
       * Execute PROPATCH method for this WebdavResource.
       *
       * @param properties name and value pairs to set
       * (name can be a String or PropertyName)
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @deprecated it could be removed after the major version changes
       */
      public boolean proppatchMethod(Hashtable properties)
          throws HttpException, IOException {
  
          boolean result = proppatchMethod(httpURL.getPath(), properties, true);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute PROPATCH method for this resource with the given properties.
       *
       * @param properties the name(= <code>String</code> or <code>PropertyName
       * </code> and value(= <code>String</code>) pairs for proppatch action
       * If the proppatch action is being removed, the value is null or any.
       * @param action true if it's being set, false if it's being removed
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean proppatchMethod(Hashtable properties, boolean action)
          throws HttpException, IOException {
  
          boolean result = proppatchMethod(httpURL.getPath(), properties, action);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute PROPATCH method for the given WebdavResource.
       *
       * @param path the server relative path of the resource to act on
       * @param properties name and value pairs to set
       * (name can be a String or PropertyName)
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @deprecated it could be removed after the major version changes
       */
      public boolean proppatchMethod(String path, Hashtable properties)
          throws HttpException, IOException {
  
          return proppatchMethod(path, properties, true);
      }
  
  
      /**
       * Execute PROPATCH method for the specified resource with the given
       * properties.
       *
       * @param path the server relative path of the resource to act on
       * @param properties the name(= <code>String</code> or <code>PropertyName
       * </code> and value(= <code>String</code>) pairs for proppatch action
       * If the proppatch action is being removed, the value is null or any.
       * @param action true if it's being set, false if it's being removed
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean proppatchMethod(String path, Hashtable properties,
                                     boolean action) throws HttpException, IOException {
  
          setClient();
          PropPatchMethod method = new PropPatchMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          Enumeration names = properties.keys();
          boolean hasSomething = false;
          if (names.hasMoreElements()) {
              hasSomething = true;
          }
          while (names.hasMoreElements()) {
              Object item = names.nextElement();
              if (item instanceof String) {
                  String name = (String) item;
                  String value = (String) properties.get(item);
                  if (action) {
                      method.addPropertyToSet(name, value);
                  } else {
                      method.addPropertyToRemove(name);
                  }
              } else if (item instanceof PropertyName) {
                  String name         = ((PropertyName) item).getLocalName();
                  String namespaceURI = ((PropertyName) item).getNamespaceURI();
                  String value        = (String) properties.get(item);
                  if (action) {
                      method.addPropertyToSet(name, value, null, namespaceURI);
                  } else {
                      method.addPropertyToRemove(name, null, namespaceURI);
                  }
              } else {
                  // unknown type, debug or ignore it
              }
          }
          if (hasSomething) {
              generateTransactionHeader(method);
              generateAdditionalHeaders(method);
              int statusCode = client.executeMethod(method);
              // Possbile Status Codes => SC_OK
              // WebdavStatus.SC_FORBIDDEN, SC_CONFLICT, SC_LOCKED, 507
              setStatusCode(statusCode);
              if (statusCode >= 200 && statusCode < 300) {
                  return true;
              }
          }
          return false;
      }
  
  
      /**
       * Execute the HEAD method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean headMethod()
          throws HttpException, IOException {
  
          return headMethod(httpURL.getPathQuery());
      }
  
  
      /**
       * Execute the HEAD method for the given path.
       *
       * @param path the server relative path of the resource to request
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean headMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          HeadMethod method = new HeadMethod(URIUtil.encodePathQuery(path));
  
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the DELETE method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean deleteMethod()
          throws HttpException, IOException {
  
          boolean result = deleteMethod(httpURL.getPath());
          if (result) {
              setExistence(false);
          }
  
          return result;
      }
  
  
      /**
       * Execute the DELETE method for the given path.
       *
       * @param path the server relative path of the resource to delete
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean deleteMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          DeleteMethod method = new DeleteMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the MOVE method for this WebdavReource.
       *
       * @param destination the destination to move to as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean moveMethod(String destination)
          throws HttpException, IOException {
  
          boolean result = moveMethod(httpURL.getPath(), destination);
          if (result) {
              httpURL.setPath(destination);
              refresh();
          }
  
          return result;
      }
  
  
      /**
       * Execute the MOVE method for the given source and destination.
       *
       * @param source the source resource as a server relativ path
       * @param destination the destination to move to as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean moveMethod(String source, String destination)
          throws HttpException, IOException {
  
          setClient();
          MoveMethod method = new MoveMethod(URIUtil.encodePath(source),
                                             URIUtil.encodePath(destination));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateIfHeader(method);
          method.setOverwrite(overwrite);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          // Possbile MOVE Status Codes => SC_CREATED, SC_NO_CONTENT
          // WebdavStatus.SC_FORBIDDEN, SC_CONFLICT, SC_PRECONDITION_FAILED,
          // SC_LOCKED, SC_BAD_GATEWAY
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the COPY method for the given destination path.
       *
       * @param destination the destination as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean copyMethod(String destination)
          throws HttpException, IOException {
  
          boolean result = copyMethod(httpURL.getPath(), destination);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the COPY method the given source and destination.
       *
       * @param source the source resource as a server relative path
       * @param destination the destination as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean copyMethod(String source, String destination)
          throws HttpException, IOException {
  
          setClient();
          CopyMethod method = new CopyMethod(URIUtil.encodePath(source),
                                             URIUtil.encodePath(destination));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          method.setOverwrite(overwrite);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          // Possbile COPY Status Codes => SC_CREATED, SC_NO_CONTENT
          // WebdavStatus.SC_FORBIDDEN, SC_CONFLICT, SC_PRECONDITION_FAILED,
          // SC_LOCKED, SC_BAD_GATEWAY, SC_INSUFFICIENT_STORAGE
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
  
      /**
       * Execute the MKCOL method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean mkcolMethod()
          throws HttpException, IOException {
  
          boolean result = mkcolMethod(httpURL.getPath());
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the MKCOL method for the given path.
       *
       * @param path the server relative path at which to create a new collection
       *        resource
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean mkcolMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          MkcolMethod method = new MkcolMethod(URIUtil.encodePath(path));
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          // Possbile MKCOL Status Codes => SC_CREATED
          // WebdavStatus.SC_FORBIDDEN, SC_METHOD_NOT_ALLOWED, SC_CONFLICT,
          // SC_LOCKED, SC_UNSUPPORTED_MEDIA_TYPE, SC_INSUFFICIENT_STORAGE
          setStatusCode(statusCode);
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the LOCK method for this WebdavResource. This method tries to
       * acquire an exclusive write lock with a timeout of 120 seconds.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean lockMethod()
          throws HttpException, IOException {
  
          String owner = (httpURL.getUser() != null) ?
              httpURL.getUser() : defaultOwner;
  
          boolean result = lockMethod(httpURL.getPath(), owner, 120);
          if (result) refresh();
  
          return result;
      }
  
  
  
      /**
       * Execute the LOCK method for this WebdavResource. This method tries to
       * acquire an exclusive write lock with the given timeout value.
       *
       * @param owner the owner string.
       * @param timeout the timeout
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean lockMethod(String owner, int timeout)
          throws HttpException, IOException {
  
          boolean result = lockMethod(httpURL.getPath(), owner, timeout);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the LOCK method for the given path. This method tries to acquire
       * an exclusive write lock with a timeout of 120 seconds.
       *
       * @param path the server relative path of the resource to lock
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean lockMethod(String path)
          throws HttpException, IOException {
  
          String owner = (httpURL.getUser() != null) ?
              httpURL.getUser() : defaultOwner;
  
          return lockMethod(path, owner, 120);
      }
  
  
      /**
       * Execute the LOCK method for the given path. This method tries to acquire
       * an exclusive write lock with the given timeout value.
       *
       * @param path the server relative path of the resource to lock
       * @param owner The owner string.
       * @param timeout the timeout value.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean lockMethod(String path, String owner, int timeout)
          throws HttpException, IOException {
  
          return lockMethod(path, owner, timeout, LockMethod.SCOPE_EXCLUSIVE);
      }
  
      /**
       * Execute the LOCK method for the given path. This method tries to acquire
       * an exclusive write lock with the given timeout value.
       *
       * @param path the server relative path of the resource to lock
       * @param owner The owner string.
       * @param timeout the timeout value.
       * @param locktype, the scope of lock.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean lockMethod(String path, String owner, int timeout, short lockType)
          throws HttpException, IOException {
  
          return lockMethod(path, owner, timeout, lockType, DepthSupport.DEPTH_INFINITY);    
      }    
      
  
      /**
       * Execute the LOCK method for the given path. This method tries to acquire
       * an exclusive write lock with the given timeout value.
       *
       * @param path the server relative path of the resource to lock
       * @param owner The owner string.
       * @param timeout the timeout value.
       * @param locktype, the scope of lock.
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean lockMethod(String path, String owner, int timeout, short lockType, int depth)
          throws HttpException, IOException {            
  
          setClient();
  
          if (owner == null) {
              owner = (httpURL.getUser() != null) ? httpURL.getUser() : defaultOwner;
          }
  
          // default lock type setting
          LockMethod method = new LockMethod(URIUtil.encodePath(path), owner,
                                             lockType, timeout);
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          method.setDepth(depth);        
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
          String lock = method.getLockToken();
          WebdavState state = (WebdavState) client.getState();
          if (state != null) {
              state.addLock(path, lock);
          }
          this.owner = method.getOwner();
  
          // Possbile LOCK Status Codes => SC_OK
          // WebdavStatus.SC_SC_PRECONDITION_FAILED, SC_LOCKED
          setStatusCode(statusCode, lock);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the LOCK method for this WebdavResource.
       *
       * @see LockMethod
       * @deprecated The timeout value MUST NOT be greater than 2^32-1.
       */
      public boolean lockMethod(String owner, short timeout)
          throws HttpException, IOException {
  
          return lockMethod(owner, (int) timeout);
      }
  
  
      /**
       * Execute the LOCK method for the given path.
       *
       * @see LockMethod
       * @deprecated The timeout value MUST NOT be greater than 2^32-1.
       */
      public boolean lockMethod(String path, String owner, short timeout)
          throws HttpException, IOException {
  
          return lockMethod(path, owner, (int) timeout);
      }
  
      /**
       * Begins a new transaction. 
       * The transaction handle returned by the WebDAV server will be remembered and included
       * as a header of subsequent requests until either {@link #commitTransaction()} or {@link #abortTransaction()}
       * are called. You can retrieve it using {@link #getTransactionHandle()}.    
       * 
       * @param owner the owner of this transaction
       * @param timeout timeout in milleseconds
       * @return <code>true</code> if the transaction has been successfully started, <code>false</code> otherwise
       * @throws IOException if anything goes wrong
       * @see #commitTransaction()
       * @see #abortTransaction()
       * @see #getTransactionHandle()
       */
      public boolean startTransaction(String owner, int timeout) throws IOException {
          String path = httpURL.getPath();
          
          setClient();
  
          if (owner == null) {
              owner = (httpURL.getUser() != null) ? httpURL.getUser() : defaultOwner;
          }
  
          // default lock type setting
          LockMethod method = new LockMethod(path, owner, timeout, true);
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
          String txHandle = method.getLockToken();
          WebdavState state = (WebdavState) client.getState();
          if (state != null) {
              state.setTransactionHandle(txHandle);
          }
          this.owner = method.getOwner();
  
          // Possbile LOCK Status Codes => SC_OK
          // WebdavStatus.SC_SC_PRECONDITION_FAILED, SC_LOCKED
          setStatusCode(statusCode, txHandle);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
      /**
       * Returns the transaction handle set by {@link #startTransaction(String, int)}. 
       * 
       * @return the current transaction handle or <code>null</code> if the client does not operate inside a transaction
       * @throws IOException if anything goes wrong
       * @see #startTransaction(String, int)
       */
      public String getTransactionHandle() throws IOException {
          setClient();
  
          // Get the lock for the given path.
          WebdavState state = (WebdavState) client.getState();
          if (state == null) return null;
          String txHandle = state.getTransactionHandle();
          return txHandle;
      }
      
      /**
       * Commits the transaction started by {@link #startTransaction(String, int)} and resets the transaction handle.
       *  
       * @return <code>true</code> if the transaction has been successfully committed, <code>false</code> otherwise
       * @throws IOException if anything goes wrong
       * @see #startTransaction(String, int)
       * @see #abortTransaction()
       * @see #getTransactionHandle()
       */
      public boolean commitTransaction() throws IOException {
          String path = httpURL.getPath();
          return endTransaction(path, UnlockMethod.COMMIT_TRANSACTION);
      }
  
      /**
       * Aborts - i.e. rolls back all changes of - the transaction started by {@link #startTransaction(String, int)} and resets the transaction handle.
       *  
       * @return <code>true</code> if the transaction has been successfully committed, <code>false</code> otherwise
       * @throws IOException if anything goes wrong
       * @see #startTransaction(String, int)
       * @see #abortTransaction()
       * @see #getTransactionHandle()
       */
      public boolean abortTransaction() throws IOException {
          String path = httpURL.getPath();
          return endTransaction(path, UnlockMethod.ABORT_TRANSACTION);
      }
  
      protected boolean endTransaction(String path, int transactionStatus) throws IOException {
          setClient();
  
          // Get the lock for the given path.
          WebdavState state = (WebdavState) client.getState();
          if (state == null) return false;
          String txHandle = state.getTransactionHandle();
          if (txHandle == null) return false;
          UnlockMethod method = new UnlockMethod(path, txHandle, transactionStatus);
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          if (statusCode >= 200 && statusCode < 300) {
              state.setTransactionHandle(null);
              return true;
          }
          return false;
      }
  
      /**
       * Execute the Unlock method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean unlockMethod() throws HttpException, IOException {
  
          String owner = (httpURL.getUser() != null) ?
              httpURL.getUser() : defaultOwner;
  
          boolean result = unlockMethod(httpURL.getPath(), owner);
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the Unlock method for the given path.
       *
       * @param path the server relative path of the resource to unlock
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean unlockMethod(String path)
          throws HttpException, IOException {
  
          String owner = (httpURL.getUser() != null) ?
              httpURL.getUser() : defaultOwner;
  
          return unlockMethod(path, owner);
      }
  
  
      /**
       * Execute the Unlock method for the given path.
       *
       * @param path the server relative path of the resource to unlock
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean unlockMethod(String path, String owner)
          throws HttpException, IOException {
  
          setClient();
  
          if (owner == null) {
              owner = (httpURL.getUser() != null) ? httpURL.getUser() : defaultOwner;
          }
  
          // Get the lock for the given path.
          WebdavState state = (WebdavState) client.getState();
          // Discover the locktoken from the given lock owner
  
          state = discoverLock(owner, path, state);
          String lock = state.getLock(path);
          if (lock == null) return false;
          // unlock for the given path.
          UnlockMethod method = new UnlockMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          method.setLockToken(lock);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
          if (statusCode >= 200 && statusCode < 300) {
              state.removeLocks(path);
              return true;
          }
  
          return false;
      }
  
  
      /**
       * Discover and refresh lock tokens.
       *
       * @exception HttpException
       * @exception IOException
       */
      public void discoverOwnLocks()
      throws HttpException, IOException {
  
          setClient();
          String owner = (httpURL.getUser() != null) ?
              httpURL.getUser() : defaultOwner;
  
          WebdavState state = (WebdavState) client.getState();
          state = discoverLock(owner, httpURL.getPath(), state);
          client.setState(state);
      }
  
  
      /**
       * Discover and refresh lock tokens for a specific owner.
       *
       * @param owner the owner who's locks are to be discovered.
       * @exception HttpException
       * @exception IOException
       */
      public void discoverOwnLocks(String owner)
      throws HttpException, IOException {
  
          setClient();
  
          WebdavState state = (WebdavState) client.getState();
          state = discoverLock(owner, httpURL.getPath(), state);
          client.setState(state);
      }
  
  
      /**
       * Discover the given owner and locktoken and set the locktoken
       *
       * @param owner the activelock owner
       * @param path the server relative path of the resource to request
       * @param state the state to save the locktoken
       * @return state probably having lock information renewly
       */
      protected WebdavState discoverLock(String owner, String path,
                                         WebdavState state) {
          try {
              lockDiscovery=lockDiscoveryPropertyFindMethod(path);
          } catch (Exception e) {
              return state;
          }
  
  
          if (lockDiscovery == null) return state;
          Lock[] activeLocks = lockDiscovery.getActiveLocks();
  
          if (activeLocks == null) return state;
          for (int i = 0; i < activeLocks.length; i++) {
              String activeLockOwner = activeLocks[i].getOwner();
              if (activeLockOwner.equals(owner)) {
                  String locktoken = activeLocks[i].getLockToken();
                  state.addLock(path, locktoken);
              }
          }
          return state;
      }
  
  
      /**
       * Update this resource to the specified target
       *
       * @param target the path of the history element to update this resource
       *        from
       * @return true if the method has succeeded
       * @exception HttpException
       * @exception IOException
       */
      public boolean updateMethod(String target)
          throws HttpException, IOException {
  
          return updateMethod(httpURL.getPath(), target);
      }
  
  
      /**
       * Update the specified resource to the specified target
       *
       * @param path the server relative path of the resource to update
       * @param target path of the target to update from (history resource)
       * @return true if the method has succeeded
       * @exception HttpException
       * @exception IOException
       */
      public boolean updateMethod(String path, String target)
          throws HttpException, IOException {
  
          setClient();
          UpdateMethod method = new UpdateMethod(URIUtil.encodePath(path),
                                                 URIUtil.encodePath(target));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      public boolean versionControlMethod(String path)
          throws HttpException, IOException {
  
          setClient();
  
          VersionControlMethod method = new VersionControlMethod(
                                              URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      public boolean versionControlMethod(String path, String target)
          throws HttpException, IOException {
  
          setClient();
  
          VersionControlMethod method = new VersionControlMethod(
                                       URIUtil.encodePath(path),
                                       URIUtil.encodePath(target));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the MKWORKSPACE method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean mkWorkspaceMethod()
          throws HttpException, IOException {
  
          boolean result = mkWorkspaceMethod(httpURL.getPath());
          if (result) refresh();
  
          return result;
      }
  
  
      /**
       * Execute the MKCOL method for the given path.
       *
       * @param path the server relative path at which to create a new workspace
       *        resource
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean mkWorkspaceMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          MkWorkspaceMethod method =
              new MkWorkspaceMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          // Possbile MKCOL Status Codes => SC_CREATED
          // WebdavStatus.SC_FORBIDDEN, SC_METHOD_NOT_ALLOWED, SC_CONFLICT,
          // SC_LOCKED, SC_UNSUPPORTED_MEDIA_TYPE, SC_INSUFFICIENT_STORAGE
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      // -------------------------------------------------------- Basic Methods
  
  
      /**
       * Compare to the WebdavResource object.
       *
       * @param another the other WebdavResource object
       * @return the value 0 if the argument is equal.
       */
      public int compareToWebdavResource(WebdavResource another) {
  
          try {
              HttpURL anotherUrl = another.getHttpURL();
  
              String thisHost = httpURL.getHost();
              String anotherHost= anotherUrl.getHost();
              if (!thisHost.equalsIgnoreCase(anotherHost))
                  return thisHost.compareTo(anotherHost);
  
              int thisPort = httpURL.getPort();
              int anotherPort= anotherUrl.getPort();
              if (thisPort != anotherPort)
                  return (thisPort < anotherPort) ? -1 : 1;
  
              boolean thisCollection = isCollection();
              boolean anotherCollection = another.isCollection();
              if (thisCollection && !anotherCollection)
                  return -1;
              if (anotherCollection && !thisCollection)
                  return 1;
  
              String thisPath = httpURL.getPathQuery();
              String anotherPath= anotherUrl.getPathQuery();
              return thisPath.compareTo(anotherPath);
          } catch (Exception e) {
              // FIXME: not to return 0.
          }
  
          return 0;
      }
  
  
      /**
       * Compare to the given another object.
       *
       * @param another the other WebdavResource object
       * @return the value 0 if another is equal.
       */
      public int compareTo(Object another) {
  
          if ((another != null) && (another instanceof WebdavResource)) {
              return compareToWebdavResource((WebdavResource) another);
          }
  
          String thisUrl = toString();
          String anotherUrl = another.toString();
  
          return thisUrl.compareTo(anotherUrl);
      }
  
  
      /**
       * Test the object.
       *
       * @param obj the other object
       * @return true if it's equal.
       */
      public boolean equals(Object obj) {
  
          if ((obj != null) && (obj instanceof WebdavResource)) {
              return compareTo(obj) == 0;
          }
          return false;
      }
  
  
      /**
       * Return the http URL string.
       *
       * @return the http URL string.
       */
      public String toString() {
          return httpURL.toString();
      }
  
  
      /**
       * Execute the CHECKIN method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean checkinMethod()
          throws HttpException, IOException {
  
          return checkinMethod(httpURL.getPath());
      }
  
  
      /**
       * Execute the CHECKIN method for the given path.
       *
       * @param path the server relative path of the resource to check in
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean checkinMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          CheckinMethod method = new CheckinMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the CHECKOUT method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean checkoutMethod()
          throws HttpException, IOException {
  
          return checkoutMethod(httpURL.getPath());
      }
  
  
      /**
       * Execute the CHECKOUT method for the given path.
       *
       * @param path the server relative path of the resource to check out
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean checkoutMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          CheckoutMethod method = new CheckoutMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
  
      /**
       * Execute the CHECKOUT method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean uncheckoutMethod()
          throws HttpException, IOException {
  
          return uncheckoutMethod(httpURL.getPath());
      }
  
  
  
  
      /**
       * Execute the CHECKOUT method for the given path.
       *
       * @param path the server relative path of the resource to act on
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean uncheckoutMethod(String path)
          throws HttpException, IOException {
  
          setClient();
          UncheckoutMethod method =
              new UncheckoutMethod(URIUtil.encodePath(path));
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
  
          generateIfHeader(method);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          setStatusCode(statusCode);
  
          return (statusCode >= 200 && statusCode < 300) ? true : false;
      }
  
      /**
       * Create a new WebdavResource object (as a seperate method so that it can
       * be overridden by subclasses.
       *
       * @param client HttpClient to be used by this webdavresource.
       * @return A new WebdavResource object.
       */
      protected WebdavResource createWebdavResource(HttpClient client) {
          WebdavResource resource = new WebdavResource(client);
          resource.setProxy(proxyHost, proxyPort);
          resource.setProxyCredentials(proxyCredentials);
          return resource;
      }
  
      /**
       * Process a property, setting various member variables depending
       * on what the property is.
       *
       * @param property The property to process.
       */
      protected void processProperty(Property property) {
          if (property.getLocalName().equals(DISPLAYNAME)) {
              displayName = property.getPropertyAsString();
          }
          else if (property.getLocalName().equals(GETCONTENTLENGTH)) {
              String getContentLength = property.getPropertyAsString();
              setGetContentLength(getContentLength);
          }
          else if (property.getLocalName().equals(RESOURCETYPE)) {
              ResourceTypeProperty resourceType =
                  (ResourceTypeProperty) property;
              setResourceType(resourceType);
          }
          else if (property.getLocalName().equals(GETCONTENTTYPE)) {
              String getContentType = property.getPropertyAsString();
              setGetContentType(getContentType);
          }
          else if (property.getLocalName().equals(GETLASTMODIFIED)) {
              String getLastModified = property.getPropertyAsString();
              setGetLastModified(getLastModified);
          }
          else if (property.getLocalName().equals(CREATIONDATE)) {
              String creationDate = property.getPropertyAsString();
              setCreationDate(creationDate);
          }
          else if (property.getLocalName().equals(GETETAG)) {
              String getEtag = property.getPropertyAsString();
              setGetEtag(getEtag);
          }
          else if (property.getLocalName().equals(ISHIDDEN)) {
              String isHidden = property.getPropertyAsString();
              setIsHidden(isHidden);
          }
          else if (property.getLocalName().equals(ISCOLLECTION)) {
              String isCollection = property.getPropertyAsString();
              setIsCollection(isCollection);
          }
          else if (property.getLocalName().equals(SUPPORTEDLOCK)) {
              String supportedLock = property.getPropertyAsString();
              setSupportedLock(supportedLock);
          }
          else if (property.getLocalName().equals(LOCKDISCOVERY)) {
              LockDiscoveryProperty lockDiscovery =
                  (LockDiscoveryProperty) property;
              setLockDiscovery(lockDiscovery);
          }
      }
  
  
      /**
       * Execute REPORT method.
       * This method is for the special Access Control Reports:
       * - acl-principal-prop-set (not supported yet)
       * - principal-match (not supported yet)
       * - principal-property-search
       * - principal-search-property-set (not supported yet)
       *
       * @param path the server relative path of the resource to request
       * @param properties The named properties.
       * @return an enumeration of <code>ResponseEntity</code>
       * @exception HttpException
       * @exception IOException
       */
      public Enumeration aclReportMethod(
          String path,
          Collection properties,
          int reportType)
          throws HttpException, IOException {
  
          setClient();
          AclReportMethod method =
              new AclReportMethod(
                  URIUtil.encodePath(path),
                  properties,
                  DepthSupport.DEPTH_0,
                  reportType);
  
          method.setDebug(debug);
          method.setFollowRedirects(this.followRedirects);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int status = client.executeMethod(method);
  
          // Set status code for this resource.
          if (thisResource == true) {
              // Set the status code.
              setStatusCode(method.getStatusLine().getStatusCode());
          }
  
          //slide/tamino delivers status code OK.
          //can be removed when the server sends MULTI_STATUS
          if (status != HttpStatus.SC_MULTI_STATUS && status != HttpStatus.SC_OK) {
              HttpException ex = new HttpException();
              ex.setReasonCode(status);
              throw ex;
          }
          thisResource = false;
  
          return method.getResponses();
      }
  
  
      /**
       * Execute the BIND method for this WebdavResource, given
       * an existing path to bind with.
       *
       * @param newBinding  the new binding as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @see #setOverwrite(boolean)
       */
      public boolean bindMethod(String newBinding)
          throws HttpException, IOException {
          return bindMethod(httpURL.getPath(), newBinding);
      }
  
      /**
       * Execute the BIND method given the new path to bind to an existing path.
       *
       * @param existingBinding  the existing binding as a server relative path
       * @param newBinding       the new binding as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @see #setOverwrite(boolean)
       */
      public boolean bindMethod(String existingBinding, String newBinding)
          throws HttpException, IOException {
  
          setClient();
          BindMethod method =
              new BindMethod(URIUtil.encodePath(existingBinding),
                             URIUtil.encodePath(newBinding));
          method.setDebug(debug);
          method.setOverwrite(overwrite);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          // Possbile BIND Status Codes => SC_CREATED, SC_NO_CONTENT
          // SC_FORBIDDEN, SC_CONFLICT, SC_PRECONDITION_FAILED,
          // SC_LOCKED, SC_BAD_GATEWAY, SC_INSUFFICIENT_STORAGE,
          // SC_LOOP_DETECTED
          setStatusCode(statusCode);
          return statusCode >= 200 && statusCode < 300;
      }
  
      /**
       * Execute the UNBIND method for this WebdavResource.
       *
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean unbindMethod() throws HttpException, IOException {
          boolean result = unbindMethod(httpURL.getPath());
          if (result) {
              setExistence(false);
          }
  
          return result;
      }
  
      /**
       * Execute the UNBIND method given the resource to Unbind.
       *
       * @param binding  the server relative path of the resource to unbind
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       */
      public boolean unbindMethod(String binding)
          throws HttpException, IOException {
  
          setClient();
          UnbindMethod method =
              new UnbindMethod(URIUtil.encodePath(binding));
          method.setDebug(debug);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          // Possbile BIND Status Codes => SC_CREATED, SC_NOT_FOUND
          // WebdavStatus.SC_FORBIDDEN, SC_CONFLICT, SC_PRECONDITION_FAILED,
          // SC_LOCKED, SC_BAD_GATEWAY
          setStatusCode(statusCode);
          return statusCode >= 200 && statusCode < 300;
      }
  
      /**
       * Execute the Rebind method for this WebdavResource given the new
       * Resource to bind with.
       * The REBIND method removes a binding to a resource from one collection,
       * and adds a binding to that resource into another collection. It is
       * effectively an atomic form of a MOVE request.
       *
       * @param newBinding the new binding as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @see #setOverwrite(boolean)
       */
      public boolean rebindMethod(String newBinding)
          throws HttpException, IOException {
          boolean result = rebindMethod(httpURL.getPath(), newBinding);
          if (result) {
              httpURL.setPath(newBinding);
              refresh();
          }
  
          return result;
      }
  
      /**
       * Execute the Rebind method given a resource to rebind and the new
       * Resource to bind with.
       * The REBIND method removes a binding to a resource from one collection,
       * and adds a binding to that resource into another collection. It is
       * effectively an atomic form of a MOVE request
       *
       * @param existingBinding  the existing binding as a server relative path
       * @param newBinding       the new binding as a server relative path
       * @return true if the method is succeeded.
       * @exception HttpException
       * @exception IOException
       * @see #setOverwrite(boolean)
       */
      public boolean rebindMethod(String existingBinding, String newBinding)
          throws HttpException, IOException {
  
          setClient();
          RebindMethod method =
              new RebindMethod(URIUtil.encodePath(existingBinding),
                               URIUtil.encodePath(newBinding));
          method.setDebug(debug);
          method.setOverwrite(overwrite);
          generateTransactionHeader(method);
          generateAdditionalHeaders(method);
          int statusCode = client.executeMethod(method);
  
          // Possbile BIND Status Codes => SC_CREATED, SC_NO_CONTENT
          // WebdavStatus.SC_FORBIDDEN, SC_CONFLICT, SC_PRECONDITION_FAILED,
          // SC_LOCKED, SC_BAD_GATEWAY, SC_INSUFFICIENT_STORAGE,
          // SC_LOOP_DETECTED
          setStatusCode(statusCode);
          return statusCode >= 200 && statusCode < 300;
      }
  
      /**
       * Subscribes for notifications for modifications of WebDAV resources.
       * 
       * @param path URL path of the resource that is to be subscribed
       * @param notificationType 
       * @param callback the URL to be registered for notification, may be 
       *        <code>null</code> if no callback shall be registered.
       * @param notificationDelay
       * @param depth the depth of the subscription (for valid values see 
       *    {@link DepthSupport})
       * @param lifetime duration of that subscription in seconds (Note: the
       *    server may change this and return an other one; 
       *    see {@link Subscription#getLifetime()}.
       * 
       * @return a {@link Subscription} or <code>null</code> if an error occurs
       * @throws HttpException
       * @throws IOException
       */
      public Subscription subscribeMethod(String path, 
            String notificationType,
            String callback,
            long notificationDelay,
            int depth,
            long lifetime) 
         throws HttpException, IOException
      {
         setClient();
         
         SubscribeMethod method = new SubscribeMethod(path);
         method.setDebug(debug);
         method.setFollowRedirects(this.followRedirects);
  
         method.setCallback(callback);
         method.setDepth(depth);
         method.setSubsciptionLifetime(lifetime);
         method.setNotificationType(notificationType);
         method.setNotificationDelay(notificationDelay);
         generateTransactionHeader(method);
         generateAdditionalHeaders(method);
  
         int statusCode = client.executeMethod(method);
         
         if (statusCode == HttpStatus.SC_OK) {
            return new Subscription(
                        path, 
                        method.getResponsedSubscriptionId(),
                        method.getCallback(),
                        method.getResponsedSubscriptionLifetime(),
                        method.getResponsedContentLocation(),
                        method.getNotificationType()
                  );
         } else {
            return null;
         }
      }
      
      /**
       * Refreshes a subscription.
       * 
       * @return <code>true</code> on success.
       */
      public boolean subscribeMethod(String path, int subscriptionId)
         throws HttpException, IOException
      {
         setClient();
         
         SubscribeMethod method = new SubscribeMethod(path);
         method.setDebug(debug);
         method.setFollowRedirects(this.followRedirects);
         
         method.setSubscriptionId(subscriptionId);
         generateTransactionHeader(method);
         generateAdditionalHeaders(method);
  
         int statusCode = client.executeMethod(method);
         
         if (statusCode == HttpStatus.SC_OK) {
            return true;
         } else {
            return false;
         } 
      }
      
      /**
       * Refreshes a subscription.
       * 
       * @param subscription The subscription to be refreshed.
       * @return <code>true</code> on success
       */
      public boolean subscribeMethod(Subscription subscription)
         throws HttpException, IOException
      {
         return subscribeMethod(subscription.getPath(), subscription.getId());
      }
      
      /**
       * Cancels a subscription.
       * @param path URL path for that was subscribed 
       * @return <code>true</code> on success
       */
      public boolean unsubscribeMethod(String path, int subscriptionId) 
         throws HttpException, IOException
      {
         setClient();
         
         UnsubscribeMethod method = new UnsubscribeMethod(path);
         method.setDebug(debug);
         method.setFollowRedirects(this.followRedirects);   
         
         method.addSubscriptionId(subscriptionId);
         generateTransactionHeader(method);
         generateAdditionalHeaders(method);
  
         int statusCode = client.executeMethod(method);
         
         if (statusCode == HttpStatus.SC_OK) {
            return true;
         } else {
            return false;
         }
      }
      /**
       * Cancels a subscription.
       * @param subscription
       * @return <code>true</code> on success
       */
      public boolean unsubscribeMethod(Subscription subscription) 
         throws HttpException, IOException
      {
         return unsubscribeMethod(subscription.getPath(),subscription.getId());
      }
      
      /**
       * Asks the server whether events for a given subscription are fired.
       * @param contentLocation URL path returned by the SUBSCRIBE methods
       *                        Content-Location header
       * @param subscriptionId id of the subscription
       * @return <code>true</code> if an event was fired
       */
      public boolean pollMethod(String contentLocation, int subscriptionId)
         throws HttpException, IOException
      {
         setClient();
         
         PollMethod method = new PollMethod(contentLocation);
         method.setDebug(debug);
         method.setFollowRedirects(this.followRedirects);
         
         method.addSubscriptionId(subscriptionId);
         generateTransactionHeader(method);
         generateAdditionalHeaders(method);
  
         int statusCode = client.executeMethod(method);
         
         if (statusCode == HttpStatus.SC_MULTI_STATUS) {
            return method.getSubscriptionsWithEvents().size() > 0;
         } else {
            return false;
         }
      }
      /**
       * Asks the server whether events for a given subscription are fired.
       * @param subscription the subscription to ask for
       * @return <code>true</code> if an event was fired
       */
      public boolean pollMethod(Subscription subscription)
         throws HttpException, IOException
      {
         return pollMethod(subscription.getContentLocation(), subscription.getId());
      }
  
      
      
      private static String getName(String uri, boolean decode) {
          String escapedName = URIUtil.getName(
              uri.endsWith("/") ? uri.substring(0, uri.length() - 1): uri);
          if (decode) {
              try {
                  return URIUtil.decode(escapedName);
              } catch (URIException e) {
                  // Oh well
              }
          }
          return escapedName;
      }
  
      /**
       * Unescape octets for some characters that a server might (but should not)
       * have escaped. These are: "-", "_", ".", "!", "~", "*", "'", "(", ")"
       * Look at section 2.3 of RFC 2396.
       */
      private static String decodeMarks(String input) {
          char[] sequence = input.toCharArray();
          StringBuffer decoded = new StringBuffer(sequence.length);
          for (int i = 0; i < sequence.length; i++) {
              if (sequence[i] == '%' && i < sequence.length - 2) {
                  switch (sequence[i + 1]) {
                  case '2':
                      switch (sequence[i + 2]) {
                      case 'd':
                      case 'D':
                          decoded.append('-');
                          i += 2;
                          continue;
                      case 'e':
                      case 'E':
                          decoded.append('.');
                          i += 2;
                          continue;
                      case '1':
                          decoded.append('!');
                          i += 2;
                          continue;
                      case 'a':
                      case 'A':
                          decoded.append('*');
                          i += 2;
                          continue;
                      case '7':
                          decoded.append('\'');
                          i += 2;
                          continue;
                      case '8':
                          decoded.append('(');
                          i += 2;
                          continue;
                      case '9':
                          decoded.append(')');
                          i += 2;
                          continue;
                      }
                      break;
                  case '5':
                      switch (sequence[i + 2]) {
                      case 'f':
                      case 'F':
                          decoded.append('_');
                          i += 2;
                          continue;
                      }
                      break;
                  case '7':
                      switch (sequence[i + 2]) {
                      case 'e':
                      case 'E':
                          decoded.append('~');
                          i += 2;
                          continue;
                      }
                      break;
                  }
              }
              decoded.append(sequence[i]);
          }
          return decoded.toString();
      }
  }
  
  
  
  1.1      date: 2007/02/23 06:04:33;  author: vivekl;  state: Exp;repository.jboss.com/apache-slide/2.1-brew/src/jakarta-slide-webdavclient-3.0-compat.patch
  
  Index: jakarta-slide-webdavclient-3.0-compat.patch
  ===================================================================
  --- ./commandline/src/java/org/apache/webdav/cmd/Slide.java.sav	2006-04-21 10:32:26.000000000 -0400
  +++ ./commandline/src/java/org/apache/webdav/cmd/Slide.java	2006-04-21 10:38:01.000000000 -0400
  @@ -23,8 +23,7 @@
   
   package org.apache.webdav.cmd;
   
  -
  -import org.apache.commons.httpclient.contrib.ssl.*;
  +import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
   import org.apache.commons.httpclient.protocol.Protocol;
   
   
  @@ -79,7 +78,7 @@
                       case 's':
                           Protocol.registerProtocol("https", 
                                                     new Protocol("https",
  -                                                               new EasySSLProtocolSocketFactory(), 
  +                                                               new SSLProtocolSocketFactory(), 
                                                                  443));
                           break;
                       default:
  
  
  
  1.1      date: 2007/02/23 06:04:33;  author: vivekl;  state: Exp;repository.jboss.com/apache-slide/2.1-brew/src/jakarta-slide-webdavclient-src-2.1.tar.gz
  
  	<<Binary file>>
  
  



More information about the jboss-cvs-commits mailing list