Index: server/lib/gutenbach/server/requests.py
===================================================================
--- server/lib/gutenbach/server/requests.py	(revision 3cb6c7be45d023f070ae737d47a76efd79c67999)
+++ server/lib/gutenbach/server/requests.py	(revision 75928fe03ccd22fe1cca8a9c5a659838b1b9aecc)
@@ -126,5 +126,5 @@
     def print_job(self, request, response):
         """RFC 2911: 3.2.1 Print-Job Operation
-
+        
         This REQUIRED operation allows a client to submit a print job
         with only one document and supply the document data (rather
@@ -232,31 +232,58 @@
 
         This REQUIRED operation is similar to the Print-Job operation
-        (section 3.2.1) except that a client supplies no document data and
-        the Printer allocates no resources (i.e., it does not create a new
-        Job object).  This operation is used only to verify capabilities of a
-        printer object against whatever attributes are supplied by the client
-        in the Validate-Job request.  By using the Validate-Job operation a
-        client can validate that an identical Print-Job operation (with the
-        document data) would be accepted. The Validate-Job operation also
-        performs the same security negotiation as the Print-Job operation
-        (see section 8), so that a client can check that the client and
-        Printer object security requirements can be met before performing a
-        Print-Job operation.
-
-        The Validate-Job operation does not accept a 'document-uri' attribute
-        in order to allow a client to check that the same Print-URI operation
-        will be accepted, since the client doesn't send the data with the
-        Print-URI operation.  The client SHOULD just issue the Print-URI
-        request.
-
-        The Printer object returns the same status codes, Operation
-        Attributes (Group 1) and Unsupported Attributes (Group 2) as the
-        Print-Job operation.  However, no Job Object Attributes (Group 3) are
-        returned, since no Job object is created.
+        (section 3.2.1) except that a client supplies no document data
+        and the Printer allocates no resources (i.e., it does not
+        create a new Job object).  This operation is used only to
+        verify capabilities of a printer object against whatever
+        attributes are supplied by the client in the Validate-Job
+        request.  By using the Validate-Job operation a client can
+        validate that an identical Print-Job operation (with the
+        document data) would be accepted. The Validate-Job operation
+        also performs the same security negotiation as the Print-Job
+        operation (see section 8), so that a client can check that the
+        client and Printer object security requirements can be met
+        before performing a Print-Job operation.
+
+        The Validate-Job operation does not accept a 'document-uri'
+        attribute in order to allow a client to check that the same
+        Print-URI operation will be accepted, since the client doesn't
+        send the data with the Print-URI operation.  The client SHOULD
+        just issue the Print-URI request.
+
+        Request
+        -------
+        Group 1: Operation Attributes
+            REQUIRED 'attributes-charset' 
+            REQUIRED 'attributes-natural-language' 
+            REQUIRED 'printer-uri' (uri) 
+            OPTIONAL 'requesting-user-name' (name(MAX))
+            OPTIONAL 'job-name' (name(MAX))
+            OPTIONAL 'ipp-attribute-fidelity' (boolean)
+            OPTIONAL 'document-name' (name(MAX))
+            OPTIONAL 'compression' (type3 keyword)
+            OPTIONAL 'document-format' (mimeMediaType)
+            OPTIONAL 'document-natural-language' (naturalLanguage)
+            OPTIONAL 'job-k-octets' (integer(0:MAX))
+            OPTIONAL 'job-impressions' (integer(0:MAX))
+            OPTIONAL 'job-media-sheets' (integer(0:MAX))
+        Group 2: Job Template Attributes
+        Group 3: Document Content
+
+        Response
+        --------
+        Group 1: Operation Attributes
+            OPTIONAL 'status-message' (text(255))
+            OPTIONAL 'detailed-status-message' (text(MAX))
+            REQUIRED 'attributes-charset'
+            REQUIRED 'attributes-natural-language'
+        Group 2: Unsupported Attributes
+        
         """
+
         operation = request.attribute_groups[0]
         user_name = None
         job_name = None
         job_k_octets = None
+
         # requested printer uri
         if 'printer-uri' not in operation:
@@ -282,6 +309,4 @@
             job_name=job_name,
             job_k_octets = job_k_octets) 
-
-        #raise ipp.errors.ServerErrorOperationNotSupported
 
     @handler_for(ipp.OperationCodes.GET_JOBS)
@@ -378,113 +403,42 @@
         """3.2.2 Print-URI Operation
 
-        This OPTIONAL operation is identical to the Print-Job operation
-        (section 3.2.1) except that a client supplies a URI reference to the
-        document data using the 'document-uri' (uri) operation attribute (in
-        Group 1) rather than including the document data itself.  Before
-        returning the response, the Printer MUST validate that the Printer
-        supports the retrieval method (e.g., http, ftp, etc.) implied by the
-        URI, and MUST check for valid URI syntax.  If the client-supplied URI
-        scheme is not supported, i.e. the value is not in the Printer
-        object's 'referenced-uri-scheme-supported' attribute, the Printer
-        object MUST reject the request and return the 'client-error-uri-
-        scheme-not-supported' status code.
-
-        The IPP Printer MAY validate the accessibility of the document as
-        part of the operation or subsequently.  If the Printer determines an
-        accessibility problem before returning an operation response, it
-        rejects the request and returns the 'client-error-document-access-
-        error' status code.  The Printer MAY also return a specific document
-        access error code using the 'document-access-error' operation
-        attribute (see section 3.1.6.4).
-
-        If the Printer determines this document accessibility problem after
-        accepting the request and returning an operation response with one
-        of the successful status codes, the Printer adds the
-        'document-access- error' value to the job's 'job-state-reasons'
-        attribute and MAY populate the job's 'job-document-access-errors'
-        Job Description attribute (see section 4.3.11).  See The
-        Implementer's Guide [IPP- IIG] for suggested additional checks.
+        This OPTIONAL operation is identical to the Print-Job
+        operation (section 3.2.1) except that a client supplies a URI
+        reference to the document data using the 'document-uri' (uri)
+        operation attribute (in Group 1) rather than including the
+        document data itself.  Before returning the response, the
+        Printer MUST validate that the Printer supports the retrieval
+        method (e.g., http, ftp, etc.) implied by the URI, and MUST
+        check for valid URI syntax.  If the client-supplied URI scheme
+        is not supported, i.e. the value is not in the Printer
+        object's 'referenced-uri-scheme-supported' attribute, the
+        Printer object MUST reject the request and return the
+        'client-error-uri- scheme-not-supported' status code.
+
+        The IPP Printer MAY validate the accessibility of the document
+        as part of the operation or subsequently.  If the Printer
+        determines an accessibility problem before returning an
+        operation response, it rejects the request and returns the
+        'client-error-document-access- error' status code.  The
+        Printer MAY also return a specific document access error code
+        using the 'document-access-error' operation attribute (see
+        section 3.1.6.4).
+
+        If the Printer determines this document accessibility problem
+        after accepting the request and returning an operation
+        response with one of the successful status codes, the Printer
+        adds the 'document-access- error' value to the job's
+        'job-state-reasons' attribute and MAY populate the job's
+        'job-document-access-errors' Job Description attribute (see
+        section 4.3.11).  See The Implementer's Guide [IPP- IIG] for
+        suggested additional checks.
                                                                               
-        If the Printer object supports this operation, it MUST support the
-        'reference-uri-schemes-supported' Printer attribute (see section 4.4.27).
-
-        It is up to the IPP object to interpret the URI and subsequently
-        'pull' the document from the source referenced by the URI string."""
-        operation = request.attribute_groups[0]
-        document = request.data        
-        user_name = None
-        job_name = None
-        job_k_octets = None
-        document_format = None
-        document_natural_language = None
-        compression = None
-        last_document = None
-
-
-        # requested printer uri
-        if 'printer-uri' not in operation:
-            raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
-        printer_uri = verify_attribute(operation['printer-uri'], ipp.PrinterUri)[0]
-        if printer_uri not in self.printer.uris:
-            raise ipp.errors.ClientErrorAttributes(
-                str(operation['printer-uri']), operation['printer-uri'])
-
-        if 'requesting-user-name' in operation:
-            user_name = verify_attribute(
-                operation['requesting-user-name'], ipp.RequestingUserName)[0]
-
-        if 'job-name' in operation:
-            job_name = verify_attribute(
-                operation['job-name'], ipp.JobName)[0]
-
-        if 'job-k-octets' in operation:
-            job_k_octets = verify_attribute(
-                operation['job-k-octets'], ipp.JobKOctets)[0]
-
-        if 'ipp-attribute-fidelity' in operation:
-            pass # don't care
-        if 'job-impressions' in operation:
-            pass # don't care
-        if 'job-media-sheets' in operation:
-            pass # don't care
-
-        # get attributes from the printer and add to response
-        try:
-            job_id = self.printer.print_uri(document,
-                    document_name               = document_name,
-                    document_format             = document_format,
-                    document_natural_language   = document_natural_language,
-                    requesting_user_name        = user_name,
-                    compression                 = compression,
-                    job_name                    = job_name,
-                    job_k_octets                = job_k_octets)
-        except InvalidJobException:
-            raise ipp.errors.ClientErrorNotFound("bad job: %d" % job_id)
-
-
-        attrs = self.printer.get_job_attributes(job_id)
-     
-        #Actually append the attributes we pulled
-        response.attribute_groups.append(ipp.AttributeGroup(
-            ipp.AttributeTags.JOB, attrs))
-
- 
-       #raise ipp.errors.ServerErrorOperationNotSupported
-
-    @handler_for(ipp.OperationCodes.CREATE_JOB)
-    def create_job(self, request, response):
-        """RFC 2911: 3.2.4 Create-Job Operation
-
-        This OPTIONAL operation is similar to the Print-Job operation
-        (section 3.2.1) except that in the Create-Job request, a
-        client does not supply document data or any reference to
-        document data. Also, the client does not supply any of the
-        'document-name', 'document- format', 'compression', or
-        'document-natural-language' operation attributes. This
-        operation is followed by one or more Send-Document or Send-URI
-        operations. In each of those operation requests, the client
-        OPTIONALLY supplies the 'document-name', 'document-format',
-        and 'document-natural-language' attributes for each document
-        in the multi-document Job object.
+        If the Printer object supports this operation, it MUST support
+        the 'reference-uri-schemes-supported' Printer attribute (see
+        section 4.4.27).
+
+        It is up to the IPP object to interpret the URI and
+        subsequently 'pull' the document from the source referenced by
+        the URI string.
 
         Request
@@ -493,8 +447,13 @@
             REQUIRED 'attributes-charset' 
             REQUIRED 'attributes-natural-language' 
-            REQUIRED 'printer-uri' (uri) 
+            REQUIRED 'printer-uri' (uri)
+            REQUIRED 'document-uri' (uri)
             OPTIONAL 'requesting-user-name' (name(MAX))
             OPTIONAL 'job-name' (name(MAX))
             OPTIONAL 'ipp-attribute-fidelity' (boolean)
+            OPTIONAL 'document-name' (name(MAX))
+            OPTIONAL 'compression' (type3 keyword)
+            OPTIONAL 'document-format' (mimeMediaType)
+            OPTIONAL 'document-natural-language' (naturalLanguage)
             OPTIONAL 'job-k-octets' (integer(0:MAX))
             OPTIONAL 'job-impressions' (integer(0:MAX))
@@ -517,4 +476,110 @@
             OPTIONAL 'job-state-message' (text(MAX))
             OPTIONAL 'number-of-intervening-jobs' (integer(0:MAX))
+
+        """
+
+        operation = request.attribute_groups[0]
+        document = request.data        
+        user_name = None
+        job_name = None
+        job_k_octets = None
+        document_format = None
+        document_natural_language = None
+        compression = None
+        last_document = None
+
+        # requested printer uri
+        if 'printer-uri' not in operation:
+            raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
+        printer_uri = verify_attribute(operation['printer-uri'], ipp.PrinterUri)[0]
+        if printer_uri not in self.printer.uris:
+            raise ipp.errors.ClientErrorAttributes(
+                str(operation['printer-uri']), operation['printer-uri'])
+
+        if 'requesting-user-name' in operation:
+            user_name = verify_attribute(
+                operation['requesting-user-name'], ipp.RequestingUserName)[0]
+
+        if 'job-name' in operation:
+            job_name = verify_attribute(
+                operation['job-name'], ipp.JobName)[0]
+
+        if 'job-k-octets' in operation:
+            job_k_octets = verify_attribute(
+                operation['job-k-octets'], ipp.JobKOctets)[0]
+
+        if 'ipp-attribute-fidelity' in operation:
+            pass # don't care
+        if 'job-impressions' in operation:
+            pass # don't care
+        if 'job-media-sheets' in operation:
+            pass # don't care
+
+        # get attributes from the printer and add to response
+        try:
+            job_id = self.printer.print_uri(
+                document,
+                document_name=document_name,
+                document_format=document_format,
+                document_natural_language=document_natural_language,
+                requesting_user_name=user_name,
+                compression=compression,
+                job_name=job_name,
+                job_k_octets=job_k_octets)
+
+        except InvalidJobException:
+            raise ipp.errors.ClientErrorNotFound("bad job: %d" % job_id)
+
+        attrs = self.printer.get_job_attributes(job_id)
+     
+        # Actually append the attributes we pulled
+        response.attribute_groups.append(ipp.AttributeGroup(
+            ipp.AttributeTags.JOB, attrs))
+
+    @handler_for(ipp.OperationCodes.CREATE_JOB)
+    def create_job(self, request, response):
+        """RFC 2911: 3.2.4 Create-Job Operation
+
+        This OPTIONAL operation is similar to the Print-Job operation
+        (section 3.2.1) except that in the Create-Job request, a
+        client does not supply document data or any reference to
+        document data. Also, the client does not supply any of the
+        'document-name', 'document- format', 'compression', or
+        'document-natural-language' operation attributes. This
+        operation is followed by one or more Send-Document or Send-URI
+        operations. In each of those operation requests, the client
+        OPTIONALLY supplies the 'document-name', 'document-format',
+        and 'document-natural-language' attributes for each document
+        in the multi-document Job object.
+
+        Request
+        -------
+        Group 1: Operation Attributes
+            REQUIRED 'attributes-charset' 
+            REQUIRED 'attributes-natural-language' 
+            REQUIRED 'printer-uri' (uri) 
+            OPTIONAL 'requesting-user-name' (name(MAX))
+            OPTIONAL 'job-name' (name(MAX))
+            OPTIONAL 'ipp-attribute-fidelity' (boolean)
+            OPTIONAL 'job-k-octets' (integer(0:MAX))
+            OPTIONAL 'job-impressions' (integer(0:MAX))
+            OPTIONAL 'job-media-sheets' (integer(0:MAX))
+        Group 2: Job Template Attributes
+
+        Response
+        --------
+        Group 1: Operation Attributes
+            OPTIONAL 'status-message' (text(255))
+            OPTIONAL 'detailed-status-message' (text(MAX))
+            REQUIRED 'attributes-charset'
+            REQUIRED 'attributes-natural-language'
+        Group 2: Unsupported Attributes
+        Group 3: Job Object Attributes
+            REQUIRED 'job-uri' (uri)
+            REQUIRED 'job-id' (integer(1:MAX))
+            REQUIRED 'job-state' (type1 enum)
+            REQUIRED 'job-state-reasons' (1setOf type2 keyword)
+            OPTIONAL 'job-state-message' (text(MAX))
+            OPTIONAL 'number-of-intervening-jobs' (integer(0:MAX))
         
         """
@@ -566,125 +631,54 @@
     @handler_for(ipp.OperationCodes.PAUSE_PRINTER)
     def pause_printer(self, request, response):
+        """3.2.7 Pause-Printer Operation
+
+        This OPTIONAL operation allows a client to stop the Printer
+        object from scheduling jobs on all its devices.  Depending on
+        implementation, the Pause-Printer operation MAY also stop the
+        Printer from processing the current job or jobs.  Any job that
+        is currently being printed is either stopped as soon as the
+        implementation permits or is completed, depending on
+        implementation.  The Printer object MUST still accept create
+        operations to create new jobs, but MUST prevent any jobs from
+        entering the 'processing' state.
+
+        If the Pause-Printer operation is supported, then the
+        Resume-Printer operation MUST be supported, and vice-versa.
+
+        The IPP Printer MUST accept the request in any state and
+        transition the Printer to the indicated new 'printer-state'
+        before returning as follows:
+
+        Current       New         Reasons             Reponse
+        --------------------------------------------------------------
+        'idle'       'stopped'    'paused'            'successful-ok'
+        'processing' 'processing' 'moving-to-paused'  'successful-ok'
+        'processing' 'stopped'    'paused'            'successful-ok'
+        'stopped'    'stopped'    'paused'            'successful-ok'
+
+
+        Request
+        -------
+        Group 1: Operation Attributes
+            REQUIRED 'attributes-charset' 
+            REQUIRED 'attributes-natural-language' 
+            REQUIRED 'printer-uri' (uri) 
+            OPTIONAL 'requesting-user-name' (name(MAX))
+
+        Response
+        --------
+        Group 1: Operation Attributes
+            OPTIONAL 'status-message' (text(255))
+            OPTIONAL 'detailed-status-message' (text(MAX))
+            REQUIRED 'attributes-charset'
+            REQUIRED 'attributes-natural-language'
+        Group 2: Unsupported Attributes
+   
         """
-            3.2.7 Pause-Printer Operation
-
-            This OPTIONAL operation allows a client to stop the Printer object
-            from scheduling jobs on all its devices.  Depending on
-            implementation, the Pause-Printer operation MAY also stop the Printer
-            from processing the current job or jobs.  Any job that is currently
-            being printed is either stopped as soon as the implementation permits
-            or is completed, depending on implementation.  The Printer object
-            MUST still accept create operations to create new jobs, but MUST
-            prevent any jobs from entering the 'processing' state.
-
-            If the Pause-Printer operation is supported, then the Resume-Printer
-            operation MUST be supported, and vice-versa.
-
-            The IPP Printer stops the current job(s) on its device(s) that were
-            in the 'processing' or 'processing-stopped' states as soon as the
-            implementation permits.  If the implementation will take appreciable
-            time to stop, the IPP Printer adds the 'moving-to-paused' value to
-            the Printer object's 'printer-state-reasons' attribute (see section
-            4.4.12).  When the device(s) have all stopped, the IPP Printer
-            transitions the Printer object to the 'stopped' state, removes the
-            'moving-to-paused' value, if present, and adds the 'paused' value to
-            the Printer object's 'printer-state-reasons' attribute.
-
-            When the current job(s) complete that were in the 'processing' state,
-            the IPP Printer transitions them to the 'completed' state.  When the
-            current job(s) stop in mid processing that were in the 'processing'
-            state, the IPP Printer transitions them to the 'processing-stopped'
-            state and adds the 'printer-stopped' value to the job's 'job-state-
-            reasons' attribute.
-
-            For any jobs that are 'pending' or 'pending-held', the 'printer-
-            stopped' value of the jobs' 'job-state-reasons' attribute also
-            applies.  However, the IPP Printer NEED NOT update those jobs' 'job-
-            state-reasons' attributes and only need return the 'printer-stopped'
-            value when those jobs are queried (so-called 'lazy evaluation').
-
-            Whether the Pause-Printer operation affects jobs that were submitted
-            to the device from other sources than the IPP Printer object in the
-            same way that the Pause-Printer operation affects jobs that were
-            submitted to the IPP Printer object using IPP, depends on
-            implementation, i.e., on whether the IPP protocol is being used as a
-            universal management protocol or just to manage IPP jobs,
-            respectively.
-
-            The IPP Printer MUST accept the request in any state and transition
-            the Printer to the indicated new 'printer-state' before returning as
-            follows:
-
-            Current        New      'printer   IPP Printer's response status
-            'printer-    'printer-   -state-          code and action:
-            state'       state'    reasons'
-
-            'idle'       'stopped'    'paused'  'successful-ok'
-            'processing' 'processing' 'moving-  OPTION 1: 'successful-ok';
-                                                      to-       Later, when all output has
-                                                      paused'   stopped, the 'printer-state'
-                                                                            becomes 'stopped', and the
-                                                                            'paused' value replaces the
-                                                                            'moving-to-paused' value in the
-                                                                            'printer-state-reasons'
-                                                                            attribute
-            'processing' 'stopped'    'paused'  OPTION 2: 'successful-ok';
-                                                                            all device output stopped
-                                                                            immediately
-            'stopped'    'stopped'    'paused'  'successful-ok'
-
-            Access Rights: The authenticated user (see section 8.3) performing
-            this operation must be an operator or administrator of the Printer
-            object (see Sections 1 and 8.5).   Otherwise, the IPP Printer MUST
-            reject the operation and return:  'client-error-forbidden', 'client-
-            error-not-authenticated', or 'client-error-not-authorized' as
-            appropriate.
-
-            3.2.7.1 Pause-Printer Request
-
-            The following groups of attributes are part of the Pause-Printer
-            Request:
-
-            Group 1: Operation Attributes
-
-            Natural Language and Character Set:
-            The 'attributes-charset' and 'attributes-natural-language'
-            attributes as described in section 3.1.4.1.
-
-            Target:
-            The 'printer-uri' (uri) operation attribute which is the target
-            for this operation as described in section 3.1.5.
-
-            Requesting User Name:
-            The 'requesting-user-name' (name(MAX)) attribute SHOULD be
-            supplied by the client as described in section 8.3.
-
-            3.2.7.2 Pause-Printer Response
-
-            The following groups of attributes are part of the Pause-Printer
-            Response:
-
-            Group 1: Operation Attributes
-
-            Status Message:
-            In addition to the REQUIRED status code returned in every
-            response, the response OPTIONALLY includes a 'status-message'
-            (text(255)) and/or a 'detailed-status-message' (text(MAX))
-            operation attribute as described in sections 13 and  3.1.6.
-
-            Natural Language and Character Set:
-            The 'attributes-charset' and 'attributes-natural-language'
-            attributes as described in section 3.1.4.2.
-
-            Group 2: Unsupported Attributes
-
-            See section 3.1.7 for details on returning Unsupported Attributes.
-
-   
-    """
-    operation = request.attribute_groups[0]
-    printer_uri = None
-    user_name   = None
-    if 'printer-uri' not in operation:
+
+        operation = request.attribute_groups[0]
+        printer_uri = None
+        user_name   = None
+        if 'printer-uri' not in operation:
             raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
         printer_uri = verify_attribute(operation['printer-uri'], ipp.PrinterUri)[0]
@@ -693,63 +687,64 @@
                 str(operation['printer-uri']), operation['printer-uri'])
 
-    if 'requesting-user-name' in operation:
-        user_name = verify_attribute(
-            operation['requesting-user-name'], ipp.RequestingUserName)[0]
-   self.printer.pause_printer()
-
-
-    #    raise ipp.errors.ServerErrorOperationNotSupported
+        if 'requesting-user-name' in operation:
+            user_name = verify_attribute(
+                operation['requesting-user-name'], ipp.RequestingUserName)[0]
+        self.printer.pause_printer()
 
     @handler_for(ipp.OperationCodes.RESUME_PRINTER)
     def resume_printer(self, request, response):
-        """
-        3.2.8 Resume-Printer Operation
+        """3.2.8 Resume-Printer Operation
 
         This operation allows a client to resume the Printer object
-        scheduling jobs on all its devices.  The Printer object MUST remove
-        the 'paused' and 'moving-to-paused' values from the Printer object's
-        'printer-state-reasons' attribute, if present.  If there are no other
-        reasons to keep a device paused (such as media-jam), the IPP Printer
-        is free to transition itself to the 'processing' or 'idle' states,
+        scheduling jobs on all its devices.  The Printer object MUST
+        remove the 'paused' and 'moving-to-paused' values from the
+        Printer object's 'printer-state-reasons' attribute, if
+        present.  If there are no other reasons to keep a device
+        paused (such as media-jam), the IPP Printer is free to
+        transition itself to the 'processing' or 'idle' states,
         depending on whether there are jobs to be processed or not,
         respectively, and the device(s) resume processing jobs.
 
-        If the Pause-Printer operation is supported, then the Resume-Printer
-        operation MUST be supported, and vice-versa.
-
-        The IPP Printer removes the 'printer-stopped' value from any job's
-        'job-state-reasons' attributes contained in that Printer.
-
-        The IPP Printer MUST accept the request in any state, transition the
-        Printer object to the indicated new state as follows:
-
-
-        Current    New 'printer-  IPP Printer's response status code and
-        'printer-      state'                     action:
-        state'
-
+        If the Pause-Printer operation is supported, then the
+        Resume-Printer operation MUST be supported, and vice-versa.
+
+        The IPP Printer removes the 'printer-stopped' value from any
+        job's 'job-state-reasons' attributes contained in that
+        Printer.
+
+        The IPP Printer MUST accept the request in any state,
+        transition the Printer object to the indicated new state as
+        follows:
+
+        Current       New           Response
+        ---------------------------------------------
         'idle'       'idle'         'successful-ok'
         'processing' 'processing'   'successful-ok'
-
-        'stopped'    'processing'   'successful-ok';
-                                                   when there are jobs to be processed
-        'stopped'    'idle'         'successful-ok';
-                                                   when there are no jobs to be processed.
-
-        Access Rights: The authenticated user (see section 8.3) performing
-        this operation must be an operator or administrator of the Printer
-        object (see Sections 1 and 8.5).  Otherwise, the IPP Printer MUST
-        reject the operation and return:  'client-error-forbidden', 'client-
-        error-not-authenticated', or 'client-error-not-authorized' as
-        appropriate.
-
-        The Resume-Printer Request and Resume-Printer Response have the same
-        attribute groups and attributes as the Pause-Printer operation (see
-        sections 3.2.7.1 and 3.2.7.2).                 
+        'stopped'    'processing'   'successful-ok'
+        'stopped'    'idle'         'successful-ok'
+
+        Request
+        -------
+        Group 1: Operation Attributes
+            REQUIRED 'attributes-charset' 
+            REQUIRED 'attributes-natural-language' 
+            REQUIRED 'printer-uri' (uri) 
+            OPTIONAL 'requesting-user-name' (name(MAX))
+
+        Response
+        --------
+        Group 1: Operation Attributes
+            OPTIONAL 'status-message' (text(255))
+            OPTIONAL 'detailed-status-message' (text(MAX))
+            REQUIRED 'attributes-charset'
+            REQUIRED 'attributes-natural-language'
+        Group 2: Unsupported Attributes
+
         """
-    operation = request.attribute_groups[0]
-    printer_uri = None
-    user_name   = None
-    if 'printer-uri' not in operation:
+        
+        operation = request.attribute_groups[0]
+        printer_uri = None
+        user_name   = None
+        if 'printer-uri' not in operation:
             raise ipp.errors.ClientErrorBadRequest("Missing 'printer-uri' attribute")
         printer_uri = verify_attribute(operation['printer-uri'], ipp.PrinterUri)[0]
@@ -758,9 +753,9 @@
                 str(operation['printer-uri']), operation['printer-uri'])
 
-    if 'requesting-user-name' in operation:
-        user_name = verify_attribute(
-            operation['requesting-user-name'], ipp.RequestingUserName)[0]
-   self.printer.resume_printer()
-
+        if 'requesting-user-name' in operation:
+            user_name = verify_attribute(
+                operation['requesting-user-name'], ipp.RequestingUserName)[0]
+
+        self.printer.resume_printer()
 
     @handler_for(ipp.OperationCodes.GET_PRINTER_ATTRIBUTES)
@@ -845,13 +840,14 @@
         """3.3.3 Cancel-Job Operation
 
-        This REQUIRED operation allows a client to cancel a Print Job from
-        the time the job is created up to the time it is completed, canceled,
-        or aborted. Since a Job might already be printing by the time a
-        Cancel-Job is received, some media sheet pages might be printed
-        before the job is actually terminated.
-
-        The IPP object MUST accept or reject the request based on the job's
-        current state and transition the job to the indicated new state as
-        follows:
+        This REQUIRED operation allows a client to cancel a Print Job
+        from the time the job is created up to the time it is
+        completed, canceled, or aborted. Since a Job might already be
+        printing by the time a Cancel-Job is received, some media
+        sheet pages might be printed before the job is actually
+        terminated.
+
+        The IPP object MUST accept or reject the request based on the
+        job's current state and transition the job to the indicated
+        new state as follows:
 
         Current State       New State           Response
