Repository: pywbem/pywbemtools (language: python)

Issue:
Fix issue using instance get with multiple namespace (-n) option
NOTE:  waiting on M. Walker test but ready for review.

The instance get command with multiple namespaces (-n
root/cimv2,root/cimv3) and the .? flag to display namespaces caused an
exception.  However, this lead to realizing that we were only displaying
a single instance rather than the instances from each namespace.
Corrected those issues.

I did not create an issue since this is an issue with the code in a prior PR for the the current release and the code only exists for that release.

Enumerate Instance with Multiple Namespaces
I use Enumerate Instance with multiple namespaces (-n interop,device) to find where instances of a class exist. Currently, if the class only exists in one namespace I get an exception and am bounced out of my interactive session. What I would prefer is that enumerate list the instances it found and not raise an exception.
If the results are in only one namespace, I would still like to get an indication of the namespace where it was found. If not, then a warning message saying which namespace(s) had no instances would be nice.
Enumerate Instance with Multiple Namespaces
I use Enumerate Instance with multiple namespaces (-n interop,device) to find where instances of a class exist. Currently, if the class only exists in one namespace I get an exception and am bounced out of my interactive session. What I would prefer is that enumerate list the instances it found and not raise an exception.
If the results are in only one namespace, I would still like to get an indication of the namespace where it was found. If not, then a warning message saying which namespace(s) had no instances would be nice.


Discussion / hints:

[![Coverage Status](https://coveralls.io/builds/50994715/badge)](https://coveralls.io/builds/50994715)

Coverage remained the same at 92.789% when pulling **0c989c6371074a6c5ffcc5506693f69f9d5663f3 on ks/fix-issue-getinst-nsoption** into **4451e3ee53c812d766bc2d4ea4afd20016a3cfbd on master**.

The "Using the --namespace option conflicts with specifying a namespace in INSTANCENAME" error has been fixed on the following instance commands: Associators, Enumerate, Get and References. The error also does not occur on the shrub  command, but the shrub command simply ignores the --namespace option and uses the default namespace.

COMMENT: Coding Error, fixed
Mikes comment has been fixed and tests added to assure that with the instance commands that use the multiple namespace option, a command that specifies just the non-default namespace is processed with just that namespace.
I have run some tests and the --namespace option is working. You might want to change the error message when two namespaces is used on instance shrub. Also need to note in the documentation that multiple namespaces cannot be used on the instance shrub command.
I was able to run my modified "Interop namespace" script with the revised code.
Karl, you forgot to act on those comments that are in the hidden section.
Fixed the issues I had overlooked.  Back for review.
Approved, except for the conflicts that need to be resolved.
Note M. Walker has couple of issue with the exact approach but I asked him to put them into new issue. Mostly when we generate exception and when we return what we have. 

Checked against master and it is up-to-date. Not sure what issues have yet to be resolved.   TKS Karl



Fix patch:
diff --git a/docs/pywbemcli/features.rst b/docs/pywbemcli/features.rst
index 87f674fb..6c9e4eee 100644
--- a/docs/pywbemcli/features.rst
+++ b/docs/pywbemcli/features.rst
@@ -512,15 +512,15 @@ namespace ``interop``.
 However, pywbemcli expands this to allow some requests to be executed against
 multiple namespaces in a single request.  This was done primarily to allow
 viewing CIM objects in the server across namespaces (ex. comparing classes
-between namespaces).
+or instances between namespaces).
 
-The commands enumerate, get, associators, and references for the command groups
-class and instance allow issuing requests on multiple namespaces in a single
-pywbemcli command. The qualifiers group enumerate command also handles multiple
-namespaces. Multiple namespace for a command is defined with the
-``--namespace`` option by defining the set of namespaces to be included  rather
-than just a single namespace. If the ``default-namespace`` is not defined is
-the connection default namespace.
+The commands ``enumerate``, ``get``, ``associators``, and ``references`` for
+the command groups ``class`` and ``instance`` and the ``enumerate`` and ``get``
+for the command group qualifiers allow issuing requests on multiple namespaces
+in a single pywbemcli command. Multiple namespace for a command is defined with
+the ``--namespace`` option by defining the set of namespaces to be included
+rather than just a single namespace. If the ``default-namespace`` is not
+defined is the connection default namespace.
 
 The responses are displayed in the same form as with a single namespace except
 that the namespace is included for each type of display to allow the user to
@@ -532,12 +532,12 @@ For example:
 
 .. code-block:: text
 
-    # pywbemcli instance enumerate CIM_Door --namespace root/cimv2, root/cimv3
+    # pywbemcli instance enumerate CIM_Door --namespace root/cimv2,root/cimv3
 
     # pywbemcli instance get CIM_Subscription.? --namespace root/cimv2 --namespace root/cimv3
 
 
-returns the instances of CIM_Door from two namespaces.
+return the instances of CIM_Door from two namespaces root/cimv2 and root/cimv3.
 
 A table output has the following form with table output
 
@@ -571,9 +571,19 @@ A table output has the following form with table output
 
 The --namespace option can be defined either using multiple definitions of the
 option: ``--namespace root/cimv2 --namespace root/cimv3`` or as a single
-options with the namespace names comma-separated: ``--namespace root/cimv2,root/cimv3``.
+options with comma-separated namespace names : ``--namespace root/cimv2,root/cimv3``.
 
 The :ref:`Class find command` and  also process multiple namespaces in a single
 request but the default if the namespace is not provided is to use all of the
 namespaces defined in the server since the goal of these commands is to execute
 a wide search for the define class or instance entities.
+
+To execute a request for multiple namespaces, pywbemcli executes the
+corresponding server request (ex. GetInstance) once for each namespace defined
+in the ``--namespace`` parameter. If a request for processing a command for
+multiple namespaces gets an exception for some of the requests but not all of
+them (ex. the class for a class get request only exists in some of the
+namespaces) it continues processing until all of the namespaces are processed
+and generates a warning message for each request exception.  If all the
+requests fail, the command fails.  If any of server requests return results,
+those results are displayed.
diff --git a/pywbemtools/_output_formatting.py b/pywbemtools/_output_formatting.py
index 03497663..eac0c59a 100644
--- a/pywbemtools/_output_formatting.py
+++ b/pywbemtools/_output_formatting.py
@@ -100,7 +100,7 @@ def output_format_is_cimobject(output_format):
     return output_format in CIM_OBJECT_FORMATS
 
 
-def output_format_is_testgroup(output_format):
+def output_format_is_textgroup(output_format):
     """
     Return boolean indicating whether an output format is a text format.
 
diff --git a/pywbemtools/pywbemcli/__init__.py b/pywbemtools/pywbemcli/__init__.py
index 87cf7456..707f8117 100644
--- a/pywbemtools/pywbemcli/__init__.py
+++ b/pywbemtools/pywbemcli/__init__.py
@@ -22,29 +22,31 @@
 
 from __future__ import absolute_import, print_function
 
-from .._utils import *              # noqa: F403,F401
-from .._click_extensions import *   # noqa: F403,F401
-from .._options import *            # noqa: F403,F401
-from .._output_formatting import *  # noqa: F403,F401
-from ._cmd_namespace import *       # noqa: F403,F401
-from ._common import *              # noqa: F403,F401
-from ._pywbem_server import *       # noqa: F403,F401
-from ._cmd_class import *           # noqa: F403,F401
-from ._cmd_instance import *        # noqa: F403,F401
-from ._cmd_qualifier import *       # noqa: F403,F401
-from ._cmd_server import *          # noqa: F403,F401
-from ._cmd_connection import *      # noqa: F403,F401
-from ._cmd_profile import *         # noqa: F403,F401
-from ._cmd_statistics import *      # noqa: F403,F401
-from ._cmd_subscription import *    # noqa: F403,F401
-from ._context_obj import *         # noqa: F403,F401
+from .._utils import *                # noqa: F403,F401
+from .._click_extensions import *     # noqa: F403,F401
+from .._options import *              # noqa: F403,F401
+from .._output_formatting import *    # noqa: F403,F401
+from ._cmd_namespace import *         # noqa: F403,F401
+from ._common import *                # noqa: F403,F401
+from ._pywbem_server import *         # noqa: F403,F401
+
+from ._cmd_class import *             # noqa: F403,F401
+from ._cmd_instance import *          # noqa: F403,F401
+from ._cmd_qualifier import *         # noqa: F403,F401
+from ._cmd_server import *            # noqa: F403,F401
+from ._cmd_connection import *        # noqa: F403,F401
+from ._cmd_profile import *           # noqa: F403,F401
+from ._cmd_statistics import *        # noqa: F403,F401
+from ._cmd_subscription import *      # noqa: F403,F401
+
+from ._context_obj import *           # noqa: F403,F401
 from ._connection_repository import *   # noqa: F403,F401
-from .pywbemcli import *            # noqa: F403,F401
-from .config import *               # noqa: F403,F401
+from .pywbemcli import *              # noqa: F403,F401
+from .config import *                 # noqa: F403,F401
 from ._pywbemcli_operations import *  # noqa: F403,F401
-from ._association_shrub import *   # noqa: F403,F401
-from ._cimvalueformatter import *   # noqa: F403,F401
-from ._display_cimobjects import *   # noqa: F403,F401
-
+from ._association_shrub import *     # noqa: F403,F401
+from ._cimvalueformatter import *     # noqa: F403,F401
+from ._display_cimobjects import *    # noqa: F403,F401
+from ._common_cmd_functions import *  # noqa: F403,F401
 
-from .._version import __version__  # noqa: F401
+from .._version import __version__    # noqa: F401
diff --git a/pywbemtools/pywbemcli/_cmd_class.py b/pywbemtools/pywbemcli/_cmd_class.py
index 6fac7dca..f425486a 100644
--- a/pywbemtools/pywbemcli/_cmd_class.py
+++ b/pywbemtools/pywbemcli/_cmd_class.py
@@ -24,20 +24,20 @@
 from __future__ import absolute_import, print_function
 
 import copy
-from collections import namedtuple
 import click
 
-from pywbem import Error, CIMClassName, CIMError, ModelError, CIM_ERR_NOT_FOUND
+from pywbem import Error, CIMClassName, CIMError
+
 
 from pywbem._nocasedict import NocaseDict
 
 from .pywbemcli import cli
 from ._common import filter_namelist, resolve_propertylist, \
     process_invokemethod, pywbem_error_exception,  \
-    get_subclass_names, depending_classnames, get_leafclass_names, \
-    parse_version_value
+    depending_classnames
 
-from ._display_cimobjects import display_cim_objects
+from ._common_cmd_functions import get_namespaces, enumerate_classes_filtered, \
+    ResultsHandler
 
 from ._common_options import propertylist_option, names_only_option, \
     include_classorigin_class_option, namespace_option, summary_option, \
@@ -48,7 +48,7 @@
     CMD_OPTS_TXT, GENERAL_OPTS_TXT, SUBCMD_HELP_TXT
 from .._options import add_options, help_option
 from .._output_formatting import output_format_is_table, \
-    validate_output_format, format_table, warning_msg
+    validate_output_format, format_table
 
 #
 #   Common option definitions for class group
@@ -480,7 +480,10 @@ def class_tree(context, classname, **options):
 #
 #  Common functions for cmd_class processing
 #  This includes functions used by the command action functions
-#  in this fmodule and possibly other modules
+#  in this module and possibly other modules
+#
+#  get_namespaces, enumerate_classes_filtered, and handle_multi_ns_exc
+#  are called from the instance and qualifier command processors.
 #
 ####################################################################
 
@@ -533,329 +536,6 @@ def get_classnames_in_namespaces(context, options, namespaces, classname_glob):
     return names_dict
 
 
-def parse_version_str(version_str):
-    """
-    Parse a string with 3 positive integers seperated by period (CIM version
-    string) into a 3 integer tuple and return the tuple. Used to parse the
-    version value of the DMTF Version qualifier.
-
-    Parameters:
-        version_str (:term: str):
-            String defining 3 components of a CIM version
-
-    Returns:
-        tuple containing 3 integers
-
-    Raises:
-        click.ClickException if the version_str is invalid (not integers,
-        not seperated by ".", not 3 values)
-    """
-    try:
-        version_tuple = [int(x) for x in version_str.split('.')]
-    except ValueError:
-        raise click.ClickException('--since option value invalid. '
-                                   'Must contain 3 integer elements: '
-                                   'int.int.int". {} received'.
-                                   format(version_str))
-    if len(version_tuple) != 3:
-        raise click.ClickException('Version value must contain 3 integer '
-                                   'elements (int.int.int). '
-                                   '{} received'.format(version_str))
-    return version_tuple
-
-
-# Namedtupe defining each entry in the filters dictionary values
-FILTERDEF = namedtuple('FILTERDEF', 'optionvalue qualifiername scopes')
-
-
-def _build_filters_dict(conn, ns, options):
-    """
-    Build a dictionary defining the filters to be processed against list
-    of classes from
-    the filter definitons in the Click options dictionary. There is an entry
-    in the dictionary for each filter to be applied to filter a list of
-    classes.
-
-    Returns:
-      Dict of filters where the names are the  filtersthemselves , the types
-      are the type of test (i.e. qualifier, superclass)
-      and the value for each is a tuple:
-      * Name of the qualifier (:term:`string`)
-      * The value of the qualifier filter option (True or False which
-        determines whether to display the existence or non-existence of the
-        qualifier
-      * A tuple containing Booleans for the value of each of the possible
-        element scopes (class, property, method, parameter) indicating whether
-        the qualifier is allowed in that element.
-    """
-    filters = {}
-
-    def set_qualifier_option(qname, option_value):
-        qualdecl = conn.GetQualifier(qname, ns)
-        # Note: qualdecl.scopes performs test case-insensitively
-        if qualdecl.scopes['any']:
-            scopes_map = [True, True, True, True]
-        else:
-            scopes_map = [False, False, False, False]
-            scopes_map[0] = any([qualdecl.scopes['class'],
-                                 qualdecl.scopes['association'],
-                                 qualdecl.scopes['indication']])
-            scopes_map[1] = qualdecl.scopes['property']
-            scopes_map[2] = qualdecl.scopes['method']
-            scopes_map[3] = qualdecl.scopes['parameter']
-        filters['qualifier'] = FILTERDEF(option_value, qname,
-                                         tuple(scopes_map))
-
-    # Qualifier options
-    if options['association'] is not None:
-        set_qualifier_option('association', options['association'])
-    if options['indication'] is not None:
-        set_qualifier_option('indication', options['indication'])
-    if options['experimental'] is not None:
-        set_qualifier_option('experimental', options['experimental'])
-    # If set, the entity is deprecated
-    if options['deprecated'] is not None:
-        set_qualifier_option('deprecated', options['deprecated'])
-    if options['since'] is not None:
-        version_tuple = parse_version_str(options['since'])
-        set_qualifier_option('version', version_tuple)
-
-    if options['schema'] is not None:
-        test_str = "{}_".format(options['schema'].lower())
-        filters['schema'] = FILTERDEF(test_str, None, None)
-
-    if options['subclass_of'] is not None:
-        filters['subclass_of'] = FILTERDEF(options['subclass_of'], None, None)
-    if options['leaf_classes'] is not None:
-        filters['leaf_classes'] = FILTERDEF(options['leaf_classes'], None, None)
-    return filters
-
-
-def _filter_classes(classes, filters, names_only, iq):
-    """
-    Filter a list of classes for the qualifiers defined by  the
-    qualifier_filter parameter where this parameter is a list of tuples.
-    each tuple contains the qualifier name and a dictionary with qualifier
-     name as key and tuple containing the option_value(True or False) and
-    a list of booleans where each boolean represents one of the scope types
-    ()
-    whether to display or not display if it exists.
-
-    This method only works for boolean qualifiers
-
-    Parameters:
-
-      classes (list of :class:`~pywbem.CIMClass`):
-        list of classes to be filtered
-
-      qualifier_filters (dict):
-        Dictionary defining the filtering to be performed. It contains an entry
-        for each qualifier filter that is defined. See _build_qualifier_filters
-        for a definition of this list.
-
-      names_only (:class:`py:bool`):
-        If True, return only the classnames. Otherwise returns the filtered
-        classes. This is because we must get the classes from the server to
-        perform the filtering
-
-      iq (:class:`py:bool`):
-        If not True, remove any qualifiers from the classes.  This is because
-        we must get the classes from the server with qualifiers to
-        perform the filtering.
-    """
-
-    def class_has_qualifier(cls, qname, scopes):
-        """
-        Determine if the qualifier defined by qname exists in the elements
-        of the class where the elements are defined by the scopes parameter
-        for this filter.
-
-        Parameters:
-
-          cls (:class:`~pywbem.CIMClass`):
-            The class to be inspected for the qualifier defined by qname
-
-          qname (:term:`string`):
-            The qualifier for which we are searching
-
-          scopes (tuple of booleans):
-            A tuple containing a boolean value for each of the possible scopes
-            (class, property, method, parameter)
-
-        Returns:
-          True if the qualifier with name quname is found in the elements where
-          the scope is True. Otherwise, False is returned
-
-        """
-        # Test class scope
-        if scopes[0] and qname in cls.qualifiers:
-            return True
-
-        # if property scope, test properties
-        if scopes[1]:
-            for prop in cls.properties.values():
-                if qname in prop.qualifiers:
-                    return True
-        # If method scope, test methods and if parameter scope, test parameters
-        if scopes[2]:
-            for method in cls.methods.values():
-                if qname in method.qualifiers:
-                    return True
-                if scopes[3]:
-                    params = method.parameters
-                    for param in params.values():
-                        if qname in param.qualifiers:
-                            return True
-        return False
-
-    # Test all classes in the input property for the defined filters.
-    filtered_classes = []
-    subclass_names = []
-    # Build list of subclass names that will be used later as a filter on the
-    # classes to be returned
-    if 'subclass_of' in filters:
-        try:
-            subclass_names = get_subclass_names(
-                classes,
-                classname=filters['subclass_of'].optionvalue,
-                deep_inheritance=True)
-        except ValueError:
-            raise click.ClickException(
-                'Classname {} for "subclass-of" not found in returned classes.'
-                .format(filters['subclass_of'].optionvalue))
-
-    # Build a list of leaf class names that will be used later as a filter on
-    # the classes to be returned.
-    if 'leaf_classes' in filters:
-        try:
-            if subclass_names:
-                clsx = [cls for cls in classes if cls.classname in
-                        subclass_names]
-                leafclass_names = get_leafclass_names(clsx)
-            else:
-                leafclass_names = get_leafclass_names(classes)
-
-        except ValueError:
-            raise click.ClickException(
-                'Classname {} for "leaf_classes-of" not found in returned '
-                'classes.'.format(filters['leaf_classes'].optionvalue))
-
-    for cls in classes:
-        show_class_list = []
-        for filter_name, filter_ in filters.items():
-            if filter_name == 'qualifier':
-                option_value = filter_.optionvalue
-                if class_has_qualifier(cls, filter_.qualifiername,
-                                       filter_.scopes):
-                    if filter_.qualifiername == 'version':
-                        if filter_.qualifiername in cls.qualifiers:
-                            cls_version = \
-                                cls.qualifiers[filter_.qualifiername].value
-                            val = parse_version_value(cls_version,
-                                                      cls.classname)
-                            option_value = bool(val >= filter_.optionvalue)
-
-                    show_class_list.append(option_value)
-                else:
-                    show_class_list.append(not option_value)
-
-            elif filter_name == 'schema':
-                show_class_list.append(
-                    cls.classname.lower().startswith(filter_.optionvalue))
-            elif filter_name == 'subclass_of':
-                show_class_list.append(cls.classname in subclass_names)
-            elif filter_name == 'leaf_classes':
-                show_class_list.append(cls.classname in leafclass_names)
-
-            else:
-                assert False  # Future for other test_types
-
-        # Show if all options are True for this class
-        show_this_class = all(show_class_list)
-
-        if show_this_class:
-            # If returning instances, honor the names_only option
-            if not names_only and not iq:
-                cls.qualifiers = []
-                for p in cls.properties.values():
-                    p.qualifiers = []
-                for m in cls.methods.values():
-                    m.qualifiers = []
-                    for p in m.parameters.values():
-                        p.qualifiers = []
-            filtered_classes.append(cls)
-
-    # If names_only parameter create list of classnames
-    if names_only:
-        filtered_classes = [cls.classname for cls in filtered_classes]
-    return filtered_classes
-
-
-def enumerate_classes_filtered(context, namespace, classname, options):
-    """
-    Execute EnumerateClasses or EnumerateClassNames in a single namespace
-    defined in options['namespace'] and return results.
-
-    If any of the class qualifier filters are defined in the options parameter,
-    enumerate the classes, filter the result for those parameters, and return
-    only class names if --names-only set.
-
-    This function may be executed by multiple command action functions with
-    varying options in the options. Each option must be tested to validate
-    that it exists in the options dictionary
-
-    Parameters:
-
-      context:  (instance of :class:`ContextObj`):
-        Used to retrieve conn parameter
-
-      classname (:term:`string`):
-        classname for the enumerate or None if all classes to be enumerated.
-
-      options: Click options dictionary
-        Options that form basis for this Enumerate and filter processing.
-
-    Returns:
-        List of classes or classnames that satisfy the criteria
-
-    Raises:
-        pywbem Error exceptions generated by EnumerateClassNames and
-        enumerateClasses
-    """
-    conn = context.pywbem_server.conn
-    filters = _build_filters_dict(conn, namespace, options)
-
-    names_only = options.get('names_only', False)
-
-    iq = options.get('no_qualifiers', True)
-
-    # Force IncludeQualifier true if results are to be filtered since
-    # the filter requires that qualifiers exist.
-    request_iq = True if filters else iq
-
-    local_only = options.get('local_only', False)
-    deep_inheritance = options.get('deep_inheritance', True)
-    include_classorigin = options.get('include_classorigin', True)
-
-    if names_only and not filters:
-        results = conn.EnumerateClassNames(
-            ClassName=classname,
-            namespace=namespace,
-            DeepInheritance=deep_inheritance)
-    else:
-        results = conn.EnumerateClasses(
-            ClassName=classname,
-            namespace=namespace,
-            LocalOnly=local_only,
-            DeepInheritance=deep_inheritance,
-            IncludeQualifiers=request_iq,
-            IncludeClassOrigin=include_classorigin)
-        if filters:
-            results = _filter_classes(results, filters,
-                                      names_only, iq)
-    return results
-
-
 def get_format_group(context, options):
     """
     Define the format groups allowed based on the options. This is particular
@@ -904,23 +584,29 @@ def cmd_class_get(context, classname, options):
     conn = context.pywbem_server.conn
     format_group = get_format_group(context, options)
     output_format = validate_output_format(context.output_format, format_group)
-    ns_names = get_namespaces(context, options['namespace'])
 
-    # NocaseDict insures ordering with old versions of Python
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
-            results[ns] = conn.GetClass(
+    results = ResultsHandler(context, options, output_format, "class",
+                             classname)
+
+    for ns in results:
+        try:
+            results.add(conn.GetClass(
                 classname,
                 namespace=ns,
                 LocalOnly=options['local_only'],
                 IncludeQualifiers=options['no_qualifiers'],
                 IncludeClassOrigin=options['include_classorigin'],
-                PropertyList=resolve_propertylist(options['propertylist']))
-        display_cim_objects(context, results, output_format=output_format)
+                PropertyList=resolve_propertylist(options['propertylist'])))
 
-    except Error as er:
-        raise pywbem_error_exception(er)
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
+
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+    results.display()
 
 
 def cmd_class_invokemethod(context, classname, methodname, options):
@@ -943,20 +629,24 @@ def cmd_class_enumerate(context, classname, options):
     """
     format_group = get_format_group(context, options)
     output_format = validate_output_format(context.output_format, format_group)
-    ns_names = get_namespaces(context, options['namespace'])
 
-    # NocaseDict insures ordering with old versions of Python
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
-            results[ns] = enumerate_classes_filtered(context, ns, classname,
-                                                     options)
+    results = ResultsHandler(context, options, output_format, "class",
+                             classname)
 
-        display_cim_objects(context, results, output_format,
-                            summary=options['summary'])
+    for ns in results:
+        try:
+            results.add(enumerate_classes_filtered(
+                context, ns, classname, options))
 
-    except Error as er:
-        raise pywbem_error_exception(er)
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
+
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+    results.display()
 
 
 def cmd_class_references(context, classname, options):
@@ -967,32 +657,36 @@ def cmd_class_references(context, classname, options):
     conn = context.pywbem_server.conn
     format_group = get_format_group(context, options)
     output_format = validate_output_format(context.output_format, format_group)
-    ns_names = get_namespaces(context, options['namespace'])
 
-    # NocaseDict insures ordering with old versions of Python
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
+    results = ResultsHandler(context, options, output_format, "class",
+                             classname)
+
+    for ns in results:
+        try:
             cln = CIMClassName(classname, namespace=ns)
             if options['names_only']:
-                results[ns] = conn.ReferenceNames(
+                results.add(conn.ReferenceNames(
                     cln,
                     ResultClass=options['result_class'],
-                    Role=options['role'])
+                    Role=options['role']))
             else:
-                results[ns] = conn.References(
+                results.add(conn.References(
                     cln,
                     ResultClass=options['result_class'],
                     Role=options['role'],
                     IncludeQualifiers=options['no_qualifiers'],
                     IncludeClassOrigin=options['include_classorigin'],
-                    PropertyList=resolve_propertylist(options['propertylist']))
+                    PropertyList=resolve_propertylist(options['propertylist'])))
 
-        display_cim_objects(context, results, output_format,
-                            summary=options['summary'])
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
 
-    except Error as er:
-        raise pywbem_error_exception(er)
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+    results.display()
 
 
 def cmd_class_associators(context, classname, options):
@@ -1004,22 +698,22 @@ def cmd_class_associators(context, classname, options):
 
     format_group = get_format_group(context, options)
     output_format = validate_output_format(context.output_format, format_group)
-    ns_names = get_namespaces(context, options['namespace'])
 
-    # NocaseDict insures ordering with old versions of Python
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
+    results = ResultsHandler(context, options, output_format, "class",
+                             classname)
+
+    for ns in results:
+        try:
             cln = CIMClassName(classname, namespace=ns)
             if options['names_only']:
-                results[ns] = conn.AssociatorNames(
+                results.add(conn.AssociatorNames(
                     cln,
                     AssocClass=options['assoc_class'],
                     Role=options['role'],
                     ResultClass=options['result_class'],
-                    ResultRole=options['result_role'])
+                    ResultRole=options['result_role']))
             else:
-                results[ns] = conn.Associators(
+                results.add(conn.Associators(
                     cln,
                     AssocClass=options['assoc_class'],
                     Role=options['role'],
@@ -1027,98 +721,17 @@ def cmd_class_associators(context, classname, options):
                     ResultRole=options['result_role'],
                     IncludeQualifiers=options['no_qualifiers'],
                     IncludeClassOrigin=options['include_classorigin'],
-                    PropertyList=resolve_propertylist(options['propertylist']))
+                    PropertyList=resolve_propertylist(options['propertylist'])))
 
-        display_cim_objects(context, results, output_format,
-                            summary=options['summary'])
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
 
-    except Error as er:
-        raise pywbem_error_exception(er)
-
-
-def get_namespaces(context, namespaces, default_all_ns=False):
-    """
-    Returns either the namespaces defined in --namespaces parameter or if
-    namespaces is empty, either all of the namespaces available in the server or
-    the value None depending on the value of the parameter default_all_ns.
-
-    Processes either single namespace string, single string containing
-    multiple comma-separated,namespace definitions  or combination of string
-    and tuple.
-
-    This allows a single processor for the namespace option that returns
-    namespace or default in a form that matches the type of namespaces
-    (tuple, list) or (string, string)
-
-    Parameters:
-
-      context context (:class:`ContextObj` provided with command)
-
-      namespaces (tuple of :term:`string` or :term:`string`)
-        tuple of strings where each string is one or more namespace names.
-        Any single string can contain one or multiple namespaces by
-        comma-separating the namespace names.
-
-      default_all_ns (:class:`py:bool`):
-        Boolean that determines return value if namespaces is None or []:
-          True: Return all namespaces in server
-          False: Return default namespace for current conn (default)
-
-    Returns:
-        If namespaces is a tuple, returns list of namespaces with comma
-        separated strings separated into single items in the list
-        If namespaces is string returns the single namespace string
-        if namespaces is None return None if default_all_ns is False
-        or all namespaces in environment if default_all_ns is True
-
-    Raises:
-        CIMError if status code not CIM_ERR_NOT_FOUND
-    """
-    def get_default_ns(default_ns):
-        return default_ns if not isinstance(namespaces, tuple) else [default_ns]
-
-    # Return the provided namespace(s) by expanding each entry that has
-    # comma-separated values add adding those without comma
-
-    ns_names = []
-    if namespaces:
-        if isinstance(namespaces, tuple):
-            for ns in namespaces:
-                ns_names.extend(ns.split(','))
-            return ns_names
-        return namespaces
-
-    # If default input param is None, return the default namespace.
-    # We set the default namespace here rather than None (where the request
-    # would get the default namespace) because the find command
-    # attempts to build a dict with namespace and None fails
-    conn = context.pywbem_server.conn
-    default_ns = conn.default_namespace
-    assert default_all_ns is not None
-    if default_all_ns is False:
-        return get_default_ns(default_ns)
-
-    # Otherwise get all namespaces from server
-    wbem_server = context.pywbem_server.wbem_server
-    try:
-        assert isinstance(namespaces, tuple)
-        ns_names = wbem_server.namespaces
-        ns_names.sort()
-        return ns_names
-
-    except ModelError:
-        return get_default_ns(default_ns)
-    except CIMError as ce:
-        # Allow processing to continue if no interop namespace
-        if ce.status_code == CIM_ERR_NOT_FOUND:
-            warning_msg('{}. Using default_namespace {}.'
-                        .format(ce, conn.default_namespace))
-            return get_default_ns(default_ns)
-        raise click.ClickException('Failed to find namespaces. Exception: {} '
-                                   .format(ce))
+        except Error as er:
+            raise pywbem_error_exception(er)
 
-    except Error as er:
-        raise pywbem_error_exception(er)
+    results.display()
 
 
 def cmd_class_find(context, classname_glob, options):
diff --git a/pywbemtools/pywbemcli/_cmd_instance.py b/pywbemtools/pywbemcli/_cmd_instance.py
index 5c873c28..39ec9aa8 100644
--- a/pywbemtools/pywbemcli/_cmd_instance.py
+++ b/pywbemtools/pywbemcli/_cmd_instance.py
@@ -29,8 +29,6 @@
 from pywbem import CIMInstanceName, CIMClassName, Error, CIMError, \
     CIM_ERR_NOT_FOUND
 
-from pywbem._nocasedict import NocaseDict
-
 from .pywbemcli import cli
 from ._common import pick_instance, resolve_propertylist, create_ciminstance, \
     filter_namelist, verify_operation, process_invokemethod, \
@@ -48,7 +46,8 @@
 from ._association_shrub import AssociationShrub
 
 from .config import DEFAULT_QUERY_LANGUAGE
-from ._cmd_class import get_namespaces, enumerate_classes_filtered
+from ._common_cmd_functions import get_namespaces, enumerate_classes_filtered, \
+    ResultsHandler
 from .._click_extensions import PywbemtoolsGroup, PywbemtoolsCommand, \
     CMD_OPTS_TXT, GENERAL_OPTS_TXT, SUBCMD_HELP_TXT
 from .._options import add_options, help_option, validate_required_arg
@@ -884,6 +883,9 @@ def validate_namespace_option(class_path):
                     "namespace in INSTANCENAME: {}".format(options['namespace'],
                                                            instancename))
 
+    # If option is a tuple, expand option to get list of all namespaces
+    # defined. Option may be multiple uses of the option and/or comma-separated
+    # string for any option value
     if isinstance(options['namespace'], tuple):
         ns_names = get_namespaces(context, options['namespace'],
                                   default_all_ns=default_all_ns)
@@ -1021,34 +1023,30 @@ def cmd_instance_get(context, instancename, options):
     # Returns list of namespaces from namespace option
     instancepath = get_instancename(context, instancename, options)
 
-    # If namespace returned from get_instancename in path, put it into
-    # ns_names. path on the instance overrides the use of --namespace and
-    # therefore return from get_namespaces()
-    if instancepath.namespace:
-        ns_names = [instancepath.namespace]
-    else:
-        ns_names = get_namespaces(context, options['namespace'])
-
     property_list = resolve_propertylist(options['propertylist'])
 
-    # NocaseDict insures ordering with old versions of Python
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
+    results = ResultsHandler(context, options, output_fmt, "instance",
+                             instancepath, instpath=instancepath)
+
+    for ns in results:
+        try:
             instancepath.namespace = ns
-            results[ns] = conn.GetInstance(
+            results.add(conn.GetInstance(
                 instancepath,
                 LocalOnly=options['local_only'],
                 IncludeQualifiers=options['include_qualifiers'],
                 IncludeClassOrigin=options['include_classorigin'],
-                PropertyList=property_list)
+                PropertyList=property_list))
 
-        display_cim_objects(
-            context, results, output_fmt, property_list=property_list,
-            ignore_null_properties=not options['show_null'])
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
 
-    except Error as er:
-        raise pywbem_error_exception(er)
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+    results.display()
 
 
 def cmd_instance_delete(context, instancename, options):
@@ -1060,6 +1058,7 @@ def cmd_instance_delete(context, instancename, options):
         Otherwise attempt to delete the instance defined by instancename
     """
     conn = context.pywbem_server.conn
+
     instancepath = get_instancename(context, instancename, options)
 
     try:
@@ -1204,10 +1203,15 @@ def get_filterquerylanguage(options):
 
 
 def enumerate_instances(conn, context, options, namespace, classname,
-                        property_list):
+                        property_list, return_original_err=False):
     """
+    Internal method.
+
     Issue the command to enumerate either the paths or instances for the
     namespace defined by the namespace parameter.
+
+    If the return_original_err is True, reraise any  Error or CIMError
+    exception.
     """
     try:
         if options['names_only']:
@@ -1231,7 +1235,13 @@ def enumerate_instances(conn, context, options, namespace, classname,
             PropertyList=property_list)
 
     except Error as er:
+        # Return either the original exception or the ClickException.
+        if return_original_err:
+            raise er
         raise pywbem_error_exception(er)
+
+    # Exception from Enumerate and the FilterQuery.  This exception would
+    # apply  to all namespaces so just terminate.
     except ValueError as ve:
         raise click.ClickException(
             'Instance enumerate failed because FilterQuery not allowed with '
@@ -1252,18 +1262,24 @@ def cmd_instance_enumerate(context, classname, options):
 
     property_list = resolve_propertylist(options['propertylist'])
 
-    ns_names = get_namespaces(context, options['namespace'])
+    results = ResultsHandler(context, options, output_fmt, "class", classname,
+                             property_list=property_list)
 
-    # NocaseDict insures ordering with old versions of Python
-    results = NocaseDict()
-    for ns in ns_names:
-        results[ns] = enumerate_instances(conn, context, options, ns,
-                                          classname, property_list)
+    for ns in results:
+        try:
+            results.add(enumerate_instances(conn, context, options, ns,
+                                            classname, property_list,
+                                            return_original_err=True))
 
-    display_cim_objects(
-        context, results, output_fmt, summary=options['summary'],
-        property_list=property_list,
-        ignore_null_properties=not options['show_null'])
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
+
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+    results.display()
 
 
 def cmd_instance_references(context, instancename, options):
@@ -1281,28 +1297,25 @@ def cmd_instance_references(context, instancename, options):
 
     instancepath = get_instancename(context, instancename, options)
 
-    if instancepath.namespace:
-        ns_names = [instancepath.namespace]
-    else:
-        ns_names = get_namespaces(context, options['namespace'])
-
     property_list = resolve_propertylist(options['propertylist'])
 
-    # NocaseDict because it insures ordering with old versions of Python
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
+    results = ResultsHandler(context, options, output_fmt, "instance",
+                             instancepath, instpath=instancepath,
+                             property_list=property_list)
+
+    for ns in results:
+        try:
             instancepath.namespace = ns
             if options['names_only']:
-                results[ns] = conn.PyWbemcliReferenceInstancePaths(
+                results.add(conn.PyWbemcliReferenceInstancePaths(
                     instancepath,
                     ResultClass=options['result_class'],
                     Role=options['role'],
                     FilterQuery=options['filter_query'],
                     FilterQueryLanguage=get_filterquerylanguage(options),
-                    MaxObjectCount=context.pywbem_server.pull_max_cnt)
+                    MaxObjectCount=context.pywbem_server.pull_max_cnt))
             else:
-                results[ns] = conn.PyWbemcliReferenceInstances(
+                results.add(conn.PyWbemcliReferenceInstances(
                     instancepath,
                     ResultClass=options['result_class'],
                     Role=options['role'],
@@ -1311,20 +1324,23 @@ def cmd_instance_references(context, instancename, options):
                     FilterQuery=options['filter_query'],
                     FilterQueryLanguage=get_filterquerylanguage(options),
                     MaxObjectCount=context.pywbem_server.pull_max_cnt,
-                    PropertyList=property_list)
+                    PropertyList=property_list))
 
-        display_cim_objects(
-            context, results, output_fmt, summary=options['summary'],
-            property_list=property_list,
-            ignore_null_properties=not options['show_null'])
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
 
-    except Error as er:
-        raise pywbem_error_exception(er)
-    except ValueError as ve:
-        raise click.ClickException(
-            'Instance references failed because FilterQuery not allowed with '
-            'traditional References. --use-pull {}. Exception: {}: {}'
-            .format(context.pywbem_server.use_pull, ve.__class__.__name__, ve))
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+        except ValueError as ve:
+            raise click.ClickException(
+                'Instance references failed because FilterQuery not allowed '
+                'with traditional References. --use-pull {}. Exception: {}: {}'
+                .format(context.pywbem_server.use_pull, ve.__class__.__name__,
+                        ve))
+    results.display()
 
 
 def cmd_instance_associators(context, instancename, options):
@@ -1339,20 +1355,17 @@ def cmd_instance_associators(context, instancename, options):
 
     instancepath = get_instancename(context, instancename, options)
 
-    if instancepath.namespace:
-        ns_names = [instancepath.namespace]
-    else:
-        ns_names = get_namespaces(context, options['namespace'])
-
     property_list = resolve_propertylist(options['propertylist'])
 
-    # NocaseDict because it insures ordering with old versions of Python
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
+    results = ResultsHandler(context, options, output_fmt, "class",
+                             instancepath, instpath=instancepath,
+                             property_list=property_list)
+
+    for ns in results:
+        try:
             instancepath.namespace = ns
             if options['names_only']:
-                results[ns] = conn.PyWbemcliAssociatorInstancePaths(
+                results.add(conn.PyWbemcliAssociatorInstancePaths(
                     instancepath,
                     AssocClass=options['assoc_class'],
                     Role=options['role'],
@@ -1360,9 +1373,9 @@ def cmd_instance_associators(context, instancename, options):
                     ResultRole=options['result_role'],
                     FilterQuery=options['filter_query'],
                     FilterQueryLanguage=get_filterquerylanguage(options),
-                    MaxObjectCount=context.pywbem_server.pull_max_cnt)
+                    MaxObjectCount=context.pywbem_server.pull_max_cnt))
             else:
-                results[ns] = conn.PyWbemcliAssociatorInstances(
+                results.add(conn.PyWbemcliAssociatorInstances(
                     instancepath,
                     AssocClass=options['assoc_class'],
                     Role=options['role'],
@@ -1373,21 +1386,25 @@ def cmd_instance_associators(context, instancename, options):
                     FilterQuery=options['filter_query'],
                     FilterQueryLanguage=get_filterquerylanguage(options),
                     MaxObjectCount=context.pywbem_server.pull_max_cnt,
-                    PropertyList=property_list)
+                    PropertyList=property_list))
 
-        display_cim_objects(
-            context, results, output_fmt, summary=options['summary'],
-            property_list=property_list,
-            ignore_null_properties=not options['show_null'])
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
 
-    except Error as er:
-        raise pywbem_error_exception(er)
+        except Error as er:
+            raise pywbem_error_exception(er)
 
-    except ValueError as ve:
-        raise click.ClickException(
-            'Instance associators failed because FilterQuery not allowed with '
-            'traditional Associators. --use-pull: {}. Exception: {}: {}'
-            .format(context.pywbem_server.use_pull, ve.__class__.__name__, ve))
+        except ValueError as ve:
+            raise click.ClickException(
+                'Instance associators failed because FilterQuery not allowed '
+                'with traditional Associators. --use-pull: {}. Exception: {}: '
+                '{}'
+                .format(context.pywbem_server.use_pull, ve.__class__.__name__,
+                        ve))
+
+    results.display()
 
 
 def cmd_instance_count(context, classname, options):
diff --git a/pywbemtools/pywbemcli/_cmd_qualifier.py b/pywbemtools/pywbemcli/_cmd_qualifier.py
index 23d20aa3..38344bb4 100644
--- a/pywbemtools/pywbemcli/_cmd_qualifier.py
+++ b/pywbemtools/pywbemcli/_cmd_qualifier.py
@@ -24,13 +24,12 @@
 
 import click
 
-from pywbem import Error
-from pywbem._nocasedict import NocaseDict
+from pywbem import Error, CIMError
 
 from .pywbemcli import cli
 from ._common import sort_cimobjects, pywbem_error_exception
-from ._display_cimobjects import display_cim_objects
-from ._cmd_class import get_namespaces
+
+from ._common_cmd_functions import ResultsHandler
 from ._common_options import namespace_option, summary_option, \
     multiple_namespaces_option_dflt_conn
 from .._click_extensions import PywbemtoolsGroup, PywbemtoolsCommand, \
@@ -143,17 +142,23 @@ def cmd_qualifier_get(context, qualifiername, options):
     conn = context.pywbem_server.conn
     output_format = validate_output_format(context.output_format, ['CIM',
                                                                    'TABLE'])
-    # Request qual decls for all namespaces provided and set to display
-    # as dictionary of <ns>: [qual decls]
-    ns_names = get_namespaces(context, options['namespace'])
-    try:
-        results = NocaseDict()
-        for ns in ns_names:
-            results[ns] = conn.GetQualifier(qualifiername, namespace=ns)
-    except Error as er:
-        raise pywbem_error_exception(er)
 
-    display_cim_objects(context, results, output_format)
+    results = ResultsHandler(context, options, output_format, "QualDeclName",
+                             qualifiername)
+
+    for ns in results:
+        try:
+            results.add(conn.GetQualifier(qualifiername, namespace=ns))
+
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
+
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+    results.display()
 
 
 def cmd_qualifier_delete(context, qualifiername, options):
@@ -177,17 +182,20 @@ def cmd_qualifier_enumerate(context, options):
     conn = context.pywbem_server.conn
     output_format = validate_output_format(context.output_format, ['CIM',
                                                                    'TABLE'])
-    # Request qual decls for all namespaces provided and set to display
-    # as dictionary of <ns>: [qual decls]
-    ns_names = get_namespaces(context, options['namespace'])
-    results = NocaseDict()
-    try:
-        for ns in ns_names:
-            results[ns] = sort_cimobjects(
-                conn.EnumerateQualifiers(namespace=ns))
 
-        display_cim_objects(context, results, output_format,
-                            summary=options['summary'])
+    results = ResultsHandler(context, options, output_format, "QualDeclName",
+                             None)
 
-    except Error as er:
-        raise pywbem_error_exception(er)
+    for ns in results:
+        try:
+            results.add(sort_cimobjects(conn.EnumerateQualifiers(namespace=ns)))
+
+        except CIMError as ce:
+            # Process error and continue or generate exception
+            results.handle_exception(ns, ce)
+            continue
+
+        except Error as er:
+            raise pywbem_error_exception(er)
+
+    results.display()
diff --git a/pywbemtools/pywbemcli/_common.py b/pywbemtools/pywbemcli/_common.py
index 5f4e92e0..04e74bc5 100644
--- a/pywbemtools/pywbemcli/_common.py
+++ b/pywbemtools/pywbemcli/_common.py
@@ -35,8 +35,9 @@
 
 from pywbem import CIMInstanceName, CIMInstance, CIMClass, \
     CIMQualifierDeclaration, CIMProperty, CIMClassName, \
-    cimvalue, Error, ToleratedSchemaIssueWarning, \
-    CIMFloat, CIMInt, CIMDateTime
+    cimvalue, Error, CIMError, ToleratedSchemaIssueWarning, \
+    CIMFloat, CIMInt, CIMDateTime, CIM_ERR_NOT_FOUND, CIM_ERR_INVALID_CLASS, \
+    CIM_ERR_INVALID_NAMESPACE, CIM_ERR_INVALID_PARAMETER
 from pywbem._nocasedict import NocaseDict
 
 from ._cimvalueformatter import cimvalue_to_fmtd_string
@@ -253,11 +254,24 @@ def pick_instance(context, classname, namespaces=None):
     elif isinstance(namespaces, six.string_types):
         namespaces = [namespaces]
 
+    # Get the possible instances from all namespaces defined for the
+    # the request
     instance_names = []
     for ns in namespaces:
         try:
             instance_names.extend(conn.PyWbemcliEnumerateInstancePaths(
                 classname, ns))
+        except CIMError as ce:
+            # When multiple namespaces bypass the following errors. They will
+            # be caught when the requests are processed.
+            if len(namespaces) > 1:
+                if ce.status_code in (CIM_ERR_NOT_FOUND,
+                                      CIM_ERR_INVALID_CLASS,
+                                      CIM_ERR_INVALID_NAMESPACE,
+                                      CIM_ERR_INVALID_PARAMETER):
+                    continue
+            raise pywbem_error_exception(ce)
+
         except Error as ex:
             raise pywbem_error_exception(ex)
 
@@ -1321,7 +1335,9 @@ def pywbem_error_exception(exc, intro=None):
     """
     Return the standard click exception for a pywbem Error exception.  These
     exceptions do not cause interactive mode failure but display the exception
-    class and its str value and return to the repl mode.
+    class and its str value and return to the repl mode: .
+
+    Note: This method returns the exception. It does not raise it.
 
     Parameters:
 
diff --git a/pywbemtools/pywbemcli/_common_cmd_functions.py b/pywbemtools/pywbemcli/_common_cmd_functions.py
new file mode 100644
index 00000000..d8e34519
--- /dev/null
+++ b/pywbemtools/pywbemcli/_common_cmd_functions.py
@@ -0,0 +1,648 @@
+# (C) Copyright 2022 IBM Corp.
+# (C) Copyright 2022 Inova Development Inc.
+# All Rights Reserved
+#
+# 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 a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+Functions and classes used by the _cmd_xxxx.py command implementations but that
+apply across multiple command groups (ex. they are used by both _cmd_class
+and _cmd_instance).
+"""
+
+from __future__ import absolute_import, print_function
+
+from collections import namedtuple
+import click
+
+from pywbem._nocasedict import NocaseDict
+
+from pywbem import Error, CIMError, ModelError, \
+    CIM_ERR_NOT_FOUND, CIM_ERR_INVALID_CLASS, CIM_ERR_INVALID_PARAMETER, \
+    CIM_ERR_INVALID_NAMESPACE
+
+from ._common import pywbem_error_exception, get_subclass_names, \
+    get_leafclass_names, parse_version_value
+
+from ._display_cimobjects import display_cim_objects
+
+from .._output_formatting import output_format_is_table, \
+    format_table, warning_msg, output_format_is_cimobject, \
+    output_format_is_textgroup
+
+
+class ResultsHandler(object):
+    """
+    Class that manages the handling of the namespaces, interim results, and
+    errors in those request action methods that use multiple namespaces.
+
+    This class:
+      - Initializes the structures that gather data from pywbem server requests
+        when multiple requests are to be executed because the command
+        defines multiple namespaces for the requests,
+      - Manages determination of the namespaces to be processed.
+      - Provides methods (add(...) and handle_exception() to capture the
+        command results
+      - Manages continuation of execution of requests if a CIMError is
+        encountered
+      - Provides a method (display(...) that calls the display_cimobjects to
+        display the request results
+      - Displays any error results in a form compatible with the requested
+        display format and data format.
+
+    The pattern for this class is:
+
+      results = ResultsHandler(...)
+      for namespace in results:
+         # execute server request and append results to any previous results
+         results.add(<request method>)
+      exception CIMError as ce:
+        # Capture the CIMError exception and either terminate if not one of the
+        # ones for which continuing would be logical or return
+        results.handle_exception(ns, ce)
+        continue
+      # terminate because an Error exception is going to apply to all requests
+      exception Error as er:
+            raise pywbem_error_exception(er)
+
+      results.display()
+    """
+    def __init__(self, context, options, output_format, obj_type,
+                 target_object, instpath=None, property_list=None):
+        """
+          context (:class:`py:dict`):
+            click command context dictionary
+          options (:class:`py:dict`):
+            click command options dictionary
+          output_format (:term:`string`)
+            Output format string that is passed to display_cimobjects())
+          obj_type ((:term:`string`)):
+            String defining type of object "class", "instance", etc.
+          target_object
+
+          instpath (:term:`string` or :class:`~pywbem.CIMInstanceName`):
+            Identification of the request target object to be included in
+            error display
+
+          property_list (list of :term:`string, :term:`string` or None)
+            Resolved property list passed to display_cimobjects
+        """
+
+        self.context = context
+        self.obj_type = obj_type
+        self.target_object = target_object
+        self.output_format = output_format
+        self.options = options
+        self.property_list = property_list
+
+        # If namespace returned from get_instancename in path, put it into
+        # ns_names. path on the instance overrides the use of --namespace and
+        # therefore return from get_namespaces()
+        if instpath and instpath.namespace:
+            self.ns_names = [instpath.namespace]
+        else:
+            self.ns_names = get_namespaces(context, options['namespace'])
+
+        self.results = NocaseDict()
+
+        # set the requested namespaces into the results dictionary
+        for ns in self.ns_names:
+            self.results[ns] = None
+
+        self.result_errors = {}
+        self.results_to_date = 0
+
+    def __contains__(self, key):
+        return key in self.results
+
+    def keys(self):
+        """
+        Return result dictionary keys
+        """
+        return self.results.keys()
+
+    def __iter__(self):
+        """
+        Used to iterate the namespaces for which requests are to be made
+        """
+        return iter(self.results)
+
+    def add(self, request_result):
+        """
+        Adds reguest_result to results dictionary
+        """
+        self.results[self.ns_names[self.results_to_date]] = request_result
+        self.results_to_date += 1
+
+    def handle_exception(self, ns, exc):
+        """
+        Handle CIM_Error exceptions from multi-namespace requests.  This method
+        processes an exception from a server request methods and determines if
+        the processing will continue for other namespaces or terminate with an
+        exception. If one of the listed CIMError status codes in being
+        processed, it allows the processing to continue but issues a warning
+        message.
+
+        If all namespaces in the ns_names list have been processed and there
+        are no valid responses in the ns_names list, it raises the error shown
+        by exc.
+
+        Parameters:
+          exc (Exception):
+            The exception caught and  being processed.
+
+          target_object (:term:`string` or CIMInstanceName,):
+            The request target object that caused the exception or None
+        """
+        # If not one of the following CIMError status codes, terminate with
+        # Click exception
+        if exc.status_code not in (CIM_ERR_NOT_FOUND,
+                                   CIM_ERR_INVALID_CLASS,
+                                   CIM_ERR_INVALID_NAMESPACE,
+                                   CIM_ERR_INVALID_PARAMETER):
+            raise pywbem_error_exception(exc)
+
+        # If all returns were in error, terminate with last exception but show
+        # the errors as part of the errors display
+        self.results_to_date += 1
+        self.result_errors[ns] = (exc)
+        if self.results_to_date == len(self.results):
+            if not any(self.results.values()):
+                if self.result_errors:
+                    self.display_errors(terminate=False)
+                raise pywbem_error_exception(exc)
+
+    def display(self):
+        """
+        Execute the displays. This will cause the display of both the
+        results and result_errors.  Note that this method gets specifiec
+        options from self.options that are required by display_cimobjects
+        """
+        summary = self.options.get('summary', None)
+        ignore_null = not self.options.get('show_null', None)
+
+        display_cim_objects(self.context, self.results, self.output_format,
+                            summary=summary,
+                            ignore_null_properties=ignore_null,
+                            property_list=self.property_list)
+
+        if self.result_errors:
+            if any(self.result_errors.values()):
+                self.display_errors(terminate=True)
+
+    def display_errors(self, terminate=False):
+        """
+        Display any errors in an appropriate format consistent with the
+        output format but to stderr.
+        """
+        rows = []
+        # values are (exception, self.obj_type, target_object)
+        for ns, exc in self.result_errors.items():
+            rows.append([ns, exc.status_code_name, exc.status_description])
+
+        title = "Request Response Errors for Target: ({}) {}". \
+            format(self.obj_type, self.target_object)
+
+        if output_format_is_table(self.output_format):
+            headers = ['namespace', 'CIMError', "Description"]
+
+            click.echo(format_table(rows, headers,
+                                    title=title,
+                                    table_format=self.output_format))
+
+        elif output_format_is_cimobject(self.output_format):
+            click.echo("\n{}".format(title))
+            for row in rows:
+                click.echo(
+                    "namespace:{} CIMError:{} Description:{}".
+                    format(row[0], row[1], row[2]), err=True)
+
+        elif output_format_is_textgroup(self.output_format):
+            click.echo("\n{}".format(title))
+            for row in rows:
+                click.echo(
+                    "namespace:{} CIMError:{} Description:{}".
+                    format(row[0], row[1], row[2]), err=True)
+
+        # Close with an exception so exception code is raised.
+        if terminate:
+            raise click.ClickException(
+                "Errors encountered on {} server request(s)".
+                format(len(self.result_errors)))
+
+
+def get_namespaces(context, namespaces, default_all_ns=False):
+    """
+    Returns either the namespaces defined in --namespaces parameter or if
+    namespaces is empty, either all of the namespaces available in the server or
+    the value None depending on the value of the parameter default_all_ns.
+
+    Processes either single namespace string, single string containing
+    multiple comma-separated,namespace definitions  or combination of string
+    and tuple.
+
+    This allows a single processor for the namespace option that returns
+    namespace or default in a form that matches the type of namespaces
+    (tuple, list) or (string, string)
+
+    Parameters:
+
+      context context (:class:`ContextObj` provided with command)
+
+      namespaces (tuple of :term:`string` or :term:`string`)
+        tuple of strings where each string is one or more namespace names.
+        Any single string can contain one or multiple namespaces by
+        comma-separating the namespace names.
+
+      default_all_ns (:class:`py:bool`):
+        Boolean that determines return value if namespaces is None or []:
+          True: Return all namespaces in server
+          False: Return default namespace for current conn (default)
+
+    Returns:
+        If namespaces is a tuple, returns list of namespaces with
+        comma-separated strings separated into single items in the list
+        If namespaces is string, returns the single namespace string
+        if namespaces is None, returns None if default_all_ns is False
+        or all namespaces in environment if default_all_ns is True
+
+    Raises:
+        CIMError if status code not CIM_ERR_NOT_FOUND
+    """
+    def get_default_ns(default_ns):
+        return default_ns if not isinstance(namespaces, tuple) else [default_ns]
+
+    # Return the provided namespace(s) by expanding each entry that has
+    # comma-separated values add adding those without comma
+    ns_names = []
+    if namespaces:
+        if isinstance(namespaces, tuple):
+            for ns in namespaces:
+                ns_names.extend(ns.split(','))
+            return ns_names
+        return namespaces
+
+    # If default input param is None, return the default namespace.
+    # We set the default namespace here rather than None (where the request
+    # would get the default namespace) because the find command
+    # attempts to build a dict with namespace and None fails
+    conn = context.pywbem_server.conn
+    default_ns = conn.default_namespace
+    assert default_all_ns is not None
+    if default_all_ns is False:
+        return get_default_ns(default_ns)
+
+    # Otherwise get all namespaces from server
+    wbem_server = context.pywbem_server.wbem_server
+    try:
+        assert isinstance(namespaces, tuple)
+        ns_names = wbem_server.namespaces
+        ns_names.sort()
+        return ns_names
+
+    except ModelError:
+        return get_default_ns(default_ns)
+
+    except CIMError as ce:
+        # Allow processing to continue if no interop namespace
+        if ce.status_code == CIM_ERR_NOT_FOUND:
+            warning_msg('{}. Using default_namespace {}.'
+                        .format(ce, conn.default_namespace))
+            return get_default_ns(default_ns)
+        raise click.ClickException('Failed to find namespaces. Exception: {} '
+                                   .format(ce))
+
+    except Error as er:
+        raise pywbem_error_exception(er)
+
+
+def enumerate_classes_filtered(context, namespace, classname, options):
+    """
+    Execute EnumerateClasses or EnumerateClassNames in a single namespace
+    defined in options['namespace'] and return results.
+
+    If any of the class qualifier filters are defined in the options parameter,
+    enumerate the classes, filter the result for those parameters, and return
+    only class names if --names-only set.
+
+    This function may be executed by multiple command action functions with
+    varying options in the options. Each option must be tested to validate
+    that it exists in the options dictionary
+
+    Parameters:
+
+      context:  (instance of :class:`ContextObj`):
+        Used to retrieve conn parameter
+
+      classname (:term:`string`):
+        classname for the enumerate or None if all classes to be enumerated.
+
+      options: Click options dictionary
+        Options that form basis for this Enumerate and filter processing.
+
+    Returns:
+        List of classes or classnames that satisfy the criteria
+
+    Raises:
+        pywbem Error exceptions generated by EnumerateClassNames and
+        enumerateClasses
+    """
+    conn = context.pywbem_server.conn
+    filters = _build_filters_dict(conn, namespace, options)
+
+    names_only = options.get('names_only', False)
+
+    iq = options.get('no_qualifiers', True)
+
+    # Force IncludeQualifier true if results are to be filtered since
+    # the filter requires that qualifiers exist.
+    request_iq = True if filters else iq
+
+    local_only = options.get('local_only', False)
+    deep_inheritance = options.get('deep_inheritance', True)
+    include_classorigin = options.get('include_classorigin', True)
+
+    if names_only and not filters:
+        results = conn.EnumerateClassNames(
+            ClassName=classname,
+            namespace=namespace,
+            DeepInheritance=deep_inheritance)
+    else:
+        results = conn.EnumerateClasses(
+            ClassName=classname,
+            namespace=namespace,
+            LocalOnly=local_only,
+            DeepInheritance=deep_inheritance,
+            IncludeQualifiers=request_iq,
+            IncludeClassOrigin=include_classorigin)
+        if filters:
+            results = _filter_classes(results, filters,
+                                      names_only, iq)
+    return results
+
+
+# Namedtupe defining each entry in the filters dictionary values
+FILTERDEF = namedtuple('FILTERDEF', 'optionvalue qualifiername scopes')
+
+
+def _build_filters_dict(conn, ns, options):
+    """
+    Build a dictionary defining the filters to be processed against list
+    of classes from
+    the filter definitons in the Click options dictionary. There is an entry
+    in the dictionary for each filter to be applied to filter a list of
+    classes.
+
+    Returns:
+      Dict of filters where the names are the  filtersthemselves , the types
+      are the type of test (i.e. qualifier, superclass)
+      and the value for each is a tuple:
+      * Name of the qualifier (:term:`string`)
+      * The value of the qualifier filter option (True or False which
+        determines whether to display the existence or non-existence of the
+        qualifier
+      * A tuple containing Booleans for the value of each of the possible
+        element scopes (class, property, method, parameter) indicating whether
+        the qualifier is allowed in that element.
+    """
+    filters = {}
+
+    def set_qualifier_option(qname, option_value):
+        qualdecl = conn.GetQualifier(qname, ns)
+        # Note: qualdecl.scopes performs test case-insensitively
+        if qualdecl.scopes['any']:
+            scopes_map = [True, True, True, True]
+        else:
+            scopes_map = [False, False, False, False]
+            scopes_map[0] = any([qualdecl.scopes['class'],
+                                 qualdecl.scopes['association'],
+                                 qualdecl.scopes['indication']])
+            scopes_map[1] = qualdecl.scopes['property']
+            scopes_map[2] = qualdecl.scopes['method']
+            scopes_map[3] = qualdecl.scopes['parameter']
+        filters['qualifier'] = FILTERDEF(option_value, qname,
+                                         tuple(scopes_map))
+
+    # Qualifier options
+    if options['association'] is not None:
+        set_qualifier_option('association', options['association'])
+    if options['indication'] is not None:
+        set_qualifier_option('indication', options['indication'])
+    if options['experimental'] is not None:
+        set_qualifier_option('experimental', options['experimental'])
+    # If set, the entity is deprecated
+    if options['deprecated'] is not None:
+        set_qualifier_option('deprecated', options['deprecated'])
+    if options['since'] is not None:
+        version_tuple = parse_version_str(options['since'])
+        set_qualifier_option('version', version_tuple)
+
+    if options['schema'] is not None:
+        test_str = "{}_".format(options['schema'].lower())
+        filters['schema'] = FILTERDEF(test_str, None, None)
+
+    if options['subclass_of'] is not None:
+        filters['subclass_of'] = FILTERDEF(options['subclass_of'], None, None)
+    if options['leaf_classes'] is not None:
+        filters['leaf_classes'] = FILTERDEF(options['leaf_classes'], None, None)
+    return filters
+
+
+def parse_version_str(version_str):
+    """
+    Parse a string with 3 positive integers seperated by period (CIM version
+    string) into a 3 integer tuple and return the tuple. Used to parse the
+    version value of the DMTF Version qualifier.
+
+    Parameters:
+        version_str (:term: str):
+            String defining 3 components of a CIM version
+
+    Returns:
+        tuple containing 3 integers
+
+    Raises:
+        click.ClickException if the version_str is invalid (not integers,
+        not seperated by ".", not 3 values)
+    """
+    try:
+        version_tuple = [int(x) for x in version_str.split('.')]
+    except ValueError:
+        raise click.ClickException('--since option value invalid. '
+                                   'Must contain 3 integer elements: '
+                                   'int.int.int". {} received'.
+                                   format(version_str))
+    if len(version_tuple) != 3:
+        raise click.ClickException('Version value must contain 3 integer '
+                                   'elements (int.int.int). '
+                                   '{} received'.format(version_str))
+    return version_tuple
+
+
+def _filter_classes(classes, filters, names_only, iq):
+    """
+    Filter a list of classes for the qualifiers defined by  the
+    qualifier_filter parameter where this parameter is a list of tuples.
+    each tuple contains the qualifier name and a dictionary with qualifier
+     name as key and tuple containing the option_value(True or False) and
+    a list of booleans where each boolean represents one of the scope types
+    ()
+    whether to display or not display if it exists.
+
+    This method only works for boolean qualifiers
+
+    Parameters:
+
+      classes (list of :class:`~pywbem.CIMClass`):
+        list of classes to be filtered
+
+      qualifier_filters (dict):
+        Dictionary defining the filtering to be performed. It contains an entry
+        for each qualifier filter that is defined. See _build_qualifier_filters
+        for a definition of this list.
+
+      names_only (:class:`py:bool`):
+        If True, return only the classnames. Otherwise returns the filtered
+        classes. This is because we must get the classes from the server to
+        perform the filtering
+
+      iq (:class:`py:bool`):
+        If not True, remove any qualifiers from the classes.  This is because
+        we must get the classes from the server with qualifiers to
+        perform the filtering.
+    """
+
+    def class_has_qualifier(cls, qname, scopes):
+        """
+        Determine if the qualifier defined by qname exists in the elements
+        of the class where the elements are defined by the scopes parameter
+        for this filter.
+
+        Parameters:
+
+          cls (:class:`~pywbem.CIMClass`):
+            The class to be inspected for the qualifier defined by qname
+
+          qname (:term:`string`):
+            The qualifier for which we are searching
+
+          scopes (tuple of booleans):
+            A tuple containing a boolean value for each of the possible scopes
+            (class, property, method, parameter)
+
+        Returns:
+          True if the qualifier with name quname is found in the elements where
+          the scope is True. Otherwise, False is returned
+
+        """
+        # Test class scope
+        if scopes[0] and qname in cls.qualifiers:
+            return True
+
+        # if property scope, test properties
+        if scopes[1]:
+            for prop in cls.properties.values():
+                if qname in prop.qualifiers:
+                    return True
+        # If method scope, test methods and if parameter scope, test parameters
+        if scopes[2]:
+            for method in cls.methods.values():
+                if qname in method.qualifiers:
+                    return True
+                if scopes[3]:
+                    params = method.parameters
+                    for param in params.values():
+                        if qname in param.qualifiers:
+                            return True
+        return False
+
+    # Test all classes in the input property for the defined filters.
+    filtered_classes = []
+    subclass_names = []
+    # Build list of subclass names that will be used later as a filter on the
+    # classes to be returned
+    if 'subclass_of' in filters:
+        try:
+            subclass_names = get_subclass_names(
+                classes,
+                classname=filters['subclass_of'].optionvalue,
+                deep_inheritance=True)
+        except ValueError:
+            raise click.ClickException(
+                'Classname {} for "subclass-of" not found in returned classes.'
+                .format(filters['subclass_of'].optionvalue))
+
+    # Build a list of leaf class names that will be used later as a filter on
+    # the classes to be returned.
+    if 'leaf_classes' in filters:
+        try:
+            if subclass_names:
+                clsx = [cls for cls in classes if cls.classname in
+                        subclass_names]
+                leafclass_names = get_leafclass_names(clsx)
+            else:
+                leafclass_names = get_leafclass_names(classes)
+
+        except ValueError:
+            raise click.ClickException(
+                'Classname {} for "leaf_classes-of" not found in returned '
+                'classes.'.format(filters['leaf_classes'].optionvalue))
+
+    for cls in classes:
+        show_class_list = []
+        for filter_name, filter_ in filters.items():
+            if filter_name == 'qualifier':
+                option_value = filter_.optionvalue
+                if class_has_qualifier(cls, filter_.qualifiername,
+                                       filter_.scopes):
+                    if filter_.qualifiername == 'version':
+                        if filter_.qualifiername in cls.qualifiers:
+                            cls_version = \
+                                cls.qualifiers[filter_.qualifiername].value
+                            val = parse_version_value(cls_version,
+                                                      cls.classname)
+                            option_value = bool(val >= filter_.optionvalue)
+
+                    show_class_list.append(option_value)
+                else:
+                    show_class_list.append(not option_value)
+
+            elif filter_name == 'schema':
+                show_class_list.append(
+                    cls.classname.lower().startswith(filter_.optionvalue))
+            elif filter_name == 'subclass_of':
+                show_class_list.append(cls.classname in subclass_names)
+            elif filter_name == 'leaf_classes':
+                show_class_list.append(cls.classname in leafclass_names)
+
+            else:
+                assert False  # Future for other test_types
+
+        # Show if all options are True for this class
+        show_this_class = all(show_class_list)
+
+        if show_this_class:
+            # If returning instances, honor the names_only option
+            if not names_only and not iq:
+                cls.qualifiers = []
+                for p in cls.properties.values():
+                    p.qualifiers = []
+                for m in cls.methods.values():
+                    m.qualifiers = []
+                    for p in m.parameters.values():
+                        p.qualifiers = []
+            filtered_classes.append(cls)
+
+    # If names_only parameter create list of classnames
+    if names_only:
+        filtered_classes = [cls.classname for cls in filtered_classes]
+    return filtered_classes
diff --git a/pywbemtools/pywbemcli/_display_cimobjects.py b/pywbemtools/pywbemcli/_display_cimobjects.py
index 3eb53cc6..652b5c92 100644
--- a/pywbemtools/pywbemcli/_display_cimobjects.py
+++ b/pywbemtools/pywbemcli/_display_cimobjects.py
@@ -183,22 +183,26 @@ def display_cim_objects(context, cim_objects, output_format, summary=False,
     # CIMClassName, CIMClass
     if isinstance(cim_objects, NocaseDict):
         for ns, ns_objects in cim_objects.items():
-            if not isinstance(ns_objects, list):
-                ns_objects = [ns_objects]
-            ns_objects = sort_cimobjects(ns_objects)
-            for obj in ns_objects:
-                _display_one_cim_object(
-                    context, obj, output_format, property_list, quote_strings,
-                    ignore_null_properties, namespace=ns)
+            if ns_objects:
+                if not isinstance(ns_objects, list):
+                    ns_objects = [ns_objects]
+                ns_objects = sort_cimobjects(ns_objects)
+
+                for obj in ns_objects:
+                    _display_one_cim_object(
+                        context, obj, output_format, property_list,
+                        quote_strings, ignore_null_properties, namespace=ns)
         return
 
     # If not NocaseDict, it is list or single object. Sort by classname and
     # then call _display_one_cim_objects with each item from list
     if not isinstance(cim_objects, list):
         cim_objects = [cim_objects]
+
     if isinstance(cim_objects, list):
         # Sort the objects by classname and call to display each object
         cim_objects = sort_cimobjects(cim_objects)
+
         for obj in cim_objects:
             _display_one_cim_object(
                 context, obj, output_format, property_list, quote_strings,
@@ -237,6 +241,7 @@ def _display_one_cim_object(context, cim_object, output_format, property_list,
             if namespace:
                 click.echo("#pragma namespace (\"{}\")".format(namespace))
             click.echo(mofstr)
+
         except AttributeError:
             # inserting NL between instance names for readability
             if isinstance(cim_object, CIMInstanceName):
@@ -308,7 +313,9 @@ def _display_one_cim_object(context, cim_object, output_format, property_list,
 class QualDeclWrapper():  # pylint: disable=too-few-public-methods
     """
     Convert qualifier declaractions to instance of this class to be able to
-    pass the namespace to the display function unambiguously.
+    pass the namespace to the display function unambiguously.  This is only
+    a wrapper within the display_cim_objects method and its submethods since
+    the CIM_QualifierDeclaration has no namespace component.
     """
     def __init__(self, namespace, qual_decl_inst):
         self.qualdecl = qual_decl_inst
@@ -455,7 +462,8 @@ def _display_cim_objects_summary(context, objects, output_format):
         for ns, objlist in objects.items():
             if not cim_type:
                 cim_type = _get_cimtype(objlist)
-            rows.append([ns, len(objlist), cim_type])
+            objlistlen = len(objlist) if objlist else 0
+            rows.append([ns, objlistlen, cim_type])
     else:
         headers = ['Count', 'CIM Type']
         if isinstance(objects, list):


Test patch:
diff --git a/tests/unit/pywbemcli/mock_prompt_pick_response_11.py b/tests/unit/pywbemcli/mock_prompt_pick_response_11.py
index 67ba0974..149cd484 100644
--- a/tests/unit/pywbemcli/mock_prompt_pick_response_11.py
+++ b/tests/unit/pywbemcli/mock_prompt_pick_response_11.py
@@ -13,11 +13,6 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
-# The previous statement is used by pywbemcli to force this script to be
-# run at pywbemcli startup and not included in the list of --mock-server
-# files that are used to build the repository.  This is a development
-# test aid.
 """
     Python code to mock pywbemcli._common.pywbemcli_prompt. Returns the
     value defined in RETURN_VALUE
diff --git a/tests/unit/pywbemcli/mock_prompt_pick_response_12.py b/tests/unit/pywbemcli/mock_prompt_pick_response_12.py
index 828376a4..78ade8c7 100644
--- a/tests/unit/pywbemcli/mock_prompt_pick_response_12.py
+++ b/tests/unit/pywbemcli/mock_prompt_pick_response_12.py
@@ -14,10 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# The previous statement is used by pywbemcli to force this script to be
-# run at pywbemcli startup and not included in the list of --mock-server
-# files that are used to build the repository.  This is a development
-# test aid.
 """
     Python code to mock pywbemcli._common.pywbemcli_prompt. Returns the
     value defined in RETURN_VALUE
diff --git a/tests/unit/pywbemcli/test_class_cmds.py b/tests/unit/pywbemcli/test_class_cmds.py
index 282ba701..d72efa00 100644
--- a/tests/unit/pywbemcli/test_class_cmds.py
+++ b/tests/unit/pywbemcli/test_class_cmds.py
@@ -877,7 +877,7 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'general': ['--output-format', 'xml']},
      {'stdout': CIMFOO_SUB_SUB_NO_QUALS_XML,
       'test': 'linesnows'},
-     SIMPLE_MOCK_FILE, PYTHON_GE_38],  # issue 1173, Property attributs ordering
+     SIMPLE_MOCK_FILE, PYTHON_GE_38],  # issue 1173, Property attribute ordering
 
     ['Verify class command enumerate  --di --no --namespace',
      ['enumerate', '--di', '--no', '-n', 'interop'],
@@ -1284,7 +1284,7 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
 
     ['Verify class command enumerate nonexistent class name',
      ['enumerate', 'CIM_FClassDoesNotExist'],
-     {'stderr': ['CIMError', 'CIM_ERR_INVALID_CLASS'],
+     {'stderr': ['CIM_ERR_INVALID_CLASS'],
       'rc': 1,
       'test': 'regex'},
      SIMPLE_MOCK_FILE, OK],
@@ -1297,6 +1297,33 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'innows'},
      SIMPLE_MOCK_FILE, OK],
 
+    ['Verify class command enumerate invalid namespace.',
+     ['enumerate', '-n', 'blah'],
+     {'stderr': ["namespace:blah", "CIMError:CIM_ERR_INVALID_NAMESPACE",
+                 "Description:Namespace does not exist in CIM repository:",
+                 " 'blah'"],
+      'rc': 1,
+      'test': 'innows'},
+     SIMPLE_MOCK_FILE, OK],
+
+    ['Verify class command enumerate non-existent class).',
+     ['enumerate', 'InvalidClassname'],
+     {'stderr': ["namespace:root/cimv2", "CIM_ERR_INVALID_CLASS",
+                 "Description:The class 'InvalidClassname' defined by "
+                 "'ClassName' parameter does not exist in namespace "
+                 "'root/cimv2'"],
+      'rc': 1,
+      'test': 'innows'},
+     SIMPLE_MOCK_FILE, OK],
+
+    ['Verify class command enumerate non-existent svr. fails).',
+     {'args': ['enumerate'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
     #
     # Test class get
     #
@@ -1637,6 +1664,14 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'innows'},
      SIMPLE_MOCK_FILE, OK],
 
+    ['Verify class command get non-existent svr. fails).',
+     {'args': ['get', 'CIM_Foo'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
     #
     # find command
     #
@@ -2429,6 +2464,14 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'regex'},
      SIMPLE_ASSOC_MOCK_FILE, OK],
 
+    ['Verify class command references non-existent svr. fails).',
+     {'args': ['associators', 'CIM_Foo'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
     #
     # references command tests
     #
@@ -2485,7 +2528,7 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'innows'},
      SIMPLE_ASSOC_MOCK_FILE, OK],
 
-    ['Verify class command refereces table output fails).',
+    ['Verify class command references table output fails).',
      {'args': ['associators', 'TST_Person'],
       'general': ['--output-format', 'table']},
      {'stderr': ['Output format "table" ', 'not allowed', 'Only CIM formats:'],
@@ -2517,6 +2560,14 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'regex'},
      SIMPLE_ASSOC_MOCK_FILE, OK],
 
+    ['Verify class command references non-existent svr. fails).',
+     {'args': ['references', 'CIM_Foo'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
     #
     # invokemethod command tests
     #
@@ -2653,6 +2704,33 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
+    ['Verify class get from two namespaces 2nd ns no class ',
+     {'args': ['get', 'CIM_Foo', '--namespace', 'root/cimv2,interop']},
+     {'stdout': ['#pragma namespace ("root/cimv2")',
+                 'CIM_Foo {'],
+      'stderr': ["Namespace: interop", 'CIMError:CIM_ERR_NOT_FOUND'],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify class get from two namespaces first ns no class ',
+     {'args': ['get', 'CIM_Foo', '--namespace', 'interop,root/cimv2']},
+     {'stdout': ['#pragma namespace ("root/cimv2")',
+                 'CIM_Foo {'],
+      'stderr': ["Namespace: interop", 'CIMError:CIM_ERR_NOT_FOUND',
+                 "Error: Errors encountered on 1 server request(s)"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify class get from two namespaces class not in either namespace ',
+     {'args': ['get', 'CIM_Foox', '--namespace', 'root/cimv3,root/cimv2']},
+     {'stderr': ["namespace:root/cimv3", "CIMError:CIM_ERR_NOT_FOUND",
+                 "namespace:root/cimv2", "CIMError:CIM_ERR_NOT_FOUND"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
     ['Verify class enumerate from two namespaces multiple namespace option,'
      ' no classname',
      {'args': ['enumerate', '--namespace', 'root/cimv2',
@@ -2737,6 +2815,24 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
+    ['Verify class enumerate from two namespaces first ns no class ',
+     {'args': ['enumerate', 'CIM_Foo', '--namespace', 'interop,root/cimv2']},
+     {'stdout': ['#pragma namespace ("root/cimv2")',
+                 'CIM_Foo {'],
+      'stderr': ["namespace:interop", "CIMError:CIM_ERR_INVALID_NAMESPACE"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify class enumerate from two namespaces class not in either ns ',
+     {'args': ['enumerate', 'CIM_Foox', '--namespace',
+               'root/cimv3,root/cimv2']},
+     {'stderr': ["namespace:root/cimv3", "CIMError:CIM_ERR_INVALID_CLASS"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+
     #  References requests with multiple namespaces tests
 
     ['Verify class references classnames from two namespaces',
@@ -2814,6 +2910,17 @@ class CIM_FooAssoc {
       'test': 'innows'},
      THREE_NS_MOCK_FILE, FAIL],  # Fails compare of XML
 
+    ['Verify references classname (--no) from two namespaces, not in one ns',
+     {'args': ['references', 'CIM_FooRef1', '--no',
+               '--namespace', 'interop,root/cimv2'], },
+     {'stdout': """//FakedUrl:5988/root/cimv2:CIM_FooAssoc
+
+""",
+      'stderr': ["interop"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
     # Associators requests with multiple namespaces tests
 
     ['Verify associators classnames from two namespaces --names-only',
@@ -2951,11 +3058,29 @@ class CIM_FooRef2 : CIM_BaseRef {
      THREE_NS_MOCK_FILE, OK],
 
     # pylint: enable=line-too-long
+
+    ['Verify associators classnames from two namespaces --names-only',
+     {'args': ['associators', 'CIM_FooRef1', '--no',
+               '--namespace', 'root/cimv2,interop'], },
+     {'stdout': """//FakedUrl:5988/root/cimv2:CIM_FooRef2
+""",
+      'stderr': ['Error', 'interop'],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify associators classnames from two namespaces class not in either',
+     {'args': ['associators', 'CIM_FooRefX', '--no',
+               '--namespace', 'root/cimv2,root/cimv3'], },
+     {'stderr': ['Error', 'root/cimv2', 'root/cimv3', 'CIM_FooRefX'],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
 ]
 
 # TODO command class delete. Extend this test to use stdin (delete, test)
 # namespace
-# TODO: add test for  errors: class invalid, namespace invalid
 # other tests.  Test local-only on top level
 # TODO: Test class  REPR outputs
 
diff --git a/tests/unit/pywbemcli/test_general_options.py b/tests/unit/pywbemcli/test_general_options.py
index 85167f97..1f7864b9 100644
--- a/tests/unit/pywbemcli/test_general_options.py
+++ b/tests/unit/pywbemcli/test_general_options.py
@@ -930,7 +930,8 @@ class       Command group for CIM classes.
       'test': 'innows'},
      None, OK],
 
-    ['Create a server with user but no password. stdin to test for prompt',
+    ['Open non-existent server with user but no password. use stdin to test '
+     'for prompt',
      # NOTE: the class enumerate fails but is required to ask for pw
      {'general': ['--server', "http://blahblah",
                   '--user', 'john'],
diff --git a/tests/unit/pywbemcli/test_instance_cmds.py b/tests/unit/pywbemcli/test_instance_cmds.py
index de9e02a7..f1d8f8ef 100644
--- a/tests/unit/pywbemcli/test_instance_cmds.py
+++ b/tests/unit/pywbemcli/test_instance_cmds.py
@@ -1409,7 +1409,7 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
      INSTANCE_TABLE_MODEL_FILE, OK],
 
     ['Verify instance command enumerate of CIM_Foo as table returns correct '
-     'properties witho --show-null',
+     'properties with --show-null',
      {'args': ['enumerate', 'CIM_Foo', '--show-null'],
       'general': ['--output-format', 'table', '--use-pull', 'no']},
      {'stdout': """
@@ -1428,11 +1428,10 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
      INSTANCE_TABLE_MODEL_FILE, OK],
 
     ['Verify instance command enumerate of CIM_Foo as table returns correct '
-     'properties witho --show-null',
+     'properties without --show-null',
      {'args': ['enumerate', 'CIM_Foo', '--di', ],
       'general': ['--output-format', 'table', '--use-pull', 'no']},
-     {'stdout': """
-Instances: CIM_Foo
+     {'stdout': """Instances: CIM_Foo
 +-------------------+----------------------+---------------+
 | InstanceID        | cimfoo_str           | IntegerProp   |
 |-------------------+----------------------+---------------|
@@ -1447,7 +1446,7 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
      INSTANCE_TABLE_MODEL_FILE, OK],
 
     ['Verify instance command enumerate of CIM_Foo as table returns correct '
-     'properties witho --show-null',
+     'properties without --show-null',
      {'args': ['enumerate', 'CIM_Foo', '--di', '--show-null'],
       'general': ['--output-format', 'table', '--use-pull', 'no']},
      {'stdout': """
@@ -2884,8 +2883,8 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
 +----------------------------------------+--------------+
 | parent                                 | InstanceID   |
 |----------------------------------------+--------------|
-| "/root/cimv2:TST_Person.name=\\"Mike\\"" | "MikeGabi"   |
-| "/root/cimv2:TST_Person.name=\\"Mike\\"" | "MikeSofi"   |
+| "/root/cimv2:TST_Person.name=\\"Mike\\"" | "MikeGabi" |
+| "/root/cimv2:TST_Person.name=\\"Mike\\"" | "MikeSofi" |
 +----------------------------------------+--------------+
 """],
       'rc': 0,
@@ -3807,6 +3806,27 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
+
+    ['Verify instance get from two namespaces one without class',
+     {'args': ['get', 'CIM_Foo.?', '--namespace', 'root/cimv3,interop'],
+      'general': [],
+      'env': {MOCK_DEFINITION_ENVVAR: GET_TEST_PATH_STR(MOCK_PROMPT_0_FILE)}},
+     {'stdout': """#pragma namespace ("root/cimv3")
+instance of CIM_Foo {
+   InstanceID = "CIM_Foo1";
+   IntegerProp = 1;
+};
+""",
+      'stderr': ['Target: (instance) root/cimv2:CIM_Foo.InstanceID="CIM_Foo1"',
+                 'namespace:interop CIMError:CIM_ERR_INVALID_CLASS',
+                 "Description:Class 'CIM_Foo' for GetInstance of instance",
+                 "CIMInstanceName(classname='CIM_Foo', keybindings=NocaseDict(",
+                 " does not exist.",
+                 "Error: Errors encountered on 1 server request(s)"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
     ['Verify instance get from two namespaces table output',
      {'args': ['get', 'CIM_Foo', '--key', 'InstanceID=CIM_Foo1', '--namespace',
                'root/cimv2', '--namespace', 'root/cimv3'],
@@ -3939,6 +3959,14 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
+    ['Verify instnace command enumerate non-existent svr. fails).',
+     {'args': ['enumerate', 'CIM_Foo'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
     # Get instance multiple request multiple namespaces tests
 
     ['Verify instance get from two namespaces --key option',
@@ -3976,7 +4004,6 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
-
     ['Verify instance get from two namespaces pick option.',
      {'args': ['get', 'CIM_Foo.?',
                '--namespace', 'root/cimv2,root/cimv3'],
@@ -4056,14 +4083,13 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
-    ['Verify instance get from two namespaces full instance name, fail ban ns',
-     {'args': ['get', 'CIM_Foo.InstanceID="CIM_Foo1"',
-               '--namespace', 'root/cimv2,root/DoesNotExist']},
-     {'stderr': "CIMError: 3 (CIM_ERR_INVALID_NAMESPACE): Namespace does "
-                "not exist in CIM repository: 'root/DoesNotExist'",
+    ['Verify instance command get non-existent svr. fails).',
+     {'args': ['get', 'root/cimv3:CIM_Foo.InstanceID="CIM_Foo1"'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
       'rc': 1,
       'test': 'innows'},
-     THREE_NS_MOCK_FILE, OK],
+     None, OK],
 
     # instance references request multiple namespaces
 
@@ -4185,6 +4211,13 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
+    ['Verify instance command references non-existent svr. fails).',
+     {'args': ['references', 'CIM_FooRef1', '--key', 'InstanceID=CIM_FooRef11'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
 
     # instance associators request
 
@@ -4260,10 +4293,130 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
 """,
       'rc': 0,
       'test': 'innows'},
-     THREE_NS_MOCK_FILE, RUN],
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify instance command associators non-existent svr. fails).',
+     {'args': ['associators', 'CIM_FooRef1', '--key',
+               'InstanceID=CIM_FooRef11'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
+    ['Verify instance enumerate from two namespaces, CIM_Foo one ns bad',
+     {'args': ['enumerate', 'CIM_Foo', '--namespace', 'root/cimv2,root/INV']},
+     {'stderr': ['namespace:root/INV', 'CIMError:CIM_ERR_INVALID_NAMESPACE'],
+      'stdout': ['#pragma namespace ("root/cimv2")',
+                 "instance of CIM_Foo {",
+                 'InstanceID = "CIM_Foo1";',
+                 'IntegerProp = 1;'],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify instance enumerate from one namespace, ns bad',
+     {'args': ['enumerate', 'CIM_Foo', '--namespace', 'root/INV']},
+     {'stderr': ["namespace:root/INV", "CIMError:CIM_ERR_INVALID_NAMESPACE",
+                 "CIMError: 3 (CIM_ERR_INVALID_NAMESPACE):"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify instance enumerate from two namespaces, Invalid Classname',
+     {'args': ['enumerate', 'CIM_Foox', '--namespace',
+               'root/cimv2,root/cimv3']},
+     {'stderr': ["namespace:root/cimv2", "CIMError:CIM_ERR_INVALID_CLASS",
+                 "namespace:root/cimv3"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify instance enumerate from two namespaces --summary, table. ns bad ',
+     {'args': ['enumerate', 'CIM_Foo', '--summary',
+               '--namespace', 'root/cimv2,root/INV'],
+      'general': ['--output-format', 'table']},
+     {'stdout': """Summary of CIMInstance(s) returned
++-------------+---------+-------------+
+| Namespace   |   Count | CIM Type    |
+|-------------+---------+-------------|
+| root/cimv2  |      12 | CIMInstance |
+| root/INV    |       0 | CIMInstance |
++-------------+---------+-------------+
+""",
+      'stderr': ["namespace:root/INV", "CIM_ERR_INVALID_NAMESPACE"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify instance get from two namespaces full instance name, one bad ns',
+     {'args': ['get', 'CIM_Foo.InstanceID="CIM_Foo1"',
+               '--namespace', 'root/cimv2,root/DoesNotExist']},
+     {'stdout': ['#pragma namespace ("root/cimv2")',
+                 "instance of CIM_Foo {",
+                 'InstanceID = "CIM_Foo1";',
+                 "IntegerProp = 1;",
+                 "};"],
+      'stderr': ["namespace:root/DoesNotExist"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify instance get from one namespace, invalid namespace',
+     {'args': ['get', 'CIM_Foo', '--key', 'InstanceID=CIM_Foo1',
+               '--namespace', 'root/InvalidNamespace']},
+     {'stderr': ['CIMError: 3 (CIM_ERR_INVALID_NAMESPACE):',
+                 "'root/InvalidNamespace'"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    ['Verify instance get from two namespaces, invalid instance',
+     {'args': ['get', 'CIM_Foo', '--key', 'InstanceID=INVALID',
+               '--namespace', 'root/cimv2,root/cimv3']},
+     {'stderr': ["namespace:root/cimv2", "CIMError:CIM_ERR_NOT_FOUND",
+                 "namespace:root/cimv3", "CIMError:CIM_ERR_NOT_FOUND",
+                 "CIMError: 6 (CIM_ERR_NOT_FOUND):"],
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+
+    # pylint: disable=line-too-long
+    ['Verify associators names-only non-default namespaces -o table, invalid '
+     'ns',
+     {'args': ['associators', 'CIM_FooRef1', '--key', 'InstanceID=CIM_FooRef11',
+               '--no', '--namespace', 'root/cimv3,root/Invalid'],
+      'general': ['--output-format', 'table']},
+     {'stdout': """InstanceNames: CIM_FooRef2
++---------------+-------------+-------------+--------------+
+| host          | namespace   | class       | key=         |
+|               |             |             | InstanceID   |
+|---------------+-------------+-------------+--------------|
+| FakedUrl:5988 | root/cimv3  | CIM_FooRef2 | CIM_FooRef21 |
++---------------+-------------+-------------+--------------+
+""",
+      'stderr': """Request Response Errors for Target: (class) root/Invalid:CIM_FooRef1.InstanceID="CIM_FooRef11"
++--------------+---------------------------+------------------------------------------------------------+
+| namespace    | CIMError                  | Description                                                |
+|--------------+---------------------------+------------------------------------------------------------|
+| root/Invalid | CIM_ERR_INVALID_NAMESPACE | Namespace does not exist in CIM repository: 'root/Invalid' |
++--------------+---------------------------+------------------------------------------------------------+
+Error: Errors encountered on 1 server request(s)
+""", # noqa E501
+      'rc': 1,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
+    # pylint: enable=line-too-long
 
     # Test multi-namespace enum/get where there are no instances returned
 
+    # Add tests for multiple-ns Enumerate, get, References, Associators where
+    # for both table and mof output.
+    # 1. one of the targets (class, instancename) is invalid
+    # 2. One of multiple namespaces does not exist
+    # 3. The only target is invalid
+    # 4. The only namespace is invalid
+
 
     # TODO test results if we have keys that get hidden.  This will require
     # a more complex model with CreationClassName, etc. in paths.
diff --git a/tests/unit/pywbemcli/test_qualdecl_cmds.py b/tests/unit/pywbemcli/test_qualdecl_cmds.py
index 5230136b..e691af2e 100644
--- a/tests/unit/pywbemcli/test_qualdecl_cmds.py
+++ b/tests/unit/pywbemcli/test_qualdecl_cmds.py
@@ -485,7 +485,7 @@
 
     ['Verify qualifier command get invalid qual decl name .',
      ['get', 'NoSuchQualDecl'],
-     {'stderr': ["Error: CIMError: 6"],
+     {'stderr': ["namespace:root/cimv2", "CIMError:CIM_ERR_NOT_FOUND"],
       'rc': 1,
       'test': 'in'},
      SIMPLE_MOCK_FILE, OK],
@@ -551,7 +551,7 @@
 
     ['Verify qualifier command enumerate invalid namespace Fails',
      ['enumerate', '--namespace', 'root/blah'],
-     {'stderr': ["Error: CIMError: 3", "CIM_ERR_INVALID_NAMESPACE"],
+     {'stderr': ["namespace:root/blah", "CIMError:CIM_ERR_INVALID_NAMESPACE"],
       'rc': 1,
       'test': 'innows'},
      SIMPLE_MOCK_FILE, OK],
@@ -625,6 +625,14 @@
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
+    ['Verify qualifier command enumerate non-existent svr. fails).',
+     {'args': ['enumerate'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
     ['Verify qualifier command get table, multiple ns',
      {'args': ['get', 'Abstract', '--namespace', 'root/cimv2,root/cimv3'],
       'general': ['-o', 'table']},
@@ -644,8 +652,11 @@
     ['Verify qualifier command get MOF out, multiple ns only in one ns',
      {'args': ['get', 'EmbeddedObject', '--namespace', 'root/cimv2,interop'],
       'general': []},
-     {'stderr': "CIMError: 6 (CIM_ERR_NOT_FOUND): Qualifier declaration "
-                "'EmbeddedObject' not found in namespace 'interop'.",
+     {'stdout': ['#pragma namespace ("root/cimv2")',
+                 'Qualifier EmbeddedObject : boolean = false,'],
+      'stderr': ["namespace:interop", "error:CIM_ERR_NOT_FOUND",
+                 "Description:Qualifier declaration 'EmbeddedObject' not "
+                 "found in namespace 'interop'"],
       'rc': 1,
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
@@ -653,11 +664,21 @@
     ['Verify qualifier command get MOF out, multiple ns not found',
      {'args': ['get', 'Invalid_QD', '--namespace', 'root/cimv2,root/cimv3'],
       'general': []},
-     {'stderr': "CIMError: 6 (CIM_ERR_NOT_FOUND): Qualifier "
-                "declaration 'Invalid_QD' not found in namespace 'root/cimv2'.",
+     {'stderr': ["namespace:root/cimv2", "CIMError:CIM_ERR_NOT_FOUND",
+                 "Description:Qualifier declaration 'Invalid_QD' not found in "
+                 "namespace 'root/cimv2'", "namespace:root/cimv3"],
       'rc': 1,
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
+
+    ['Verify qualifier get non-existent svr. fails).',
+     {'args': ['get', 'EmbeddedObject'],
+      'general': ['--server', 'http://NotAValidServer']},
+     {'stderr': ["Error: ConnectionError:"],
+      'rc': 1,
+      'test': 'innows'},
+     None, OK],
+
 ]