Index: server/lib/gutenbach/ipp/attributegroup.py
===================================================================
--- server/lib/gutenbach/ipp/attributegroup.py	(revision d04a6891fc6c9f9ce772732907214ccd85485868)
+++ server/lib/gutenbach/ipp/attributegroup.py	(revision b2e077a94f58512ca52085a59f40ffecab7178d5)
@@ -16,16 +16,16 @@
     """
 
-    def __init__(self, attribute_group_tag=None, attributes=[]):
+    def __init__(self, tag=None, attributes=[]):
         """Initialize an AttributeGroup.  An AttributeGroup can be
         initialized in three ways:
 
             AttributeGroup()
-            AttributeGroup(attribute_group_tag)
-            AttributeGroup(attribute_group_tag, attributes)
+            AttributeGroup(tag)
+            AttributeGroup(tag, attributes)
 
         Arguments:
 
-            attribute_group_tag -- a signed char, holds the tag of the
-                                   attribute group
+            tag -- a signed char, holds the tag of the
+                   attribute group
 
             attributes -- a list of attributes
@@ -33,10 +33,9 @@
         """
 
-        if attribute_group_tag is not None:
-            assert isinstance(attribute_group_tag, int), \
-                   "attribute_group_tag must be a character!"
-            
+        if tag is not None:
+            assert isinstance(tag, int), \
+                   "tag must be a character!"
 
-        self.attribute_group_tag = attribute_group_tag
+        self.tag = tag
         self.attributes = []
         self.extend(attributes)
@@ -97,6 +96,6 @@
         """
 
-        # conver the attribute_group_tag to binary
-        tag = struct.pack('>b', self.attribute_group_tag)
+        # convert the tag to binary
+        tag = struct.pack('>b', self.tag)
 
         # convert each of the attributes to binary
@@ -107,3 +106,3 @@
 
     def __repr__(self):
-        return '<IPPAttributeGroup (%r, %r)>' % (self.attribute_group_tag, self.attributes)
+        return '<IPPAttributeGroup (%r, %r)>' % (self.tag, self.attributes)
Index: server/lib/gutenbach/server/__init__.py
===================================================================
--- server/lib/gutenbach/server/__init__.py	(revision d04a6891fc6c9f9ce772732907214ccd85485868)
+++ server/lib/gutenbach/server/__init__.py	(revision b2e077a94f58512ca52085a59f40ffecab7178d5)
@@ -1,3 +1,3 @@
-from requests import GutenbachIPPHandler
+from requests import GutenbachIPPServer
 import BaseHTTPServer
 import logging
@@ -8,5 +8,5 @@
 def start():
     server_address = ('', 8000)
-    httpd = BaseHTTPServer.HTTPServer(server_address, GutenbachIPPHandler)
+    httpd = BaseHTTPServer.HTTPServer(server_address, GutenbachIPPServer)
     httpd.serve_forever()
 
Index: server/lib/gutenbach/server/exceptions.py
===================================================================
--- server/lib/gutenbach/server/exceptions.py	(revision df510617607a17049c40187f93c7ce3d26508ae1)
+++ server/lib/gutenbach/server/exceptions.py	(revision b2e077a94f58512ca52085a59f40ffecab7178d5)
@@ -12,2 +12,9 @@
     def __str__(self):
 	return self.message
+
+class MalformedIPPRequestException(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
Index: server/lib/gutenbach/server/job.py
===================================================================
--- server/lib/gutenbach/server/job.py	(revision d04a6891fc6c9f9ce772732907214ccd85485868)
+++ server/lib/gutenbach/server/job.py	(revision b2e077a94f58512ca52085a59f40ffecab7178d5)
@@ -7,4 +7,13 @@
 class Job(object):
 
+    attributes = [
+        "job-id",
+        "job-name",
+        "job-originating-user-name",
+        "job-k-octets",
+        "job-state",
+        "job-printer-uri"
+        ]
+
     def __init__(self, document=None):
 	"""Initialize a Gutenbach job.
@@ -14,17 +23,54 @@
 	"""
 	 
-	self._jobid = None
-	self._status = 'initializing'
+	self._id = None
+        self._name = document
+	self._status = None
 	self._document = document
 	self._printer = None
 
     @property
-    def jobid(self):
-	return self._jobid
+    def job_id(self):
+	return ipp.Attribute(
+            'job-id',
+            [ipp.Value(ipp.Tags.INTEGER, self._id)])
 
-    @jobid.setter
-    def jobid(self, val):
-	raise AttributeError("Setting jobid is illegal!")
+    @property
+    def job_name(self):
+        return ipp.Attribute(
+            'job-name',
+            [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, self._name)])
 
+    # XXX: we need to actually calculate this!
+    @property
+    def job_originating_user_name(self):
+        return ipp.Attribute(
+            'job-originating-user-name',
+            [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, "jhamrick")])
+
+    # XXX: we need to actually calculate this!
+    @property
+    def job_k_octets(self):
+        return ipp.Attribute(
+            'job-k-octets',
+            [ipp.Value(ipp.Tags.INTEGER, 1)])
+
+    @property
+    def job_state(self):
+        return ipp.Attribute(
+            'job-state',
+            [ipp.Value(ipp.Tags.ENUM, self._status)])
+
+    @property
+    def job_printer_uri(self):
+        return ipp.Attribute(
+            'job-printer-uri',
+            [ipp.Value(ipp.Tags.URI, self._printer._uri)])
+
+    def get_job_attributes(self, request):
+        attributes = [getattr(self, attr.replace("-", "_")) for attr in self.attributes]
+        return attributes
+
+    
+    #######
     @property
     def document(self):
@@ -41,28 +87,16 @@
 	return self._status
 
-    @status.setter
-    def status(self, val):
-	raise AttributeError(
-	    "Setting status directly is illegal!  " + \
-	    "Please use enqueue(), play(), or finish().")
-
     @property
     def printer(self):
 	return self._printer
 
-    @printer.setter
-    def printer(self, val):
-	raise AttributeError(
-	    "Setting printer directly is illegal!  " + \
-	    "Please use enqueue().")
-
-    def enqueue(self, printer, jobid):
-	if self.status != 'initializing':
+    def enqueue(self, printer, job_id):
+	if self._status != None:
 	    raise InvalidJobException(
 		"Cannot enqueue a job that has " + \
 		"already been initialized!")
 	self._printer = printer
-        self._jobid = jobid
-	self._status = 'active'
+        self._job_id = job_id
+	self._status = const.JobStates.PENDING
 
     def play(self):
@@ -71,11 +105,11 @@
 		"Cannot play an inactive job!")
 	
-	self._status = 'playing'
+	self._status = const.JobStates.PROCESSING
 	# TODO: add external call to music player
         print "Playing job %s" % str(self)
-	self.printer.complete_job(self.jobid)
+	self._printer.complete_job(self._id)
 
     def finish(self):
-	self._status = 'finished'
+	self._status = const.JobStates.COMPLETE
 
     def __repr__(self):
@@ -84,4 +118,4 @@
     def __str__(self):
         return "<Job %d '%s'>" % \
-               (self.jobid if self.jobid is not None else -1, \
-                                  self.document)
+               (self._id if self._id is not None else -1, \
+                self._document)
Index: server/lib/gutenbach/server/printer.py
===================================================================
--- server/lib/gutenbach/server/printer.py	(revision d04a6891fc6c9f9ce772732907214ccd85485868)
+++ server/lib/gutenbach/server/printer.py	(revision b2e077a94f58512ca52085a59f40ffecab7178d5)
@@ -1,25 +1,52 @@
+#import alsaaudio as aa
 from .exceptions import InvalidJobException, InvalidPrinterStateException
 from gutenbach.ipp.attribute import Attribute
-import alsaaudio as aa
-import gutenbach.ipp
+import gutenbach.ipp as ipp
+import gutenbach.ipp.constants as const
+import logging
+import time
 
 # initialize logger
 logger = logging.getLogger(__name__)
 
-class Printer(object):
-
-    def __init__(self, name, card, mixer):
-
-	self.name = name
-
-	if card >= len(aa.cards()):
-	    raise aa.ALSAAudioError(
-		"Audio card at index %d does not exist!" % card)
-	elif mixer not in aa.mixers(card):
-	    raise aa.ALSAAudioError(
-		"Audio mixer '%s' does not exist!" % mixer)
+class GutenbachPrinter(object):
+
+    attributes = [
+        "printer-uri-supported",
+        "uri-authentication-supported",
+        "uri-security-supported",
+        "printer-name",
+        "printer-state",
+        "printer-state-reasons",
+        "ipp-versions-supported",
+        "operations-supported",
+        "charset-configured",
+        "charset-supported",
+        "natural-language-configured",
+        "generated-natural-language-supported",
+        "document-format-default",
+        "document-format-supported",
+        "printer-is-accepting-jobs",
+        "queued-job-count",
+        "pdl-override-supported",
+        "printer-up-time",
+        "compression-supported"]
+
+    #def __init__(self, name, card, mixer):
+    def __init__(self, name):
+
+	self._name = name
+        self._uri = "ipp://localhost:8000/printers/" + self._name
+        self._time_created = int(time.time())
+
+	# if card >= len(aa.cards()):
+	#     raise aa.ALSAAudioError(
+	# 	"Audio card at index %d does not exist!" % card)
+	# elif mixer not in aa.mixers(card):
+	#     raise aa.ALSAAudioError(
+	# 	"Audio mixer '%s' does not exist!" % mixer)
 	
-	self.card = card
-	self.mixer = mixer
+	# self.card = card
+	# self.mixer = mixer
 
 	self.finished_jobs = []
@@ -29,12 +56,131 @@
 	self._next_jobid = 0
 
+    ## Printer attributes
+    @property
+    def printer_uri_supported(self):
+        return ipp.Attribute(
+            "printer-uri-supported",
+            [ipp.Value(ipp.Tags.URI, self._uri)])
+    
+    @property
+    def uri_authentication_supported(self):
+        return ipp.Attribute(
+            "uri-authentication-supported",
+            [ipp.Value(ipp.Tags.KEYWORD, "none")])
+
+    @property
+    def uri_security_supported(self):
+        return ipp.Attribute(
+            "uri-security-supported",
+            [ipp.Value(ipp.Tags.KEYWORD, "none")])
+
+    @property
+    def printer_name(self):
+        return ipp.Attribute(
+            "printer-name",
+            [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, self._name)])
+        
+    @property
+    def printer_state(self):
+        return ipp.Attribute(
+            "printer-state",
+            [ipp.Value(ipp.Tags.ENUM, const.PrinterStates.IDLE)])
+        
+    @property
+    def printer_state_reasons(self):
+        return ipp.Attribute(
+            "printer-state-reasons",
+            [ipp.Value(ipp.Tags.KEYWORD, "none")])
+
+    @property
+    def ipp_versions_supported(self):
+        return ipp.Attribute(
+            "ipp-versions-supported",
+            [ipp.Value(ipp.Tags.KEYWORD, "1.0"),
+             ipp.Value(ipp.Tags.KEYWORD, "1.1")])
+
+    # XXX: We should query ourself for the supported operations
+    @property
+    def operations_supported(self):
+        return ipp.Attribute(
+            "operations-supported",
+            [ipp.Value(ipp.Tags.ENUM, const.Operations.GET_JOBS)])
+
+    @property
+    def charset_configured(self):
+        return ipp.Attribute(
+            "charset-configured",
+            [ipp.Value(ipp.Tags.CHARSET, "utf-8")])
+
+    @property
+    def charset_supported(self):
+        return ipp.Attribute(
+            "charset-supported",
+            [ipp.Value(ipp.Tags.CHARSET, "utf-8")])
+
+    @property
+    def natural_language_configured(self):
+        return ipp.Attribute(
+            "natural-language-configured",
+            [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")])
+
+    @property
+    def generated_natural_language_supported(self):
+        return ipp.Attribute(
+            "generated-natural-language-supported",
+            [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")])
+
+    @property
+    def document_format_default(self):
+        return ipp.Attribute(
+            "document-format-default",
+            [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream")])
+
+    @property
+    def document_format_supported(self):
+        return ipp.Attribute(
+            "document-format-supported",
+            [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream"),
+             ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "audio/mp3")])
+
+    @property
+    def printer_is_accepting_jobs(self):
+        return ipp.Attribute(
+            "printer-is-accepting-jobs",
+            [ipp.Value(ipp.Tags.BOOLEAN, True)])
+
+    @property
+    def queued_job_count(self):
+        return ipp.Attribute(
+            "queued-job-count",
+            [ipp.Value(ipp.Tags.INTEGER, len(self.active_jobs))])
+
+    @property
+    def pdl_override_supported(self):
+        return ipp.Attribute(
+            "pdl-override-supported",
+            [ipp.Value(ipp.Tags.KEYWORD, "not-attempted")])
+
+    @property
+    def printer_up_time(self):
+        return ipp.Attribute(
+            "printer-up-time",
+            [ipp.Value(ipp.Tags.INTEGER, int(time.time()) - self._time_created)])
+
+    @property
+    def compression_supported(self):
+        return ipp.Attribute(
+            "compression-supported",
+            [ipp.Value(ipp.Tags.KEYWORD, "none")])
+
+    def get_printer_attributes(self, request):
+        attributes = [getattr(self, attr.replace("-", "_")) for attr in self.attributes]
+        return attributes
+
+    ## Printer operations
     @property
     def next_jobid(self):
 	self._next_jobid += 1
 	return self._next_jobid
-
-    @next_jobid.setter
-    def next_jobid(self, val):
-	raise AttributeError("Setting next_jobid is illegal!")
 
     def print_job(self, job):
@@ -75,7 +221,11 @@
 	return self.jobs[jobid]
 
+    def get_jobs(self):
+        jobs = [self.jobs[job_id] for job_id in self.active_jobs]
+        return jobs            
+
     def __repr__(self):
 	return str(self)
 
     def __str__(self):
-	return "<Printer '%s'>" % self.name
+	return "<Printer '%s'>" % self._name
Index: server/lib/gutenbach/server/requests.py
===================================================================
--- server/lib/gutenbach/server/requests.py	(revision d04a6891fc6c9f9ce772732907214ccd85485868)
+++ server/lib/gutenbach/server/requests.py	(revision b2e077a94f58512ca52085a59f40ffecab7178d5)
@@ -1,7 +1,8 @@
 import BaseHTTPServer
-import gutenbach.ipp
+import gutenbach.ipp as ipp
 import gutenbach.ipp.constants as const
+from gutenbach.server.printer import GutenbachPrinter
+from gutenbach.server.exceptions import MalformedIPPRequestException
 import logging
-import time
 
 # initialize logger
@@ -20,130 +21,90 @@
     return f
 
-class IPPRequestHandler(object):
-    """A generic base class for IPP requests.  Provides a dispatch
-    function to conver request operation ids to handler functions.
-
-    """
+class GutenbachRequestHandler(object):
+
+    def __init__(self):
+        self.printers = {
+            "test": GutenbachPrinter(name="test")
+            }
+        self.default = "test"
     
-    def _ipp_dispatch(self, request):
+    def handle(self, request, response):
+        # look up the handler
+        handler = None
         for d in dir(self):
             if getattr(getattr(self, d), "ipp_operation", None) == request.operation_id:
-                return getattr(self, d)
-        return self.unknown_operation
+                handler = getattr(self, d)
+                break
+        # we couldn't find a handler, so default to unknown operation
+        if handler is None:
+            handler = self.unknown_operation
+        # call the handler
+        handler(request, response)
 
     def unknown_operation(self, request, response):
-        print "Received UNKNOWN OPERATION %x" % request.operation_id
+        print "Received unknown operation %x" % request.operation_id
         response.operation_id = const.StatusCodes.OPERATION_NOT_SUPPORTED
 
-class PrinterRequestHandler(IPPRequestHandler):
-    """This handles requests that are printer-specific: for example,
-    the printer's name or state.
-
-    """
-    
-    def __init__(self, name):
-        self.name = name
-
-    @handler_for(const.Operations.GET_PRINTER_ATTRIBUTES)
-    def get_printer_attributes(self, request, response):
-        printer_attributes = ipp.AttributeGroup(const.AttributeTags.PRINTER)
-        printer_attributes.append(ipp.Attribute(
-            "printer-uri-supported",
-            [ipp.Value(ipp.Tags.URI, "ipp://localhost:8000/printers/" + self.name)]))
-
-        printer_attributes.append(ipp.Attribute(
-            "uri-authentication-supported",
-            [ipp.Value(ipp.Tags.KEYWORD, "none")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "uri-security-supported",
-            [ipp.Value(ipp.Tags.KEYWORD, "none")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "printer-name",
-            [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, self.name)]))
-
-        printer_attributes.append(ipp.Attribute(
-            "printer-state",
-            [ipp.Value(ipp.Tags.ENUM, const.PrinterStates.IDLE)]))
-
-        printer_attributes.append(ipp.Attribute(
-            "printer-state-reasons",
-            [ipp.Value(ipp.Tags.KEYWORD, "none")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "ipp-versions-supported",
-            [ipp.Value(ipp.Tags.KEYWORD, "1.0"),
-             ipp.Value(ipp.Tags.KEYWORD, "1.1")]))
-
-        # XXX: We should query ourself for the supported operations
-        printer_attributes.append(ipp.Attribute(
-            "operations-supported",
-            [ipp.Value(ipp.Tags.ENUM, const.Operations.GET_JOBS)]))
-
-        printer_attributes.append(ipp.Attribute(
-            "charset-configured",
-            [ipp.Value(ipp.Tags.CHARSET, "utf-8")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "charset-supported",
-            [ipp.Value(ipp.Tags.CHARSET, "utf-8")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "natural-language-configured",
-            [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "generated-natural-language-supported",
-            [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, "en-us")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "document-format-default",
-            [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "document-format-supported",
-            [ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "application/octet-stream"),
-             ipp.Value(ipp.Tags.MIME_MEDIA_TYPE, "audio/mp3")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "printer-is-accepting-jobs",
-            [ipp.Value(ipp.Tags.BOOLEAN, True)]))
-
-        printer_attributes.append(ipp.Attribute(
-            "queued-job-count",
-            [ipp.Value(ipp.Tags.INTEGER, 1)]))
-
-        printer_attributes.append(ipp.Attribute(
-            "pdl-override-supported",
-            [ipp.Value(ipp.Tags.KEYWORD, "not-attempted")]))
-
-        printer_attributes.append(ipp.Attribute(
-            "printer-up-time",
-            [ipp.Value(ipp.Tags.INTEGER, int(time.time()))]))
-
-        printer_attributes.append(ipp.Attribute(
-            "compression-supported",
-            [ipp.Value(ipp.Tags.KEYWORD, "none")]))
-
-        response.attribute_groups.append(printer_attributes)
-        response.operation_id = const.StatusCodes.OK
-        print "get_printer_attributes called"
-
-class RootRequestHandler(IPPRequestHandler):
-    printers = [PrinterRequestHandler(name="sipbmp3")]
+    def _get_printer_attributes(self, printer, request, response):
+        response.attribute_groups.append(ipp.AttributeGroup(
+            const.AttributeTags.PRINTER,
+            printer.get_printer_attributes(request)))
+
+    def _get_job_attributes(self, job_id, printer, request, response):
+        response.attribute_groups.append(ipp.AttributeGroup(
+            const.AttributeTags.JOB,
+            job.get_job_attributes(request)))
+
+    def _get_printer_name(self, request):
+        # make sure the first group is an OPERATION group
+        group_tag = request.attribute_groups[0].tag
+        if group_tag != const.AttributeTags.OPERATION:
+            raise MalformedIPPRequestException, \
+                  "Expected OPERATION group tag, got %d\n", group_tag
+
+        # make sure the printer-uri value is appropriate
+        printername_attr = request.attribute_groups[0]['printer-uri']
+        printername_value_tag = printername_attr.values[0].value_tag
+        if printername_value_tag != const.CharacterStringTags.URI:
+            raise MalformedIPPRequestException, \
+                  "Expected URI value tag, got %s" % printername_value_tag
+
+        # actually get the printer name
+        printername_value = printername_attr.values[0].value
+        # XXX: hack -- CUPS will strip the port from the request, so
+        # we can't do an exact comparison (also the hostname might be
+        # different, depending on the CNAME or whether it's localhost)
+        printername = printername_value.split("/")[-1]
+
+        # make sure the printername is valid
+        if printername not in self.printers:
+            raise ValueError, "Invalid printer uri: %s" % printername_value
+
+        return printername
 
     @handler_for(const.Operations.CUPS_GET_DEFAULT)
     def cups_get_default(self, request, response):
         print "get_default called"
-        return self.printers[0].get_printer_attributes(request, response)
+        self._get_printer_attributes(self.printers[self.default], request, response)
+        response.operation_id = const.StatusCodes.OK
+
+    @handler_for(const.Operations.GET_PRINTER_ATTRIBUTES)
+    def get_printer_attributes(self, request, response):
+        print "get_printer_attributes called"
+
+        # this is just like cups_get_default, except the printer name
+        # is given
+        printername = self._get_printer_name(request)
+        self._get_printer_attributes(self.printers[printername], request, response)
+        response.operation_id = const.StatusCodes.OK
 
     @handler_for(const.Operations.CUPS_GET_PRINTERS)
     def cups_get_printers(self, request, response):
         print "get_printers called"
-        response.operation_id = const.StatusCodes.OK
+        
         # Each printer will append a new printer attribute group.
-        for p in self.printers:
-            p.get_printer_attributes(request, response)
+        for printer in self.printers:
+            self._get_printer_attributes(self.printers[printer], request, response)
+        response.operation_id = const.StatusCodes.OK
 
     @handler_for(const.Operations.CUPS_GET_CLASSES)
@@ -153,7 +114,17 @@
         # We have no printer classes, so nothing to return.
 
-class GutenbachIPPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+    @handler_for(const.Operations.GET_JOBS)
+    def get_jobs(self, request, response):
+        print "get_jobs called"
+
+        printername = self._get_printer_name(request)
+        # Each job will append a new job attribute group.
+        for job in self.printers[printername].get_jobs():
+            self._get_job_attributes(job, request, response)
+        response.operation_id = const.StatusCodes.OK
+
+class GutenbachIPPServer(BaseHTTPServer.BaseHTTPRequestHandler):
     def setup(self):
-        self.root = RootRequestHandler()
+        self.root = GutenbachRequestHandler()
         BaseHTTPServer.BaseHTTPRequestHandler.setup(self)
 
@@ -196,6 +167,5 @@
 
         # Get the handler and pass it the request and response objects
-        handler = self.root._ipp_dispatch(request)
-        handler(request, response)
+        self.root.handle(request, response)
         print "Sending response:", repr(response)
 
@@ -207,53 +177,4 @@
         self.wfile.write(response.packed_value)
 
-    def get_jobs(self, request, response_kwargs):
-        """get-jobs response"""
-
-        # Job attributes
-        job_attributes = [
-            ipp.Attribute(
-                'job-id',
-                [ipp.Value(ipp.Tags.INTEGER, 12345)]),
-            ipp.Attribute(
-                'job-name',
-                [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, 'foo')]),
-            ipp.Attribute(
-                'job-originating-user-name',
-                [ipp.Value(ipp.Tags.NAME_WITHOUT_LANGUAGE, 'jhamrick')]),
-            ipp.Attribute(
-                'job-k-octets',
-                [ipp.Value(ipp.Tags.INTEGER, 1)]),
-            ipp.Attribute(
-                'job-state',
-                [ipp.Value(ipp.Tags.ENUM, const.JobStates.HELD)]),
-            ipp.Attribute(
-                'job-printer-uri',
-                [ipp.Value(ipp.Tags.URI, 'ipp://localhost:8000/printers/foo')])
-            ]
-        # Job attribute group
-        job_attribute_group = ipp.AttributeGroup(
-            const.AttributeTags.JOB,
-            job_attributes)
-
-        # Operation attributions
-        op_attributes = [
-            ipp.Attribute(
-                'attributes-charset',
-                [ipp.Value(ipp.Tags.CHARSET, 'utf-8')]),
-            ipp.Attribute(
-                'attributes-natural-language',
-                [ipp.Value(ipp.Tags.NATURAL_LANGUAGE, 'en-us')])
-            ]
-        # Operation attribution group
-        op_attributes_group = ipp.AttributeGroup(
-            const.AttributeTags.OPERATION,
-            op_attributes)
-
-        # Setup the actual response dictionary
-        response_kwargs['attribute_groups'] = [op_attributes_group,job_attribute_group]
-        response_kwargs['operation_id'] = const.StatusCodes.OK
-
-        return response_kwargs
-
     ##### Printer Commands
 
