    super.setSupports(oss);
  }



  /*----------------------------------------------------------------------------------------*/

  /**
   * Whether the archiver requires manual confirmation before initiating an archive or 
   * restore operation. <P> 
   * 
   * Subclasses should override this method to return <CODE>true</CODE> when human 
   * interaction is required to change tapes or other removable media before attempting to 
   * archive or restore files.  Archivers which are capable of performing archive and 
   * restore operation without human intervention are considered automatic and may use the
   * default implementation which returns <CODE>false</CODE>.
   * 
   * If this method returns <CODE>true</CODE>, Pipeline will query the user for confirmation
   * before executing the {@link #archive archive} or {@link #restore restore} methods. <P> 
   * 
   * By default, this method returns <CODE>false</CODE>.
   */ 
  public boolean
  isManual()
  {
    return false;
  }

  /**
   * Get the capacity of the media volume (in bytes). <P> 
   * 
   * Subclasses must override this methods to return the size of the archive media used 
   * by the archiver plugin. <P> 
   * 
   * This size is used assign the versions to be archived to one or more archive volumes 
   * which do not exceed this capacity.  <P> 
   * 
   * By default this method returns (OL). 
   */ 
  public long
  getCapacity()
  {
    return 0L;
  }
  


  /*----------------------------------------------------------------------------------------*/
  /*   P A R A M E T E R S                                                                  */
  /*----------------------------------------------------------------------------------------*/
 
  /**
   * Does the archiver have any parameters?
   */ 
  public final boolean 
  hasParams()
  {
    return (!pParams.isEmpty());
  }

  /**
   * Add a parameter to this Archiver. <P>
   *
   * This method is used by subclasses in their constructors initialize the set of 
   * parameters that they support.
   *
   * @param param  
   *   The parameter to add.
   */
  protected final void 
  addParam
  (
   ArchiverParam param 
  ) 
  {
    if(pParams.containsKey(param.getName())) 
      throw new IllegalArgumentException
	("A parameter named (" + param.getName() + ") already exists!");

    pParams.put(param.getName(), param); 
  }

  /** 
   * Get the value of the parameter with the given name.
   * 
   * @param name  
   *   The name of the parameter. 
   *
   * @return 
   *   The parameter value.
   * 
   * @throws PipelineException 
   *   If no parameter with the given name exists.
   */ 
  public final Comparable
  getParamValue
  (
   String name   
  ) 
    throws PipelineException
  {
    ArchiverParam param = getParam(name); 
    if(param == null)
      throw new PipelineException
	("Unable to determine the value of the (" + name + ") parameter!");
    return param.getValue();
  }

  /** 
   * Get the parameter with the given name.
   * 
   * @param name  
   *   The name of the parameter. 
   *
   * @return 
   *   The parameter or <CODE>null</CODE> if no parameter with the given name exists.
   */ 
  public final ArchiverParam
  getParam
  (
   String name   
  ) 
  {
    if(name == null)
      throw new IllegalArgumentException("The parameter name cannot be (null)!");
    return pParams.get(name);
  }

  /** 
   * Get all of the parameters. <P> 
   * 
   * The returned ArrayList may be empty if the archiver does not have any parameters.
   * 
   * @return 
   *   The set of parameters for this archiver.  
   */ 
  public final Collection<ArchiverParam>
  getParams()
  {
    return Collections.unmodifiableCollection(pParams.values());
  }

  /**
   * Set the value of a parameter. 
   * 
   * @param name  
   *   The name of the parameter. 
   * 
   * @param value  
   *   The new value of the parameter. 
   */ 
  public final void 
  setParamValue
  (
   String name, 
   Comparable value
  ) 
  {
    if(name == null)
      throw new IllegalArgumentException("The parameter name cannot be (null)!");

    ArchiverParam param = pParams.get(name);
    if(param == null) 
      throw new IllegalArgumentException
	("No parameter named (" + param.getName() + ") exists for this archiver!");

    try {
      param.setValue(value);
    }
    catch(IllegalArgumentException ex) {
      LogMgr.getInstance().log
        (LogMgr.Kind.Ops, LogMgr.Level.Warning,
         "While attempting to set a parameter of the Archiver " +
         "(" + pName + " v" + pVersionID + ") from vendor (" + pVendor + "):\n  " + 
         ex.getMessage());
    }
  }

  /** 
   * Copy the values of all of the parameters from the given archiver. <P> 
   * 
   * Note that there is no requirement that the given archiver be the same plugin type or 
   * version.  Any incompatible parameters will simply be ignored by the copy operation.
   * 
   * @param archiver  
   *   The archiver to use as the source of parameter values.
   */
  public final void 
  setParamValues
  (
   BaseArchiver archiver   
  ) 
  {
    for(String name : pParams.keySet()) {
      ArchiverParam aparam = archiver.getParam(name);
      if(aparam!= null) {
	ArchiverParam param = pParams.get(name);
	try {
	  param.setValue(aparam.getValue());
	}
	catch(IllegalArgumentException ex) {
          LogMgr.getInstance().log
            (LogMgr.Kind.Ops, LogMgr.Level.Warning,
             "While attempting to set a parameter of the Archiver " +
             "(" + pName + " v" + pVersionID + ") from vendor (" + pVendor + "):\n  " + 
             ex.getMessage());
	}
      }
    }
  }



  /*----------------------------------------------------------------------------------------*/
  /*   U S E R   I N T E R F A C E                                                          */
  /*----------------------------------------------------------------------------------------*/

  /**
   * Set the layout of parameters in the user interface. <P> 
   * 
   * The <CODE>layout</CODE> argument must contain the name of each parameter exactly once, 
   * but may also contain <CODE>null</CODE> values.  The order of the parameter names in this 
   * layout list determines that order that the parameters are listed in the user interface.  
   * Extra space will be added between parameters for each <CODE>null</CODE> value 
   * encountered.  In this way parameters can be grouped by inserting <CODE>null</CODE>
   * entries between parameter names. <P> 
   * 
   * This method should be called by subclasses in their constructor after intializing all 
   * parameters with the {@link #addParam addParam} method.
   * 
   * @param layout
   *   The names of the parameters.
   */
  protected final void
  setLayout
  (
   Collection<String> layout
  ) 
  {
    for(String name : layout)
      if((name!= null) &&!pParams.containsKey(name)) 
	throw new IllegalArgumentException
	  ("There is no parameter (" + name + ") defined for this Archiver!");

    for(String pname : pParams.keySet()) {
      int cnt = 0;
      for(String name : layout) 
	if((name!= null) && name.equals(pname)) 
	  cnt++;
      
      switch(cnt) {
      case 0:
	throw new IllegalArgumentException
	  ("The parameter (" + pname + ") was not specified in the layout!");
	
      case 1:
	break;

      default:
	throw new IllegalArgumentException
	  ("The parameter (" + pname + ") was specified (" + cnt + ") times " +
	   "by the layout!  Each parameter may only be specified once.");
      }
    }

    pLayout = new ArrayList<String>(layout);    
  }

  /**
   * Get the layout of parameters in the user interface. <P> 
   * 
   * The returned parameter names will include all single valued parameters exactly