leosimons    2002/12/04 05:42:56

  Added:       resolver package.html Query.java Resolvable.java
                        ResolverException.java Resolver.java Token.java
  Log:
  moving sandbox materials from other avalon cvses here. This came from 
jakarta-avalon/src/proposal/resolver.
  
  Revision  Changes    Path
  1.1                  avalon-sandbox/resolver/package.html
  
  Index: package.html
  ===================================================================
  <html>
    <head>
      <title>Package Documentation for org.apache.avalon.framework.resolver 
Package</title>
    </head>
    <body bgcolor="white">
      A flexible Object resolver mechanism.
      <br><br>
      <a name="doc.Description"></a>
      <div align="center">
        <a href="#doc.Intro">[Introduction]</a>
      </div>
  
      <a name="doc.Intro"></a>
      <h2>Introduction</h2>
      <p>The <code>org.apache.avalon.excalibur.resolver</code> package contains 
interfaces and classes
      for resolving objects, components, and services. The design is 
sufficiently flexible to handle all
      lookup needs.  Below is an example component that demonstrates how the 
package can be used.
      </p>
      <pre>
        public class SampleComponent implements Parameterizable, Resolveable, 
Sample
        {
            private final Query      m_query;
            private       Resolver   m_resolver;
            private       Parameters m_params;
  
            public SampleComponent()
            {
                m_query = new Query();
                m_query.addKey( Query.COMPONENT, DataSourceComponent.ROLE );
                m_query.addKey( Query.COMPONENT, Parser.ROLE );
                m_query.addKey( Query.COMPONENT, EntityResolver.ROLE );
            }
  
            /**
             * Add parameters to specialize the query.
             */
            public void parameterize( Parameters params )
                throws ParameterException
            {
                m_params = params;
                m_query.addAttribute("database", m_params.getParameter( 
"dbname", "default" ));
            }
  
            /**
             * Ensure a valid working space
             */
            public void resolver( Resolver resolver )
                throws ResolverException
            {
                m_resolver = resolver;
                boolean[] isReferenced resolver.hasReferences( m_query );
  
                // test if the optional reference to the resolver exists
                if ( ! isReferenced[2] ) {
                    // if not remove the lookup (it will cause resolver to 
throw an exception
                    m_query.removeKey( EntityResolver.ROLE );
                }
  
                // test if the required references are available
                if ( ! isReferenced[0] || ! isReferenced[1] ) {
                    throw new ResolverException("Required references not 
available");
                }
            }
  
            /**
             * Perform the work from the Sample interface
             */
            public Object doWork()
            {
                Token values = null;
  
                try
                {
                    values = m_resolver.lookup( m_query );
                    Object[] refs = values.references();
  
                    DataSourceComponent datasource = (DataSourceComponent) 
refs[0];
                    Parser parser = (Parser) refs[1];
  
                    // ... do stuff with the datasource to get input stream
                    if (refs.length &gt; 2) {
                        parser.setEntityResolver( (EntityResolver)refs[2] );
                    }
  
                    SampleContentHandler handler = getContentHandler();
                    parser.parse(handler);
                    return handler().getObject();
                }
                catch (Exception e)
                {
                    // handle the exception
                }
                finally
                {
                    if ( null != values )
                    {
                        values.release();
                    }
                }
            }
  
            /**
             * The ContentHandler for the parser.
             */
            SampleContentHandler getContentHandler()
            {
                //defined elsewhere
                return new SampleContentHandler();
            }
        }
      </pre>
   </body>
  </html>
  
  
  
  1.1                  avalon-sandbox/resolver/Query.java
  
  Index: Query.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
   
   Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
   
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
   
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
   
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
   
   4. The names "Jakarta", "Apache Avalon", "Avalon Excalibur", "Avalon
      Framework" and "Apache Software Foundation"  must not be used to endorse
      or promote products derived  from this  software without  prior written
      permission. For written permission, please contact [EMAIL PROTECTED]
   
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
   
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <[EMAIL PROTECTED]>. For more  information on the Apache 
   Software Foundation, please see <http://www.apache.org/>.
   
  */
  package org.apache.avalon.framework.resolver;
  
  import org.apache.avalon.framework.context.Context;
  
  /**
   * A <code>Query</code> will identify all the objects needed for a specific 
lookup.
   * The <code>Query</code> will help the resolver obtain reference to the 
necessary
   * objects in order.  In other words, if we asked for three objects, the 
order of
   * the objects returned by the <code>Resolver</code> will match the order 
that the
   * keys were added to the <code>Query</code> object.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
   */
  public interface Query
  {
  
      /**
       * Add a lookup key.  The Lookup key consists of a psuedo protocol, and 
the key
       * value.  That way, we can ensure that the object you get is the proper 
type.
       * The required psuedo protocols include "component", "service", and 
"object".
       *
       * <p>Example:</p>
       * <pre>
       *   query.addKey( 
"component:org.apache.avalon.excalibur.datasource.DataSourceComponent" );
       *   query.addKey( 
"service:org.apache.avalon.cornerstone.services.ConnectionManager"; );
       *   query.addKey( "object:foo-object" );
       * </pre>
       */
      void addKey( String value );
  
      /**
       * Remove a lookup key.  This facilitates a quick test/resolve approach.  
The
       * <code>Query</code> object can be initialized in the constructor 
complete with
       * references to optional components.  Your code can then call
       * <code>hasReferences</code> and remove any optional keys from the Query 
that the
       * <code>Resolver</code> cannot handle.
       */
      void removeKey( String value );
  
      /**
       * You can add further hints, or attributes to the query that can help the
       * <code>Resolver</code> get the specific instance you want.  It is 
important
       * to note that the attributes do apply to all the key values.  The
       * <code>Resolver</code> does have the right to ignore any or all of the
       * attributes if it wants.
       */
      void addAttribute( String name, Object value );
  
      /**
       * You can remove hints, or attributes to the query that can help the
       * <code>Resolver</code> get the specific instance you want.
       */
      void removeAttribute( String name );
  
      /**
       * This obtains a reference to the attribute context used by the
       * code>Resolver</code>.  The context uses resolveable entryies to 
determine
       * the keys, and what types they are.
       */
      Context queryContext();
  }
  
  
  
  1.1                  avalon-sandbox/resolver/Resolvable.java
  
  Index: Resolvable.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
   
   Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
   
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
   
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
   
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
   
   4. The names "Jakarta", "Apache Avalon", "Avalon Excalibur", "Avalon
      Framework" and "Apache Software Foundation"  must not be used to endorse
      or promote products derived  from this  software without  prior written
      permission. For written permission, please contact [EMAIL PROTECTED]
   
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
   
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <[EMAIL PROTECTED]>. For more  information on the Apache 
   Software Foundation, please see <http://www.apache.org/>.
   
  */
  package org.apache.avalon.framework.resolver;
  
  /**
   * A <code>Resolveable</code> will pass a reference of the 
<code>Resolver</code>
   * to your component.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
   */
  public interface Resolvable
  {
      /**
       * Provide the reference to the resolver.
       */
      void setResolver( Resolver resolver )
          throws ResolverException;
  
  }
  
  
  
  1.1                  avalon-sandbox/resolver/ResolverException.java
  
  Index: ResolverException.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
   
   Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
   
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
   
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
   
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
   
   4. The names "Jakarta", "Apache Avalon", "Avalon Excalibur", "Avalon
      Framework" and "Apache Software Foundation"  must not be used to endorse
      or promote products derived  from this  software without  prior written
      permission. For written permission, please contact [EMAIL PROTECTED]
   
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
   
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <[EMAIL PROTECTED]>. For more  information on the Apache 
   Software Foundation, please see <http://www.apache.org/>.
   
  */
  package org.apache.avalon.framework.resolver;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * The exception thrown to indicate a problem with resolver or the resolver 
query.
   * It is usually thrown by Resolver.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
   * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
   */
  public class ResolverException
      extends CascadingException
  {
      /**
       * Construct a new <code>ResolverException</code> instance.
       *
       * @param message the exception message
       * @param throwable the throwable
       */
      public ResolverException( final String message, final Throwable throwable 
)
      {
          super( message, throwable );
      }
  
      /**
       * Construct a new <code>ResolverException</code> instance.
       *
       * @param message the exception message
       */
      public ResolverException( final String message )
      {
          super( message, null );
      }
  }
  
  
  
  1.1                  avalon-sandbox/resolver/Resolver.java
  
  Index: Resolver.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
   
   Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
   
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
   
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
   
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
   
   4. The names "Jakarta", "Apache Avalon", "Avalon Excalibur", "Avalon
      Framework" and "Apache Software Foundation"  must not be used to endorse
      or promote products derived  from this  software without  prior written
      permission. For written permission, please contact [EMAIL PROTECTED]
   
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
   
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <[EMAIL PROTECTED]>. For more  information on the Apache 
   Software Foundation, please see <http://www.apache.org/>.
   
  */
  package org.apache.avalon.framework.resolver;
  
  /**
   * A <code>Resolver</code> will resolve one or more objects and return a 
token.
   * The responsibility of the Resolver is to get all references identified by 
the
   * <code>Query</code> object and return a <code>Token</code>.  The 
<code>Token</code>
   * then is responsible for releasing any objects that need to be returned to a
   * pool or properly decommissioned.
   *
   * <p>The types of objects returned by the Resolver are usually components 
and services,
   * but can be any arbitrary type.</p>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
   */
  public interface Resolver
  {
      /**
       * Resolve an 
<code>Object</code>/<code>Component</code>/<code>Service</code>
       * from a lookup parameter.  The Lookup parameter has a core value and 
attributes
       * associated with it.
       */
      Token lookup( Query query )
          throws ResolverException;
  
      /**
       * Resolve an 
<code>Object</code>/<code>Component</code>/<code>Service</code>
       * from a lookup parameter.  The Lookup parameter translates a URI into 
the
       * requested Object type.  The Resolver is free to directly resolve this 
uriQuery
       * directly, or it may create an interim Query object.
       *
       * <p>
       *  The psuedo-protocols that must be supported are: "component", 
"service", and
       *  "object".  Further protocols may be "jndi", "orb", etc.
       * </p>
       */
      Token lookup( String uriQuery )
          throws ResolverException;
  
      /**
       * Test to see if the <code>Resolver</code> can resolve all the keys in 
the
       * <code>Query</code> object.  The order of boolean responses matches the 
order
       * of <code>Query</code> keys.
       */
      boolean[] hasReferences( Query query );
  }
  
  
  
  1.1                  avalon-sandbox/resolver/Token.java
  
  Index: Token.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
   
   Copyright (C) @year@ The Apache Software Foundation. All rights reserved.
   
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
   
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
   
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
   
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
   
   4. The names "Jakarta", "Apache Avalon", "Avalon Excalibur", "Avalon
      Framework" and "Apache Software Foundation"  must not be used to endorse
      or promote products derived  from this  software without  prior written
      permission. For written permission, please contact [EMAIL PROTECTED]
   
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
   
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <[EMAIL PROTECTED]>. For more  information on the Apache 
   Software Foundation, please see <http://www.apache.org/>.
   
  */
  package org.apache.avalon.framework.Resolver;
  
  import java.util.Iterator;
  
  /**
   * A <code>Token</code> is responsible for returning the actual Objects 
requested
   * from the <code>Resolver</code>.  It is also responsible for collectively 
returnning
   * all the requested tokens back to the <code>Resolver</code> if they are 
pooled
   * or otherwise managed resources.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
   */
  public interface Token
  {
      /**
       * Obtain the actual references from the query.  The order of references 
must match
       * the order of keys in the Query object.
       */
      Object[] references();
  
      /**
       * Obtain a reference to the first Object in the Token.  This is more for 
convenience
       * when only one object was requested to begin with.
       */
      Object reference();
  
      /**
       * Obtain the reference to the Objects via an Iterator.  This is for the 
case where
       * you have many objects requested, and would rather use an iterator than 
the
       * array.
       */
      Iterator iterator();
  
      /**
       * Releases the hold on all the referenced objects.  The 
<code>Token</code> is no
       * longer usable, and should be discarded after this method is called.
       */
      void release();
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to