diff --git a/quantum/client/__init__.py b/quantum/client/__init__.py
index 70a629c8d..861d4a0a4 100644
--- a/quantum/client/__init__.py
+++ b/quantum/client/__init__.py
@@ -25,19 +25,104 @@ from quantum.common import exceptions
 from quantum.common.serializer import Serializer
 
 LOG = logging.getLogger('quantum.client')
-EXCEPTIONS = {
-    400: exceptions.BadInputError,
-    401: exceptions.NotAuthorized,
-    420: exceptions.NetworkNotFound,
-    421: exceptions.NetworkInUse,
-    430: exceptions.PortNotFound,
-    431: exceptions.StateInvalid,
-    432: exceptions.PortInUseClient,
-    440: exceptions.AlreadyAttachedClient,
-    501: exceptions.NotImplementedError}
 AUTH_TOKEN_HEADER = "X-Auth-Token"
 
 
+def exception_handler_v10(status_code, error_content):
+    """ Exception handler for API v1.0 client
+
+        This routine generates the appropriate
+        Quantum exception according to the contents of the
+        response body
+
+        :param status_code: HTTP error status code
+        :param error_content: deserialized body of error response
+    """
+
+    quantum_error_types = {
+        420: 'networkNotFound',
+        421: 'networkInUse',
+        430: 'portNotFound',
+        431: 'requestedStateInvalid',
+        432: 'portInUse',
+        440: 'alreadyAttached'
+        }
+
+    quantum_errors = {
+        400: exceptions.BadInputError,
+        401: exceptions.NotAuthorized,
+        404: exceptions.NotFound,
+        420: exceptions.NetworkNotFoundClient,
+        421: exceptions.NetworkInUseClient,
+        430: exceptions.PortNotFoundClient,
+        431: exceptions.StateInvalidClient,
+        432: exceptions.PortInUseClient,
+        440: exceptions.AlreadyAttachedClient,
+        501: NotImplementedError
+        }
+
+    # Find real error type
+    error_type = None
+    if isinstance(error_content, dict):
+        error_type = quantum_error_types.get(status_code)
+    if error_type:
+        error_dict = error_content[error_type]
+        error_message = error_dict['message'] + "\n" +\
+                        error_dict['detail']
+    else:
+        error_message = error_content
+    # raise the appropriate error!
+    ex = quantum_errors[status_code](message=error_message)
+    ex.args = ([dict(status_code=status_code,
+                     message=error_message)],)
+    raise ex
+
+
+def exception_handler_v11(status_code, error_content):
+    """ Exception handler for API v1.1 client
+
+        This routine generates the appropriate
+        Quantum exception according to the contents of the
+        response body
+
+        :param status_code: HTTP error status code
+        :param error_content: deserialized body of error response
+    """
+
+    quantum_errors = {
+        'NetworkNotFound': exceptions.NetworkNotFoundClient,
+        'NetworkInUse': exceptions.NetworkInUseClient,
+        'PortNotFound': exceptions.PortNotFoundClient,
+        'RequestedStateInvalid': exceptions.StateInvalidClient,
+        'PortInUse': exceptions.PortInUseClient,
+        'AlreadyAttached': exceptions.AlreadyAttachedClient,
+        }
+
+    error_dict = None
+    if isinstance(error_content, dict):
+        error_dict = error_content.get('QuantumError')
+    # Find real error type
+    if error_dict:
+        # If QuantumError key is found, it will definitely contain
+        # a 'message' and 'type' keys
+        error_type = error_dict['type']
+        error_message = (error_dict['message'] + "\n" +
+                         error_dict['detail'])
+        # raise the appropriate error!
+        ex = quantum_errors[error_type](message=error_message)
+        ex.args = ([dict(status_code=status_code,
+                         message=error_message)],)
+        raise ex
+    # If we end up here the exception was not a quantum error
+    raise exceptions.QuantumClientException(status_code + "-" + error_content)
+
+
+EXCEPTION_HANDLERS = {
+    '1.0': exception_handler_v10,
+    '1.1': exception_handler_v11
+}
+
+
 class ApiCall(object):
     """A Decorator to add support for format and tenant overriding"""
     def __init__(self, function):
@@ -86,7 +171,8 @@ class Client(object):
     def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None,
                 format="xml", testingStub=None, key_file=None, cert_file=None,
                 auth_token=None, logger=None,
-                action_prefix="/v1.0/tenants/{tenant_id}"):
+                version="1.1",
+                uri_prefix="/tenants/{tenant_id}"):
         """
         Creates a new client to some service.
 
@@ -113,7 +199,24 @@ class Client(object):
         self.cert_file = cert_file
         self.logger = logger
         self.auth_token = auth_token
-        self.action_prefix = action_prefix
+        self.version = version
+        self.action_prefix = "/v%s%s" % (version, uri_prefix)
+
+    def _handle_fault_response(self, status_code, response_body):
+        # Create exception with HTTP status code and message
+        error_message = response_body
+        LOG.debug("Server returned error: %s", status_code)
+        LOG.debug("Error message: %s", error_message)
+        # Add deserialized error message to exception arguments
+        try:
+            des_error_body = Serializer().deserialize(error_message,
+                                                      self.content_type())
+        except:
+            # If unable to deserialized body it is probably not a
+            # Quantum error
+            des_error_body = {'message': error_message}
+        # Raise the appropriate exception
+        EXCEPTION_HANDLERS[self.version](status_code, des_error_body)
 
     def get_connection_type(self):
         """
@@ -138,7 +241,7 @@ class Client(object):
         return conn.getresponse()
 
     def do_request(self, method, action, body=None,
-                   headers=None, params=None, exception_args={}):
+                   headers=None, params=None):
         """
         Connects to the server and issues a request.
         Returns the result data, or raises an appropriate exception if
@@ -155,7 +258,6 @@ class Client(object):
         # Ensure we have a tenant id
         if not self.tenant:
             raise Exception("Tenant ID not set")
-
         # Add format and tenant_id
         action += ".%s" % self.format
         action = self.action_prefix + action
@@ -165,7 +267,6 @@ class Client(object):
             action += '?' + urllib.urlencode(params)
         if body:
             body = self.serialize(body)
-
         try:
             connection_type = self.get_connection_type()
             headers = headers or {"Content-Type":
@@ -176,7 +277,6 @@ class Client(object):
             # Open connection and send request, handling SSL certs
             certs = {'key_file': self.key_file, 'cert_file': self.cert_file}
             certs = dict((x, certs[x]) for x in certs if certs[x] != None)
-
             if self.use_ssl and len(certs):
                 conn = connection_type(self.host, self.port, **certs)
             else:
@@ -184,7 +284,6 @@ class Client(object):
             res = self._send_request(conn, method, action, body, headers)
             status_code = self.get_status_code(res)
             data = res.read()
-
             if self.logger:
                 self.logger.debug("Quantum Client Reply (code = %s) :\n %s" \
                         % (str(status_code), data))
@@ -194,17 +293,7 @@ class Client(object):
                                httplib.NO_CONTENT):
                 return self.deserialize(data, status_code)
             else:
-                error_message = res.read()
-                LOG.debug("Server returned error: %s", status_code)
-                LOG.debug("Error message: %s", error_message)
-                # Create exception with HTTP status code and message
-                if res.status in EXCEPTIONS:
-                    raise EXCEPTIONS[res.status](**exception_args)
-                # Add error code and message to exception arguments
-                ex = Exception("Server returned error: %s" % status_code)
-                ex.args = ([dict(status_code=status_code,
-                                 message=error_message)],)
-                raise ex
+                self._handle_fault_response(status_code, data)
         except (socket.error, IOError), e:
             msg = "Unable to connect to server. Got error: %s" % e
             LOG.exception(msg)
@@ -263,8 +352,7 @@ class Client(object):
         """
         Fetches the details of a certain network
         """
-        return self.do_request("GET", self.network_path % (network),
-                                        exception_args={"net_id": network})
+        return self.do_request("GET", self.network_path % (network))
 
     @ApiCall
     def create_network(self, body=None):
@@ -278,16 +366,14 @@ class Client(object):
         """
         Updates a network
         """
-        return self.do_request("PUT", self.network_path % (network), body=body,
-                                        exception_args={"net_id": network})
+        return self.do_request("PUT", self.network_path % (network), body=body)
 
     @ApiCall
     def delete_network(self, network):
         """
         Deletes the specified network
         """
-        return self.do_request("DELETE", self.network_path % (network),
-                                        exception_args={"net_id": network})
+        return self.do_request("DELETE", self.network_path % (network))
 
     @ApiCall
     def list_ports(self, network):
@@ -301,24 +387,21 @@ class Client(object):
         """
         Fetches the details of a certain port
         """
-        return self.do_request("GET", self.port_path % (network, port),
-                       exception_args={"net_id": network, "port_id": port})
+        return self.do_request("GET", self.port_path % (network, port))
 
     @ApiCall
     def create_port(self, network, body=None):
         """
         Creates a new port on a given network
         """
-        return self.do_request("POST", self.ports_path % (network), body=body,
-                       exception_args={"net_id": network})
+        return self.do_request("POST", self.ports_path % (network), body=body)
 
     @ApiCall
     def delete_port(self, network, port):
         """
         Deletes the specified port from a network
         """
-        return self.do_request("DELETE", self.port_path % (network, port),
-                       exception_args={"net_id": network, "port_id": port})
+        return self.do_request("DELETE", self.port_path % (network, port))
 
     @ApiCall
     def update_port(self, network, port, body=None):
@@ -326,17 +409,14 @@ class Client(object):
         Sets the attributes of the specified port
         """
         return self.do_request("PUT",
-            self.port_path % (network, port), body=body,
-                       exception_args={"net_id": network,
-                                       "port_id": port})
+            self.port_path % (network, port), body=body)
 
     @ApiCall
     def show_port_attachment(self, network, port):
         """
         Fetches the attachment-id associated with the specified port
         """
-        return self.do_request("GET", self.attachment_path % (network, port),
-                       exception_args={"net_id": network, "port_id": port})
+        return self.do_request("GET", self.attachment_path % (network, port))
 
     @ApiCall
     def attach_resource(self, network, port, body=None):
@@ -344,10 +424,7 @@ class Client(object):
         Sets the attachment-id of the specified port
         """
         return self.do_request("PUT",
-            self.attachment_path % (network, port), body=body,
-                       exception_args={"net_id": network,
-                                       "port_id": port,
-                                       "attach_id": str(body)})
+            self.attachment_path % (network, port), body=body)
 
     @ApiCall
     def detach_resource(self, network, port):
@@ -355,5 +432,28 @@ class Client(object):
         Removes the attachment-id of the specified port
         """
         return self.do_request("DELETE",
-                               self.attachment_path % (network, port),
-                    exception_args={"net_id": network, "port_id": port})
+                               self.attachment_path % (network, port))
+
+
+class ClientV11(Client):
+    """
+    This class overiddes some methods of the Client class in order to deal with
+    features specific to API v1.1 such as filters
+    """
+
+    @ApiCall
+    def list_networks(self, **filters):
+        """
+        Fetches a list of all networks for a tenant
+        """
+        # Pass filters in "params" argument to do_request
+        return self.do_request("GET", self.networks_path, params=filters)
+
+    @ApiCall
+    def list_ports(self, network, **filters):
+        """
+        Fetches a list of ports on a given network
+        """
+        # Pass filters in "params" argument to do_request
+        return self.do_request("GET", self.ports_path % (network),
+                               params=filters)
diff --git a/quantum/client/cli.py b/quantum/client/cli.py
index 99057368a..d2337fe7e 100755
--- a/quantum/client/cli.py
+++ b/quantum/client/cli.py
@@ -1,7 +1,7 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
-# Copyright 2011 Nicira Networks, Inc.
-# Copyright 2011 Citrix Systems
+# Copyright 2012 Nicira Networks, Inc.
+# Copyright 2012 Citrix Systems
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
 #    not use this file except in compliance with the License. You may obtain
@@ -26,6 +26,7 @@ import sys
 
 from optparse import OptionParser
 
+from quantum.common import exceptions
 
 possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
                                    os.pardir,
@@ -37,13 +38,16 @@ gettext.install('quantum', unicode=1)
 
 from quantum.client import cli_lib
 from quantum.client import Client
+from quantum.client import ClientV11
+from quantum.common import utils
 
 #Configure logger for client - cli logger is a child of it
 #NOTE(salvatore-orlando): logger name does not map to package
 #this is deliberate. Simplifies logger configuration
 LOG = logging.getLogger('quantum')
+DEFAULT_QUANTUM_VERSION = '1.1'
 FORMAT = 'json'
-commands = {
+commands_v10 = {
   "list_nets": {
     "func": cli_lib.list_nets,
     "args": ["tenant-id"]},
@@ -81,36 +85,122 @@ commands = {
     "func": cli_lib.unplug_iface,
     "args": ["tenant-id", "net-id", "port-id"]}, }
 
+commands_v11 = commands_v10.copy()
+commands_v11.update({
+  "list_nets": {
+    "func": cli_lib.list_nets_v11,
+    "args": ["tenant-id"],
+    "filters": ["name", "op-status", "port-op-status", "port-state",
+                "has-attachment", "attachment", "port"]},
+  "list_ports": {
+    "func": cli_lib.list_ports_v11,
+    "args": ["tenant-id", "net-id"],
+    "filters": ["name", "op-status", "has-attachment", "attachment"]},
+     })
+commands = {
+    '1.0': commands_v10,
+    '1.1': commands_v11
+    }
+clients = {
+    '1.0': Client,
+    '1.1': ClientV11
+    }
 
-def help():
+
+def help(version):
     print "\nCommands:"
-    for k in commands.keys():
-        print "    %s %s" % (k,
-          " ".join(["<%s>" % y for y in commands[k]["args"]]))
+    cmds = commands[version]
+    for k in cmds.keys():
+        print "    %s %s %s" % (k,
+          " ".join(["<%s>" % y for y in cmds[k]["args"]]),
+          'filters' in cmds[k] and "[filterspec ...]" or "")
+
+
+def print_usage(cmd, version):
+    cmds = commands[version]
+    print "Usage:\n    %s %s" % (cmd,
+      " ".join(["<%s>" % y for y in cmds[cmd]["args"]]))
 
 
 def build_args(cmd, cmdargs, arglist):
-    args = []
-    orig_arglist = arglist[:]
-    try:
-        for x in cmdargs:
-            args.append(arglist[0])
-            del arglist[0]
-    except:
-        LOG.error("Not enough arguments for \"%s\" (expected: %d, got: %d)" % (
-          cmd, len(cmdargs), len(orig_arglist)))
-        print "Usage:\n    %s %s" % (cmd,
-          " ".join(["<%s>" % y for y in commands[cmd]["args"]]))
-        return None
-    if len(arglist) > 0:
-        LOG.error("Too many arguments for \"%s\" (expected: %d, got: %d)" % (
-          cmd, len(cmdargs), len(orig_arglist)))
-        print "Usage:\n    %s %s" % (cmd,
-          " ".join(["<%s>" % y for y in commands[cmd]["args"]]))
-        return None
+    arglist_len = len(arglist)
+    cmdargs_len = len(cmdargs)
+    if arglist_len < cmdargs_len:
+        message = "Not enough arguments for \"%s\" (expected: %d, got: %d)"\
+                   % (cmd, len(cmdargs), arglist_len)
+        raise exceptions.QuantumCLIError(message=message)
+    args = arglist[:cmdargs_len]
     return args
 
 
+def build_filters(cmd, cmd_filters, filter_list, version):
+    filters = {}
+    # Each filter is expected to be in the <key>=<value> format
+    for flt in filter_list:
+        split_filter = flt.split("=")
+        if len(split_filter) != 2:
+            message = "Invalid filter argument detected (%s)" % flt
+            raise exceptions.QuantumCLIError(message=message)
+        filter_key, filter_value = split_filter
+        # Ensure the filter is allowed
+        if not filter_key in cmd_filters:
+            message = "Invalid filter key (%s)" % filter_key
+            raise exceptions.QuantumCLIError(message=message)
+        filters[filter_key] = filter_value
+    return filters
+
+
+def build_cmd(cmd, cmd_args, cmd_filters, arglist, version):
+    """
+    Builds arguments and filters to be passed to the cli library routines
+
+    :param cmd: Command to be executed
+    :param cmd_args: List of arguments required by the command
+    :param cmd_filters: List of filters allowed by the command
+    :param arglist: Command line arguments (includes both arguments and
+                    filter specifications)
+    :param version: API version
+    """
+    arglist_len = len(arglist)
+    try:
+        # Parse arguments
+        args = build_args(cmd, cmd_args, arglist)
+        # Parse filters
+        filters = None
+        if cmd_filters:
+            # Pop consumed arguments
+            arglist = arglist[len(args):]
+            filters = build_filters(cmd, cmd_filters, arglist, version)
+    except exceptions.QuantumCLIError as cli_ex:
+        LOG.error(cli_ex.message)
+        print " Error in command line:%s" % cli_ex.message
+        print_usage(cmd, version)
+        return None, None
+    filter_len = (filters is not None) and len(filters) or 0
+    if len(arglist) - len(args) - filter_len > 0:
+        message = "Too many arguments for \"%s\" (expected: %d, got: %d)"\
+                   % (cmd, len(cmd_args), arglist_len)
+        LOG.error(message)
+        print "Error in command line: %s " % message
+        print "Usage:\n    %s %s" % (cmd,
+          " ".join(["<%s>" % y for y in commands[version][cmd]["args"]]))
+        return None, None
+    # Append version to arguments for cli functions
+    args.append(version)
+    return args, filters
+
+
+def instantiate_client(host, port, ssl, tenant, token, version):
+    client = clients[version](host,
+                              port,
+                              ssl,
+                              tenant,
+                              FORMAT,
+                              auth_token=token,
+                              version=version)
+    return client
+
+
 def main():
     usagestr = "Usage: %prog [OPTIONS] <command> [args]"
     parser = OptionParser(usage=usagestr)
@@ -126,13 +216,15 @@ def main():
       type="string", default="syslog", help="log file path")
     parser.add_option("-t", "--token", dest="token",
       type="string", default=None, help="authentication token")
+    parser.add_option('--version',
+        default=utils.env('QUANTUM_VERSION', default=DEFAULT_QUANTUM_VERSION),
+        help='Accepts 1.1 and 1.0, defaults to env[QUANTUM_VERSION].')
     options, args = parser.parse_args()
 
     if options.verbose:
         LOG.setLevel(logging.DEBUG)
     else:
         LOG.setLevel(logging.WARN)
-    #logging.handlers.WatchedFileHandler
 
     if options.logfile == "syslog":
         LOG.addHandler(logging.handlers.SysLogHandler(address='/dev/log'))
@@ -141,29 +233,45 @@ def main():
         # Set permissions on log file
         os.chmod(options.logfile, 0644)
 
+    version = options.version
+    if not version in commands:
+        LOG.error("Unknown API version specified:%s", version)
+        print "Unknown API version: %s" % version
+
     if len(args) < 1:
         parser.print_help()
-        help()
+        help(version)
         sys.exit(1)
 
     cmd = args[0]
-    if cmd not in commands.keys():
+    if cmd not in commands[version].keys():
         LOG.error("Unknown command: %s" % cmd)
-        help()
+        help(version)
         sys.exit(1)
 
-    args = build_args(cmd, commands[cmd]["args"], args[1:])
+    # Build argument list for CLI command
+    # The argument list will include the version number as well
+    args, filters = build_cmd(cmd,
+                              commands[version][cmd]["args"],
+                              commands[version][cmd].get("filters", None),
+                              args[1:],
+                              options.version)
     if not args:
         sys.exit(1)
     LOG.info("Executing command \"%s\" with args: %s" % (cmd, args))
 
-    client = Client(options.host, options.port, options.ssl,
-                    args[0], FORMAT,
-                    auth_token=options.token)
-    commands[cmd]["func"](client, *args)
+    client = instantiate_client(options.host,
+                                options.port,
+                                options.ssl,
+                                args[0],
+                                options.token,
+                                options.version)
+    # append filters to arguments
+    # this will allow for using the same prototype for v10 and v11
+    # TODO: Use **kwargs instead of *args (keyword is better than positional)
+    if filters:
+        args.append(filters)
+    commands[version][cmd]["func"](client, *args)
 
     LOG.info("Command execution completed")
     sys.exit(0)
-
-if __name__ == "__main__":
-    main()
diff --git a/quantum/client/cli_lib.py b/quantum/client/cli_lib.py
index 6e202ff6a..8d73695e1 100755
--- a/quantum/client/cli_lib.py
+++ b/quantum/client/cli_lib.py
@@ -91,7 +91,7 @@ class CmdOutputTemplate(OutputTemplate):
         Extends OutputTemplate loading a different template for each command.
     """
 
-    _templates = {
+    _templates_v10 = {
         "list_nets":      "Virtual Networks for Tenant %(tenant_id)s\n" +
                           "%(networks|\tNetwork ID: %(id)s)s",
         "show_net":       "Network ID: %(network.id)s\n" +
@@ -130,13 +130,31 @@ class CmdOutputTemplate(OutputTemplate):
                           "on Virtual Network: %(network_id)s\n" +
                           "for Tenant: %(tenant_id)s"}
 
-    def __init__(self, cmd, data):
-        super(CmdOutputTemplate, self).__init__(self._templates[cmd], data)
+    _templates_v11 = _templates_v10.copy()
+    _templates_v11.update({
+        "show_net":       "Network ID: %(network.id)s\n" +
+                          "network Name: %(network.name)s\n" +
+                          "operational Status: %(network.op-status)s",
+        "show_port":      "Logical Port ID: %(port.id)s\n" +
+                          "administrative state: %(port.state)s\n" +
+                          "operational status: %(port.op-status)s\n" +
+                          "interface: %(port.attachment)s\n" +
+                          "on Virtual Network: %(network_id)s\n" +
+                          "for Tenant: %(tenant_id)s",
+        })
+
+    _templates = {
+        '1.0': _templates_v10,
+        '1.1': _templates_v11
+        }
+
+    def __init__(self, cmd, data, version):
+        super(CmdOutputTemplate, self).__init__(
+            self._templates[version][cmd], data)
 
 
 def _handle_exception(ex):
     LOG.exception(sys.exc_info())
-    print "Exception:%s - %s" % (sys.exc_info()[0], sys.exc_info()[1])
     status_code = None
     message = None
     # Retrieve dict at 1st element of tuple at last argument
@@ -149,67 +167,94 @@ def _handle_exception(ex):
         LOG.exception(msg_1 + "-" + msg_2)
         print msg_1
         print msg_2
+    else:
+        print "An unexpected exception occured:%s (%s)" % (sys.exc_info()[1],
+                                                           sys.exc_info()[0])
 
 
-def prepare_output(cmd, tenant_id, response):
-    LOG.debug("Preparing output for response:%s", response)
+def prepare_output(cmd, tenant_id, response, version):
+    LOG.debug("Preparing output for response:%s, version:%s"
+              % (response, version))
     response['tenant_id'] = tenant_id
-    output = str(CmdOutputTemplate(cmd, response))
+    output = str(CmdOutputTemplate(cmd, response, version))
     LOG.debug("Finished preparing output for command:%s", cmd)
     return output
 
 
 def list_nets(client, *args):
-    tenant_id = args[0]
-    res = client.list_networks()
-    LOG.debug("Operation 'list_networks' executed.")
-    output = prepare_output("list_nets", tenant_id, res)
-    print output
+    tenant_id, version = args
+    try:
+        res = client.list_networks()
+        LOG.debug("Operation 'list_networks' executed.")
+        output = prepare_output("list_nets", tenant_id, res, version)
+        print output
+    except Exception as ex:
+        _handle_exception(ex)
+
+
+def list_nets_v11(client, *args):
+    filters = {}
+    tenant_id, version = args[:2]
+    if len(args) > 2:
+        filters = args[2]
+    try:
+        res = client.list_networks(**filters)
+        LOG.debug("Operation 'list_networks' executed.")
+        output = prepare_output("list_nets", tenant_id, res, version)
+        print output
+    except Exception as ex:
+        _handle_exception(ex)
 
 
 def create_net(client, *args):
-    tenant_id, name = args
+    tenant_id, name, version = args
     data = {'network': {'name': name}}
     new_net_id = None
     try:
         res = client.create_network(data)
         new_net_id = res["network"]["id"]
         LOG.debug("Operation 'create_network' executed.")
-        output = prepare_output("create_net", tenant_id,
-                                          dict(network_id=new_net_id))
+        output = prepare_output("create_net",
+                                tenant_id,
+                                dict(network_id=new_net_id),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def delete_net(client, *args):
-    tenant_id, network_id = args
+    tenant_id, network_id, version = args
     try:
         client.delete_network(network_id)
         LOG.debug("Operation 'delete_network' executed.")
-        output = prepare_output("delete_net", tenant_id,
-                            dict(network_id=network_id))
+        output = prepare_output("delete_net",
+                                tenant_id,
+                                dict(network_id=network_id),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def show_net(client, *args):
-    tenant_id, network_id = args
+    tenant_id, network_id, version = args
     try:
         #NOTE(salvatore-orlando) changed for returning exclusively
         # output for GET /networks/{net-id} API operation
         res = client.show_network_details(network_id)["network"]
         LOG.debug("Operation 'show_network_details' executed.")
-        output = prepare_output("show_net", tenant_id,
-                                          dict(network=res))
+        output = prepare_output("show_net",
+                                tenant_id,
+                                dict(network=res),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def update_net(client, *args):
-    tenant_id, network_id, param_data = args
+    tenant_id, network_id, param_data, version = args
     data = {'network': {}}
     for kv in param_data.split(","):
         k, v = kv.split("=")
@@ -219,47 +264,67 @@ def update_net(client, *args):
         client.update_network(network_id, data)
         LOG.debug("Operation 'update_network' executed.")
         # Response has no body. Use data for populating output
-        output = prepare_output("update_net", tenant_id, data)
+        output = prepare_output("update_net", tenant_id, data, version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def list_ports(client, *args):
-    tenant_id, network_id = args
+    tenant_id, network_id, version = args
     try:
         ports = client.list_ports(network_id)
         LOG.debug("Operation 'list_ports' executed.")
         data = ports
         data['network_id'] = network_id
-        output = prepare_output("list_ports", tenant_id, data)
+        output = prepare_output("list_ports", tenant_id, data, version)
+        print output
+    except Exception as ex:
+        _handle_exception(ex)
+
+
+def list_ports_v11(client, *args):
+    filters = {}
+    tenant_id, network_id, version = args[:3]
+    if len(args) > 3:
+        filters = args[3]
+    try:
+        ports = client.list_ports(network_id, **filters)
+        LOG.debug("Operation 'list_ports' executed.")
+        data = ports
+        data['network_id'] = network_id
+        output = prepare_output("list_ports", tenant_id, data, version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def create_port(client, *args):
-    tenant_id, network_id = args
+    tenant_id, network_id, version = args
     try:
         res = client.create_port(network_id)
         LOG.debug("Operation 'create_port' executed.")
         new_port_id = res["port"]["id"]
-        output = prepare_output("create_port", tenant_id,
+        output = prepare_output("create_port",
+                                tenant_id,
                                 dict(network_id=network_id,
-                                     port_id=new_port_id))
+                                     port_id=new_port_id),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def delete_port(client, *args):
-    tenant_id, network_id, port_id = args
+    tenant_id, network_id, port_id, version = args
     try:
         client.delete_port(network_id, port_id)
         LOG.debug("Operation 'delete_port' executed.")
-        output = prepare_output("delete_port", tenant_id,
+        output = prepare_output("delete_port",
+                                tenant_id,
                                 dict(network_id=network_id,
-                                     port_id=port_id))
+                                     port_id=port_id),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
@@ -267,7 +332,7 @@ def delete_port(client, *args):
 
 
 def show_port(client, *args):
-    tenant_id, network_id, port_id = args
+    tenant_id, network_id, port_id, version = args
     try:
         port = client.show_port_details(network_id, port_id)["port"]
         LOG.debug("Operation 'list_port_details' executed.")
@@ -280,16 +345,18 @@ def show_port(client, *args):
             port['attachment'] = attach['id']
         else:
             port['attachment'] = '<none>'
-        output = prepare_output("show_port", tenant_id,
+        output = prepare_output("show_port",
+                                tenant_id,
                                 dict(network_id=network_id,
-                                     port=port))
+                                     port=port),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def update_port(client, *args):
-    tenant_id, network_id, port_id, param_data = args
+    tenant_id, network_id, port_id, param_data, version = args
     data = {'port': {}}
     for kv in param_data.split(","):
         k, v = kv.split("=")
@@ -300,14 +367,14 @@ def update_port(client, *args):
         client.update_port(network_id, port_id, data)
         LOG.debug("Operation 'udpate_port' executed.")
         # Response has no body. Use data for populating output
-        output = prepare_output("update_port", tenant_id, data)
+        output = prepare_output("update_port", tenant_id, data, version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def plug_iface(client, *args):
-    tenant_id, network_id, port_id, attachment = args
+    tenant_id, network_id, port_id, attachment, version = args
     try:
         data = {'attachment': {'id': '%s' % attachment}}
         client.attach_resource(network_id, port_id, data)
@@ -315,20 +382,23 @@ def plug_iface(client, *args):
         output = prepare_output("plug_iface", tenant_id,
                                 dict(network_id=network_id,
                                      port_id=port_id,
-                                     attachment=attachment))
+                                     attachment=attachment),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
 
 
 def unplug_iface(client, *args):
-    tenant_id, network_id, port_id = args
+    tenant_id, network_id, port_id, version = args
     try:
         client.detach_resource(network_id, port_id)
         LOG.debug("Operation 'detach_resource' executed.")
-        output = prepare_output("unplug_iface", tenant_id,
+        output = prepare_output("unplug_iface",
+                                tenant_id,
                                 dict(network_id=network_id,
-                                     port_id=port_id))
+                                     port_id=port_id),
+                                version)
         print output
     except Exception as ex:
         _handle_exception(ex)
diff --git a/quantum/client/tests/unit/test_cli.py b/quantum/client/tests/unit/test_cli.py
index 09c84453b..bfd2f02d6 100644
--- a/quantum/client/tests/unit/test_cli.py
+++ b/quantum/client/tests/unit/test_cli.py
@@ -33,6 +33,7 @@ from quantum.db import api as db
 from quantum.tests.unit.client_tools import stubs as client_stubs
 
 LOG = logging.getLogger('quantum.tests.test_cli')
+API_VERSION = "1.1"
 FORMAT = 'json'
 
 
@@ -49,9 +50,12 @@ class CLITest(unittest.TestCase):
         self.tenant_id = "test_tenant"
         self.network_name_1 = "test_network_1"
         self.network_name_2 = "test_network_2"
+        self.version = API_VERSION
         # Prepare client and plugin manager
-        self.client = Client(tenant=self.tenant_id, format=FORMAT,
-                             testingStub=client_stubs.FakeHTTPConnection)
+        self.client = Client(tenant=self.tenant_id,
+                             format=FORMAT,
+                             testingStub=client_stubs.FakeHTTPConnection,
+                             version=self.version)
         # Redirect stdout
         self.fake_stdout = client_stubs.FakeStdout()
         sys.stdout = self.fake_stdout
@@ -64,10 +68,13 @@ class CLITest(unittest.TestCase):
     def _verify_list_networks(self):
             # Verification - get raw result from db
             nw_list = db.network_list(self.tenant_id)
-            networks = [dict(id=nw.uuid, name=nw.name) for nw in nw_list]
+            networks = [{'id': nw.uuid, 'name': nw.name}
+                         for nw in nw_list]
             # Fill CLI template
-            output = cli.prepare_output('list_nets', self.tenant_id,
-                                        dict(networks=networks))
+            output = cli.prepare_output('list_nets',
+                                        self.tenant_id,
+                                        dict(networks=networks),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -79,8 +86,10 @@ class CLITest(unittest.TestCase):
                 self.fail("No network created")
             network_id = nw_list[0].uuid
             # Fill CLI template
-            output = cli.prepare_output('create_net', self.tenant_id,
-                                        dict(network_id=network_id))
+            output = cli.prepare_output('create_net',
+                                        self.tenant_id,
+                                        dict(network_id=network_id),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -91,8 +100,10 @@ class CLITest(unittest.TestCase):
             if len(nw_list) != 0:
                 self.fail("DB should not contain any network")
             # Fill CLI template
-            output = cli.prepare_output('delete_net', self.tenant_id,
-                                        dict(network_id=network_id))
+            output = cli.prepare_output('delete_net',
+                                        self.tenant_id,
+                                        dict(network_id=network_id),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -101,10 +112,13 @@ class CLITest(unittest.TestCase):
             # Verification - get raw result from db
             nw_list = db.network_list(self.tenant_id)
             network_data = {'id': nw_list[0].uuid,
-                            'name': nw_list[0].name}
+                            'name': nw_list[0].name,
+                            'op-status': nw_list[0].op_status}
             # Fill CLI template
-            output = cli.prepare_output('update_net', self.tenant_id,
-                                        dict(network=network_data))
+            output = cli.prepare_output('update_net',
+                                        self.tenant_id,
+                                        dict(network=network_data),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -112,10 +126,14 @@ class CLITest(unittest.TestCase):
     def _verify_show_network(self):
             # Verification - get raw result from db
             nw = db.network_list(self.tenant_id)[0]
-            network = dict(id=nw.uuid, name=nw.name)
+            network = {'id': nw.uuid,
+                       'name': nw.name,
+                       'op-status': nw.op_status}
             # Fill CLI template
-            output = cli.prepare_output('show_net', self.tenant_id,
-                                        dict(network=network))
+            output = cli.prepare_output('show_net',
+                                        self.tenant_id,
+                                        dict(network=network),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -126,9 +144,11 @@ class CLITest(unittest.TestCase):
             ports = [dict(id=port.uuid, state=port.state)
                      for port in port_list]
             # Fill CLI template
-            output = cli.prepare_output('list_ports', self.tenant_id,
+            output = cli.prepare_output('list_ports',
+                                        self.tenant_id,
                                         dict(network_id=network_id,
-                                             ports=ports))
+                                             ports=ports),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -140,9 +160,11 @@ class CLITest(unittest.TestCase):
                 self.fail("No port created")
             port_id = port_list[0].uuid
             # Fill CLI template
-            output = cli.prepare_output('create_port', self.tenant_id,
+            output = cli.prepare_output('create_port',
+                                        self.tenant_id,
                                         dict(network_id=network_id,
-                                             port_id=port_id))
+                                             port_id=port_id),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -153,9 +175,11 @@ class CLITest(unittest.TestCase):
             if len(port_list) != 0:
                 self.fail("DB should not contain any port")
             # Fill CLI template
-            output = cli.prepare_output('delete_port', self.tenant_id,
+            output = cli.prepare_output('delete_port',
+                                        self.tenant_id,
                                         dict(network_id=network_id,
-                                             port_id=port_id))
+                                             port_id=port_id),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -163,11 +187,15 @@ class CLITest(unittest.TestCase):
     def _verify_update_port(self, network_id, port_id):
             # Verification - get raw result from db
             port = db.port_get(port_id, network_id)
-            port_data = {'id': port.uuid, 'state': port.state}
+            port_data = {'id': port.uuid,
+                         'state': port.state,
+                         'op-status': port.op_status}
             # Fill CLI template
-            output = cli.prepare_output('update_port', self.tenant_id,
+            output = cli.prepare_output('update_port',
+                                        self.tenant_id,
                                         dict(network_id=network_id,
-                                             port=port_data))
+                                             port=port_data),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -177,15 +205,19 @@ class CLITest(unittest.TestCase):
             # TODO(salvatore-orlando): Must resolve this issue with
             # attachment in separate bug fix.
             port = db.port_get(port_id, network_id)
-            port_data = {'id': port.uuid, 'state': port.state,
-                         'attachment': "<none>"}
+            port_data = {'id': port.uuid,
+                         'state': port.state,
+                         'attachment': "<none>",
+                         'op-status': port.op_status}
             if port.interface_id is not None:
                 port_data['attachment'] = port.interface_id
 
             # Fill CLI template
-            output = cli.prepare_output('show_port', self.tenant_id,
+            output = cli.prepare_output('show_port',
+                                        self.tenant_id,
                                         dict(network_id=network_id,
-                                             port=port_data))
+                                             port=port_data),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -194,10 +226,12 @@ class CLITest(unittest.TestCase):
             # Verification - get raw result from db
             port = db.port_get(port_id, network_id)
             # Fill CLI template
-            output = cli.prepare_output("plug_iface", self.tenant_id,
+            output = cli.prepare_output("plug_iface",
+                                        self.tenant_id,
                                         dict(network_id=network_id,
                                              port_id=port['uuid'],
-                                             attachment=port['interface_id']))
+                                             attachment=port['interface_id']),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -206,9 +240,11 @@ class CLITest(unittest.TestCase):
             # Verification - get raw result from db
             port = db.port_get(port_id, network_id)
             # Fill CLI template
-            output = cli.prepare_output("unplug_iface", self.tenant_id,
+            output = cli.prepare_output("unplug_iface",
+                                        self.tenant_id,
                                         dict(network_id=network_id,
-                                             port_id=port['uuid']))
+                                             port_id=port['uuid']),
+                                        self.version)
             # Verify!
             # Must add newline at the end to match effect of print call
             self.assertEquals(self.fake_stdout.make_string(), output + '\n')
@@ -219,7 +255,9 @@ class CLITest(unittest.TestCase):
             db.network_create(self.tenant_id, self.network_name_1)
             db.network_create(self.tenant_id, self.network_name_2)
 
-            cli.list_nets(self.client, self.tenant_id)
+            cli.list_nets(self.client,
+                          self.tenant_id,
+                          self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_list_networks failed due to an exception")
@@ -230,7 +268,10 @@ class CLITest(unittest.TestCase):
 
     def test_create_network(self):
         try:
-            cli.create_net(self.client, self.tenant_id, "test")
+            cli.create_net(self.client,
+                           self.tenant_id,
+                           "test",
+                           self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_create_network failed due to an exception")
@@ -243,7 +284,10 @@ class CLITest(unittest.TestCase):
         try:
             db.network_create(self.tenant_id, self.network_name_1)
             network_id = db.network_list(self.tenant_id)[0]['uuid']
-            cli.delete_net(self.client, self.tenant_id, network_id)
+            cli.delete_net(self.client,
+                           self.tenant_id,
+                           network_id,
+                           self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_delete_network failed due to an exception")
@@ -256,7 +300,10 @@ class CLITest(unittest.TestCase):
         try:
             # Load some data into the datbase
             net = db.network_create(self.tenant_id, self.network_name_1)
-            cli.show_net(self.client, self.tenant_id, net['uuid'])
+            cli.show_net(self.client,
+                         self.tenant_id,
+                         net['uuid'],
+                         self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_detail_network failed due to an exception")
@@ -269,8 +316,11 @@ class CLITest(unittest.TestCase):
         try:
             net = db.network_create(self.tenant_id, self.network_name_1)
             network_id = net['uuid']
-            cli.update_net(self.client, self.tenant_id,
-                           network_id, 'name=%s' % self.network_name_2)
+            cli.update_net(self.client,
+                           self.tenant_id,
+                           network_id,
+                           'name=%s' % self.network_name_2,
+                           self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_update_network failed due to an exception")
@@ -286,7 +336,10 @@ class CLITest(unittest.TestCase):
             network_id = net['uuid']
             db.port_create(network_id)
             db.port_create(network_id)
-            cli.list_ports(self.client, self.tenant_id, network_id)
+            cli.list_ports(self.client,
+                           self.tenant_id,
+                           network_id,
+                           self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_list_ports failed due to an exception")
@@ -301,7 +354,10 @@ class CLITest(unittest.TestCase):
             # Pre-populate data for testing using db api
             net = db.network_create(self.tenant_id, self.network_name_1)
             network_id = net['uuid']
-            cli.create_port(self.client, self.tenant_id, network_id)
+            cli.create_port(self.client,
+                            self.tenant_id,
+                            network_id,
+                            self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_create_port failed due to an exception")
@@ -319,7 +375,11 @@ class CLITest(unittest.TestCase):
             network_id = net['uuid']
             port = db.port_create(network_id)
             port_id = port['uuid']
-            cli.delete_port(self.client, self.tenant_id, network_id, port_id)
+            cli.delete_port(self.client,
+                            self.tenant_id,
+                            network_id,
+                            port_id,
+                            self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_delete_port failed due to an exception")
@@ -335,8 +395,12 @@ class CLITest(unittest.TestCase):
             port = db.port_create(network_id)
             port_id = port['uuid']
             # Default state is DOWN - change to ACTIVE.
-            cli.update_port(self.client, self.tenant_id, network_id,
-                               port_id, 'state=ACTIVE')
+            cli.update_port(self.client,
+                            self.tenant_id,
+                            network_id,
+                            port_id,
+                            'state=ACTIVE',
+                            self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_update_port failed due to an exception")
@@ -354,7 +418,11 @@ class CLITest(unittest.TestCase):
             network_id = net['uuid']
             port = db.port_create(network_id)
             port_id = port['uuid']
-            cli.show_port(self.client, self.tenant_id, network_id, port_id)
+            cli.show_port(self.client,
+                          self.tenant_id,
+                          network_id,
+                          port_id,
+                          self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_show_port_no_attach failed due to an exception")
@@ -374,7 +442,11 @@ class CLITest(unittest.TestCase):
             port = db.port_create(network_id)
             port_id = port['uuid']
             db.port_set_attachment(port_id, network_id, iface_id)
-            cli.show_port(self.client, self.tenant_id, network_id, port_id)
+            cli.show_port(self.client,
+                          self.tenant_id,
+                          network_id,
+                          port_id,
+                          self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_show_port_with_attach failed due to an exception")
@@ -392,8 +464,12 @@ class CLITest(unittest.TestCase):
             network_id = net['uuid']
             port = db.port_create(net['uuid'])
             port_id = port['uuid']
-            cli.plug_iface(self.client, self.tenant_id, network_id,
-                           port_id, "test_iface_id")
+            cli.plug_iface(self.client,
+                           self.tenant_id,
+                           network_id,
+                           port_id,
+                           "test_iface_id",
+                           self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_plug_iface failed due to an exception")
@@ -412,7 +488,11 @@ class CLITest(unittest.TestCase):
             port = db.port_create(net['uuid'])
             port_id = port['uuid']
             db.port_set_attachment(port_id, network_id, "test_iface_id")
-            cli.unplug_iface(self.client, self.tenant_id, network_id, port_id)
+            cli.unplug_iface(self.client,
+                             self.tenant_id,
+                             network_id,
+                             port_id,
+                             self.version)
         except:
             LOG.exception("Exception caught: %s", sys.exc_info())
             self.fail("test_plug_iface failed due to an exception")
diff --git a/quantum/common/exceptions.py b/quantum/common/exceptions.py
index f4cf55efe..043d4f1ed 100644
--- a/quantum/common/exceptions.py
+++ b/quantum/common/exceptions.py
@@ -49,30 +49,6 @@ class QuantumException(Exception):
         return self._error_string
 
 
-class ProcessExecutionError(IOError):
-    def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None,
-                 description=None):
-        if description is None:
-            description = "Unexpected error while running command."
-        if exit_code is None:
-            exit_code = '-'
-        message = "%s\nCommand: %s\nExit code: %s\nStdout: %r\nStderr: %r" % (
-                  description, cmd, exit_code, stdout, stderr)
-        IOError.__init__(self, message)
-
-
-class Error(Exception):
-    def __init__(self, message=None):
-        super(Error, self).__init__(message)
-
-
-class ApiError(Error):
-    def __init__(self, message='Unknown', code='Unknown'):
-        self.message = message
-        self.code = code
-        super(ApiError, self).__init__('%s: %s' % (code, message))
-
-
 class NotFound(QuantumException):
     pass
 
@@ -111,34 +87,87 @@ class AlreadyAttached(QuantumException):
                 "already plugged into port %(att_port_id)s")
 
 
-# NOTE: on the client side, we often do not know all of the information
-# that is known on the server, thus, we create separate exception for
-# those scenarios
-class PortInUseClient(QuantumException):
-    message = _("Unable to complete operation on port %(port_id)s " \
-                "for network %(net_id)s. An attachment " \
-                "is plugged into the logical port.")
+class QuantumClientException(QuantumException):
+
+    def __init__(self, **kwargs):
+        self.message = kwargs.get('message', "")
+        super(QuantumClientException, self).__init__(**kwargs)
 
 
-class AlreadyAttachedClient(QuantumException):
-    message = _("Unable to plug the attachment %(att_id)s into port " \
-                "%(port_id)s for network %(net_id)s. The attachment is " \
-                "already plugged into another port.")
+# NOTE: on the client side, we use different exception types in order
+# to allow client library users to handle server exceptions in try...except
+# blocks. The actual error message is the one generated on the server side
+class NetworkNotFoundClient(QuantumClientException):
+    pass
 
 
-class MalformedRequestBody(QuantumException):
-    message = _("Malformed request body: %(reason)s")
+class PortNotFoundClient(QuantumClientException):
+    pass
 
 
 class MalformedResponseBody(QuantumException):
     message = _("Malformed response body: %(reason)s")
 
 
-class Duplicate(Error):
+class StateInvalidClient(QuantumClientException):
     pass
 
 
-class NotAuthorized(Error):
+class NetworkInUseClient(QuantumClientException):
+    pass
+
+
+class PortInUseClient(QuantumClientException):
+    pass
+
+
+class AlreadyAttachedClient(QuantumClientException):
+    pass
+
+
+class NotAuthorized(QuantumClientException):
+    pass
+
+
+class QuantumCLIError(QuantumClientException):
+    """ Exception raised when command line parsing fails """
+    pass
+
+
+class BadInputError(Exception):
+    """Error resulting from a client sending bad input to a server"""
+    pass
+
+
+class ProcessExecutionError(IOError):
+    def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None,
+                 description=None):
+        if description is None:
+            description = "Unexpected error while running command."
+        if exit_code is None:
+            exit_code = '-'
+        message = "%s\nCommand: %s\nExit code: %s\nStdout: %r\nStderr: %r" % (
+                  description, cmd, exit_code, stdout, stderr)
+        IOError.__init__(self, message)
+
+
+class Error(Exception):
+    def __init__(self, message=None):
+        super(Error, self).__init__(message)
+
+
+class ApiError(Error):
+    def __init__(self, message='Unknown', code='Unknown'):
+        self.message = message
+        self.code = code
+        super(ApiError, self).__init__('%s: %s' % (code, message))
+
+
+class MalformedRequestBody(QuantumException):
+    message = _("Malformed request body: %(reason)s")
+
+
+class Duplicate(Error):
     pass
 
 
@@ -154,11 +183,6 @@ class InvalidContentType(Invalid):
     message = _("Invalid content type %(content_type)s.")
 
 
-class BadInputError(Exception):
-    """Error resulting from a client sending bad input to a server"""
-    pass
-
-
 class MissingArgumentError(Error):
     pass
 
diff --git a/quantum/common/utils.py b/quantum/common/utils.py
index 1d425a033..acd72b737 100644
--- a/quantum/common/utils.py
+++ b/quantum/common/utils.py
@@ -22,7 +22,6 @@
 
 import ConfigParser
 import datetime
-import exceptions as exception
 import inspect
 import logging
 import os
@@ -44,6 +43,18 @@ from quantum.common import exceptions as exception
 from quantum.common.exceptions import ProcessExecutionError
 
 
+def env(*vars, **kwargs):
+    """
+    returns the first environment variable set
+    if none are non-empty, defaults to '' or keyword arg default
+    """
+    for v in vars:
+        value = os.environ.get(v)
+        if value:
+            return value
+    return kwargs.get('default', '')
+
+
 def import_class(import_str):
     """Returns a class from a string including module and class."""
     mod_str, _sep, class_str = import_str.rpartition('.')