/* IppRequest.java -- 
 Copyright (C) 2006 Free Software Foundation, Inc.

 This file is part of GNU Classpath.

 GNU Classpath is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.

 GNU Classpath is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GNU Classpath; see the file COPYING.  If not, write to the
 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301 USA.

 Linking this library statically or dynamically with other modules is
 making a combined work based on this library.  Thus, the terms and
 conditions of the GNU General Public License cover the whole
 combination.

 As a special exception, the copyright holders of this library give you
 permission to link this library with independent modules to produce an
 executable, regardless of the license terms of these independent
 modules, and to copy and distribute the resulting executable under
 terms of your choice, provided that you also meet, for each linked
 independent module, the terms and conditions of the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */


package gnu.javax.print.ipp;

import gnu.classpath.debug.Component;
import gnu.classpath.debug.SystemLogger;
import gnu.javax.print.ipp.attribute.CharsetSyntax;
import gnu.javax.print.ipp.attribute.NaturalLanguageSyntax;
import gnu.javax.print.ipp.attribute.RequestedAttributes;
import gnu.javax.print.ipp.attribute.job.AttributesCharset;
import gnu.javax.print.ipp.attribute.job.AttributesNaturalLanguage;
import gnu.javax.print.ipp.attribute.job.JobId;
import gnu.javax.print.ipp.attribute.job.JobUri;
import gnu.javax.print.ipp.attribute.printer.DocumentFormat;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Logger;

import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.DateTimeSyntax;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.ResolutionSyntax;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.TextSyntax;
import javax.print.attribute.URISyntax;
import javax.print.attribute.standard.Compression;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.DocumentName;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.Finishings;
import javax.print.attribute.standard.JobHoldUntil;
import javax.print.attribute.standard.JobImpressions;
import javax.print.attribute.standard.JobKOctets;
import javax.print.attribute.standard.JobMediaSheets;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.JobOriginatingUserName;
import javax.print.attribute.standard.JobPriority;
import javax.print.attribute.standard.JobSheets;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MultipleDocumentHandling;
import javax.print.attribute.standard.NumberUp;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.PrinterURI;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;

/**
 * <code>IppRequest</code> models a request to an IPP compatible
 * server as described in RFC 2910 - IPP/1.1: Encoding and Transport.
 * <p>
 * The byte stream is structured as follows (for an official description
 * please have a look at the RFC document mentioned above):
 * <ul>
 * <li>version-number          - 2 bytes - required</li>
 * <li>operation-id            - 2 bytes - required</li>
 * <li>request-id              - 4 bytes - required</li>
 * <li>attribute-group         - n bytes - 0 or more</li>
 * <li>end-of-attributes-tag   - 1 byte  - required</li>
 * <li>data                    - q bytes - optional</li>
 * </ul>
 * </p>
 * 
 * @author Wolfgang Baer (WBaer@gmx.de)
 */
public class IppRequest
{

  /**
   * The printer-poll timeout. 
   */
  private static final int timeout = 1000;

  /**
   * Helper class used to write the attributes of a request
   * into the supplied data output stream in the correct way.
   * 
   * @author Wolfgang Baer (WBaer@gmx.de)
   */
  class RequestWriter
  {    
    private DataOutputStream out;
    
    /**
     * Creates a RequestWriter.
     * 
     * @param stream the stream to write to.
     */
    RequestWriter(DataOutputStream stream)
    {
      out = stream;
    }
    
    /**
     * Writes an attribute in IntegerSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(IntegerSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.INTEGER);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(4); // length, integer is 4 bytes
      out.writeInt(attribute.getValue());
    }

    /**
     * Writes an attribute in EnumSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(EnumSyntax attribute) throws IOException
    {
      // in JPS API enum syntax is used for enums, keyword and boolean types
      String name = ((Attribute) attribute).getName();

      // the enum value types
      if (attribute instanceof Finishings
          || attribute instanceof OrientationRequested
          || attribute instanceof PrintQuality)
        {
          out.writeByte(IppValueTag.ENUM);
          out.writeShort(name.length());
          out.write(name.getBytes());
          out.writeShort(4); // length, enum is 4 bytes
          out.writeInt(attribute.getValue());
        }
      // the boolean value type
      else if (attribute instanceof Fidelity)
        {
          out.writeByte(IppValueTag.BOOLEAN);
          out.writeShort(name.length());
          out.write(name.getBytes());
          out.writeShort(1); // length, boolean is 1 bytes
          out.writeByte(attribute.getValue() == 0 ? 0x00 : 0x01);
        }
      // the keyword value types
      else
        {
          String keyword = attribute.toString();
          out.writeByte(IppValueTag.KEYWORD);
          out.writeShort(name.length());
          out.write(name.getBytes());
          out.writeShort(keyword.length());
          out.write(keyword.getBytes());
        }
    }

    /**
     * Writes an attribute in SetOfIntegerSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(SetOfIntegerSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      int[][] ranges = attribute.getMembers();
      for (int i = 0; i < ranges.length; i++)
        {
          out.writeByte(IppValueTag.RANGEOFINTEGER);
          if (i == 0)
            {
              out.writeShort(name.length());
              out.write(name.getBytes());
            }
          else
            out.writeShort(0x0000); // only name-length 

          out.writeShort(8); // range is 8 bytes
          out.writeInt(ranges[i][0]);
          out.writeInt(ranges[i][1]);
        }
    }

    /**
     * Writes an attribute in ResolutionSyntax into the stream.
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(ResolutionSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.RESOLUTION);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(9); // length fixed to 9
      out.writeInt(attribute.getCrossFeedResolution(ResolutionSyntax.DPI));
      out.writeInt(attribute.getFeedResolution(ResolutionSyntax.DPI));
      out.writeByte(ResolutionSyntax.DPI);
    }

    /**
     * Writes an attribute in DateTimeSyntax into the stream.
     * <p>
     * The syntax value is defined as 11 octets follwing the
     * DateAndTime format of RFC 1903. (see IppResponse)
     * </p>
     *
     * @param attribute the attribute
     * @throws IOException if thrown by the stream
     */
    private void write(DateTimeSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.DATETIME);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(11); // length fixed to 11

      Date date = attribute.getValue();
      Calendar cal = new GregorianCalendar();
      cal.setTime(date);

      out.writeShort(cal.get(Calendar.YEAR));
      out.writeByte(cal.get(Calendar.MONTH));
      out.writeByte(cal.get(Calendar.DAY_OF_MONTH));
      out.writeByte(cal.get(Calendar.HOUR_OF_DAY));
      out.writeByte(cal.get(Calendar.MINUTE));
      int second = cal.get(Calendar.SECOND);
      out.writeByte(second == 0 ? 60 : second);
      out.writeByte(cal.get(Calendar.MILLISECOND) / 100);

      int offsetInMillis = cal.get(Calendar.ZONE_OFFSET);
      char directionFromUTC = '+';
      if (offsetInMillis < 0)
        {
          directionFromUTC = '-';
          offsetInMillis = offsetInMillis * (-1);
        }

      out.writeByte(directionFromUTC);
      out.writeByte(offsetInMillis / 3600000); // hours    
      out.writeByte((offsetInMillis % 3600000) / 60000); // minutes
    }

    /**
     * Writes an attribute in TextSyntax into the stream.
     * <p>
     * By default attributes are qritten as TEXT_WITHOUT_LANGUAGE value-tag.
     * As some attributes in the JPS are TextSyntax attributes but actually
     * of NAME value-tag in IPP this method checks for these attributes and
     * writes them as NAME_WITHOUT_LANGUAGE value-tag into the stream.
     * </p>
     * 
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(TextSyntax attribute) throws IOException
    {
      // We only use *WithoutLanguage, correct according to spec.
      String name = ((Attribute) attribute).getName();

      if (attribute instanceof RequestingUserName
          || attribute instanceof JobName
          || attribute instanceof DocumentName
          || attribute instanceof JobOriginatingUserName)
        out.writeByte(IppValueTag.NAME_WITHOUT_LANGUAGE);
      else if (attribute instanceof DocumentFormat)
        out.writeByte(IppValueTag.MIME_MEDIA_TYPE);
      else
        out.writeByte(IppValueTag.TEXT_WITHOUT_LANGUAGE);
      
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(attribute.getValue().length());
      out.write(attribute.getValue().getBytes());     
    }

    /**
     * Writes an attribute in URISyntax into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(URISyntax attribute) throws IOException
    {
      // only uriScheme syntax type should not appear
      // in a request (reference-uri-schemes-supported)
      String name = ((Attribute) attribute).getName();
      String uriAscii = attribute.getURI().toASCIIString();
      out.writeByte(IppValueTag.URI);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(uriAscii.length());
      out.write(uriAscii.getBytes());
    }

    /**
     * Writes an attribute in CharsetSyntax into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(CharsetSyntax attribute) throws IOException
    {      
      String name = ((Attribute) attribute).getName();      
      out.writeByte(IppValueTag.CHARSET);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(attribute.getValue().length());
      out.write(attribute.getValue().getBytes());
    }

    /**
     * Writes an attribute in NaturalLanguageSyntax into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(NaturalLanguageSyntax attribute) throws IOException
    {
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.NATURAL_LANGUAGE);
      out.writeShort(name.length());
      out.write(name.getBytes());
      out.writeShort(attribute.getValue().length());
      out.write(attribute.getValue().getBytes());
    }
    
    /**
     * Writes an attribute in RequestedAttributes into the stream.
     * @param attribute the attribute
     * @param out the stream to write to
     * @throws IOException if thrown by the stream
     */
    private void write(RequestedAttributes attribute) throws IOException
    {
      List values = attribute.getValues();
      
      String name = ((Attribute) attribute).getName();
      out.writeByte(IppValueTag.KEYWORD);
      out.writeShort(name.length());
      out.write(name.getBytes()); 
      out.writeShort(((String) values.get(0)).length());
      out.write(((String) values.get(0)).getBytes());
      
      for (int i=1; i < values.size(); i++)
        {
          out.writeByte(IppValueTag.KEYWORD);
          out.writeShort(0x0000); // length for additional value
          out.writeShort(((String) values.get(i)).length());
          out.write(((String) values.get(i)).getBytes());  
        }
    } 

    
    /**
     * Writes the given operation attribute group of the given map instance
     * (key=group, values=set of attributes) into the supplied data
     * output stream.
     * 
     * @param attributes the set with the attributes.
     * 
     * @throws IOException if thrown by the used DataOutputStream.
     * @throws IppException if unknown attributes occur.
     */
    public void writeOperationAttributes(AttributeSet attributes)
        throws IOException, IppException
    {
      out.write(IppDelimiterTag.OPERATION_ATTRIBUTES_TAG);
      
      // its essential to write these two in this order and as first ones
      Attribute att = attributes.get(AttributesCharset.class);
      write((CharsetSyntax) att);
      
      logger.log(Component.IPP, "Attribute: Name: <" 
        + att.getCategory().getName() + "> Value: <" + att.toString() + ">");  
      
      attributes.remove(AttributesCharset.class);
      
      att = attributes.get(AttributesNaturalLanguage.class);
      write((NaturalLanguageSyntax) att);
      attributes.remove(AttributesNaturalLanguage.class);
      
      logger.log(Component.IPP, "Attribute: Name: <" 
        + att.getCategory().getName() + "> Value: <" + att.toString() + ">");
      
      // furthermore its essential to now write out the target attribute
      PrinterURI printerUri = (PrinterURI) attributes.get(PrinterURI.class);
      JobUri jobUri = (JobUri) attributes.get(JobUri.class);
      JobId jobId = (JobId) attributes.get(JobId.class);
      if (printerUri != null && jobId == null && jobUri == null)
        {
          write(printerUri);
          attributes.remove(PrinterURI.class);
          logger.log(Component.IPP, "Attribute: Name: <" + printerUri
            .getCategory().getName() + "> Value: <" + printerUri.toString() + ">");
        }
      else if (jobUri != null && jobId == null && printerUri == null)
        {
          write(jobUri);
          attributes.remove(JobUri.class);
          logger.log(Component.IPP, "Attribute: Name: <" + jobUri
            .getCategory().getName() + "> Value: <" + jobUri.toString() + ">");
        }
      else if (printerUri != null && jobId != null && jobUri == null)
        {
          write(printerUri); // must be third
          write(jobId);
          attributes.remove(PrinterURI.class);
          attributes.remove(JobId.class);
          logger.log(Component.IPP, "Attribute: Name: <" + printerUri
            .getCategory().getName() + "> Value: <" + printerUri.toString() + ">");
          logger.log(Component.IPP, "Attribute: Name: <" + jobId.getCategory()
            .getName() + "> Value: <" + jobId.toString() + ">");
        }
      else if (jobUri != null && jobId != null)
        {
          write(jobUri);
          attributes.remove(JobUri.class);
          attributes.remove(JobId.class); // MUST NOT redundant
          logger.log(Component.IPP, "Attribute: Name: <" + jobUri.getCategory()
            .getName() + "> Value: <" + jobUri.toString() + ">");
        }
      else
        {
          new IppException("Unknown target operation attribute combination.");
        }      
      
      writeAttributes(attributes);
    }
    
    /**
     * Writes the given attribute groups of the given map instance
     * (key=group, values=set of attributes) into the supplied data
     * output stream.
     * 
     * @param attributes the set with the attributes.
     * 
     * @throws IOException if thrown by the used DataOutputStream.
     * @throws IppException if unknown attributes occur.
     */
    public void writeAttributes(AttributeSet attributes)
        throws IOException, IppException
    {
      Attribute[] attributeArray = attributes.toArray();
      for (int i = 0; i < attributeArray.length; i++)
        {
          logger.log(Component.IPP, "Attribute: Name: <" + attributeArray[i]
            .getCategory().getName() + "> Value: <" 
            + attributeArray[i].toString() + ">");          
          
          if (attributeArray[i] instanceof IntegerSyntax)
            write((IntegerSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof TextSyntax)
            write((TextSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof DateTimeSyntax)
            write((DateTimeSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof ResolutionSyntax)
            write((ResolutionSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof SetOfIntegerSyntax)
            write((SetOfIntegerSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof EnumSyntax)
            write((EnumSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof URISyntax)
            write((URISyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof CharsetSyntax)
            write((CharsetSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof NaturalLanguageSyntax)
            write((NaturalLanguageSyntax) attributeArray[i]);
          else if (attributeArray[i] instanceof RequestedAttributes)
            write((RequestedAttributes) attributeArray[i]);
          else
            throw new IppException("Unknown syntax type");
        }
    }

  }

  /**
   * Logger for tracing - enable by passing
   * -Dgnu.classpath.debug.components=ipp to the vm.
   */
  static final Logger logger = SystemLogger.SYSTEM;

  /**
   * The request id counter simply counts up
   * to give unique request ids per JVM instance.
   */
  private static int requestIdCounter = 1;

  /** The IPP version defaults to 1.1 */
  private static final short VERSION = 0x0101;

  /** Signals if the request is already on its way */
  private boolean alreadySent = false;

  /** The operation type of this request. */
  private short operation_id;

  /** 
   * The request id of this request. This is 
   * assigned automatically by the constructor.
   */
  private final int request_id;

  private AttributeSet operationAttributes;

  private AttributeSet printerAttributes;

  private AttributeSet jobAttributes;

  private Object data;
  
  private URI requestUri;

  /** The underlying connection - IPP is http based */
  private HttpURLConnection  connection;
  
  /**
   * Creates an IPPRequest instance.
   * 
   * @param uri the URI of the request
   * @param user the user if any
   * @param password the password of the supplied user
   */
  public IppRequest(URI uri, String user, String password)
  {   
    request_id = incrementRequestIdCounter();
    requestUri = uri;
    
    try
      {
        URL url = new URL("http", 
                      user == null 
                      ? uri.getHost() : user + ":" 
                      + password + "@" + uri.getHost(), 
                      uri.getPort(), uri.getPath());
       
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        
        connection.setRequestProperty("Content-type", "application/ipp");
        connection.setRequestProperty("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2");        
      }   
    catch (IOException e)
      {
        // MalformedURLException - uri is already checked
        // ProtocolException - POST is correct method type
        // IOException -HTTPURLConnection constructor actually 
        // does never throw this exception.
        logger.log(Component.IPP, "Unexpected IOException", e);
      }
    
    logger.log(Component.IPP, "[IppConnection] Host: " + uri.getHost()
                              + " Port: " + uri.getPort() + " Path: "
                              + uri.getPath());
  }

  /**
   * Synchronized method to be called by the constructor
   * to assign a unique request id to this request.
   * 
   * @return The unique request id.
   */
  private synchronized int incrementRequestIdCounter()
  {
    return IppRequest.requestIdCounter++;
  }

  /**
   * Returns the id of this request.
   * 
   * @return The request ID.
   */
  public int getRequestID()
  {
    return request_id;
  }

  /** 
   * Sets the data of the request. The data used in this 
   * request will be the one of the supplied inputstream
   * instead of the alternative byte array possibility.
   * 
   * @param stream the input stream to use for the data.
   */
  public void setData(InputStream stream)
  {
    data = stream;
  }

  /** 
   * Sets the data of the request. The data used in this 
   * request will be the one of the supplied byte[]
   * instead of the alternative input stream possibility.
   * 
   * @param bytes the byte[] to use for the data.
   */
  public void setData(byte[] bytes)
  {
    data = bytes;
  }

  /**
   * Sets the operation id for this request.
   * 
   * @param id the operation id.
   */
  public void setOperationID(short id)
  {
    operation_id = id;
  }

  /**
   * Adds the default values for the operation
   * attributes "attributes-charset" and 
   * "attributes-natural-language"
   */
  public void setOperationAttributeDefaults()
  {
    if (operationAttributes == null)
      operationAttributes = new HashAttributeSet();

    operationAttributes.add(AttributesCharset.UTF8);
    operationAttributes.add(AttributesNaturalLanguage.EN);
  }
  
  /**
   * Add the job attribute of this request to the given
   * attribute set.
   * 
   * @param attribute the job attribute.
   */
  public void addJobAttribute(Attribute attribute)
  {
    if (jobAttributes == null)
      jobAttributes = new HashAttributeSet();
    
    jobAttributes.add(attribute);
  }
  
  /**
   * Sets the printer attribute of this request to the given
   * attribute set.
   * 
   * @param attribute the printer attribute.
   */
  public void addPrinterAttributes(Attribute attribute)
  {
    if (printerAttributes == null)
      printerAttributes = new HashAttributeSet();
    
    printerAttributes.add(attribute);
  }

  /**
   * Adds the given attribute to the operation attributes set.
   * 
   * @param attribute the operation attribute to add.
   */
  public void addOperationAttribute(Attribute attribute)
  {
    if (operationAttributes == null)
      operationAttributes = new HashAttributeSet();
    
    operationAttributes.add(attribute);
  }
  
  /**
   * Filters from the given attribute set the job operation out
   * and adds them to the operation attributes set.
   * 
   * @param set the attributes to filter, may not be <code>null</code>.
   */
  public void addAndFilterJobOperationAttributes(AttributeSet set)
  {
    if (operationAttributes == null)
      operationAttributes = new HashAttributeSet();
    
    // document-natural-language - not defined in JPS attributes
    // document-format - specified outside, special treatment
    Attribute[] tmp = set.toArray();
    for (int i = 0; i < tmp.length; i++) 
      {        
        if (tmp[i].getCategory().equals(JobName.class)
            || tmp[i].getCategory().equals(Fidelity.class)
            || tmp[i].getCategory().equals(JobImpressions.class)
            || tmp[i].getCategory().equals(JobKOctets.class)
            || tmp[i].getCategory().equals(JobMediaSheets.class)
            || tmp[i].getCategory().equals(Compression.class)
            || tmp[i].getCategory().equals(DocumentName.class)
            || tmp[i].getCategory().equals(RequestingUserName.class))
                
          operationAttributes.add(tmp[i]);            
      }    
  }
  
  /**
   * Filters from the given attribute set the job template attributes
   * out and adds them to the job attributes set.
   * 
   * @param set the attributes to filter, may not be <code>null</code>.
   */
  public void addAndFilterJobTemplateAttributes(AttributeSet set)
  {
    if (jobAttributes == null)
      jobAttributes = new HashAttributeSet();
    
    // document-natural-language - not defined in JPS attributes
    // document-format - specified outside, special treatment
    Attribute[] tmp = set.toArray();
    for (int i = 0; i < tmp.length; i++) 
      {        
        if (tmp[i].getCategory().equals(JobPriority.class)
            || tmp[i].getCategory().equals(JobHoldUntil.class)
            || tmp[i].getCategory().equals(JobSheets.class)
            || tmp[i].getCategory().equals(MultipleDocumentHandling.class)
            || tmp[i].getCategory().equals(Copies.class)
            || tmp[i].getCategory().equals(Finishings.class)
            || tmp[i].getCategory().equals(PageRanges.class)
            || tmp[i].getCategory().equals(NumberUp.class)
            || tmp[i].getCategory().equals(OrientationRequested.class)
            || tmp[i].getCategory().equals(Media.class)
            || tmp[i].getCategory().equals(PrinterResolution.class)
            || tmp[i].getCategory().equals(PrintQuality.class)
            || tmp[i].getCategory().equals(SheetCollate.class)
            || tmp[i].getCategory().equals(Sides.class))
                
          jobAttributes.add(tmp[i]);            
      }    
  }

  /**
   * Does some validation of the supplied parameters and then
   * sends the request to the ipp server or service.
   * 
   * @return The response if any.
   * 
   * @throws IllegalStateException if request is already sent
   * @throws IppException if connection or request failed.
   * @throws IOException if writing of the header, attributes or footer fails. 
   */
  public IppResponse send() throws IppException, IOException
  {
    if (alreadySent)
      throw new IllegalStateException("Request is already sent");
    
    alreadySent = true;
      
    OutputStream stream = connection.getOutputStream();   
    DataOutputStream out = new DataOutputStream(stream);
        
    //  the header 8 bytes long
    out.writeShort(VERSION);
    out.writeShort(operation_id);
    out.writeInt(request_id);
        
    logger.log(Component.IPP, "OperationID: " + Integer.toHexString(operation_id) 
      + " RequestID: " + request_id); 
        
    // Pass stuff the the attribute writer which knows how to
    // write the attributes in correct order
    logger.log(Component.IPP, "Operation Attributes");
        
    RequestWriter writer = new RequestWriter(out);
    writer.writeOperationAttributes(operationAttributes);       
        
    if (jobAttributes != null)
      {
        logger.log(Component.IPP, "Job Attributes");
        out.write(IppDelimiterTag.JOB_ATTRIBUTES_TAG);
        writer.writeAttributes(jobAttributes);
      }           
    if (printerAttributes != null)
      {
        logger.log(Component.IPP, "Printer Attributes");
        out.write(IppDelimiterTag.PRINTER_ATTRIBUTES_TAG);
        writer.writeAttributes(printerAttributes);
      }          

    // write the delimiter to the data
    out.write(IppDelimiterTag.END_OF_ATTRIBUTES_TAG);               

    // check if data is byte[] or inputstream
    if (data instanceof InputStream)
      {
        byte[] readbuf = new byte[2048];
        int len = 0;            
        while( (len = ((InputStream) data).read(readbuf)) > 0)
          out.write(readbuf, 0, len);
      }
    else if (data != null)
      {
        out.write((byte[]) data);
      }
             
    out.flush();
    stream.flush();  
  
    // Set the connection timeout, for if the printer is offline.
    // FIXME: The print services polling should probably be done in its
    // own thread.
    connection.setConnectTimeout( timeout );

    int responseCode = connection.getResponseCode();
    
    if (responseCode == HttpURLConnection.HTTP_OK)
      { 
        IppResponse response = new IppResponse(requestUri, operation_id);        
        response.setResponseData(connection.getInputStream());     
        return response;
      }

    logger.log(Component.IPP, "HTTP-Statuscode: " + responseCode);

    throw new IppException("Request failed got HTTP status code " 
                           + responseCode);
  }

}
