diff --git a/cli/cli.py b/cli/cli.py
new file mode 100755
index 0000000..e6987af
--- /dev/null
+++ b/cli/cli.py
@@ -0,0 +1,7879 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2010,2011,2012,2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+
+#  sdnsh - The Controller Shell
+# --------------------------------------------------------------------------------
+#
+# LOOK! TODO --
+#
+# create tokens for modify actions in StaticFlowEntryPusher and here
+#
+# extend completion to show help text
+#
+# need to verify we can talk to the controller
+#
+# flow-entry naming - unique across all switches?
+#
+# joins on show commands (port names, ids, etc.)
+#
+# accept enums in addition to numbers - "ether-type arp" or "ether-type ip"
+#
+# cli commands not mapping to database model (this is an -undo-)
+#
+# simple options/singletons in the CLI ("logging level 5" "twitter username blah")
+#
+# csv, left/right justification in columns, sorts
+#
+# completion with multi command lines
+#
+# disallow 'switch' field and name as options flow-entry ('key' fields in general)
+#
+# delayed commit semantics (depends on 1?)
+#
+# delete config files?
+#
+# --------------------------------------------------------------------------------
+#
+# Notes:
+#
+#  support functions for a command, consider, for example, 'vns-definition'
+#
+#   For a new command, for example 'vns-definition', there will be a variety
+#   of different support functions to manage different required functionaly.
+#   do_vns_definition() describes what to do to execute the actual command.
+#   cp_vns_definition() describes how to perform command completion for the same.
+#   do_show_vns_definition() would describe how to show the vns-definitions
+#     (this procedure doesn't exist, but is implemented by 'show vns' via
+#     do_show_vns), while
+#   cp_show_vns_definition() would describe how to complete the show command for
+#   this particular command.  Other functions may also be needed, for example
+#   specialized changes to the 'no' command for the same command.
+#
+#  command completion
+#
+#   currently in many cases, there's a specialized completion handler
+#   it would make sense to manage 'no' completion by overloading the
+#   same completion handler.
+#
+#
+#  error processing:
+#
+#   Keep in mond that al errors ought to use a similar prefix so that
+#   all the error conditions acan be identifyed by the automated test
+#   procedures.  these prefixes are regular expressions in bigtest/cli.py
+#   The prefixed currently recognized as errors are 'Error: Not Found",
+#   'Error running command ', 'Syntax error:', and 'Syntax: ' the last
+#   of which is used to display both usage for some commands, and 
+#   various specific syntax errors
+#
+#  alias management:
+#
+#   Aliases are managed by having a separate table/model for each
+#   of the aliases, for example the host table has an associated alias
+#   table called 'host-alias'.  These alias models are nothing more
+#   than an id, which is the alias name and a foreign key for the other
+#   table, in the 'host-alias' model, the associated foreign key would 
+#   point to the host.
+#   
+#   Alias tables or models are not directly configured as alias tables,
+#   the cli can find these tables by noticing the only fields within
+#   the model is a foreign key for another table.   The cli builds the
+#   alias_obj_type_xref dictionary during initialization, and later uses
+#   that association to manage aliases.   Knowing which of the tables
+#   are alias tables also allows the cli to exclude these tables from
+#   modification in typical config mode.
+#
+#   Alias are created when within the submode for a particular obj_type,
+#   for example, the host-alias table is available within the host
+#   config submode, and it appears as the 'host-alias' table there.
+#   However no further submode for the host-alias is managed; it is
+#   treated as if it were a field in the submode config object.
+#   So if 'host-alias xxx' were entered while in host config submode,
+#   the cli converts the request into a host-alias table entry.
+#
+#   Feature management.  The cli is intended to manage the availability
+#   of specific feature groups.  This isn't meant to prevent a user from
+#   getting at specific sku features (ie: licensing), but instead meant
+#   to allow a user to disable specific sub-groups of commands to 
+#   prevent unintended enabling of features.  For example,
+#   to prevent a 'static-flow' cli configured controller from enabling
+#   vns features likely resulting in a misconfigured environment.
+#
+#  changes:
+#
+#   -- new source field for obj_types in models, obj_types which are
+#      written based on discovered details are typically not editable.
+#      don't allow a config submode entry. and don't
+#      advertise such an entry is possible
+#
+#   -- integrated alias support, no special cases through the use
+#      of a separated alias tables.  this allows more integrated
+#      cli support for tables specifically constructed to manage
+#      alias names for other fields.   Currently code in the cli
+#      prevents multiple alias for a single foreign key, but this
+#      behavior can be relaxed (perhaps it ought to be configurable?)
+#
+#   -- perform alias substitution for 'no' commands obj_type's
+#
+#   -- support for primary key/id changes within a row.
+#      if an update occurs which modifies the primary key of a row,
+#      the cli now identifies whether any foreign keys point at
+#      the existing entry, and updates the foreign key to reference
+#      the updated primary key.
+#
+#   -- support for cascaded delete.
+#      when a row is deleted, if there are foreign keys associated
+#      with the row, the cli will remove them.  the climodelinfo
+#      configures which obj_types are included in the cascade deletes.
+#
+#   -- vns interface creation.
+#      vns interfaces are required to have a vns-interface-rule associated.
+#      sdnplatform writes both the interface name and the rule, but the cli needed
+#      to have code added to determine and validate the associated rule.
+#      The validation attempts to ensure the correct rule is associated with
+#      the use of the interface name (id).
+#
+
+import subprocess
+import os, atexit, stat
+import sys, traceback                   # traceback.print_exc()
+from optparse import OptionParser
+from types import StringType
+import collections
+import datetime
+import json
+import re
+import time
+import urllib2
+import httplib                          # provides error processing for isinstance
+import socket
+import select
+import fcntl
+import posixpath
+import random
+import copy
+import utif
+import fmtcnv
+import run_config
+import imp
+import locale
+
+from pkg_resources import resource_filename
+from modi import Modi
+from midw import *
+from vnsw import *
+from prettyprint import PrettyPrinter
+from storeclient import StoreClient
+from climodelinfo import CliModelInfo
+from vendor import VendorDB
+import error
+import command
+import rest_to_model
+import tech_support
+import url_cache
+import doc
+import sdndb
+
+#
+# --------------------------------------------------------------------------------
+# 
+
+class ParamException(Exception):
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return repr(self.value)
+
+class TooManyVNSException(Exception):
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return repr(self.value)
+
+TIMESTAMP_HELP = \
+    ('Enter an integer timestamp in milliseconds since the epoch or formatted\n' +
+     'as one of the following options in your local timezone:\n'
+     '"YYYY-MM-DD HH:MM:SS"      YYYY-MM-DDTHH:MM:SS\n' + 
+     '"YYYY-MM-DD HH:MM:SS+TTT"  YYYY-MM-DDTHH:MM:SS+TTT\n' +
+     'YYYY-MM-DD                 MM-DD\n' + 
+     'HH:MM                      now')
+
+
+# This is a bit of a hack. The completion and validation functions for time zones
+# are static methods, but they need to access the SDNSh object to get at the
+# controller field to be able to do a REST call to load the list of time zone
+# strings. So we set up a global for the single SDNSh instance we have. An
+# alternative would have been to have a global variable for the list of time
+# zone strings that's initialized when the CLI is initialized, but it seems
+# nicer to only load it on demand, especially since setting the time zone
+# will be a pretty infrequently invoked command.
+cli = None
+
+#
+# Constants for packet tracing
+#
+SESSIONID = 'sessionId'
+FT_VNS = 'vns'
+FT_PORT = 'port'
+FT_PORT_DPID = 'dpid'
+FT_PORT_PORT = 'port'
+FT_OUTPUT = 'output'
+FT_DIRECTION = 'direction'
+FT_PERIOD = 'period'
+FT_TIMEOUT = "FilterTimeout"
+FT_PERIOD_DEFAULT = 300
+
+onos=1
+#
+# --------------------------------------------------------------------------------
+# 
+class NotFound(Exception):
+    def __init__(self, obj_type, name):
+        self.obj_type = obj_type
+        self.name = name
+    def __str__(self):
+        return "Not Found: %s %s" % (self.obj_type, self.name)
+
+
+# LOOK!: The next two functions are copied from the sdncon code.
+# Should ideally figure out a way to share the code for utility
+# functions like this.
+
+def dotted_decimal_to_int(ip):
+    """
+    Converts a dotted decimal IP address string to a 32 bit integer
+    """
+    bytes = ip.split('.')
+    ip_int = 0
+    for b in bytes:
+        ip_int = (ip_int << 8) + int(b)
+    return ip_int
+    
+
+def same_subnet(ip1, ip2, netmask):
+    """
+    Checks whether the two ip addresses are on the same subnet as
+    determined by the netmask argument. All of the arguments are
+    dotted decimal IP address strings.
+    """
+    ip1_int = dotted_decimal_to_int(ip1)
+    ip2_int = dotted_decimal_to_int(ip2)
+    netmask_int = dotted_decimal_to_int(netmask)
+    return (ip1_int & netmask_int) == (ip2_int & netmask_int)
+
+#
+# --------------------------------------------------------------------------------
+# 
+
+class SDNSh():
+
+    debug = False               # general cli debugging
+    debug_backtrace = False     # backtrace on failures
+    description = False         # help debug command descriptions
+    display_rest = False        # display rest call details
+    display_reply_rest = False  # display rest call replies details
+
+    command_dict = {}
+    mode_stack = []
+    reserved_words = ['unknown', 'all']
+
+    known_controllers = ["127.0.0.1:8000"]
+    controller = None
+    # LOOK! manage this separately until we can cetainly
+    #       talk to eth0 addr instead of 127.0.0.1
+    controller_for_prompt = "127.0.0.1:8000"
+    cluster = "default"
+
+    run = True
+
+    # Are we running in batch mode, i.e. "cat commands | cli"
+    batch = False
+
+    # used for parsing as an arg
+    local_name_pattern = "config://([A-Za-z0-9_:@\-\.\/]+$)"
+
+    # name of boot/startup-config
+    boot_config_filename = '/opt/sdnplatform/run/boot-config'
+    saved_configs_dirname = '/opt/sdnplatform/run/saved-configs/'
+    feature_allow_experimental = '/opt/sdnplatform/feature/experimental'
+
+    # contained objects
+    pp = None
+    store = None
+    model_handler = None
+
+    # cached metadata
+    stats_metadata = None
+    stats_type_metadata = None
+    stats_restapi_map = {'controller-node': 'controller'}
+
+    stats_optional_params = {
+        'start-time': {'type': 'string',
+                       'syntax_help': TIMESTAMP_HELP},
+        'end-time': {'type': 'string',
+                     'syntax_help': TIMESTAMP_HELP},
+        'duration': {'type': 'string',
+                     'syntax_help': 
+                     "Enter an integer followed by a time unit\n" +
+                     "[integer]weeks  [integer]days  [integer]hours\n" +
+                     "[integer]mins   [integer]secs  [integer]ms"},
+        'sample-interval': {'type': 'int',
+                            'syntax_help': 'Enter an integer number of milliseconds'},
+        'sample-count': {'type': 'int',
+                         'syntax_help': 'Enter an integer target sample count'},
+        'sample-window': {'type': 'string',
+                          'syntax_help': 'Enter an integer number of milliseconds for sampling window'},
+        'data-format': {'type': 'enum', 'values': ['value', 'rate']},
+        'display': {'type': 'enum', 'values': ['latest-value', 'graph', 'table']},
+        #'limit': {'type': 'int'}
+        }
+
+    netvirt_feature_enabled_cached = False
+    warning_suppress = False            #
+
+    #
+    # --------------------------------------------------------------------------------
+    # warning
+    #  When a config is getting replayed, warnings are suporessed.  Other situations
+    #  may also require supression of warnings.
+    #
+    def warning(self, message):
+        if not self.warning_suppress:
+            print "Warning: %s" % message
+    
+    #
+    # --------------------------------------------------------------------------------
+    # supress_warnings(self)
+    #
+    def suppress_warnings(self):
+        self.warning_suppress = True
+
+    #
+    # --------------------------------------------------------------------------------
+    # enable_warnings(self)
+    #
+    def enable_warnings(self):
+        self.warning_suppress = False
+
+
+    config_replay = False               # only true while replaying config files
+    #
+    # --------------------------------------------------------------------------------
+    # config_replay_start
+    #  Behavior is different during config replay.  Warnings are
+    #  suppressed, and other error conditions may be relaxed, for example
+    #  the switch submode interface command requires that the interface exist,
+    #  and the interface names are discovered by sdnplatform, which means that during
+    #  config replay for statup, an unknown-named-interface may need to be accepted
+    #  since that interface may appear once the switch connected to sdnplatform, and
+    #  sdnplatform writes the ports for this switch.
+    #
+    def config_replay_start(self):
+        self.suppress_warnings()
+        self.config_replay = True
+    
+    #
+    # --------------------------------------------------------------------------------
+    # config_replay_done
+    #
+    def config_replay_done(self):
+        self.enable_warnings()
+        self.config_replay = False
+
+    #
+    # --------------------------------------------------------------------------------
+    # config_replay_active
+    #  Returns true when a configuration is getting replayed
+    #
+    def config_replay_active(self):
+        return self.config_replay
+
+    #
+    # --------------------------------------------------------------------------------
+    # note
+    #  When a config is getting replayed, warnings/notes are suporessed.  Other situations
+    #  may also require supression of warnings.
+    #
+    def note(self, message):
+        if not self.warning_suppress:
+            print "Note: %s" % message
+
+    #
+    # --------------------------------------------------------------------------------
+    # debug_msg
+    #  Debugging message cover.  Only enabled for display once 'debug cli' is performed.
+    #
+    def debug_msg(self, message):
+        if self.debug:
+            print "debug_msg: %s" % message
+            
+    #
+    # --------------------------------------------------------------------------------
+    # error_msg
+    #  Error message cover, to ensure consistent error messages
+    #
+    @staticmethod
+    def error_msg(message):
+        return "Error: %s" % message
+
+    #
+    # --------------------------------------------------------------------------------
+    # syntax_msg
+    #  Syntax error message cover, to ensure consistent error messages
+    #
+    @staticmethod
+    def syntax_msg(message):
+        return "Syntax: %s" % message 
+
+    #
+    # --------------------------------------------------------------------------------
+    # completion_error_msg
+    #  Error message cover during completion, to ensure consistent error messages
+    #
+    def completion_error_msg(self, message):
+        self.print_completion_help("Error: %s" % message)
+
+    #
+    # --------------------------------------------------------------------------------
+    # completion_syntax_msg
+    #  Syntax error message cover during completion, to ensure consistent error messages
+    #
+    def completion_syntax_msg(self, message):
+        self.print_completion_help("Syntax: %s" % message)
+
+    #
+    # --------------------------------------------------------------------------------
+    # init_history_file
+    #
+    def init_history_file(self):
+        history_file = os.path.join(os.environ["HOME"], ".sdnsh_history")
+        # create the initial history file group-writable,
+        # so that the tacacs users can write to it
+        if os.path.exists(history_file):
+            st = os.stat(history_file)
+            if not (st[stat.ST_MODE] & stat.S_IWGRP):
+                buf = open(history_file).read()
+                os.rename(history_file, history_file + "~")
+                mask = os.umask(007)
+                fno = os.open(history_file, os.O_WRONLY | os.O_CREAT, 0660)
+                os.umask(mask)
+                os.write(fno, buf)
+                os.close(fno)
+        else:
+            mask = os.umask(007)
+            fno = os.open(history_file, os.O_WRONLY | os.O_CREAT, 0660)
+            os.umask(mask)
+            os.close(fno)
+        try:
+            readline.read_history_file(history_file)
+        except IOError:
+            pass
+        atexit.register(readline.write_history_file, history_file)
+    
+    #
+    # --------------------------------------------------------------------------------
+    # init_command_dict
+    #
+    def init_command_dict(self):
+
+        #
+        # command_submode_dict saves a little information about
+        # submode commands.  The index is 'mode', and the resulting
+        # list contains strings, each of which is a submode command
+        # available in that mode.
+        self.command_submode_dict = {}
+
+        #
+        # associate command names with features, so that when
+        # help is provided, command names which have associated
+        # features are validated to determine whether the feature
+        # is enabled or not.
+        self.command_name_feature = {}
+
+        #
+        # command_nested_dict is indexed by mode, and contains
+        # command configured with a trailing '*', for example
+        # 'mode' : 'config-*', intended to mean "all nested
+        # submodes after config-'.  This can't be computed until
+        # all submodes are known, which means all the command
+        # describption must be configured., for these to make sense.
+        self.command_nested_dict = {}
+
+        #
+        # config mode commands
+        #
+        #self.command_dict['config'] = [ "boot" ]
+
+        #
+        # commands which start at 'login'
+        #
+        if onos == 0:
+            self.command_nested_dict['login'] = [ 'show', 'logout', 'exit',
+                                              'history', 'help', 'echo',
+                                              'date', 'trace', 'traceroute',
+                                              'ping', 'test', 'version',
+                                              'connect', 'watch', 'no' ]
+        else:
+            self.command_nested_dict['login'] = [ 'show', 'logout', 'exit',
+                                              'history', 'help', 'echo',
+                                              'date', 'trace',
+                                              'ping', 'test', 'version',
+                                              'connect', 'watch', 'no' ]
+
+        self.command_nested_dict['enable'] = [ 'clear', 'end' ]
+
+        #self.command_dict['config-internal'] = ['lint', 'permute']
+
+    #
+    # --------------------------------------------------------------------------------
+    # make_unit_formatter
+    #
+    @staticmethod
+    def make_unit_formatter(units):
+        return lambda x, y: '%s %s' % (x, units)
+
+    #
+    # --------------------------------------------------------------------------------
+    # init_stats_metadata
+    #
+    def init_stats_metadata(self):
+        # Initialize the stats metadata by pulling it from the rest api
+        json_data = self.rest_simple_request_to_dict('http://%s/rest/v1/stats/metadata/%s/' % \
+                                                     (self.controller, self.cluster))
+        metadata = {}
+        fields = {}
+        for item in json_data:
+            # XXX Requesting this stat causes a long delay in reading; bug in sdncon
+            # once this is fixed we can add back in; also add to field_orderings below
+            #if json_data[item]['name'] == 'OFActiveFlow':
+            #    continue
+
+            if json_data[item]['target_type'] in metadata:
+                metadata[json_data[item]['target_type']].append(json_data[item])
+            else:
+                metadata[json_data[item]['target_type']] = [json_data[item]]
+                fields[json_data[item]['target_type']] = {}
+
+            formatter = self.make_unit_formatter(json_data[item]['units'])
+            fields[json_data[item]['target_type']][json_data[item]['name']] = \
+                {'verbose-name': json_data[item]['verbose_name'],
+                 'units': json_data[item]['units'],
+                 'formatter': formatter}
+
+        self.stats_metadata = json_data
+        self.stats_type_metadata = metadata
+
+        self.pp.add_format('STATS-CONTROLLER',
+                           'cli.init_stats_metadata()', # origina
+                           {'stats-controller' : {
+                'field-orderings' : {'default': 
+                                     ['cpu-user', 'cpu-nice', 'cpu-system', 
+                                      'cpu-idle'
+                                      'mem-free', 'mem-used', 'swap-used',
+                                      'disk-root', 'disk-log', 'disk-boot',
+                                      'sdnplatform-cpu', 'database-cpu', 
+                                      'apache-cpu', 'cli-cpu', 'statd-cpu']},
+                'fields' : fields['controller']
+                }})
+
+        self.pp.add_format('STATS-SWITCH',
+                           'cli.init_stats_metadata()', # origina
+                           { 'stats-switch' : {
+                'field-orderings' : {'default': 
+                                     ['OFPacketIn', 'OFFlowMod', 'OFActiveFlow']},
+                'fields' : fields['switch']
+                }})
+                           
+        for obj_type in fields:
+            for field in fields[obj_type]:
+                for data_format in ['rate', 'value']:
+                    units = fields[obj_type][field]['units']
+                    if data_format == 'rate':
+                        units += '/s'
+                    self.pp.add_format('STATS-%s-%s-%s' % (obj_type,field,data_format), 
+                                       'cli.init_stats_metadata()',
+                            { 'stats-%s-%s-%s' % (obj_type,field,data_format) : { \
+                            'field-orderings' : {'default': ['value', 'timestamp']},
+                            'fields' : {'timestamp': {'verbose-name': 'Timestamp',
+                                                      'formatter': 
+                                                      lambda x,y: time.ctime(x/1000)},
+                                        'value': {'units': units,
+                                                  'verbose-name': 
+                                                  '%s (%s)' % 
+                                                  (fields[obj_type][field]['verbose-name'],
+                                                   units)}}
+                            }})
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def command_packages_path(self):
+        command_descriptions = 'desc'
+        desc_path = resource_filename(__name__, command_descriptions)
+        if desc_path:
+            # print "desc_path %s" % desc_path
+            return desc_path
+        desc_path = os.path.join(os.path.dirname(__file__), command_descriptions)
+        if os.path.exists(desc_path):
+            return desc_path
+        return None
+
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def command_packages_exists(self, version):
+        desc_path = self.command_packages_path()
+        if desc_path == None:
+            return None
+        version_path = os.path.join(desc_path, version)
+        if os.path.exists(version_path):
+            return version_path
+        return None
+
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def add_command_packages(self, version):
+        """
+        Add all command and output format components
+
+        """
+        desc_path = self.command_packages_path()
+        if desc_path == None:
+            print 'No Command Descriptions subdirectory'
+            return
+
+        for path_version in [x for x in os.listdir(desc_path) if x.startswith(version)]:
+            print path_version
+            result_tuple = imp.find_module(path_version, [desc_path])
+            imp.load_module(version, result_tuple[0], result_tuple[1], result_tuple[2])
+            new_path = result_tuple[1]
+            cmds_imported = []
+            for cmds in os.listdir(new_path):
+                (prefix, suffix) = os.path.splitext(cmds)
+                if (suffix == '.py' or suffix == '.pyc') and prefix not in cmds_imported and prefix != '__init__':
+                    cmds_imported.append(prefix)
+                    result_tuple = imp.find_module(prefix, [new_path])
+                    module = imp.load_module(prefix, result_tuple[0], result_tuple[1], result_tuple[2])
+                    command.add_commands_from_module(version, module, self.dump_syntax)
+                    self.pp.add_formats_from_module(version, module)
+            # print cmds_imported
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def choices_text_builder(self, matches, max_len = None, col_width = None):
+        """
+        @param max_len integer, describes max width of any entry in matches
+        @param col_width integer, colun width
+        """
+        # Sort the choices alphabetically, but if the token ends
+        # in a number, sort that number numerically.
+        try:
+            entries = sorted(matches, utif.completion_trailing_integer_cmp)
+        except Exception, e:
+            traceback.print_exc()
+
+        if col_width == None:
+            # request to look it up
+            (col_width, line_length) = self.pp.get_terminal_size()
+            col_width = min(120, col_width)
+
+        if max_len == None:
+            # request to compute the max length
+            max_len = len(max(matches, key=len))
+
+        count = len(matches)
+        max_len += 1 # space after each choice
+        if max_len > col_width:
+            # one per line?
+            pass
+        else:
+            per_line = col_width / max_len
+            lines = (count + (per_line - 1)) / per_line
+            if lines == 1:
+                return ''.join(['%-*s' % (max_len, m) for m in entries])
+            else:
+                # fill the columns, which means skipping around the entries
+                result = []
+                for l in range(lines):
+                    result.append(['%-*s' % (max_len, entries[i])
+                                   for i in range(l, count, lines)])
+                lines = [''.join(x) for x in result]
+                return '\n'.join(lines)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def matches_hook(self, subs, matches, max_len):
+
+        # one shot disabler, used to disable printing of completion
+        # help for two-column help display (for '?' character). 
+        # completion printing here can only display the possible selections,
+        # for two-column mode, the reason why each keyword was added
+        # needs to be displayed, which is no longer available here.
+        if self.completion_print == False:
+            self.completion_print = True
+            return
+        
+        choices_text = self.choices_text_builder(matches, max_len)
+        self.print_completion_help(choices_text)
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def pre_input_hook(self):
+        """
+        """
+        pass
+
+    
+    #
+    # --------------------------------------------------------------------------------
+    # 
+    def desc_version_to_path_elem(self, version):
+        """
+        Version numbers like 1.0 need to be converted to the path
+        element associated with the number, like version100
+        """
+        try:
+            version_number = float(version)
+            version = 'version%s' % int(version_number * 100)
+        except:
+            pass
+
+        # temporary, use until version100 exists.
+        if version == 'version100' and not self.command_packages_exists(version):
+            version = 'version200'
+
+        return version
+        
+
+    #
+    # --------------------------------------------------------------------------------
+    # init
+    #
+    def init(self):
+        global mi
+        
+        self.completion_print = True
+        self.vendordb = VendorDB()
+        self.vendordb.init()
+
+        parser = OptionParser()
+        parser.add_option("-c", "--controller", dest="controller",
+                          help="set default controller to CONTROLLER", 
+                          metavar="CONTROLLER", default=self.controller)
+        parser.add_option("-S", "--syntax", dest='dump_syntax',
+                          help="display syntax of loaded commands",
+                          action='store_true', default=False)
+        parser.add_option("-i", "--init", dest='init',
+                          help="do not perform initialization checks",
+                          action='store_true', default=False)
+        parser.add_option("-d", "--debug", dest='debug',
+                          help='enable debug for cli (debug cli)',
+                          action='store_true', default=False)
+        parser.add_option("-v", "--version", dest='desc_version',
+                          help='select command versions (description group)',
+                          default=None)
+        parser.add_option('-m', "--mode", dest='starting_mode',
+                          help='once the cli starts, nest into this mode')
+        parser.add_option('-q', "--quiet", dest='quiet',
+                          help='suppress warning messages',
+                          action='store_true', default=False)
+        (self.options, self.args) = parser.parse_args()
+        self.controller = self.options.controller
+        if not self.controller:
+            self.controller = "127.0.0.1:8000"
+        self.dump_syntax = self.options.dump_syntax
+        if not self.dump_syntax:
+            self.dump_syntax = False
+        self.debug = self.options.debug
+
+        # command option, then env, then default
+        self.desc_version = self.options.desc_version
+        if self.desc_version == None:
+            self.desc_version = os.getenv('CLI_COMMAND_VERSION')
+        if self.desc_version == None:
+            self.desc_version = '2.0'   # 'version200'
+
+        if self.desc_version:
+            self.desc_version = self.desc_version_to_path_elem(self.desc_version)
+
+        self.length = 0 # screen length.
+
+        self.set_controller_for_prompt()
+
+        if not sys.stdin.isatty():
+            self.batch = True
+
+        self.store = StoreClient()
+        self.store.set_controller(self.controller)
+
+        mi = Modi(self, CliModelInfo())
+        self.mi = mi
+        self.init_command_dict()
+
+        self.completion_reset()
+        self.completion_skip = False
+        self.completion_cache = True
+        readline.set_completer(self.completer)
+        readline.set_completer_delims("\t ")
+        # readline.set_pre_input_hook(self.pre_input_hook)
+        readline.set_completion_display_matches_hook(self.matches_hook)
+        if not self.batch:
+            self.init_history_file()
+        self.push_mode("login")
+
+        # starting mode, 
+        starting_mode = self.options.starting_mode
+        if starting_mode == None:
+            starting_mode = os.getenv('CLI_STARTING_MODE')
+
+        if starting_mode:
+            if starting_mode == 'login':
+                pass
+            elif starting_mode == 'enable':
+                self.push_mode("enable")
+            elif starting_mode == 'config':
+                self.push_mode("enable")
+                self.push_mode("config")
+            else:
+                print 'Only login, enable or config allowed as starting modes'
+
+        # process quiet option
+        quiet = self.options.quiet
+        if quiet == None:
+            quiet = os.getenv('CLI_SUPPRESS_WARNING')
+
+        if quiet:
+            self.supress_warnings()
+
+        #
+        self.pp = PrettyPrinter(self)
+
+        #
+        # pattern matches
+        #
+        self.IP_ADDR_RE = re.compile(r'^(\d{1,3}\.){3}\d{1,3}$')
+        self.CIDR_RE = re.compile(r'^((\d{1,3}\.){3}\d{1,3})/(\d{1,2}?)$')
+        self.MAC_RE = re.compile(r'^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$')
+        self.DPID_RE = re.compile(r'^(([A-Fa-f\d]){2}:?){7}[A-Fa-f\d]{2}$')
+        self.ACL_RE = re.compile(r'^\d+$')  # just the leading digits
+        self.DIGITS_RE = re.compile(r'^\d+$')
+        self.HEX_RE = re.compile(r'^0x[0-9a-fA-F]+$')
+
+        # Initialize any middleware layers
+        init_midware(self, mi)
+        init_vnsw(self, mi)
+        rest_to_model.rest_to_model_init(self, mi)
+        run_config.init_running_config(self, mi)
+
+        # Initialize all doc tags, use a subdirectory based on
+        # the locale.   This may be incorect if there's nothing
+        # in the configured locale for the returned locale value.
+        lc = locale.getdefaultlocale()
+        if lc == None or lc[0] == None:
+            print 'Locale not configured ', lc
+            lc = ('en_US', 'UTF8')
+        doc_dir = resource_filename(__name__, 'documentation/%s' % lc[0])
+        if doc_dir is None:
+            doc_dir = os.path.join(os.path.dirname(__file__), 'documentation', lc[0])
+        # print "doc_dir %s" % doc_dir
+        doc.add_doc_tags(doc_dir)
+
+        # Initialize the command module, than add command packages
+        command.init_command(self, mi)
+        self.add_command_packages(self.desc_version)
+
+        # save for possible later use
+        #print self.pp.format_table(self.pp.format_details())
+        
+        #
+        if self.debug:
+            for (n,v) in self.command_submode_dict.items():
+                print "SUBMODE %s %s" % (n,v)
+            for (n,v) in self.command_dict.items():
+                print "MODE %s %s" % (n,v)
+
+
+        self.time_zone_list = None
+        command.add_completion('time-zone-completion', SDNSh.time_zone_completion)
+        command.add_validation('time-zone-validation', SDNSh.time_zone_validation)
+        command.add_action('set-clock', SDNSh.set_clock_action, {'kwargs': {'data': '$data'}})
+        command.add_action('begin-default-gateway-check', SDNSh.begin_default_gateway_check_action)
+        command.add_action('end-default-gateway-check', SDNSh.end_default_gateway_check_action)
+    
+        command.add_command_type('config-with-default-gateway-check', {
+            'action': ('begin-default-gateway-check', 'write-fields', 'end-default-gateway-check'),
+            'no-action': ('begin-default-gateway-check', 'reset-fields', 'end-default-gateway-check')
+        })
+
+        #
+        if self.feature_enabled('experimental'):
+            print '***Warning: experimental features enabled***'
+            if self.debug:
+                self.sdndb = sdndb.SDNDB(self, self, self.pp)
+                print '--BEGIN--'
+                self.sdndb.display('core/switch', style='table')
+                self.sdndb.display('core/controller', style='table')
+                self.sdndb.display('core/controller', style='list')
+                print '--LINK--', self.pp.table_info['link']['field-orderings']
+                self.sdndb.display('topology/link')
+                self.sdndb.display('topology/switch-cluster')
+                self.sdndb.display('topology/switch-cluster', style='list')
+                self.sdndb.display('topology/enabled-port')
+
+    #
+    # --------------------------------------------------------------------------------
+    # check_rest_result
+    @staticmethod
+    def check_rest_result(result, message=None):
+        if isinstance(result, collections.Mapping):
+            error_type = result.get('error_type')
+            if error_type:
+                raise error.CommandRestError(result, message)
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_table_from_store
+    #  Caches the last result to try to cut down on the number of times large tables
+    #  are loaded from the REST API
+    #
+    def get_table_from_store(self, obj_type, key = None, val = None, match = None):
+        return self.store.get_table_from_store(obj_type, key, val, match)
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_object_from_store
+    #   cover for call to get a specific object from a table, only a convenience.
+    #
+    def get_object_from_store(self, obj_type, obj_name):
+        return self.store.get_object_from_store(obj_type, obj_name)
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_query_objects
+    #   cover for call to query objects from the database, only a convenience.
+    #
+    def rest_query_objects(self, obj_type, query_params=None):
+        return self.store.rest_query_objects(obj_type, query_params)
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_create_object
+    #  REST API call to create an object, if this is the last table which
+    #  was fetched, then discard that table.
+    #
+    def rest_create_object(self, obj_type, ident):
+        return self.store.rest_create_object(obj_type, ident)
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_delete_objects
+    #
+    def rest_delete_objects(self, obj_type, delete_params):
+        return self.store.rest_delete_objects(obj_type, delete_params)
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_delete_object
+    #
+    def rest_delete_object(self, obj_type, name):
+        if type(name) == dict:
+            return self.store.rest_delete_object(obj_type, name)
+
+        return self.store.rest_delete_object(obj_type, mi.pk(obj_type), name)
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_update_object
+    #
+    def rest_update_object(self, obj_type, name, obj_key_val, obj_key_data):
+        return self.store.rest_update_object(obj_type, name, obj_key_val, obj_key_data)
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_simple_resquest_to_dict
+    #  Issue a store_simple_request and covert the result into a dict using json.load
+    #  Performs no exception handling
+    #
+    def rest_simple_request_to_dict(self, url):
+        return json.loads(self.store.rest_simple_request(url))
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_post_request
+    #  Forward a low-level REST request to the store
+    #
+    def rest_post_request(self, url, obj, verb='PUT'):
+        return self.store.rest_post_request(url, obj, verb)
+    
+    #  
+    # --------------------------------------------------------------------------------
+    # create_object
+    #  Helper function to help identify call sites which create objects
+    #  Errors result in printing an error message, then returning True
+    #
+    def create_object(self, obj_type, field_dict):
+        try:
+            self.rest_create_object(obj_type, field_dict)
+            return False
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, obj_type)
+           
+        if errors != None:
+            print self.rest_error_dict_to_message(errors)
+            return True
+        
+    #  
+    # --------------------------------------------------------------------------------
+    # create_row
+    #  Helper function to help identify call sites which create new rows
+    #
+    #  Return a pair of bool's, the first is an error indication, while the second
+    #  is True when the row needed to be created.
+    #
+    #
+    def create_row(self, obj_type, name, row_dict = None):
+        # create the row with a dictionary which includes all the
+        # populated values for the foreign keys
+        # the row is created.
+        if row_dict == None:
+            updated_dict = {}
+        else:
+            updated_dict = row_dict
+
+        #
+        # Only set the primary key for obj_keys which aren't managed
+        # by the CassandraSetting/COMPOUND_KEY_FIELDS (this is currently
+        # a slightly different predicate than is_compound_key)
+        #
+        key = mi.pk(obj_type)
+        type_info = mi.obj_type_info_dict[obj_type]['fields'][key]['type']
+        if type_info != 'compound-key':
+            updated_dict[mi.pk(obj_type)] = name
+        updated_dict = self.associate_foreign_keys_with_dict(obj_type, updated_dict)
+
+        if self.create_object(obj_type, updated_dict):
+            return [True, False]
+        return [False, True]
+
+    #
+    # --------------------------------------------------------------------------------
+    # find_or_create_row
+    #  Return a pair of bool's, the first is an error indication, while the second
+    #  is True when the row needed to be created.
+    #
+    #  When a new row is created, if the obj_type has a private_key, an attempt
+    #  is made to identify all the private keys, and populate values for each
+    #  of them.
+    #
+    def find_or_create_row(self, obj_type, name, row_dict = None):
+        if row_dict == None:
+            row_dict = {}
+        try:
+            result = self.get_object_from_store(obj_type, name)
+            if result[mi.pk(obj_type)] == name:
+                return [False, False]
+        except Exception:
+            pass
+
+        return self.create_row(obj_type, name, row_dict)
+
+    #
+    # --------------------------------------------------------------------------------
+    # associate_foreign_keys_with_dict
+    #  Passed an obj_type, and a dictionary, returns a dictionary with updated
+    #  key:value pairs for all the known private keys.
+    #  
+    #
+    def associate_foreign_keys_with_dict(self, obj_type, create_dict):
+        #
+        # Private key names are 'well known', so the names are used here to
+        # idenify how the field ought to be populated.
+        #
+        for foreign_key_id in mi.obj_type_foreign_keys(obj_type):
+            if foreign_key_id in create_dict:
+                # already set in the dictionary
+                pass
+            elif mi.is_null_allowed(obj_type, foreign_key_id):
+                continue
+            elif foreign_key_id == 'vns':
+                create_dict[foreign_key_id] = self.vns_name()
+            elif foreign_key_id == 'vns-access-list' and \
+              self.get_current_mode_obj_type() == 'vns-access-list':
+                create_dict[foreign_key_id] = self.get_current_mode_obj()
+            elif foreign_key_id == 'rule':
+                # LOOK! this seems to need more work, what's the rule relationship?
+                if obj_type == 'vns-interface':
+                    create_dict = associate_foreign_key_for_vns_interface(dict)
+            else:
+                traceback.print_stack()
+                print self.error_msg("Internal: %s can't determine value " \
+                                     "for foreign key %s" % (obj_type, foreign_key_id))
+ 
+        return create_dict
+
+    #
+    # methods to manage the mode_stack, prompts, and mode_obj/mode_obj_type
+    #
+
+    #
+    # --------------------------------------------------------------------------------
+    # set_contoller_for_prompt
+    #
+    def set_controller_for_prompt(self):
+        if self.controller == "127.0.0.1:8000":
+            self.controller_for_prompt = socket.gethostname()
+        else:
+            self.controller_for_prompt = self.controller
+            self.update_prompt()
+
+    #
+    # --------------------------------------------------------------------------------
+    # update_prompt
+    #  There are several different prompts depending on the current mode:
+    #  'host'>                                  -- login mode
+    #  'host'#                                  -- enable mode
+    #  'host'(config)#                          -- config mode
+    #  'host'(config-vns-definition-name)#      -- vns-definition mode
+    #  'host'(config-vns-definition-interface-rule-name)# -- vns-defn,
+    #                                              interface-rule mode
+    #
+    def update_prompt(self):
+        if self.current_mode().startswith("config"):
+            current_mode = "(" + self.current_mode()
+            if self.get_current_mode_obj() != None:
+                if self.in_config_submode("config-vns"):
+                    # substitute '|' with '-'
+                    parts = self.get_current_mode_obj().split('|')
+                    current_mode += "-" + '-'.join(parts)
+            self.prompt = str(self.controller_for_prompt) + current_mode + ")# "
+        elif self.current_mode() == "enable":
+            self.prompt = str(self.controller_for_prompt) + "# "
+        else:
+            self.prompt = str(self.controller_for_prompt) + "> "
+
+    #
+    # --------------------------------------------------------------------------------
+    # push_mode
+    #  Every pushed mode is a quad: <modeName, tableName, specificRow, exitCallback>
+    #
+    #  obj_type is the name of an associated table/model (tableName)
+    #  obj is the key's value for the table/model's key (specificRow)
+    # 
+    #  The cli currently supports a mode of table/model row edit, where the
+    #  name of the table/mode is entered, along with an associated value for
+    #  key-column of the table.   Once in that mode, other fields of the table
+    #  can be edited by entering the name of the field, along with a new value.
+    #
+    #  The exitCallback is the nane of a method to call when the current pushed
+    #  level is getting pop'd.
+    #
+    def push_mode(self, mode_name, obj_type=None, obj=None, exitCallback=None):
+        self.mode_stack.append( { 'mode_name' : mode_name,
+                                  'obj_type' : obj_type,
+                                  'obj' : obj,
+                                  'exit' : exitCallback} )
+        self.update_prompt()
+
+    #
+    # --------------------------------------------------------------------------------
+    # pop_mode
+    #  Pop the top of the stack of mode's.
+    #
+    def pop_mode(self): 
+        m = self.mode_stack.pop()
+        if len(self.mode_stack) == 0:
+            self.run = False
+        else:
+            self.update_prompt()
+        return m
+    
+    #
+    # --------------------------------------------------------------------------------
+    # mode_stack_to_rest_dict
+    #  Convert the stack of pushed modes into a collection of keys.
+    #  Can be used to build the rest api dictionary used for row creates
+    #
+    def mode_stack_to_rest_dict(self, rest_dict):
+        #
+        for x in self.mode_stack:
+            if x['mode_name'].startswith('config-'):
+                rest_dict[x['obj_type']] = x['obj']
+
+        return rest_dict
+
+    #
+    # --------------------------------------------------------------------------------
+    # current_mode
+    #  Return the string describing the current (top) mode.
+    #
+    def current_mode(self): 
+        if len(self.mode_stack) < 1:
+            return ""
+        return self.mode_stack[-1]['mode_name']
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_submode
+    #  Return true when the current mode is editing the contents of one of the
+    #  rows of the table/model store.
+    #
+    def in_config_submode(self, prefix = "config-"):
+        return self.current_mode().startswith(prefix)
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_mode
+    #  Returns true for any config mode; this is any nested edit mode,
+    #  along with the base config mode
+    #
+    def in_config_mode(self):
+        return self.current_mode().startswith("config")
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_switch_mode
+    #  Returns true when the switch mode has been entered via the 'switch <dpid>' command.
+    #
+    def in_config_switch_mode(self):
+        return self.current_mode() == "config-switch"
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_switch_if_mode
+    #  Returns true when the switch-interface mode has been entered via the
+    # 'switch <dpid>' command, then the interface <name> command
+    #
+    def in_config_switch_if_mode(self):
+        return self.current_mode() == "config-switch-if"
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_name
+    #
+    def vns_name(self):
+        mode_dict = self.mode_stack_to_rest_dict({})
+        if 'vns' in mode_dict:
+            return mode_dict['vns']
+        if 'vns-definition' in mode_dict:
+            return mode_dict['vns-definition']
+        return None
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_vns_mode
+    #  Returns true when the vns mode has been entered via the 'vns <vnsId>' command.
+    #
+    def in_config_vns_mode(self):
+        return self.current_mode() == "config-vns"
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_vns_def_mode
+    #  Returns true when the vns mode has been entered via the
+    #  'vns-definition <vnsId>' command.
+    #
+    def in_config_vns_def_mode(self):
+        return self.current_mode() == "config-vns-def"
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_vns_def_if_rule_mode
+    #  Returns true when the vns mode has been entered via the
+    #  'vns-definition <vnsId>' command, then into interface-rule mode.
+    #
+    def in_config_vns_def_if_rule_mode(self):
+        return self.current_mode() == "config-vns-def-if-rule"
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_vns_acl_mode
+    #  Returns true when the vns mode has been entered via the
+    #  'vns <vnsId>' command, then into acl mode.
+    #
+    def in_config_vns_acl_mode(self):
+        return self.current_mode() == "config-vns-acl"
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_vns_if_mode
+    #  Returns true when the vns mode has been entered via the
+    #  'vns <vnsId>' command, then into interface mode.
+    #
+    def in_config_vns_if_mode(self):
+        return self.current_mode() == "config-vns-if"
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_host_mode
+    #  Returns true when the vns mode has been entered via the
+    #  'host <host-id>' command
+    #
+    def in_config_host_mode(self):
+        return self.current_mode() == "config-host"
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_controller_node_mode
+    #  Returns true when the vns mode has been entered via the
+    #  'controller-node <controller-node-id>' command
+    #
+    def in_config_controller_node_mode(self):
+        return self.current_mode() == "config-controller-node"
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_controller_interface_mode
+    #  Returns true when the controller interface mode has been entered via the
+    #  'interface Ethernet <#>' command from the controller-node config mode
+    #
+    def in_config_controller_interface_mode(self):
+        return self.current_mode() == "config-controller-if"
+
+    #
+    # --------------------------------------------------------------------------------
+    # in_config_port_channel_mode
+    #
+    def in_config_port_channel_mode(self):
+        return self.current_mode() == "config-port-channel"
+
+    # --------------------------------------------------------------------------------
+    # set_current_mode_obj
+    #  Sets the name of the selected row (key's value)
+    #
+    def set_current_mode_obj(self, obj):
+        self.mode_stack[-1]['obj'] = obj
+        
+    #
+    # --------------------------------------------------------------------------------
+    # get_current_mode_obj
+    #  Gets the name of the current mode's selected row value (key's value)
+    #  This can return None.
+    #
+    def get_current_mode_obj(self):
+        return self.mode_stack[-1]['obj']
+
+    #
+    # --------------------------------------------------------------------------------
+    # set_current_mode_obj_type
+    #  Set the table/model name for this current mode.
+    #
+    def set_current_mode_obj_type(self, obj_type):
+        self.mode_stack[-1]['obj_type'] = obj_type
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_current_mode_obj_type
+    #  Get the table/model name for this current mode.
+    #
+    def get_current_mode_obj_type(self):
+        return self.mode_stack[-1]['obj_type']
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_nested_mode_obj
+    #  Get the id of the object that matches the given object type
+    #  starting from the current mode and working backwards to the
+    #  top-level mode. If there's no mode that matches the given
+    #  object type, then return None (maybe should handle as exception?).
+    #
+    def get_nested_mode_obj(self, obj_type):
+        for i in range(1, len(self.mode_stack)+1):
+            # Use negative index so we search from the top/end of the stack
+            mode = self.mode_stack[-i]
+            if mode['obj_type'] == obj_type:
+                return mode['obj']
+        return None
+    
+    #
+    # helper functions to access commands, obj_types, and fields
+    #
+
+    #
+    # --------------------------------------------------------------------------------
+    # all_obj_types_starting_with
+    #  Returns a list of all the current object types starting with the text
+    #  parameter.
+    #
+    #
+    def all_obj_types_starting_with(self, text=""):
+        if onos == 0:
+            netvirt_feature = self.netvirt_feature_enabled()
+        else:
+            netvirt_feature = False
+
+        matched_obj_types = [x for x in mi.obj_types
+                             if x.startswith(text) and
+                                self.debug_obj_type(x) and
+                                (netvirt_feature or (x != 'vns-definition')) ]
+        # synthetic object type based on the vns config submode.
+        if self.in_config_vns_def_mode() and "interface-rule".startswith(text):
+            matched_obj_types.append("interface-rule")
+        if self.in_config_vns_mode() and "access-list".startswith(text):
+            matched_obj_types.append("access-list")
+        if self.in_config_vns_mode() and "interfaces".startswith(text):
+            matched_obj_types.append("interfaces")
+        return matched_obj_types
+    #
+    # --------------------------------------------------------------------------------
+    # feature_enabled
+    #  Return True when a particular feature is enabled.
+    #
+    def feature_enabled(self, feature):
+        # features not managed via store
+        #
+        if feature == 'experimental':
+            return os.path.exists(self.feature_allow_experimental)
+
+        if feature == 'ha':
+            try:
+                with open(self.boot_config_filename, "r") as f:
+                    for line in f:
+                        if line.startswith('ha-config='):
+                            parts = line.split('=')
+                            if len(parts) > 0 and parts[1] == 'enabled\n':
+                                return True
+            except:
+                pass
+            return False
+
+        # only current features which can be enabled disabled
+        if feature not in [
+                'vns', 'static-flow-pusher', 'performance-monitor']:
+            return False
+
+        #
+        try:
+            entry = self.get_table_from_store('feature')
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'feature')
+            print self.rest_error_dict_to_message(errors)
+            return True
+
+        feature_to_field_dict = {
+            'vns'                 : 'netvirt-feature',
+            'static-flow-pusher'  : 'static-flow-pusher-feature',
+            'performance-monitor' : 'performance-monitor-feature',
+        }
+
+        if len(entry) == 0:
+            if feature in feature_to_field_dict:
+                field = feature_to_field_dict[feature]
+                return mi.field_default_value('feature', field)
+            return True
+
+        if len(entry) != 1:
+            # need a mechanism to select one from the list
+            return True
+
+        if feature in feature_to_field_dict:
+            return entry[0][feature_to_field_dict[feature]]
+
+        # use the default value from the model (every feature needs a default value)
+        defauilt_value = mi.field_default_value('feature', feature_to_field_dict[feature])
+        if default_value == None:
+            print self.error_msg('Feature %s missing default value' % feature)
+            return True
+        return default_value
+
+    '''
+    #
+    # --------------------------------------------------------------------------
+    # address_space_default_create
+    #
+    #  Create a default address space if it doesn't exist, which enables
+    #  'address-space default',
+    #
+    def address_space_default_create(self):
+        key = mi.pk('address-space')
+        try:
+            entries = self.get_table_from_store('address-space',
+                                                key, 'default', 'exact')
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'address-space')
+            if not 'see_other' in errors:
+                print self.rest_error_dict_to_message(errors)
+            return
+
+        if len(entries) == 0:
+            self.create_row('address-space', 'default')
+
+    #
+    # --------------------------------------------------------------------------
+    # tenant_default_create
+    #
+    #  Create default tenant and system tenant if it doesn't exist, which enables
+    #  'tenant default' and tenant system, router vrsystem,
+    #
+    def tenant_default_create(self):
+        key = mi.pk('tenant')
+        try:
+            entries = self.get_table_from_store('tenant',
+                                                key, 'default', 'exact')
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'tenant')
+            if not 'see_other' in errors:
+                print self.rest_error_dict_to_message(errors)
+            return
+
+        if len(entries) == 0:
+            self.create_row('tenant', 'default')
+        #external tenant
+        try:
+            entries = self.get_table_from_store('tenant',
+                                                key, 'external', 'exact')
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'tenant')
+            if not 'see_other' in errors:
+                print self.rest_error_dict_to_message(errors)
+            return
+
+        if len(entries) == 0:
+            self.create_row('tenant', 'external')
+
+        #system tenant and system router: vrsystem
+        try:
+            entries = self.get_table_from_store('tenant',
+                                                key, 'system', 'exact')
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'tenant')
+            if not 'see_other' in errors:
+                print self.rest_error_dict_to_message(errors)
+            return
+
+        if len(entries) == 0:
+            self.create_row('tenant', 'system')
+        
+        try:
+            entries = self.get_table_from_store('virtualrouter',
+                                                key, 'vrsystem', 'exact')
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'virtualrouter')
+            if not 'see_other' in errors:
+                print self.rest_error_dict_to_message(errors)
+            return
+
+        if len(entries) == 0:
+            self.create_row('virtualrouter', 'vrsystem',{"tenant":"system","vrname":"vrsystem"})
+ 
+    #
+    # --------------------------------------------------------------------------
+    # netvirt_feature_init
+    #  perform vns featrue enablement:
+    #  Create a default vns if it doesn't exist, which enables 'vns default',
+    #
+    def netvirt_feature_init(self):
+        self.address_space_default_create()
+        self.tenant_default_create()
+        key = mi.pk('vns-definition')
+        try:
+            entries = self.get_table_from_store('vns-definition', key, 'default|default', 'exact')
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'vns-definition')
+            if not 'see_other' in errors:
+                print self.rest_error_dict_to_message(errors)
+            return
+
+        if len(entries) == 0:
+            self.create_row('vns-definition', 'default', {"tenant":"default","vnsname":"default"})
+
+    #
+    # --------------------------------------------------------------------------------
+    # netvirt_feature_enabled
+    #  Return True when the vns feature is enabled
+    #  
+    #  When vns is disabled, particular vns commands are no longer
+    #  available, along with a few specific objects.  Particular
+    #  code sites which are specifically concerned with these issues
+    #  disable these items.  Another possible approach would be to
+    #  modify the base information sources  when a feature is
+    #  enabled or disabled, ie: mi.obj_types and command_dict.
+    #  This more active approach isn't taken since during
+    #  the initialization process, a variety of different object
+    #  relationships are constructed; foreign key xref's,  alias
+    #  key xref's,  object key dictionaries, etc.  If the feature
+    #  enabled were more active, then all these relationships would also
+    #  need to be recomputed.
+    #
+    def netvirt_feature_enabled(self):
+        controller_netvirt_feature = self.feature_enabled("vns")
+        if self.netvirt_feature_enabled_cached != controller_netvirt_feature:
+            self.netvirt_feature_enabled_cached = controller_netvirt_feature
+            if self.netvirt_feature_enabled_cached:
+                self.netvirt_feature_init()
+        if controller_netvirt_feature == False:
+            return False
+        return True
+    '''
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_obj_of_type
+    #  Return a single row, or None, of the table who's name is passed as obj_type
+    #  Returns None when when there's multiple matches of the nane in the table/model
+    #  Performs no error processing
+    #
+    def get_obj_of_type(self, obj_type, name):
+        key = mi.pk(obj_type)
+        if key:
+            errors = None
+            try:
+                entries = self.get_table_from_store(obj_type)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, obj_type)
+
+            if errors:
+                print self.rest_error_dict_to_message(errors)
+                return None
+
+            entries = [x for x in entries if x.get(key, 'None') == name]
+            if len(entries) != 1:
+                return None
+            return entries[0]
+        else:
+            return None
+        
+    #
+    # --------------------------------------------------------------------------------
+    # fields_for_current_submode_starting_with
+    #  Return a list of choices which are fields names of model/store objects
+    #  Any fields which are primary keys are excluded from edit, as are any
+    #  foreign keys, this is managed through is_editable()
+    #
+    def fields_for_current_submode_starting_with(self, start_text=""):
+        if not self.in_config_submode():
+            return []
+        if self.in_config_vns_mode():
+            return []
+        obj_type = self.get_current_mode_obj_type()
+        if not obj_type in mi.obj_type_info_dict:
+            return []
+        fields = [x for x in mi.obj_type_info_dict[obj_type]['fields'].keys() \
+                  if mi.is_editable(obj_type, x)]
+
+        return [x for x in fields if x.startswith(start_text)]
+
+    #
+    # --------------------------------------------------------------------------------
+    # obj_types_for_config_mode_starting_with
+    #
+    # what obj types are available in the given submode
+    # e.g., top-level config mode has switch and config-switch has
+    # flow-entry but flow-entry should not be available in top-level
+    # config nor should switch be available in config-switch submode!
+    # LOOK! hardwired for now to test parsing - need to merge with model
+    #
+    def obj_types_for_config_mode_starting_with(self, start_text=""):
+        if not self.in_config_mode():
+            return []
+        #
+        # vns features
+        if onos == 0:
+            netvirt_features = self.netvirt_feature_enabled()
+        else:
+            netvirt_features = False
+        vns_objects = [ 'vns-definition' ]
+
+        ret_list = [x for x in mi.obj_types
+                    if self.debug_obj_type(x) and 
+                       not mi.is_obj_type_source_not_user_config(x)]
+        return [x for x in ret_list if x.startswith(start_text) and
+                    (netvirt_features or not x in vns_objects) ]
+
+    @staticmethod
+    def title_of(command):
+        return command['title'] if type(command) is dict else command
+
+    #
+    # --------------------------------------------------------------------------------
+    # commands_feature_enabled
+    #
+    def commands_feature_enabled(self, commands):
+        return [self.title_of(x) for x in commands
+                if (not self.title_of(x) in self.command_name_feature) or
+                    command.isCommandFeatureActive(self.title_of(x),
+                           self.command_name_feature[self.title_of(x)])]
+
+    #
+    # --------------------------------------------------------------------------------
+    # commands_for_mode
+    #
+    def commands_for_mode(self, mode):
+        """
+        Walk the command dict, using interior submodes and compiling
+        the list of available commands (could rebuild command_dict()
+        to contain all the possible commands, but its good to know
+        exactly which commands apply to this submode)
+        """
+
+        # make a new list, so that items don't get added to the source
+        ret_list = list(self.command_nested_dict.get('login', []))
+        if mode == 'login':
+            ret_list += self.command_dict.get('login', [])
+            return ret_list
+        ret_list += self.command_nested_dict.get('enable', [])
+        if mode == 'enable':
+            ret_list += self.command_dict.get('enable', [])
+            return ret_list
+
+        if mode == 'config':
+            ret_list += self.command_nested_dict.get('config', [])
+            ret_list += self.command_dict.get('config', [])
+            return ret_list
+        
+        for idx in [x for x in self.command_nested_dict.keys() if mode.startswith(x)]:
+            ret_list += self.command_nested_dict.get(idx, [])
+
+        ret_list += self.command_dict.get(mode, [])
+
+        # manage command who's names are regular expressions
+        result = [x['re'] if type(x) == dict else x  for x in ret_list]
+
+        return result
+
+    #
+    # --------------------------------------------------------------------------------
+    # commands_for_current_mode_starting_with
+    #
+    def commands_for_current_mode_starting_with(self,
+                                                start_text = "", completion = None):
+        """
+        One of the difficult issues here is when the first item
+        isn't a token, but rather a regular expression.  This currently occur
+        in a few places in the command description, and the mechanism for
+        dealing with the issue here is ... uhm ... poor.  The code here is
+        a stopgap, and assumes the only regular expression supported
+        is the <digits> one.  This could be make a bit better based on
+        the submode, but really, this entire first-token management should
+        be improved.
+        """
+        if completion == None:
+            completion = False
+        #
+        # vns features commands include:
+        netvirt_feature_commands = ['vns', 'vns-definition']
+        if onos == 0:
+            netvirt_feature = self.netvirt_feature_enabled()
+        else:
+            netvirt_feature = False
+
+        mode_list = self.commands_for_mode(self.current_mode())
+        ret_list = self.commands_feature_enabled(utif.unique_list_from_list(mode_list))
+
+        def prefix(x, start_text, completion):
+            if type(x) == str and x.lower().startswith(start_text.lower()):
+                return True
+            if not completion and type(x) == re._pattern_type:
+                return x.match(start_text)
+            return False
+
+        def pattern_items(ret_list, prefix):
+            matches = []
+            for p in [x for x in ret_list if type(x) == re._pattern_type]:
+                for c in command.command_registry:
+                    if c['mode'] != self.current_mode():
+                        continue
+                    if type(c['name']) != dict:
+                        continue
+                    first_word = c['name']
+                    if 'completion' not in first_word:
+                        continue
+                    completion = first_word['completion']
+                    if first_word['pattern'] == p.pattern:
+                        result = {}
+                        scopes = [ first_word,
+                                   {
+                                    'completions' : result,
+                                    'data'        : {},
+                                    'text'        : prefix,
+                                   },
+                                 ]
+                        command._call_proc(completion,
+                                           command.completion_registry,
+                                           scopes, c)
+                        matches = result.keys()
+            return matches
+
+        matches = [x for x in ret_list if prefix(x, start_text, completion)]
+        if completion:
+               matches += pattern_items(ret_list, start_text)
+        return matches
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # complete_optional_parameters
+    #
+    # Parse optional parameters.  These can occur in any order.
+    # Params argument is a hash mapping a parameter name to type
+    # information.
+    # words argument are remaining words in the command
+    # line that aren't yet parsed
+    #
+    def complete_optional_parameters(self, params, words, text):
+        i = 0
+        while i < len(words):
+            final = i+1 >= len(words)
+            word = words[i]
+            possible = [x for x in params if x.startswith(word)]
+            param_name = possible[0]
+            param = params[param_name]
+             
+            if (param['type'] != 'flag'):
+                if (final):
+                    argument = text
+                    if (param['type'] == 'enum'):
+                        return [x 
+                                for x in param['values'] 
+                                if x.startswith(argument)]
+                    elif argument == '':
+                        if ('syntax_help' in param):
+                            self.print_completion_help(param['syntax_help'])
+                        else:
+                            self.print_completion_help('[%s argument]' % word)
+                        return
+                i += 1
+            i += 1
+
+        return [x for x in params if x.startswith(text)]
+
+    #
+    # --------------------------------------------------------------------------------
+    # parse_optional_parameters
+    #
+    @staticmethod
+    def parse_optional_parameters(params, words):
+        parsed = {}
+        i = 0
+        while i < len(words):
+            word = words[i]
+            possible = [x for x in params if x.startswith(word)]
+            if len(possible) == 0:
+                raise ParamException('unknown option: %s' % word)
+            elif len(possible) > 1:
+                raise ParamException('ambiguous option: %s\n%s' % 
+                                     (word, "\n".join(possible)))
+            else:
+                param_name = possible[0]
+                param = params[param_name]
+                if (param['type'] == 'flag'):
+                    parsed[param_name] = True
+                else:
+                    if i+1 < len(words):
+                        argument = words[i+1]
+                        if (param['type'] == 'string'):
+                            parsed[param_name] = argument
+                        elif (param['type'] == 'int'):
+                            try:
+                                parsed[param_name] = int(argument)
+                            except ValueError:
+                                raise ParamException('option %s requires ' + 
+                                                     'integer argument'
+                                                     % word)
+                        elif (param['type'] == 'enum'):
+                            arg_possible = [x 
+                                            for x in param['values'] 
+                                            if x.startswith(argument)]
+                            if (len(arg_possible) == 0):
+                                raise ParamException('option %s value must be in (%s)' % 
+                                                     (word,", ".join(param['values'])))
+                            elif (len(arg_possible) > 1):
+                                raise ParamException('ambiguous option %s value:\n%s' % 
+                                                     (word, "\n".join(arg_possible)))
+                            else:
+                                parsed[param_name] = arg_possible[0]
+                        i += 1
+                    else:
+                        raise ParamException('option %s requires an argument' 
+                                                 % word)
+            i += 1
+        return parsed
+
+    #
+    # --------------------------------------------------------------------------------
+    # annotated_obj_type_id
+    #
+    #  Given an id's value for a compound key, crack the value into
+    #  parts, and annotate each part with the compound key name.
+    #
+    #  For 'Not Found' errors, the obj_type is known, along with the value
+    #  for the id which wasn't found.  If this is an id with a compound key,
+    #  leaking information about the key's implementiion should be avoided. 
+    #  Here the key's value is cracked based on the composition character,
+    #  and the items are displayed with their key-value name.
+    #  eg: Error: Not Found vns:xXx rule-id:snapple  (vns-interface-rule)
+    #
+    def annotated_obj_type_id(self, obj_type, error):
+        key = mi.pk(obj_type)
+        if mi.is_compound_key(obj_type, key):
+            result = { key : error}
+            mi.split_compound_into_dict(obj_type, key, result)
+            return ', '.join(["%s:%s" % tuple(x) for x in result.items()
+                             if x[0] != key])
+        return error
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def find_master(self):
+        """
+        Return a dictionary with two items: 'master', and 'ips'
+        'master' identifes the ip address of the master, a string
+        which is an ip address, or None.
+        'ips' is a list of interface rows with populated ip addresses.
+        """
+        # collect all the controller-interfaces
+        ips = [x for x in local_interfaces_firewall_open('tcp', [80, 8000], 'all')
+               if (x['ip'] != '' or x['discovered-ip'] != '')]
+
+        master = None
+        for ip in ips:
+            if ip['ip'] != '':
+                url = "http://%s/rest/v1/system/ha/role" % ip['ip']
+            if ip['discovered-ip'] != '': # select discovered ip over ip
+                url = "http://%s/rest/v1/system/ha/role" % ip['discovered-ip']
+            result = self.store.rest_simple_request(url, use_cache = False)
+            self.check_rest_result(result)
+            ha_role = json.loads(result)
+            if ha_role['role'] == 'MASTER':
+                if ip['ip'] != '':
+                    master = ip['ip']
+                if ip['discovered-ip'] != '':
+                    master = ip['discovered-ip']
+
+        return {'master': master, 'ips': ips}
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_error_to_dict
+    #   Turn an exception into an error dictionary, which can later be printed.
+    #   using rest_error_dict_to_message().  
+    #
+    def rest_error_to_dict(self, e, detail=None):
+        errors = None
+        # try to identifify validation requests
+        if isinstance(e, httplib.BadStatusLine):
+            errors = {'connection_error' : 'REST API server %s: '
+                                           'server not running' %
+                                           self.controller}
+            return errors
+
+        elif isinstance(e, urllib2.HTTPError):
+            code = e.code
+            error_returned = e.readline()
+
+            if code == 404:
+                if detail:
+                    errors = {'not_found_error' : 'Not Found: %s' % detail}
+                else:
+                    errors = {'not_found_error' : 'Not Found: %s' % error_returned}
+            elif code == 500 or code == 403:
+                # traceback.print_stack()
+                errors = {'connection_error' : 'REST API server %s failure: %s' %
+                                                (self.controller, error_returned)}
+            elif code == 400:
+                try:
+                    errors = json.loads(error_returned)
+                except:
+                    # if the error can't be converted into a dictionary, then imbed the complete
+                    # errors as the value for a specific error key.
+                    errors = {'error_result_error': "Can't convert returned error: %s" % error_returned}
+            elif code == 301:
+                errors = {'moved_error': 'HttpError Moved Permanently %s' % e}
+            elif code == 303:
+                # Attempt to determine what list of ip addresses is for
+                # the controller, try to find the Master.  if any failure 
+                # occurs anywhere, drop down to a simple error message.
+                try:
+                    minfo = self.find_master()
+                    ips = [x['ip'] for x in minfo['ips']]
+                    master = minfo['master']
+                
+                    if master:
+                        errors = {'see_other': 'This controller is in SLAVE '
+                                  'mode. The command must be run in MASTER mode.'
+                                  '\nMASTER at %s' % master}
+                    elif len(ips):
+                        errors = {'see_other': 'This controller is in SLAVE mode. '
+                                    'The command must be run in MASTER mode.'
+                                    '\nNo MASTER found, possible ip\'s %s' %
+                                    (', '.join(ips))}
+                    else:
+                        errors = {'see_other': 'This controller is in SLAVE mode. '
+                                    'The command must be run in MASTER mode.'
+                                    '\nNo MASTER currently exists '}
+                except:
+                    errors = {'see_other': 'This controller is in SLAVE mode. '
+                              'The command must be run in MASTER mode.'
+                              '\nNo ip addresses for controller available'}
+            else:
+                errors = {'unknown_error': 'HttpError %s' % error_returned}
+        elif isinstance(e, NotFound):
+            if e.obj_type in mi.obj_type_info_dict:
+                errors = {'not_found_error' : 'Not Found: %s (%s)' % 
+                                              (self.annotated_obj_type_id(e.obj_type,
+                                                                          e.name),
+                                               e.obj_type)}
+            else:
+                errors = {'not_found_error' : 'Not Found: %s (%s)' % 
+                                              (e.name, e.obj_type)}
+        else:
+            if self.debug or self.debug_backtrace:
+                traceback.print_stack()
+            errors = {'unknown_error': "Need error management for error %s" % type(e)}
+
+        return errors
+
+    #
+    #
+    # --------------------------------------------------------------------------------
+    # rest_error_is_not_found
+    #  Return True if this specific error was the result of a not-found situation
+    #
+    @staticmethod
+    def rest_error_is_not_found(rest_error_dict):
+        if 'not_found_error' in rest_error_dict:
+            return True
+        return False
+
+    #
+    # --------------------------------------------------------------------------------
+    # rest_error_dict_to_message
+    #   Turn an rest_error_dict returned from rest_error_to_dict
+    #   into an error message which can ge printed.  Code assumes multiple errors
+    #   won't occur; if a 'field_error' exists, for example, a 'model_error' won't
+    #   also be posted in the error
+    #
+    def rest_error_dict_to_message(self, rest_error_dict):
+        if rest_error_dict == None:
+            return rest_error_dict
+        error_msg = ""
+        if 'field_errors' in rest_error_dict:
+            for (k, v) in rest_error_dict['field_errors'].items():
+                error_msg += "Syntax error: field %s: %s" % (k, v)
+            # traceback.print_stack(), to find out why the error occured
+        elif 'model_error' in rest_error_dict:
+            error_msg += "%s" % rest_error_dict['model_error']
+        elif 'not_found_error' in rest_error_dict:
+            error_msg += "Error: %s" % rest_error_dict['not_found_error']
+        elif 'connection_error' in rest_error_dict:
+            error_msg += rest_error_dict['connection_error']
+        elif 'error_result_error' in rest_error_dict:
+            error_msg += rest_error_dict['error_result_error']
+        elif 'moved_error' in rest_error_dict:
+            error_msg += rest_error_dict['moved_error']
+        elif 'see_other' in rest_error_dict:
+            error_msg += rest_error_dict['see_other']
+        elif 'unknown_error' in rest_error_dict:
+            error_msg += rest_error_dict['unknown_error']
+        elif 'description' in rest_error_dict and  \
+          rest_error_dict["description"] == 'saved':
+            # not an error: { 'description' : 'saved' }
+            return None
+        elif 'error_type' in rest_error_dict: # http 400 errors
+            description = rest_error_dict['description']
+            if description.startswith('Error: '):
+                description = description[len('Error: '):]
+            return '%s (%s)' % (description,
+                                rest_error_dict['error_type'])
+        else:
+            error_msg = "REST API server on controller-node %s " % self.controller
+            error_msg += "had %s error:\n" % rest_error_dict['error_type']
+            error_msg += rest_error_dict['description']
+        return error_msg
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    # Commands of the CLI. A command "foo" should have two methods:
+    #   cp_foo(self, text, state) - completion for this command, return list of options
+    #   do_foo(self, line) - execute the command
+    #
+    # Given a string 'word', not containing any spaces, nor any break
+    #  characters associated with python, return the a invocable method
+    #  note that '-' are permitted, and converted to '_''s
+    #
+    # When in the vns or vns-definition mode, the selected functions
+    #  to call back have an additional component added to the called
+    #  back function.  In the non-vns case, for example, the "show"
+    #  command would result in a method called do_show, while in the
+    #  vns modes, 'vns_' in inserted between the 'verb' and the noun,
+    #  for example, resulting in 'do_vns_show'
+
+    #
+    # --------------------------------------------------------------------------------
+    # method_from_name
+    #
+    def method_from_name(self, prefix, name):
+        if type(name) != str:
+            return None
+        if self.in_config_submode("config-vns") and \
+           getattr(self, prefix + "vns_" + name.replace("-","_"), None):
+            return getattr(self, prefix + "vns_" + name.replace("-","_"))
+        return getattr(self, prefix+name.replace("-","_"), None)
+        
+    #
+    # --------------------------------------------------------------------------------
+    # command_method_from_name
+    #
+    def command_method_from_name(self, name):
+        return self.method_from_name("do_", name)               # do_XXX methods
+
+    #
+    # --------------------------------------------------------------------------------
+    # command_show_method_from_name
+    #
+    def command_show_method_from_name(self, name):
+        return self.method_from_name("do_show_", name)          # do_show_XXX methods
+
+    #
+    # --------------------------------------------------------------------------------
+    # cloud_method_from_name
+    #
+    def cloud_method_from_name(self, name):
+        return self.method_from_name("cloud_", name)            # cloud_XXX methods
+
+    #
+    # --------------------------------------------------------------------------------
+    # completion_method_from_name
+    #
+    def completion_method_from_name(self, name):
+        return self.method_from_name("cp_", name)               # cp_XXX (completion) methods
+
+    #
+    # --------------------------------------------------------------------------------
+    # completion_show_method_from_name
+    #
+    def completion_show_method_from_name(self, name):
+        return self.method_from_name("cp_show_", name)          # cp_show_XXX (completion) methods
+
+    #
+    # --------------------------------------------------------------------------------
+    # unique_key_from_non_unique
+    #
+    # Primary keys for cassandra for some keys are contenations of
+    #  several non-unique keys separated by a character not used for
+    #  any other purpose (in this case '|').  The concatenation
+    #  of non-unique keys is intended to create a unique key.
+    #
+    def unique_key_from_non_unique(self, words):
+        return "|".join(words)
+    
+    #
+    # --------------------------------------------------------------------------------
+    # prefix_search_key
+    #  Prefix's of primary keys for keys's built through unique_key_from_non_unique()
+    #
+
+    def prefix_search_key(self, words):
+        return self.unique_key_from_non_unique(words) + "|"
+
+    #
+    # --------------------------------------------------------------------------------
+    # implement_connect
+    #
+    def implement_connect(self, data):
+        new_ip = data.get('ip-address')
+        if new_ip == None:
+            new_ip = data.get('controller-id')
+        if not self.IP_ADDR_RE.match(new_ip):
+            controller_id = alias_lookup('controller-alias', new_ip)
+
+            if controller_id == None:
+                controller_id = new_ip
+
+            try:
+                ifs = self.rest_query_objects('controller-interface',
+                                              { 'controller' : controller_id } )
+                if len(ifs) == 1:
+                    new_ip = ifs[0]['ip']
+            except:
+                return self.error_msg('Can\'t find controller named %s' % new_ip)
+                pass
+
+        if 'port' in data:
+            new_ip += str(data['port'])
+        else:
+            new_ip += ":80"
+        #
+        # request the version, if it fails, then don't allow the switch
+        try:
+            version_url = 'http://%s/rest/v1/system/version' % new_ip
+            data = self.rest_simple_request_to_dict(version_url)
+        except Exception, e:
+            return self.error_msg('Could not connect to %s' % new_ip)
+
+        self.controller = new_ip
+        self.store.set_controller(new_ip)
+        self.set_controller_for_prompt()
+        while (self.current_mode() != "login"):
+            self.pop_mode()
+        print "Switching to controller %s" % self.controller
+
+        return self.pp.format_entry(data[0], 'version')
+
+    def cp_exit(self, words, text, completion_char):
+        self.print_completion_help("<cr>")
+
+    def do_exit(self, words=None):
+        if self.mode_stack[-1]['exit']:
+            method = self.mode_stack[-1]['exit']
+            method()
+        self.pop_mode()
+
+    def cp_logout(self, words, text, completion_char):
+        self.print_completion_help("<cr>")
+
+    def do_logout(self, words=None):
+        self.run = False
+
+    def cp_end(self, words, text, completion_char):
+        self.print_completion_help("<cr>")
+
+    def do_end(self, words=None):
+        while self.current_mode().startswith("config"):
+            self.pop_mode()
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_tunnel
+    #  Command descriptions has no practical support for show commands yet.
+    #
+    def do_show_tunnel(self, words):
+        if len(words) < 2:
+            print self.syntax_msg("Usage: show tunnel [ <switch> | all ] active")
+            return
+        if words[1] != "active":
+            return self.error_msg("Unknown request %s" % words[1])
+
+        # active --
+
+        if words[0] != 'all':
+            words[0] = convert_alias_to_object_key("switch", words[0])
+
+        try:
+            data = self.rest_simple_request_to_dict(
+                            'http://%s/rest/v1/tunnel-manager/%s/' %
+                             (self.controller, words[0]))
+        except:
+            return self.error_msg('Could not load tunnel-manager details')
+
+        if 'error' in data and data['error'] != None:
+            return self.error_msg('tunnel-manager response: %s' % data['error'])
+
+        entries = []
+        for entry in data['tunnMap'].keys():
+            item = data['tunnMap'][entry]
+            for remote in item['tunnelPorts']:
+                remoteIp = "%s.%s.%s.%s" % ( int(remote[3:6]),
+                                             int(remote[6:9]),
+                                             int(remote[9:12]),
+                                             int(remote[12:]))
+                entries.append({ 'dpid': entry,
+                                 'localTunnelIPAddr' : item['localTunnelIPAddr'],
+                                 'tunnelPorts' : remoteIp
+                               })
+
+        return self.display_obj_type_rows('tunnel-details', entries)
+    
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_show_vns_access_list_entry
+    #
+    def cp_show_vns_access_list_entry(self, words, text, completion_char):
+        return self.cp_vns_access_list_entry(words, text)
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_vns_access_list_entry
+    #
+    def do_show_vns_access_list_entry(self, words):
+        with_search_key = "<no_key>"
+        if self.vns_name() is None:
+            if len(words) > 0:
+                search_object = ["vns-access-list-entry", words[0]]
+            else:
+                search_object = ["vns-access-list-entry"] 
+        elif len(words) > 0:
+            with_search_key = '-'.join(words)
+            words.insert(0, self.get_current_mode_obj())
+            search_object = ["vns-access-list-entry", 
+                             self.unique_key_from_non_unique(words)]
+        else:
+            search_object = ["vns-access-list-entry",
+                             self.prefix_search_key([self.get_current_mode_obj()])]
+        return self.do_show_object(search_object, with_search_key)
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_vns_no
+    #  implement the no command while in the context of vns/vns-definition
+    #
+    def do_vns_no(self, words):
+        if len(words) < 1:
+            return "Syntax: no <item> <key> : delete from the named item the specific key"
+        else:
+            vns_name_to_table_name = { "interfaces"        : "vns-interface",
+                                       "interface-rule"    : "vns-interface-rule",
+                                       "access-list"       : "vns-access-list",
+                                       "access-list-entry" : "vns-access-list-entry",
+                                       "access-group"      : "vns-interface-access-list",
+                                     }
+            if words[0] in vns_name_to_table_name:
+                if len(words) < 2:
+                    return "Syntax: no %s <item> <key>" % words[0]
+                #
+                # the item to remove in for access-list-entry is an integer,
+                # canonicalize the name before its used to search
+                if words[0] == 'access-list-entry':
+                    if self.ACL_RE.match(words[1]):
+                        words[1] = str(int(words[1]))
+                    else:
+                        return self.error_msg('%s key %s must be an integer' % 
+                                             (words[0], words[1]))
+
+                name = self.unique_key_from_non_unique([self.get_current_mode_obj(), words[1]])
+                table = vns_name_to_table_name[words[0]]
+                errors = None
+
+                if words[0] == "entry" and not self.in_config_vns_acl_mode():
+                    return self.do_no(words) # let do_no() print error messages
+                elif words[0] == "access-group" and not self.in_config_vns_if_mode():
+                    return self.do_no(words) # let do_no() print error messages
+
+                # access-group/vns-interface-access-list has 'id's with an additional field,
+                # the in-out parameter, which is required to be able to delete the entry
+                if words[0] == "access-group":
+                    if len(words) < 3:
+                        return self.syntax_msg('no access-group <acl-name> <in|out>')
+                    choices = [x for x in ["in", "out"] if x.startswith(words[2])]
+                    if len(choices) != 1:
+                        return self.syntax_msg('no access-group <acl-name> <in|out>')
+                    name = self.unique_key_from_non_unique([self.get_current_mode_obj(),
+                                                            self.vns_name(),
+                                                            words[1]])
+                    name = name + "|" + choices[0]
+
+                try:
+                    self.rest_delete_object(table, name)
+                except Exception, e:
+                    errors = self.rest_error_to_dict(e, words[0] + " " + words[1])
+                    
+                if errors:
+                    return self.rest_error_dict_to_message(errors)
+                #
+                # cascade delete?
+                if not errors:
+                    self.cascade_delete(table, name)
+
+                return None
+
+            return self.do_no(words)
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_no_tag
+    #  Since the name and value must be present, this is currently a special
+    #  case.  additionally, the two tables 'tag-mapping' and 'tag' are 
+    #  intermingled.  the 'tag' table manages the <namespace><name><value>
+    #  tuple, while the tag-mapping add <host> to that relationship  When
+    #  the removal of the entry from the tag-mapping table leaves no further
+    #  <namespace><name><value>'s for any hosts, then the row from the
+    #  'tag' table must be removed
+    #
+    def implement_no_tag(self, words):
+        if not words or len(words) != 2 or words[1].find('=') == -1:
+            return  "Syntax: no tag <namespace.name>=<value>"
+        else:
+            name_and_value = words[1].split("=")
+            if len(name_and_value) > 2:
+                return "Syntax: no tag <namespace.name>=<value>"
+
+            name_part = name_and_value[0].split('.')
+            if len(name_part) == 1:
+                namespace = 'default'
+                name = name_part[0]
+            elif len(name_part) >= 2:
+                namespace = '.'.join(name_part[:-1])
+                name = name_part[-1]
+
+            value = name_and_value[1]
+
+            item = self.unique_key_from_non_unique([namespace,
+                                                    name,
+                                                    value,
+                                                    self.get_current_mode_obj()])
+            #
+            # To prevent leaking the unique key value in the 'Not Found'
+            # error message, look up the item first, and display a unique
+            # error message for this case
+            #
+            errors = None
+            try:
+                self.get_object_from_store('tag-mapping', item)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, "tag " + item)
+
+            if errors:
+                if self.rest_error_is_not_found(errors):
+                    return self.error_msg("tag %s.%s=%s not found" %
+                                          (namespace, name, value))
+                else:
+                    return self.rest_error_dict_to_message(errors)
+                
+            try:
+                self.rest_delete_object('tag-mapping', item)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, "tag " + item)
+
+            if errors:
+                return self.rest_error_dict_to_message(errors)
+            #
+            # if there are no more items in tag-mapping for the
+            # <namespace>|<name>|<value>, then an entry needs to
+            # removed from the 'tag' table (for cleanup)
+            #
+            key = self.unique_key_from_non_unique([namespace,
+                                                   name,
+                                                   value])
+            try:
+                tags = self.get_table_from_store('tag-mapping', 'tag', key)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, "tag-mapping tag " + key)
+
+            if errors:
+                print self.rest_error_dict_to_message(errors)
+                return
+            if len(tags) == 0:
+                try:
+                    self.rest_delete_object('tag', key)
+                except Exception, e:
+                    errors = self.rest_error_to_dict(e, "tag " + item)
+                    
+                if errors:
+                    print self.rest_error_dict_to_message(errors)
+                    return
+            #
+            # cascade delete?
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_interface_rule_tags_validate
+    #  Provides a warning when the associated tag doesn't exist
+    #
+    def vns_interface_rule_tags_validate(self, obj_type, field, value):
+        for tag_pair in value.split(','):
+            if tag_pair.find('=') == -1 or len(tag_pair.split('=')) != 2:
+                # field validation won't match the regular expression
+                return 
+            (tag_name, tag_value) = tag_pair.split('=')
+            tag_name_parts = tag_name.split('.')
+            if len(tag_name_parts) == 1:
+                tag_namespace = 'default'
+                tag_name = tag_name_parts[0]
+            elif len(tag_name_parts) >= 2:
+                tag_namespace = '.'.join(tag_name_parts[:-1])
+                tag_name = tag_name_parts[-1]
+            else:
+                # XXX not reached
+                pass
+
+            # Validating using the 'tag' model to determine whether the
+            # tag exists depends on having the tag value removed when there's
+            # no more references to the entry.  the cli manages the 
+            # 'tag'/'tag-mapping' models that way, but other uses of the 
+            # rest api may not.
+            #
+            key = self.unique_key_from_non_unique([tag_namespace, tag_name, tag_value])
+            try:
+                table = self.get_object_from_store('tag', key)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, 'tag')
+                # special case for 'not found' error message
+                if self.rest_error_is_not_found(errors):
+                    self.warning("tag `%s.%s %s' not yet defined" % \
+                                 (tag_namespace, tag_name, tag_value))
+                else:
+                    print self.rest_error_dict_to_message(errors)
+        return None
+
+    #
+    # --------------------------------------------------------------------------------
+    # validate_switch_core_switch
+    #  Intended to display a warning message when the value is set to True
+    #
+    def validate_switch_core_switch(self, obj_type, field, value):
+        if value == 'True': # XXX odd that the value needs to be quoted.
+            self.warning("enabling core-switch on a switch with "
+                         "directly connected hosts will cause the same to "
+                         "be unable to connect")
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_specific_tag_fields
+    #  Called by handle_specific_obj_type to convert fields values from the
+    #  rest api into a displayable table
+    #
+    @staticmethod
+    def handle_specific_tag_fields(entries):
+        for entry in entries:
+            fields = entry['id'].split('|')
+            # XXX error if there's not four parts
+            entry['namespace'] = fields[0]
+            entry['name'] = fields[1]
+            entry['value'] = fields[2]
+
+    #
+    # --------------------------------------------------------------------------------
+    # append_when_missing
+    #
+    @staticmethod
+    def append_when_missing(unique_list, item):
+        if not item in unique_list:
+            unique_list.append(item)
+
+    #
+    # --------------------------------------------------------------------------------
+    # show_command_prefix_matches
+    #  show command's prefix matches, return True when the command matches
+    #  fpr the prefix described, used by get_valid_show_options() during
+    #  cp_show() to collect available command choice.
+    #
+    def show_command_prefix_matches(self, command, prefix):
+        # convert any '-'s in the prefix tp "_"'s since func's have _ separators
+        prefix = prefix.replace("-", "_")
+        if command.startswith("do_show_"+prefix) and not command.startswith("do_show_vns_"):
+            return True
+        elif command.startswith("do_show_vns_" + prefix):
+            if self.in_config_submode("config-vns"):
+                if command == 'do_show_vns_access_list' and self.in_config_vns_mode():
+                    return True
+                return self.vns_debug_show_commands(command)
+            return False
+        return False
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_valid_show_options 
+    #  used by cp_show to identify completion optinos
+    #
+    # returns a dictionary with two elements: 'commands', and 'objects'.
+    # the 'commands' element is a list of possible commands while
+    # the 'objects' element is a list of possible objects (tables/models in the store)
+    #
+    def get_valid_show_options(self, text):
+        ret_hash = {}
+        # first get commands
+        opts = []
+        matching_methods = [x for x in dir(self)
+                            if self.show_command_prefix_matches(x, text)]
+
+        if onos == 0:
+            netvirt_feature = self.netvirt_feature_enabled()
+        else:
+            netvirt_feature = False
+
+        for method in matching_methods:
+            m = re.search("do_show_(.*)", method)
+            n = re.search("do_show_vns_(.*)", method)
+            if n and self.in_config_submode('config-vns'):
+                self.append_when_missing(opts, n.group(1).replace("_","-"))
+            elif m:
+                if netvirt_feature or m.group(1) != 'vns':
+                    self.append_when_missing(opts, m.group(1).replace("_","-"))
+        #
+        # remove command cases
+        opts = [x for x in opts if x not in ["statistics", "object"]]
+        if "access-group" in opts and not self.in_config_vns_if_mode():
+            if not self.vns_debug_show_commands('vns-access-group'):
+                opts.remove("access-group")
+        if "access-list" in opts and not self.in_config_vns_mode():
+            if not self.vns_debug_show_commands('vns-access-list'):
+                opts.remove("access-list")
+        if "interface" in opts and not self.in_config_vns_mode():
+            if not self.vns_debug_show_commands('vns-interface'):
+                opts.remove("interface")
+        if "interface-rule" in opts and not self.in_config_vns_def_mode():
+            if not self.vns_debug_show_commands('vns-interface-rule'):
+                opts.remove("interface-rule")
+        if "firewall" in opts and not self.in_config_controller_interface_mode():
+            opts.remove("firewall")
+        # synthetic object type based on the vnsconfig submode.
+        if "access-list-entry" in opts and not self.in_config_vns_acl_mode():
+            if not self.vns_debug_show_commands('vns-access-list-entry'):
+                opts.remove("access-list-entry")
+        ret_hash["commands"] = opts
+
+        # now get obj_types we can show
+        opts = self.all_obj_types_starting_with(text)
+        if self.in_config_submode() and "this".startswith(text):
+            opts.append("this")
+        ret_hash["objects"] = opts
+        return ret_hash
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_show_object
+    #  show <obj_type> (words[0] == obj_type)
+    #
+    def cp_show_object(self, words, text, completion_char):
+        if len(words) == 1:
+            return objects_starting_with(words[0], text)
+        else:
+            self.print_completion_help("<cr>")
+    #
+    # --------------------------------------------------------------------------------
+    # get_attachment_points
+    #
+    @staticmethod
+    def get_attachment_points(host, host_dap_dict):
+        items = host_dap_dict.get(host['mac'])
+        if not items or len(items) <= 1:
+            return items
+        #
+        # sort by most recent items, if the last-seen field
+        # exists for all entries
+        #
+        for item in items:
+            if not 'last-seen' in item or item['last-seen'] == '':
+                return items
+
+        ordered = sorted(items,
+                         key=lambda i: i['last-seen'],
+                         cmp=lambda x,y: cmp(y,x))
+        ordered[0]['prime'] = True
+        return ordered
+
+    #
+    # --------------------------------------------------------------------------------
+    # create_attachment_dict
+    #
+    def create_attachment_dict(self):
+        return create_obj_type_dict('host-attachment-point', 'mac')
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_ip_addresses
+    #
+    @staticmethod
+    def get_ip_addresses(host, host_ip_dict):
+        items = host_ip_dict.get(host['mac'])
+        if not items or len(items) <= 1:
+            return items
+
+        for item in items:
+            if not 'last-seen' in item or item['last-seen'] == '':
+                return items
+        #
+        # sort by most recent items, if every row has a 'last-seen' field
+        #
+        ordered = sorted(items,
+                         key=lambda i: i['last-seen'],
+                         cmp=lambda x,y: cmp(y,x))
+        ordered[0]['prime'] = True
+        return ordered
+
+    #
+    # --------------------------------------------------------------------------------
+    # create_ip_dict
+    #  Returns a dictionary with the host id (mac address) as the key,
+    #  and a list of associated rows for that host id.
+    #
+    def create_ip_dict(self):
+        return create_obj_type_dict('host-network-address', 'mac')
+
+    #
+    # --------------------------------------------------------------------------------
+    # show_sort_obj_type
+    #  Returns a sorted list of entries based on the sort described by
+    #  the obj-dict
+    #
+    def show_sort_obj_type(self, obj_type, entries):
+        sort = mi.obj_type_show_sort(obj_type)
+        if not sort:
+            return entries
+        if sort == 'integer':
+            key = mi.pk(obj_type)
+            return sorted(entries, key=lambda k: k[key].split('|')[-1],
+                                   cmp=lambda x,y: cmp(utif.try_int(x), utif.try_int(y)))
+        elif sort == 'tail-integer':
+            key = mi.pk(obj_type)
+            def comparer(left, right):
+                prefix = cmp(left[:-1], right[:-1])
+                if prefix != 0:
+                    return prefix
+                return cmp(utif.try_int(left[-1]), utif.try_int(right[-1]))
+
+            return sorted(entries, key=lambda k: k[key].split('|'), cmp=comparer)
+        else:
+            return self.error_msg("Unknown sort %s" % sort)
+
+    #
+    # --------------------------------------------------------------------------------
+    # display_obj_type_rows
+    #  Given an obj_type, rows, and whether or not a key was provided to search
+    #  with, generate the output table.
+    #
+    def display_obj_type_rows(self, obj_type, rows, with_key = '<no_key>', detail = "default"):
+        #
+        # handle spedicific issues with particular tables returned from storage
+        # - change vns-id's with "|" into separate columns
+        # - the host case does a 'merge' for attachment-points and IPs
+        #   (used in 'show host')
+        def handle_specific_obj_type(obj_type, entries, field_orderings = 'default'):
+            if obj_type == "host":
+                # host_tag_dict = create_obj_type_dict('tag-mapping', 'host')
+                for host in entries:
+                    host['vendor'] = self.vendordb.get_vendor(host['mac'])
+                    # host['tag'] = host_tag_dict.get(host['mac'], [])
+            if obj_type == "host-config":
+                host_dap_dict = self.create_attachment_dict()
+                host_ip_dict = self.create_ip_dict()
+                host_tag_dict = create_obj_type_dict('tag-mapping', 'mac')
+                for host in entries:
+                    host['vendor'] = self.vendordb.get_vendor(host['mac'])
+                    host['attachment-points'] = self.get_attachment_points(host, host_dap_dict)
+                    host['ips'] = self.get_ip_addresses(host, host_ip_dict)
+                    host['tag'] = host_tag_dict.get(host['mac'], [])
+            if obj_type == 'controller-node':
+                for controller_node in entries:
+                    domain_name_servers = []
+                    domain_name_servers = self.rest_query_objects(
+                        'controller-domain-name-server',
+                        {'controller': controller_node['id'],
+                         'orderby' : 'timestamp'})
+                    controller_node['domain-name-servers'] = [domain_name_server['ip']
+                        for domain_name_server in domain_name_servers]
+                    controller_node['id'] = ' '.join(controller_node['id'].split('|'))
+            if obj_type == 'controller-interface':
+                for intf in entries:
+                    rules = [x['rule'] for x in self.get_firewall_rules(intf['id'])]
+                    intf['firewall'] = ', '.join(rules)
+                    # del intf['id'] XXX should the id really get displayed?
+            tables_with_vns_ids = [ "vns-interface-rule", "vns-interface",
+                                    "host-vns-interface", "vns-access-list",
+                                    "vns-access-list-entry", "vns-interface-access-list" ]
+            if obj_type in tables_with_vns_ids:
+                self.vns_table_id_to_vns_column(obj_type, entries)
+                if self.in_config_submode("config-vns") and field_orderings == 'default':
+                    field_orderings = 'vns-config'
+                self.vns_join_host_fields(obj_type, entries)
+                self.vns_foreign_key_to_base_name(obj_type, entries)
+            if obj_type == 'vns-access-list-entry':
+                # display the alternative access-list-text format 
+                vns_acl_entries_to_brief(entries)
+                # field_orderings = 'acl-brief'
+            if obj_type == 'vns-access-list-entry-brief':
+                # display the alternative access-list-text format 
+                vns_acl_entries_to_brief(entries)
+                field_orderings = 'acl-brief'
+            #if obj_type == 'tag-mapping':
+                #self.handle_specific_tag_fields(entries)
+
+            # XXX may need to revisit to prevent don't leak vns information
+
+            if obj_type in ['dvs-port-group', 'firewall-rule', 'tag-mapping']:
+                for entry in entries:
+                    mi.split_compound_into_dict(obj_type,
+                                                mi.pk(obj_type),
+                                                entry)
+            #
+            # objects where foreigh keys are references to
+            # compount key's, needing to be split. 
+            # XXX these can be identified by scanning the objects during init
+            if obj_type in ['switch-interface-alias',
+                           ]:
+                # only pick foreign keys which are compound keys
+                fks = [x for x in mi.obj_type_foreign_keys(obj_type)
+                       if mi.is_compound_key(obj_type,x)]
+                for entry in entries:
+                    for fk in fks:
+                        if fk in entry: # fk may be null-able
+                            mi.split_compound_into_dict(obj_type, fk, entry)
+                    if 'switch-interface' in entry:
+                        si = entry['switch-interface']
+ 
+            #
+            if obj_type == 'firewall-rule':
+                self.firewall_rule_add_rule_to_entries(entries)
+            return field_orderings
+     
+        field_orderings = handle_specific_obj_type(obj_type, rows, detail)
+        #
+        # join alias names.  there is a good chance the alias's tables
+        #  are small.  since iteration over all the rows is needed,
+        #  first identify the alias tables involved, then snap the
+        #  complete table into memory, and then decorae with the
+        #  specific alias fields.  XXX it would be even better to
+        #  get a size of 'rows' vs the 'alias' table, and choose
+        #  the more performance path...
+        #
+        if obj_type in mi.alias_obj_type_xref:
+            obj_key = mi.pk(obj_type)
+            for alias in mi.alias_obj_type_xref[obj_type]:
+                alias_field = mi.alias_obj_type_field(alias)
+                if not alias_field:
+                    print self.error_msg("internal alias in display_obj_type")
+                try:
+                    alias_rows = self.get_table_from_store(alias)
+                except Exception, e:
+                    errors = self.rest_error_to_dict(e, alias)
+                    print self.rest_error_dict_to_message(errors)
+                    alias_rows = []
+
+                # invert the row once, moving the key to the data.
+                alias_key = mi.pk(alias)
+                rows_alias = dict([[a[alias_field], a[alias_key]] for a in alias_rows])
+
+                # collect the name of the field to join (fk_name)
+                # 
+                (fk_obj_type, fk_name) = \
+                    mi.foreign_key_references(alias, alias_field)
+                # now associate alias's with the row's field:
+                for row in rows:
+                    if fk_name in row:
+                        if row[fk_name] in rows_alias:
+                            row[alias] = rows_alias[row[fk_name]]
+                    elif fk_obj_type in row:
+                        if row[fk_obj_type] in rows_alias:
+                            row[alias] = rows_alias[row[fk_obj_type]]
+            #
+            # this choice is better if the alias's table is large.
+            if 0: #for row in rows:
+                key = mi.pk(obj_type)
+                for alias in mi.alias_obj_type_xref[obj_type]:
+                    field = mi.alias_obj_type_field(alias)
+                    if not field:
+                        print self.error_msg("internal alias in display_obj_type")
+                    alias_row = self.get_table_from_store(alias,
+                                                          field,
+                                                          row[key],
+                                                          "exact")
+                    if len(alias_row) > 1:
+                        print 'Error: multiple aliases for %s' % \
+                              alias
+                    elif len(alias_row) == 1:
+                        row[alias] = alias_row[0][mi.pk(alias)]
+
+        if len(rows) == 0:
+            if with_key != '<no_key>':
+                return self.error_msg("No %s %s found" % (obj_type, with_key))
+            else:
+                return self.pp.format_table(rows, obj_type, field_orderings)
+        elif len(rows) == 1 and with_key != '<no_key>':
+            return self.pp.format_entry(rows[0], obj_type,
+                                        debug = self.debug)
+
+        return self.pp.format_table(self.show_sort_obj_type(obj_type, rows),
+                                    obj_type,
+                                    field_orderings)
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_object
+    #  Implements the show command for objects (table/model output of rows)
+    #
+    def do_show_object(self, words, with_search_key = None):
+        obj_type = words[0]
+
+        #
+        # The cli replaces some user names with table names
+        if obj_type == 'tag':
+            obj_type = 'tag-mapping'
+
+        match = "startswith"
+        #
+        # Allow "this" reference if we are in config-submode, change the
+        # match to an exact match to prevent prefix matching
+        if obj_type == "this":
+            if self.in_config_submode():
+                obj_type = self.get_current_mode_obj_type()
+                words = [obj_type, "this"]
+                match = "exact"
+            else:
+                return self.error_msg("\"this\" can only be used in configuration"
+                                      " submode, such as switch, port, host, etc.")
+        #
+        # complete table lookup: 'show <table>'
+        if len(words) == 1:
+            if with_search_key == None:
+                with_search_key = "<no_key>"
+            errors = None
+            try:
+                entries = self.get_table_from_store(obj_type)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, obj_type)
+                
+            if errors:
+                return self.rest_error_dict_to_message(errors)
+            return self.display_obj_type_rows(obj_type, entries, with_search_key)
+
+        # table with key:  "show <table> <key>"
+        if len(words) == 2:
+            obj = words[1]
+            if with_search_key == None:
+                with_search_key = obj
+
+            # Allow "this" reference if we are in config-submode
+            if obj == "this" and \
+              obj_type == self.get_current_mode_obj_type() \
+              and self.in_config_submode():
+                obj = self.get_current_mode_obj()
+
+            key = mi.pk(obj_type)
+            if key:
+                obj = convert_alias_to_object_key(obj_type, obj)
+                if mi.obj_type_has_model(obj_type):
+                    entries = self.get_table_from_store(obj_type, key, obj, match)
+                else:
+                    # XXX raise internal error?  model doesn't exist.
+                    print command._line(), obj_type
+                    entries = []
+                return self.display_obj_type_rows(obj_type, entries, with_search_key)
+            else:
+                return self.pp.format_table(self.get_table_from_store(obj_type),
+                                            obj_type)
+        elif "stats".startswith(words[2]):
+            return self.helper_show_object_stats(words)
+        else:
+            return "Syntax: show <table> <key>:  " \
+                    "Unrecognized input: " + " ".join(words[2:])
+
+    #
+    # --------------------------------------------------------------------------------
+    # helper_show_object_stats
+    #
+    def helper_show_object_stats(self, words):
+        if self.stats_metadata == None:
+            self.init_stats_metadata()
+
+        # get object type
+        object_type = words[0]
+
+        # The rest stats api differs from the CLI in some of the
+        # object names, so this map allows us to fix it
+        if object_type in self.stats_restapi_map:
+            object_type = self.stats_restapi_map[object_type]
+
+        if object_type not in self.stats_type_metadata:
+            return self.error_msg('no statistics available for object type %s' % 
+                                  object_type)
+
+        # Get the specific object to operate on
+        sobject = words[1];
+        
+        # the controller-node objects don't currently have any real
+        # concept of a unique ID for a controller; for now the stats
+        # are always labeled 'localhost' even though that will never
+        # appear in the controller-node list
+        if ('controller-node'.startswith(object_type)):
+            sobject = 'localhost'
+
+        tocheck = []
+        # get statistic name
+        if len(words) > 3:
+            if (words[3] not in self.stats_metadata or 
+                self.stats_metadata[words[3]]['target_type'] != object_type):
+                return self.error_msg('no statistic %s available for object type %s' % 
+                                      (words[3], object_type))
+            tocheck.append(words[3])
+        else:
+            tocheck = [item['name'] 
+                       for item in self.stats_type_metadata[object_type]]
+
+        parsed_options = {}
+        if (len(words) > 4):
+            try:
+                parsed_options = \
+                    self.parse_optional_parameters(self.stats_optional_params, 
+                                                   words[4:])
+            except ParamException as e:
+                return self.error_msg(e)
+
+        display = 'latest-value'
+        timespec = False
+        now = int(time.time()*1000)
+        query_params = {'start-time': now - 3600000,
+                        'end-time': now,
+                        'sample-count': 25,
+                        'data-format': 'value'}
+
+        if 'start-time' in parsed_options:
+            timespec = True
+            try:
+                query_params['start-time'] = self.parse_date(parsed_options['start-time'])
+            except Exception as e:
+                return self.error_msg('invalid start time %s: %s' % 
+                                      (parsed_options['start-time'], e))
+
+        if 'end-time' in parsed_options:
+            timespec = True
+            try:
+                query_params['end-time'] = self.parse_date(parsed_options['end-time'])
+            except Exception as e:
+                return self.error_msg('invalid end time %s: %s' % 
+                                      (parsed_options['end-time'], e))
+
+        if 'duration' in parsed_options:
+            timespec = True
+            try:
+                query_params['duration'] = parsed_options['duration']
+                if 'start-time' in parsed_options:
+                    del query_params['end-time']
+                else:
+                    del query_params['start-time']
+
+            except:
+                return self.error_msg('invalid duration %s' % 
+                                      parsed_options['duration'])
+
+        if 'display' in parsed_options:
+            display = parsed_options['display']
+
+        if timespec and display == 'latest-value':
+            display = 'graph'
+
+        if display == 'graph':
+            query_params['sample-count'] = self.pp.get_terminal_size()[0]
+
+        for p in ['sample-count', 'limit', 'sample-window', 
+                  'sample-interval', 'data-format']:
+            if p in parsed_options:
+                query_params[p] = parsed_options[p]
+
+        if display == 'latest-value':
+            data = {}
+            for item in tocheck:
+                url = ('http://%s/rest/v1/stats/data/%s/%s/%s/%s/' % 
+                       (self.controller, self.cluster, object_type, 
+                        sobject, item))
+                try:
+                    (timestamp, value) = self.rest_simple_request_to_dict(url)
+                    data[self.stats_metadata[item]['name']] = "%d" % value
+                except:
+                    data[self.stats_metadata[item]['name']] = "[Null]"
+
+            return self.pp.format_entry(data, 'stats-%s' % object_type)
+        else:
+            item = tocheck[0]
+            url = ('http://%s/rest/v1/stats/data/%s/%s/%s/%s/?%s' % 
+                       (self.controller, self.cluster, object_type, 
+                        sobject, item, "&".join(['%s=%s' % (k,v)
+                                                 for k,v 
+                                                 in query_params.iteritems()])))
+            try:
+                json_data = self.rest_simple_request_to_dict(url)
+            except Exception as e:
+                if self.debug_backtrace:
+                    print 'FAILED URL', url
+                return self.error_msg('could not load stats data: %s' % e)
+
+            if display == 'table':
+                data = []
+                for (timestamp, value) in json_data:
+                    data.append({'timestamp': int(timestamp),
+                             'value': value})
+                return self.pp.format_table(data, 'stats-%s-%s-%s' % 
+                                            (object_type, item, 
+                                             query_params['data-format']))
+            elif display == 'graph':
+                return self.pp.format_time_series_graph(json_data, 
+                                                        'stats-%s-%s-%s' % 
+                                                        (object_type, item, 
+                                                         query_params['data-format']))
+    #
+    # --------------------------------------------------------------------------------
+    # parse_date
+    #
+    @staticmethod
+    def parse_date(text):
+        if (text == 'now' or text == 'current'):
+            return int(time.time()*1000)
+
+        try:
+            return int(text)
+        except: 
+            pass
+
+        for f, pre in [('%Y-%m-%dT%H:%M:%S', None),
+                       ('%Y-%m-%d %H:%M:%S', None),
+                       ('%Y-%m-%dT%H:%M:%S%z', None),
+                       ('%Y-%m-%d %H:%M:%S%z', None),
+                       ('%Y-%m-%d', None),
+                       ('%m-%d', '%Y-'),
+                       ('%H:%M', '%Y-%m-%dT')]:
+            try:
+                t = text
+                if pre:
+                    pref = datetime.datetime.now().strftime(pre)
+                    f = pre + f
+                    t = pref + t
+
+                thetime = datetime.datetime.strptime(t, f)
+                return int(time.mktime(thetime.timetuple())*1000)
+            except: 
+                pass
+
+        raise ValueError('count not parse %s as a timestamp' % text)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # display_vns_interface
+    #  Search dist is a collection of compund key entities
+    #
+    def display_vns_interface(self, vns_name, search_dict, with_search_key, detail = 'default'):
+        obj_type = 'vns-interface'
+        obj_key = mi.pk(obj_type)
+        try:
+            entries = rest_to_model.get_model_from_url(obj_type, search_dict)
+            #entries = self.rest_query_objects(obj_type,
+                                              #search_dict)
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, obj_type)
+                
+        if errors:
+            return self.rest_error_dict_to_message(errors)
+        vns_rules = create_obj_type_dict('vns-interface-rule',
+                                         mi.pk('vns-interface-rule'),
+                                         search_dict
+                                         )
+        #
+        # divide up the result into two parts, the first part is
+        # the physical interfaces, the second is the mac interfaces...
+        phys = []
+        macs = []
+            
+        for entry in entries:
+            fields = entry[obj_key].split('|')
+            entry['tenant'] = fields[0]
+            entry['vns']=fields[1]
+            # all these fields must have two parts.
+            if len(fields) != 3:
+                continue
+            
+            # choose between switch based rules and mac/ip based rules
+            rule = 'default'
+            switch = None
+            virt = None
+            #
+            # Each address-space would have a default vns named
+            # named <as>-default, except the 'default' adddress-space which
+            # has a default vns named just 'default'
+            #
+            if fields[1] == "default" or fields[1].endswith("-default"):
+                virt = 'default'
+                if fields[2].find('/') >= 0:
+                    virt = fields[2].split('/')[1]
+            else:
+                if not 'rule' in entry or entry['rule']=='default':
+                    if_rule = []
+                    virt = True
+                    # continue
+                else:
+                    rule = entry['rule']
+                    if_rule = vns_rules[rule][0]
+                
+                if 'switch' in if_rule:
+                    switch = if_rule['switch']
+                elif 'mac' in if_rule:
+                    virt = if_rule['mac']
+                    entry['mac'] = virt
+                elif 'ip-subnet' in if_rule:
+                    virt = {'ip-address': if_rule['ip-subnet']}
+                    if 'ips' in entry:
+                        entry['ips'].append(virt)
+                    else:
+                        entry['ips'] = [virt]
+                elif 'tags' in if_rule:
+                    virt = if_rule['tags']
+                    entry['tags'] = virt
+                elif 'vlans' in if_rule:
+                    virt = "vlan %s" % if_rule['vlans']
+                    entry['vlans'] = virt
+
+            if switch:
+                phys.append(entry)
+            if virt:
+                entry['veth'] = entry[obj_key].split('|')[2]
+                macs.append(entry)
+
+        output = ''
+        if len(phys):
+            self.vns_join_switch_fields(vns_name, phys)
+            output += self.display_obj_type_rows('vns-interface-phys', phys, with_search_key, detail)
+        if len(macs):
+            if len(phys):
+                output += '\n'
+            self.vns_join_host_fields(obj_type, macs)
+            output += self.display_obj_type_rows('vns-interface-macs', macs, with_search_key, detail)
+
+        if output != '':
+            return output
+        return self.pp.format_table([],'display-vns-interface')
+
+    #
+    # --------------------------------------------------------------------------------
+    # find_and_display_vns_interfaces
+    #
+    def find_and_display_vns_interface(self, vns_name, words):
+        with_search_key = "<no_key>"
+        search_dict = { 'vns' : vns_name }
+        if len(words) == 1:
+            search_dict['interface'] = words[0]
+        elif len(words) > 1:
+            return self.error_msg("Additional search keys after interace")
+
+        return self.display_vns_interface(vns_name, search_dict, with_search_key)
+        
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_vns_interfaces
+    #  This definition is needed to allow the vns-interface table/model to
+    #  be displayed in basic config mode.  do_show() searches names of functions
+    #  using the prefix of the 'show' argument; without this function,
+    #  it find 'do_show_vns_interface_rule' and selects that function to
+    #  display results for 'show vns-interface`.
+    #
+    def do_show_vns_interfaces(self, words):
+        with_search_key = "<no_key>"
+        local_vns_name = self.vns_name()
+        if self.vns_name() is None:
+            if len(words) > 0:
+                local_vns_name = words[0]
+                search_dict = { 'vns' : local_vns_name }
+            else:
+                # only case where the vns name is included is the output 
+                return self.do_show_object(['vns-interface'], with_search_key)
+        else:
+            search_dict = { 'vns' : local_vns_name }
+            if len(words) == 1:
+                with_search_key = words
+                search_dict['interface'] = words[0]
+            elif len(words) > 2:
+                return self.error_msg("Additional search keys after interace")
+
+        return self.display_vns_interface(local_vns_name, search_dict, with_search_key)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # display_vns_mac_address_table
+    #  Used by 'show vns <n> mac-address-table', and vns mode 'show mac-address-table'
+    #
+    def display_vns_mac_address_table(self, vns_name, words):
+        # note: 'config-vns' matches both vns and vns-definition mode,
+        #  while 'config-vns-' matches only vns-definition mode.
+        # the id for the host-vns-interface table has the host as the 'prefix',
+        # preventing searching based on the prefix.  the vns is not even a foreign
+        # key, which means the complete table must be read, then the vns association
+        # must be determined, and then matched
+        filter = { 'vns' : vns_name } if vns_name != 'all' else {}
+        if len(words):
+            filter['mac'] = words[0]
+        entries = rest_to_model.get_model_from_url('host-vns-interface', filter)
+        for entry in entries:
+            fields=entry['vns'].split('|')
+            entry['tenant']=fields[0]
+            entry['vns']=fields[1]
+        with_key = '<no_key>'
+        if len(words) > 0:
+            with_key = words[0]
+
+        #detail = 'vns'          # exclude vns column, vns is named
+        detail = 'default'          # exclude vns column, vns is named
+        if vns_name == 'all':
+            detail = 'default'  # include vns column, vns not named
+
+        # self.vns_join_host_fields('host-vns-interface', entries)
+        return self.display_obj_type_rows('host-vns-interface-vns', entries, with_key, 'default')
+        
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_vns_mac_address_table
+    #  config and vns mode 'show mac-address-table' command
+    #
+    def do_show_vns_mac_address_table(self, words):
+        if words == None or len(words) > 2:
+            return self.syntax_msg('show mac-address-table <host>')
+
+        if self.in_config_submode('config-vns'):
+            return self.display_vns_mac_address_table(self.vns_name(), words)
+
+        if len(words) > 0:
+            return self.do_show_object(['host'] + words, 'with_key')
+        return self.do_show_object(['host'])
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_switch_cluster
+    #
+    def do_show_switch_cluster(self, words):
+        data = self.rest_simple_request_to_dict(
+                    'http://%s/rest/v1/realtimestatus/network/cluster/' % self.controller)
+
+        formatted_data = []
+        for (clusterid, switchids) in data.items():
+            row = {}
+            row['switches'] = switchids
+            row['cluster-id'] = clusterid
+            formatted_data.append(row)
+        return self.display_obj_type_rows('switch-cluster', formatted_data)
+    
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_controller_summary
+    #
+    def do_show_controller_summary(self, words):
+        data = self.rest_simple_request_to_dict(
+                    'http://%s/rest/v1/controller/summary' % self.controller)
+
+        # XXX Need a way to sort the data in a way that makes sense
+        for (key, value) in data.items():
+            yield key + ":  " + str(value) + "\n"
+    
+    #
+    # --------------------------------------------------------------------------------
+    # get_statistics_type
+    #
+    @staticmethod
+    def get_statistics_type(stat_type):
+        for s in ["flow", "port", "table", "desc", "aggregate", "features", "trace",]:
+            if s.startswith(stat_type):
+                return s
+        return None
+
+    #
+    # --------------------------------------------------------------------------------
+    # fix_realtime_flows_wildcard_fields
+    #
+    def fix_realtime_flow_wildcard_fields(self, in_data):
+        for l in in_data:
+            if 'wildcards' in l:
+                wildcards = l['wildcards']
+                bit_field_map = {
+                    0 : 'inputPort',
+                    1 : 'dataLayerVirtualLan',
+                    2 : 'dataLayerSource',
+                    3 : 'dataLayerDestination',
+                    4 : 'dataLayerType',
+                    5 : 'networkProtocol',
+                    6 : 'transportSource',
+                    7 : 'transportDestination',
+                    13 : 'networkSource',
+                    19 : 'networkDestination',
+                    20 : 'dataLayerVirtualLanPriorityCodePoint',
+                    21 : 'networkTypeOfService',
+                    }
+                for (k, v) in bit_field_map.items():
+                    if wildcards & (1 << k):
+                        l[v] = "*"
+
+    #
+    # --------------------------------------------------------------------------------
+    # fix_realtime_flows
+    #
+    def fix_realtime_flows(self, in_data):
+        if not in_data:
+            return
+        # flatten match data
+        for l in in_data:
+            match_dict = l['match']
+            l.update(match_dict)
+            del(l['match'])
+
+        self.fix_realtime_flow_wildcard_fields(in_data)
+        return in_data
+
+    #
+    # --------------------------------------------------------------------------------
+    # add_dpid_to_data
+    #
+    @staticmethod
+    def add_dpid_to_data(data):
+        if not type(data) is dict: # backward-compatible
+            return data 
+        formatted_list = []
+        for (dpid, rows) in data.items():
+            if rows != None:
+                for row in rows:
+                    row['switch'] = dpid
+                    formatted_list.append(row)
+        ## TODO - Alex - handle timeouts + sorting
+        return formatted_list
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_statistics
+    #
+    # LOOK! we could get rid of show statistics at this point as it is all under
+    # show switch!
+    #
+    # it's confusing to remap it over here...
+    # we could remove show flow-entry realtime too for now
+    #
+    def do_show_statistics(self, words):
+        if len(words) < 1:
+            return "Syntax: show statistics < flow | port | table | desc | aggregate | " \
+                                              "features | trace > < Switch DPID | Switch alias | all >"
+        stat_type = self.get_statistics_type(words[0])
+        dpid = None
+        if len(words) > 1:
+            words[1] = convert_alias_to_object_key("switch", words[1])
+            dpid = words[1] # LOOK! Eventually optional so we can show across switches
+            if not dpid in objects_starting_with("switch", dpid) and dpid != "all": 
+                return self.error_msg("No switch %s found" % dpid)
+        if stat_type == "flow":
+            data = self.rest_simple_request_to_dict(
+                             'http://%s/rest/v1/realtimestats/flow/%s/' % (self.controller,dpid))            
+            data = self.add_dpid_to_data(data)            
+            data = self.fix_realtime_flows(data)            
+
+            # 
+            # it may make sense to move ['details', 'brief'] tp some sort of
+            # 'show_object_optional_format_keywords' list
+            field_ordering = "default"
+            if len(words) == 3:
+                choices = [x for x in ["details", "brief"] if x.startswith(words[2])]
+                if len(choices) != 1:
+                    return self.error_msg("switch flow options are either 'details' or 'brief'")
+                else:
+                    field_ordering = choices[0]
+            table_data = self.pp.format_table(data, "realtime_flow", field_ordering)
+            return table_data
+        elif stat_type == "trace":
+            return self.do_trace(words)
+        elif words[0] == "switches":
+            data = self.rest_simple_request_to_dict(
+                            'http://%s/rest/v1/controller/stats/%s/' % (self.controller, words[0]))
+            table_data = self.pp.format_table(data, "controller_"+words[0])
+            return table_data
+        else:
+            data = self.rest_simple_request_to_dict(
+                            'http://%s/rest/v1/realtimestats/%s/%s/' % (self.controller, stat_type, dpid))
+            if stat_type == "features":
+                for dpid in data:
+                    data[dpid] = data[dpid]["ports"]
+            data = self.add_dpid_to_data(data)
+            table_data = self.pp.format_table(data, "realtime_"+stat_type)
+            return table_data
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_version
+    #
+    def do_show_version(self, words):
+        # LOOK! this should probably come from the controller, but for now
+        # we assume the CLI/controller are from the same build
+        version_string = "SDNOS 1.0 - custom version"
+        try:
+            fh = open("/opt/sdnplatform/release") 
+            version_string = fh.readline().rstrip()
+            fh.close()
+        except:
+            pass
+        return version_string
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_date
+    #
+    @staticmethod
+    def do_date(words):
+        return time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime())
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_show_logging
+    #
+    def cp_show_logging(self, words, text, completion_char):
+        if len(words) == 1:
+            return [x for x in ["sdnplatform", "cassandra", "console-access",
+                                 "syslog", "authlog", "orchestrationlog",
+                                 "all" ] if x.startswith(text)]
+        else:
+            self.print_completion_help("<cr>")
+
+    #
+    # --------------------------------------------------------------------------------
+    # generate_subpprocess_output
+    #
+    def generate_subprocess_output(self, cmd):
+        process = subprocess.Popen(cmd, shell=True,
+                                   stdout=subprocess.PIPE, 
+                                   stderr=subprocess.STDOUT,
+                                   bufsize=1)
+        while True:
+            line = process.stdout.readline()
+            if line != None and line != "":
+                yield line
+            else:
+                break
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def implement_show_logging(self, words):
+        log_files = { "sdnplatform" : "cat /opt/sdnplatform/sdnplatform/log/sdnplatform.log",
+                      "cassandra" : "cat /opt/sdnplatform/db/log/system.log",
+                      "console-access" : "cat /opt/sdnplatform/con/log/access.log",
+                      "syslog" : "cat /var/log/syslog",
+                      "authlog" : "cat /var/log/auth.log",
+                      "orchestrationlog" : "cat /tmp/networkservice.log",
+                      "dmesg" : "dmesg",
+                      "all" : ""  # special
+                      }
+        if len(words) < 1:
+            yield "Syntax: show logging < %s > " % " | ".join(log_files.keys())
+            return
+        for (f, cmd) in log_files.items():
+            if (f.startswith(words[0]) or "all".startswith(words[0])) and f != "all":
+                yield "*"*80 + "\n"
+                yield "output of %s for %s\n" % (cmd, f)
+                yield "*"*80 + "\n"
+                for item in self.generate_subprocess_output(cmd):
+                    yield item
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_tech_support
+    #
+    def do_show_tech_support(self, words):
+
+        oldd = self.debug
+    
+        tech_support_table = []
+
+        # Add the user customized command in tech-support-config table
+        entries = self.get_table_from_store('tech-support-config')
+        for entry in entries:
+            # need explicit type casting str() to make command handling work
+            tech_support_table.append([str(entry['cmd-type']), str(entry['cmd']), None])
+
+        # Add the list of command configured for the basic support
+        for entry in tech_support.get_show_tech_cmd_table():
+            tech_support_table.append(entry)
+
+    
+        for entry in tech_support_table:
+            cmd_type = entry[0]
+            cmd = entry[1]
+            feature = entry[2]
+    
+            # If feature is non-null, then check feature is enabled 
+            # before executing the command
+            if feature != None and self.feature_enabled(feature) == False :
+                continue
+    
+            if cmd_type == 'cli':
+                yield "\n\n" + "-"*80 + "\nExecute cli: " + cmd + "\n\n"
+                try:
+                    for item in self.generate_command_output(self.handle_single_line(cmd)):
+                        yield item
+                except Exception as e:
+                    yield "Failed to execute %s: %s\n" % (cmd, e)
+            elif cmd_type == 'shell':
+                yield "\n\n" + "-"*80 + "\nExecuting os command: " + cmd + "\n\n"
+                try:
+                    for item in self.generate_subprocess_output(cmd):
+                        yield item
+                except Exception as e:
+                    yield "Failed to run command %s: %s\n" % (cmd, e)
+            else:
+                yield "Unknown command type %s: %s\n" % (cmd_type, cmd)
+    
+        self.debug = oldd
+
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # ell_ess_minus_r
+    #  Do "ls -R", returing the list of files underneath "prefix".
+    #  The intended external call is 
+    #  ell_ess_minus_r(returned_items, "/opt/sdnplatform/...",  ""),
+    #  where the path parameter is null to begin the walk.
+    #
+    #  The returned items won't have the original prefix in the items
+    #
+    #  XXX: There's no bounding for the recursive descent.
+    #
+    def ell_ess_minus_r(self, items, prefix, path):
+        p = os.path.join(prefix, path)
+        if os.path.isdir(p):
+            for entry in os.listdir(p):
+                new_path = os.path.join(path, entry)
+                if os.path.isdir(os.path.join(prefix, new_path)):
+                    self.ell_ess_minus_r(items, prefix, new_path)
+                else:
+                    items.append(os.path.join(path, entry))
+        return items
+            
+    #
+    # --------------------------------------------------------------------------------
+    # implement_show_config_file
+    #  'show config file' displays the local files under self.saved_configs_dirname
+    #   currently /opt/sdnplatform/run/saved-configs
+    #
+    def implement_show_config_file(self, words):
+        items = []
+        self.ell_ess_minus_r(items, self.saved_configs_dirname, "")
+
+        if len(words) == 1:
+            entries = []
+            for i in items:
+                cf = os.path.join(self.saved_configs_dirname, i)
+                t = time.strftime("%Y-%m-%d.%H:%M:%S",
+                                  time.localtime(os.path.getmtime(cf)))
+                entries.append({'name' : i,
+                                'timestamp': t,
+                                'length' : str(os.path.getsize(cf)),
+                               })
+            return self.pp.format_table(entries,'config')
+        elif len(words) == 2:
+            if words[1] in items:
+                src_file = self.path_concat(self.saved_configs_dirname, words[1])
+                if src_file == "":
+                    return self.error_msg("file %s could not be " 
+                                          "interpreted as a valid source" % words[1])
+                try:
+                    return self.store.get_text_from_url("file://" + src_file)
+                except Exception, e:
+                    return self.error_msg(words[1] + ":" + str(e))
+            else:
+                return self.error_msg("%s file unknown" % words[1])
+    #
+    #
+    # --------------------------------------------------------------------------------
+    # implement_show_config
+    #
+    def implement_show_config(self, words):
+        name = None
+        show_version = "latest"
+        # handle sh config [ <name> [ all | <version #> ] ]
+
+        if len(words) == 1:
+            if words[0] == "all":
+                show_version = "all"
+            elif words[0] == "file":
+                return self.implement_show_config_file(words)
+            elif words[0].startswith('config://'):
+                name = words[0][len('config://'):]
+            else:
+                name = words[0]
+        elif len(words) == 2:
+            if words[0] == 'file':
+                return self.implement_show_config_file(words)
+            name = words[0]
+            show_version = words[1]
+        elif len(words) == 3 and words[1] == "diff":
+            return self.diff_two_configs(words[0], words[2])
+        elif len(words) == 4 and words[1] == "diff":
+            return self.diff_two_versions(words[0], words[2], words[3])
+
+        data = self.store.get_user_data_table(name, show_version)
+        if data and len(data) > 1 or name == None:
+            return self.pp.format_table(data,'config')
+        elif data and len(data) == 1:
+            return self.store.get_user_data_file(data[0]['full_name'])[:-1]
+
+    #
+    # --------------------------------------------------------------------------------
+    # diff_two_versions
+    #
+    def diff_two_versions(self, name, va, vb):
+        va_info = self.store.get_user_data_table(name, va)
+        if len(va_info) == 0:
+            return self.error_msg("Version %s missing for %s" %  (va, name))
+        va_txt = self.store.get_user_data_file(va_info[0]['full_name'])
+        vb_info = self.store.get_user_data_table(name, vb)
+        if len(vb_info) == 0:
+            return self.error_msg("Version %s missing for %s" % (vb, name))
+        vb_txt = self.store.get_user_data_file(vb_info[0]['full_name'])
+        import tempfile
+        fa = tempfile.NamedTemporaryFile(delete=False)
+        fa.write(va_txt)
+        fa.close()
+        fb = tempfile.NamedTemporaryFile(delete=False)
+        fb.write(vb_txt)
+        fb.close()
+        cmd = 'diff %s %s ' % (fa.name, fb.name)
+        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
+        (output, stderr) = process.communicate()
+        os.unlink(fa.name)
+        os.unlink(fb.name)
+        return output
+
+    #
+    # --------------------------------------------------------------------------------
+    # diff_two_configs
+    #
+    def diff_two_configs(self, config_a, config_b):
+        items = self.store.get_user_data_table(config_a, "latest")
+        if len(items) == 0:
+            if config_a == 'running-config':
+                txt_a = run_config.implement_show_running_config([]) + "\n"
+            else:
+                return self.error_msg("%s config missing" % config_a)
+        else:
+            txt_a = self.store.get_user_data_file(items[0]['full_name'])
+
+        items = self.store.get_user_data_table(config_b, "latest")
+        if len(items) == 0:
+            if config_b == 'running-config':
+                txt_b = run_config.implement_show_running_config([]) + "\n"
+            else:
+                return self.error_msg("%s config missing" % config_b)
+        else:
+            txt_b = self.store.get_user_data_file(items[0]['full_name'])
+
+        import tempfile
+        fa = tempfile.NamedTemporaryFile(delete=False)
+        fa.write(txt_a)
+        fa.close()
+        fb = tempfile.NamedTemporaryFile(delete=False)
+        fb.write(txt_b)
+        fb.close()
+        cmd = 'diff %s %s ' % (fa.name, fb.name)
+        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
+        (output, stderr) = process.communicate()
+        os.unlink(fa.name)
+        os.unlink(fb.name)
+        return output
+
+    #
+    # --------------------------------------------------------------------------
+    #
+
+    def get_host_attachment_switch_port (self, query_dict):
+        """ 
+        Get a host's attachment point if it is not already provided.
+        see if the host has an attachment point, use the switch and port
+        of the attachment point, if its available
+        """
+        host = rest_to_model.get_model_from_url('host', query_dict)
+        if len(host) == 0:
+            print self.error_msg('Can\'t identify host details: %s' % query_dict)
+            return (False,None,None)
+        attachment_points = host[0]['attachment-points']
+        if attachment_points == None or len(attachment_points) == 0:
+            print self.error_msg('Can\'t identify attachment point %s' % query_dict)
+            return (False,None,None)
+        if len(attachment_points) == 1:
+            src_sw      = attachment_points[0]['switch']
+            src_sw_port = attachment_points[0]['ingress-port']
+            return (True, src_sw, src_sw_port)
+
+        interface_dict = create_obj_type_dict('interfaces', 'id')
+        show_list = []
+        for ap in attachment_points:
+            dpid = ap['switch']
+            ingress_port = ap['ingress-port']
+
+            # alias for dpid
+            switch_name = alias_lookup_with_foreign_key('switch-alias', dpid)
+            if not switch_name:
+                switch_name = dpid
+            # interface name for attachment point
+            ap_port_id = dpid + '|' + str(ingress_port)
+            if ap_port_id in interface_dict:
+                show_list.append("%s/%s" % (switch_name,
+                                            interface_port[ap_port_od][0]['portName']))
+            else:
+                show_list.append("%s/port %s" % (switch_name, ingress_port))
+                
+        print self.error_msg('src-host %s: multiple attachment points: %s' %
+                             (src_mac, ', '.join(show_list)))
+        print self.error_msg('rerun, and identify src-switch and interface')
+        return (False,None,None)
+
+
+    #
+    # --------------------------------------------------------------------------
+    # test packet-in: swap source and destination attributes 
+    #
+    def test_pkt_in_swap_src_dest_attributes(self, post_data):
+        # Remove the source switch and port if needed
+        if ("srcSwitchDpid" in post_data):
+            post_data.pop("srcSwitchDpid")
+        if ("srcSwitchInPort" in post_data):
+            post_data.pop("srcSwitchInPort")
+
+        #
+        # Get destination host's attachment switch/port information
+        #
+        (result, src_sw, src_sw_port) = self.get_host_attachment_switch_port(
+                                            { 'mac' : post_data["destinationMACAddress"]})
+        if not result:
+            return
+        post_data["srcSwitchDpid"] = src_sw
+        post_data["srcSwitchInPort"] = src_sw_port
+
+        # Swap the macs
+        temp = post_data["sourceMACAddress"]
+        post_data["sourceMACAddress"] = post_data["destinationMACAddress"]
+        post_data["destinationMACAddress"] = temp
+        # swap the IP addresses if specified
+        tempSrc = None
+        tempDst = None
+        if ("sourceIpAddress" in post_data):
+            tempSrc = post_data["sourceIpAddress"]
+            post_data.pop("sourceIpAddress")
+        if ("destinationIpAddress" in post_data):
+            tempDst = post_data["destinationIpAddress"]
+            post_data.pop("destinationIpAddress")
+        if (tempSrc is not None):
+            post_data["destinationIpAddress"] = tempSrc
+        if (tempDst is not None):
+            post_data["sourceIpAddress"] = tempDst
+        # swap the IP ports if specified
+        tempSrc = None
+        tempDst = None
+        if ("ipL4SourcePort" in post_data):
+            tempSrc = post_data["ipL4SourcePort"]
+            post_data.pop("ipL4SourcePort")
+        if ("ipL4DestinationPort" in post_data):
+            tempDst = post_data["ipL4DestinationPort"]
+            post_data.pop("ipL4DestinationPort")
+        if (tempSrc is not None):
+            post_data["ipL4DestinationPort"] = tempSrc
+        if (tempDst is not None):
+            post_data["ipL4SourcePort"] = tempDst
+
+    #
+    # --------------------------------------------------------------------------
+    # test packet-in: display packet-in processing result for test packet-in
+    #
+    def test_pkt_in_result_display(self, response):
+        out =  "\nResult of packet-in processing\n"
+        out += ("------------------------------\n")
+        src_vns_name = response['srcVNSName']
+        dst_vns_name = response['destVNSName']
+
+        if (response['explanation'] == "Source switch not found"):
+            out += response['explanation']
+            return out
+
+        out +=  "\nVirtual Routing Processing iterations\n"
+        out += ("--------------------------------------\n")
+        ep_vrouting = response['expPktVRouting']
+        for ep_vr in ep_vrouting:
+            srcIface = ep_vr['srcIface']
+            dstIface = ep_vr['dstIface']
+            action = ep_vr['action']
+            out += ("src VNS iface           : %s\n" % srcIface)
+            out += ("dst VNS iface           : %s\n" % dstIface)
+            out += ("action                  : %s\n" % action)
+            if action == 'DROP':
+                dropReason = ep_vr['dropReason']
+                out += ("drop reason             : %s\n" % dropReason)
+            else:
+                nextHopIp = ep_vr['nextHopIp']
+                out += ("next hop IP             : %s\n" % nextHopIp)
+                nextHopGatewayPool = ep_vr['nextHopGatewayPool']
+                if (nextHopGatewayPool != None):
+                    out += ("next hop Gateway Pool   : %s\n" % nextHopGatewayPool)
+            out += "\n"
+
+        if (src_vns_name == None) and (dst_vns_name == None):
+            out += "Source and destination hosts are not in the same vns"
+            return out
+
+        out += ("Status      : %s\n" % response['status'])
+        out += ("Explanation : %s\n" % response['explanation'])
+
+        out +=  "\nResult of Virtual Routing\n"
+        out += ("--------------------------\n")
+        out += ("Source VNS  : %s\n" % src_vns_name)
+        out += ("Dest. VNS   : %s\n" % dst_vns_name)
+        out += ("Input ACL:\n")
+        out += ("  Input ACL Name    : %s\n" % response['inputAcl']['aclName'])
+        out += ("  Input ACL Entry   : %s\n" % response['inputAcl']['aclEntry'])
+        out += ("  Input ACL Action  : %s\n" % response['inputAcl']['aclResult'])
+        out += ("Output ACL:\n")
+        out += ("  Output ACL Name   : %s\n" % response['outputAcl']['aclName'])
+        out += ("  Output ACL Entry  : %s\n" % response['outputAcl']['aclEntry'])
+        out += ("  Output ACL Action : %s\n" % response['outputAcl']['aclResult'])
+
+        if response['expPktRoute'] == None:
+            out += "\n"
+            return out
+
+        out += ("Routing Action : %s\n" % response['routingAction'])
+
+        obj_type_show_alias_update('test-pktin-route')
+        out += ('\nFlow Path:\n')
+        ep_route = response['expPktRoute']
+        for ep_cluster in ep_route:
+            ep_cluster_path = ep_cluster['path']
+            hop = 1
+            route_data = []
+            for ep_path in ep_cluster_path:
+                oneHop = {}
+                oneHop['cluster'] = ep_cluster['clusterNum']
+                oneHop['hop'] = hop
+                hop += 1
+                oneHop.update(ep_path)
+                route_data.append(oneHop)
+            route_data = self.pp.format_table(route_data, 'test-pktin-route')
+            out += route_data
+            out += "\n"
+        return out
+
+    #
+    # --------------------------------------------------------------------------------
+    # implement_test_packet_in
+    #
+    def implement_test_packet_in(self, data):
+        # Currently only supports <test packet-in> for "explain packet" feature
+        self.debug_msg("In do_test(): data=%s" % (data))
+
+        # REST API expects MAC not host aliases
+        if not 'src-host' in data:
+            print self.error_msg("Missing src-host")
+            return
+        src_mac = data['src-host']
+
+        if not 'dst-host' in data:
+            print self.error_msg("Missing dst-host")
+            return
+        dst_mac = data['dst-host']
+
+        # Check that src and dest hosts are not the same
+        if src_mac == dst_mac:
+            print self.error_msg("source and destination hosts can not be same")
+            return
+
+        #
+        if 'src-switch' in data:
+            src_sw      = data['src-switch']
+            src_sw_port = data['src-switch-port']
+        else:
+
+            #
+            # Get host's attachment switch/port information
+            #
+            (result, src_sw, src_sw_port) = \
+                self.get_host_attachment_switch_port({'mac' : src_mac})
+            if not result:
+                return
+
+        post_data = {
+            "sourceMACAddress": src_mac, "destinationMACAddress": dst_mac,
+            "srcSwitchDpid"   : src_sw,  "srcSwitchInPort"      : src_sw_port
+        }
+
+        if 'vlan' in data:
+            post_data["vlanID"] = data['vlan']
+        if 'ether-type' in data:
+            post_data["etherType"] = data['ether-type']
+            if (post_data['etherType'] != "2048"):
+                yield(self.error_msg("Supported ethertypes: 2048 (ip)"))
+                return
+        if 'priority' in data:
+            post_data["priorityCode"] = data['priority']
+        if 'src-ip-address' in data:
+            post_data["sourceIpAddress"] = data['src-ip-address']
+        if 'dst-ip-address' in data:
+            post_data["destinationIpAddress"] = data['dst-ip-address']
+        if 'protocol' in data:
+            post_data["ipv4Protocol"] = data['protocol']
+        if 'tos' in data:
+            #Uncomment the line below once we support tos in the REST API
+            #post_data["tos"] = data['tos']
+            pass
+        if 'src-port' in data:
+            post_data["ipL4SourcePort"] = data['src-port']
+        if 'dst-port' in data:
+            post_data["ipL4DestinationPort"] = data['dst-port']
+
+        self.debug_msg("Post Data = %s" % post_data)
+
+        url = "http://%s/rest/v1/realtimetest/network/explain-packet" % self.controller
+
+        try:
+            jresponse = self.store.rest_post_request(url, post_data)
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, url)
+            yield(self.error_msg(self.rest_error_dict_to_message(errors)))
+            return
+
+        response = json.loads(jresponse)
+        self.debug_msg("Response = %s" % response)
+
+
+        yield ("Input packet\n")
+        yield ("------------\n")
+        explPkt = response['explainPktParams']
+        switch_alias   = alias_lookup_with_foreign_key("switch-alias", explPkt['srcSwitchDpid'])
+        src_host_alias = alias_lookup_with_foreign_key("host-alias", explPkt['sourceMACAddress'])
+        dst_host_alias = alias_lookup_with_foreign_key("host-alias", explPkt['destinationMACAddress'])
+
+        if (src_host_alias):
+            yield ("Source host        : %s (%s), ip=%s\n" % 
+                   (explPkt['sourceMACAddress'], src_host_alias, explPkt['sourceIpAddress']))
+        else:
+            yield ("Source host        : %s, ip=%s\n" % (explPkt['sourceMACAddress'], explPkt['sourceIpAddress']))
+
+        if (dst_host_alias):
+            yield ("Destination host   : %s (%s), ip=%s\n" % 
+                    (explPkt['destinationMACAddress'], dst_host_alias, explPkt['destinationIpAddress']))
+        else:
+            yield "Destination host   : %s, ip=%s\n" % (explPkt['destinationMACAddress'], explPkt['destinationIpAddress'])
+        if (explPkt['vlanID'] == '-1'):
+            yield "VLAN               : %s (Untagged)\n" % explPkt['vlanID']
+        else:
+            yield "VLAN               : %s\n" % explPkt['vlanID']        
+        yield "802.1Q priority    : %s\n" % explPkt['priorityCode']
+        yield "Ether type         : %s\n" % explPkt['etherType']
+        if (switch_alias):
+            yield "Source switch/port : %s (%s)/%s\n" % (explPkt['srcSwitchDpid'], switch_alias, explPkt['srcSwitchInPort'])
+        else:
+            yield "Source switch/port : %s/%s\n" % (explPkt['srcSwitchDpid'], explPkt['srcSwitchInPort'])
+        yield "Protocol           : %s\n" % explPkt['ipv4Protocol']
+        yield "L4 source port     : %s\n" % explPkt['ipL4SourcePort']
+        yield "L4 destination port: %s\n" % explPkt['ipL4DestinationPort']                
+
+        yield("\nForward path:")
+        yield("=============\n")
+        yield(self.test_pkt_in_result_display(response))
+
+        # Now send the reverse test packet
+        self.test_pkt_in_swap_src_dest_attributes(post_data)
+        try:
+            jresponse = self.store.rest_post_request(url, post_data)
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, url)
+            yield(self.error_msg(self.rest_error_dict_to_message(errors)))
+            return
+
+        response = json.loads(jresponse)
+        self.debug_msg("Response = %s" % response)
+        yield("\nReverse path:")
+        yield("=============\n")
+        yield(self.test_pkt_in_result_display(response))
+
+    #
+    # --------------------------------------------------------------------------------
+    # 
+    def implement_test_path(self, data):
+
+        # compute source
+        #
+        if 'src-switch' in data:
+            src_sw      = data['src-switch']
+            src_sw_port = data['src-switch-port']
+        elif 'src-host' in data:
+            (result, src_sw, src_sw_port) = \
+                self.get_host_attachment_switch_port({ 'mac' : data['src-host']})
+            if not result:
+                return
+        elif 'src-ip' in data:
+            # look up the ip in the device api
+            (result, src_sw, src_sw_port) = \
+                self.get_host_attachment_switch_port({ 'ipv4' : data['src-ip']})
+            if not result:
+                return
+        else:
+            return self.error_msg('No source attachment point in request')
+
+        # compute dest
+        if 'dst-switch' in data:
+            dst_sw      = data['dst-switch']
+            dst_sw_port = data['dst-switch-port']
+        elif 'dst-host' in data:
+            (result, dst_sw, dst_sw_port) = \
+                self.get_host_attachment_switch_port({ 'mac' : data['dst-host']})
+            if not result:
+                return
+        elif 'dst-ip' in data:
+            # look up the ip in the device api
+            (result, dst_sw, dst_sw_port) = \
+                self.get_host_attachment_switch_port({ 'ipv4' : data['dst-ip']})
+            if not result:
+                return
+        else:
+            return self.error_msg('No dest attachment point in request')
+
+        url = "http://%s/rest/v1/realtimetest/network/path" % self.controller
+        request = {
+                    'src-switch'      : src_sw,
+                    'src-switch-port' : src_sw_port,
+                    'dst-switch'      : dst_sw,
+                    'dst-switch-port' : dst_sw_port,
+                  }
+
+        try:
+            response = self.store.rest_post_request(url, request)
+            self.debug_msg("Response = %s" % response)
+            if response != '':
+                command.query_result = json.loads(response)
+            else:
+                command.query_result = None
+
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, url)
+            return self.error_msg(self.rest_error_dict_to_message(errors))
+
+
+    #
+    # --------------------------------------------------------------------------------
+    #
+    def cp_help(self, words, text, completion_char):
+        """
+        Completion for the help command must be done using the collection
+        of command descriptions; ie: help uses the command descriptions
+        to complete the help commands.
+        """
+        if completion_char == ord('?'):
+            if len(words) > 1:
+                command.do_command_completion_help(words[1:], text)
+            else:
+                print self.help_splash([], text)
+            return
+        if len(words) == 1:
+            items = self.commands_for_current_mode_starting_with(text)
+            return utif.add_delim(items, ' ')
+        else:   
+            return command.do_command_completion(words[1:], text)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # command_short_help
+    #  Associate short help strings with known commands
+    #  These ought to be associated with the COMMAND_DESCRIPTIONs,
+    #  but since not all command use that mechanism yet, provide
+    #  these short descriptions here.
+    #
+    command_short_help = {
+        'access-list'    : 'Define access-list',
+        'access-group'   : 'Configure access-list to interface association',
+        'boot'           : "Configure boot configuration",
+        'clock'          : 'Configure timezone or set clock',
+        'clear'          : 'Reset counters',
+        'connect'        : "Connect to a controller's REST API via ip[:port]",
+        'date'           : 'Display current date and time',
+        'debug'          : 'Enter various debug modes',
+        'echo'           : 'Echo remaining arguments',
+        'enable'         : 'Move to enable mode',
+        'exit'           : 'Exit current mode',
+        'feature'        : 'Enable or disable features',
+        'firewall'       : 'Enable controller interfaces acls',
+        'help'           : 'Help on commands or topics',
+        'history'        : 'Display history of commands',
+        'ip'             : 'Configure various controller node ip values',
+        'logout'         : 'Exit from cli',
+        'logging'        : 'Configure logging/syslog',
+        'ntp'            : 'Configure ntp',
+        'ping'           : 'Ping request from controller to switch or ip address',
+        'show'           : 'Display configuration or settings',
+        'test'           : 'Test various behaviors',
+        'trace'          : 'Trace various streams',
+        'traceroute'     : 'Traceroute from controller to switch or ip address',
+        'configure'      : 'Enter configuration mode',
+        'reload'         : 'Reboot controller, reload configuration',
+        'write'          : 'Write configuraion',
+        'no'             : 'Delete or disable configuration parameters',
+        'vns-definition' : 'Enter vns-definiton submode, describe membership',
+        'vns'            : 'Enter vns submode, manage access lists',
+        'copy'           : 'Copy configurations',
+        'switchto'       : 'Switch to another vns definition',
+        'interface-rule' : 'VNS Membership rule',
+        'end'            : 'End all nested configuration modes',
+        'interface'      : 'Enter interface submode',
+        'watch'          : 'Iterate indicated command displaying results',
+    }
+
+    #
+    # --------------------------------------------------------------------------------
+    # obj_type_short_help
+    #
+    obj_type_short_help = {
+        'controller-node'           : 'Configure specific controller nodes',
+        'host'                      : 'Configure host details',
+        'statd-config'              : 'Statd Configuration',
+        'statdropd-config'          : 'Stat dropd configuration',
+        'statdropd-progress-info'   : 'Stat dropd progress configuration',
+        'switch'                    : 'Switch Configuration',
+
+        # -- debug only tables
+        'vns-access-list'           : 'VNS Access List object',
+        'vns-access-list-entry'     : 'VNS Access List Entry object',
+        'vns-interface'             : 'VNS Interface object',
+        'vns-interface-access-list' : 'VNS Interface Access List object',
+        'vns-interface-rule'        : 'VNS Interface Rule object',
+        'host-alias'                : 'Host Alias object',
+        'port-alias'                : 'Port Alias object',
+        'switch-alias'              : 'Switch Alias object',
+    }
+
+    #
+    # --------------------------------------------------------------------------------
+    # help_splash
+    #
+    def help_splash(self, words, text):
+        ret = ""
+        if not words:
+            if text == "":
+                ret += "For help on specific commands type help <topic>\n"
+
+            count = 0
+            longest_command = 0
+            # this submode commands
+            s_ret = ""
+            mode = self.current_mode()
+            nested_mode_commands = [self.title_of(x) for x in
+                                    self.command_nested_dict.get(mode, [])]
+            possible_commands = [self.title_of(x) for x in
+                                 self.command_dict.get(mode, []) ] + \
+                                nested_mode_commands
+            available_commands = self.commands_feature_enabled(possible_commands)
+            submode_commands = sorted(utif.unique_list_from_list(available_commands))
+            if len(submode_commands):
+                longest_command = len(max(submode_commands, key=len))
+            for i in submode_commands:
+                if not i.startswith(text):
+                    continue
+                count += 1
+                short_help = command.get_command_short_help(i)
+                if not short_help:
+                    short_help = self.command_short_help.get(i, None)
+                if short_help:
+                    s_ret += "  %s%s%s\n" % (i,
+                                          ' ' * (longest_command - len(i) + 1),
+                                          short_help)
+                else:
+                    s_ret += "  %s\n" % i
+
+            # commands
+            c_ret = ""
+            upper_commands = [x for x in self.commands_for_current_mode_starting_with()
+                              if not x in submode_commands]
+            commands = sorted(upper_commands)
+            if len(commands):
+                longest_command = max([len(x) for x in commands] + [longest_command])
+            for i in commands:
+                if not i.startswith(text):
+                    continue
+                count += 1
+                short_help = command.get_command_short_help(i)
+                if not short_help:
+                    short_help = self.command_short_help.get(i, None)
+                if short_help:
+                    c_ret += "  %s%s%s\n" % (i,
+                                          ' ' * (longest_command - len(i) + 1),
+                                          short_help)
+                else:
+                    c_ret += "  %s\n" % i
+                
+            # objects
+            o_ret = ""
+            if self.in_config_mode():
+                obj_types = sorted(self.obj_types_for_config_mode_starting_with())
+                if len(obj_types) > 0:
+                    for i in obj_types:
+                        longest_command = max([len(x) for x in commands] +
+                                              [longest_command])
+                    for i in obj_types:
+                        if i in commands:
+                            continue
+                        if i.startswith(text):
+                            count += 1
+                            short_help = self.obj_type_short_help.get(i, None)
+                            if short_help:
+                                o_ret += "  %s%s%s\n" % (i,
+                                            ' ' * (longest_command - len(i) + 1),
+                                            short_help)
+                            else:
+                                o_ret += "  %s\n" % i
+
+            # fields
+            f_ret = ""
+            if self.in_config_submode():
+                # try to get both the fields and the commands to line up
+                longest_field = longest_command
+                for i in self.fields_for_current_submode_starting_with():
+                    if i.startswith(text):
+                        longest_field = max(longest_field, len(i))
+ 
+                f_count = 0
+                # LOOK! could be getting the help text for each of these...
+                for i in sorted(self.fields_for_current_submode_starting_with()):
+                    if not i.startswith(text):
+                        continue
+                    count += 1
+                    field_info = mi.obj_type_info_dict[
+                                    self.get_current_mode_obj_type()]['fields'].\
+                                        get(i, None)
+                    if not field_info and self.debug:
+                        print 'no field for %s:%s' % (self.get_current_mode_obj_type(), i)
+                    if field_info and field_info.get('help_text', None):
+                        f_ret += "  %s%s%s\n" % (i,
+                                          ' ' * (longest_field - len(i) + 1),
+                                          field_info.get('help_text'))
+                    else:
+                        f_ret += "  %s\n"% i
+
+            if (text == "" or count > 1) and s_ret != "":
+                ret += "Commands:\n"
+                ret += s_ret
+
+            if (text == "" or count > 1) and c_ret != "":
+                ret += "All Available commands:\n"
+                ret += c_ret
+
+            if (text == "" or count > 1) and o_ret != "":
+                ret += "\nAvailable config submodes:\n"
+                ret += o_ret
+            
+            if (text == "" or count > 1) and f_ret != "":
+                ret += "\nAvailable fields for %s:\n" % self.get_current_mode_obj_type() 
+                ret += f_ret
+        elif words[0] in ["show", "help", "copy", "watch" ]:
+            method = self.command_method_from_name(words[0])
+            if method:
+                ret = method(None)
+            else:
+                #try:
+                    #ret = command.get_command_syntax_help(words, 'Command syntax:')
+                #except:
+                    #if self.debug or self.debug_backtrace:
+                        #traceback.print_exc()
+                    #ret = "No help available for command %s" % words[0]
+
+                try:
+                    ret = command.get_command_documentation(words)
+                except:
+                    if self.debug or self.debug_backtrace:
+                        traceback.print_exc()
+                    ret = "No help available for command %s" % words[0]
+        else:
+            #try:
+                #ret = command.get_command_syntax_help(words, 'Command syntax:')
+            #except:
+                #if self.debug or self.debug_backtrace:
+                    #traceback.print_exc()
+                #ret = "No help available for command %s" % words[0]
+            try:
+                ret = command.get_command_documentation(words)
+            except:
+                if self.debug or self.debug_backtrace:
+                    traceback.print_exc()
+                ret = "No help available for command %s" % words[0]
+        return ret
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_help
+    #
+    def do_help(self, words):
+        return self.help_splash(words, "")
+        
+    #
+    # --------------------------------------------------------------------------------
+    # do_lint
+    #
+    def do_lint(self, words):
+        return command.lint_command(words)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_history
+    #
+    def cp_history(self, words, text, completion_char):
+        if len(words) == 1:
+            ret_val = "  <num>      - to display a specific number of commands (default:all)\n"
+            ret_val += "  <cr>\n"
+            self.print_completion_help(ret_val)
+        else:
+            self.print_completion_help("<cr>")
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_history
+    #
+    def do_history(self, words = None):
+        ret_val = ""
+        how_many = num_commands = readline.get_current_history_length()
+        if words:
+            how_many = words[0]
+        for i in range(num_commands-int(how_many) + 1, num_commands):
+            yield "%s: %s\n" % (i, readline.get_history_item(i))
+        return
+
+
+    debug_cmd_options = ["python", "bash", "cassandra-cli", "netconfig", "tcpdump",
+                         "cli", "cli-backtrace", "cli-batch", "cli-interactive"]
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_debug
+    #
+    def implement_debug(self, words):
+        if len(words) < 1 or len([x for x in self.debug_cmd_options if x.startswith(words[0])]) < 1:
+            return "Syntax: debug < %s >" % " | ".join(self.debug_cmd_options)
+        def shell(args):
+            subprocess.call(["env", "SHELL=/bin/bash", "/bin/bash"] + list(args), cwd=os.environ.get("HOME"))
+            print
+        print "\n***** Warning: this is a debug command - use caution! *****"
+        if "python".startswith(words[0]):
+            print '***** Type "exit()" or Ctrl-D to return to the SDNOS CLI *****\n'
+            shell(["-l", "-c", "python"])
+        elif "bash".startswith(words[0]):
+            print '***** Type "exit" or Ctrl-D to return to the SDNOS CLI *****\n'
+            shell(["-l", "-i"])
+        elif "cassandra-cli".startswith(words[0]):
+            print '***** Type "exit" or Ctrl-D to return to the SDNOS CLI *****\n'
+            shell(["-l", "-c", "/opt/sdnplatform/db/bin/cassandra-cli --host localhost"])
+        elif "netconfig".startswith(words[0]):
+            if not re.match("/dev/ttyS?[\d]+$", os.ttyname(0)):
+                print '***** You seem to be connected via SSH or another remote protocol;'
+                print '***** reconfiguring the network interface may disrupt the connection!'
+            print '\n(Press Control-C now to leave the network configuration unchanged)\n'
+            subprocess.call(["sudo", "env", "SHELL=/bin/bash", "/opt/sdnplatform/sys/bin/bscnetconfig", "eth0"], cwd=os.environ.get("HOME"))
+        elif "tcpdump".startswith(words[0]):
+            print '***** Type Ctrl-C to return to the SDNOS CLI *****\n'
+            try:
+                shell(["-l", "-c", "sudo /opt/openflow/sbin/tcpdump " + " ".join(words[1:])])
+            except:
+                pass # really, we need to ignore this unconditionally!
+            time.sleep(0.2)
+        elif "cli".startswith(words[0]):
+            if self.debug:
+                self.debug = False
+                print "debug disabled"
+            else:
+                self.debug = True
+                print "debug enabled"
+        elif "cli-backtrace".startswith(words[0]):
+            # This feature is separated from the cli debug mode so that backtraces
+            # can be collected during cli qa
+            self.debug_backtrace = True
+            print '***** Enabled cli debug backtrace *****'
+        elif "cli-batch".startswith(words[0]):
+            self.batch = True
+            print '***** Enabled cli batch mode *****'
+        elif "cli-interactive".startswith(words[0]):
+            self.batch = False
+            print '***** Disabled cli batch mode *****'
+        else:
+            return self.error_msg("invoking debug")
+    #
+    # --------------------------------------------------------------------------------
+    # do_echo
+    #
+    def do_echo(self, words):
+        print " ".join(words)
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_trace
+    #
+    trace_optional_params = {
+        'screen': {'type': 'flag'},
+#        'port': {'type': 'string',
+#                     'syntax_help': "Enter <switch dpid> <physical port#>, where the packets traces are spanned."},
+        'file': {'type': 'string',
+                     'syntax_help': "Enter <filename> where the packets traces are captured."},
+        }
+
+    trace_cmds = ["detail", "oneline", "vns", "in", "out", "both", 
+                      "echo_reply",  "echo_request", "features_rep", "flow_mod", "flow_removed", "get_config_rep", "hello", 
+                      "packet_in", "packet_out", "port_status", "set_config", "stats_reply", "stats_reques"]
+
+    def cp_trace(self, words, text, completion_char):
+        vns_cache = objects_starting_with('vns-definition')
+        if len(words) == 1:
+            return [x for x in self.trace_cmds if x.startswith(text)]
+        elif len(words) == 2 and words[1].lower().startswith("vns"):
+            return vns_cache
+        elif len(words) == 2 and words[1].lower().startswith("output"):
+            return self.complete_optional_parameters(self.trace_optional_params,
+                                                         words[len(words):], text)
+        elif (len(words) == 3 and 
+             words[1].lower().startswith("vns") and
+             words[2].lower() in vns_cache):
+            return [x for x in ["in", "out", "both", "output"] if x.startswith(text)] 
+        elif (len(words) == 4 and 
+             words[1].lower().startswith("vns") and
+             words[2].lower() in objects_starting_with('vns-definition') and
+             words[3].lower() in ["in", "out", "both"]):
+            return [x for x in ["output"] if x.startswith(text)] 
+        elif len(words) == 2 and words[1].lower()in ["in", "out", "both"]:
+            return [x for x in ["output"] if x.startswith(text)] 
+        elif (len(words) > 2 and 
+             (words[1].lower().startswith("vns") or
+              words[1].lower().startswith("output") or
+              words[2].lower().startswith("output"))) :
+            offset = len(words)
+            if words[len(words)-1].lower() == 'screen':
+                self.print_completion_help("<cr>")
+                return []
+            elif words[len(words)-1].lower() in ['file']:
+                offset = len(words) - 1
+            return self.complete_optional_parameters(self.trace_optional_params, words[offset:], text)
+
+        self.print_completion_help("<cr>")
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_trace
+    #
+    def do_trace(self, *args):
+        dpid = None
+        if len(args) > 0:
+            args = args[0]  # first element is the array of 'real' args
+        if len(args) > 1 and args[0].lower() in ['vns', 'in', 'out', 'both', 'output']:
+            try :
+                return self.do_sdnplatform_trace(args)
+            except KeyboardInterrupt, e:
+                return
+
+        if len(args) > 1 and args[0].lower() == 'trace':
+            dpid = args[1]
+            args = args[2:] # And in this case, args are after the first 2 parameters
+        return self.do_tcpdump_trace(dpid, args)
+
+    def do_sdnplatform_trace(self, args):
+        vns = None
+        direction = 'both'
+        output = 'screen'
+        dpid = None
+        port = None
+        file_name = None
+        sessionId = None
+        error = 'Error: Invalid command syntax.\n' + \
+                'trace [vns <vnsId>] [in|out|both] output [screen]'
+#                'trace [vns <vnsId>] [in|out|both] output [screen|port <dpid> <physical port>|file <filename>]'
+
+        if args[0].lower() == 'vns':
+            if len(args) > 1:
+                vns = args[1]
+                args = args[2:]
+            else:
+                return error
+
+        while args:
+            if args[0].lower() == 'output':
+                args = args[1:]
+                continue
+            if args[0].lower() in ['in', 'out', 'both']:
+                direction = args[0].lower() 
+                args = args[1:]
+                continue
+            if args[0].lower() == 'screen':
+                output = 'screen'
+                break
+            if args[0].lower() == 'port':
+                output = 'port'
+                if len(args) > 2:
+                    dpid = args[1]
+                    port = args[2:]
+                    break
+                else:
+                    return error
+            if args[0].lower() == 'file':
+                output = 'file'
+                if len(args) > 1:
+                    file_name = args[1]
+                    break
+                else:
+                    return error
+
+        filter_request = {FT_DIRECTION:direction, FT_OUTPUT:output, FT_PERIOD:FT_PERIOD_DEFAULT}
+        if vns :
+            filter_request[FT_VNS] = vns
+        if dpid and port :
+            filter_request[FT_PORT] = {FT_PORT_DPID:dpid, FT_PORT_PORT:port}
+
+
+        post_data = json.dumps(filter_request)
+
+        while 1:
+            response_text = None
+            sessionId = None
+            url = 'http://%s/rest/v1/packettrace/' % cli.controller
+            request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
+            try:
+                response = urllib2.urlopen(request)
+                response_text = response.read()
+                response_text = json.loads(response_text)
+            except Exception, e:
+                return "Error: failed to get a response for a trace request. %s" % e
+
+            if response_text and SESSIONID in response_text:
+                sessionId = response_text[SESSIONID]
+            else :
+                return "Error: failed to get a trace session. %s" % response_text
+
+            # Span to a physical port
+            # No data is shown on cli. ^C to stop the trace
+            if output.lower() == 'port':
+                while 1:
+                    try :
+                        time.sleep(1000)
+                    except KeyboardInterrupt, e:
+                        self.terminateTrace(sessionId)
+                        return
+
+            lpurl = None
+
+            if sessionId:
+                lpurl = 'http://%s/poll/packets/%s' % (cli.controller, sessionId)
+            else:
+                return "Error: failed to start a trace session. %s" % response_text
+
+            FILE = None
+            if file_name:
+                FILE = open(file_name, "w")
+
+            flagTimeout = False
+            while 1:
+                try:
+                    response_text = urllib2.urlopen(lpurl).read()
+                    data = json.loads(response_text)
+                    if output.lower() == "screen":
+                        flagTimeout = self.dumpPktToScreen(data)
+                    elif output.lower() == 'file' and FILE != None:
+                        self.dumpPktToFile(FILE, data)
+                except KeyboardInterrupt, e:
+                    self. terminateTrace(sessionId)
+                    return
+                except Exception, e:
+                    return "Error: failed to start a trace session. %s" % e
+
+                if flagTimeout:
+                    continueString = raw_input("Do you want to continue tracing? [y/n]:  ")
+                    if 'y' in continueString.lower():
+                        break
+                    else:
+                        return
+
+
+    @staticmethod
+    def dumpPktToScreen(data):
+        for entry in data:
+            if FT_TIMEOUT in entry:
+                return True
+            else:
+                print entry
+        return False
+
+    @staticmethod
+    def dumpPktToFile(FILE, data):
+        FILE.writelines(data)
+
+    @staticmethod
+    def terminateTrace(sid):
+        post_data = json.dumps({SESSIONID:sid, FT_PERIOD:-1})
+        url = 'http://%s/rest/v1/packettrace/' % cli.controller
+        request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
+        try:
+            response = urllib2.urlopen(request)
+            response_text = response.read()
+        except Exception, e:
+            # Sdnplatform may not be running, but we don't want that to be a fatal
+            # error, so we just ignore the exception in that case.
+            pass
+
+    def do_tcpdump_trace(self, dpid, args):
+        ret = ''
+        bsc_port = '6633' # LOOK: listen addr/port are wrong in the controller-node, so hard code 6633 for now
+        trace_cmd = 'sudo /opt/sdnplatform/cli/bin/trace --filter \'%s\' %s'
+        trace_rule = '((tcp) and (port %s))' % (bsc_port,)
+        single_session = False
+
+        trace_args = '--alias'
+        if 'detail' in args:
+            trace_args += ' --detail'
+            args.remove('detail')
+        if 'oneline' in args:
+            trace_args += ' --oneline'
+            args.remove('oneline')
+        if 'single_session' in args:
+            single_session = True
+            args.remove('single_session')
+
+        if dpid:
+            query_dict = { 'dpid' : dpid }
+            row = rest_to_model.get_model_from_url('switches', query_dict)
+            if len(row) >= 1:
+                if not 'ip-address' in row[0] or row[0].get('ip-address') == '':
+                    return self.error_msg("switch %s currently not connected " % dpid)
+            addr = row[0]['ip-address']
+            port = row[0]['tcp-port']
+            if single_session:
+                trace_rule = '((tcp) and (port %s) and (host %s) and (port %s))' % (bsc_port, addr, port)
+            else:
+                trace_rule = '((tcp) and (port %s) and (host %s))' % (bsc_port, addr)
+        if len(args) > 0:
+            trace_args += (' ' + ' '.join(args))
+        try:
+            # print args, dpid, trace_cmd % (trace_rule, trace_args)
+            process = subprocess.Popen(trace_cmd % (trace_rule, trace_args), shell=True)
+            status = os.waitpid(process.pid, 0)[1]
+            if status != 0:
+                ret = 'Errno: %d' % (status, )
+        except:
+            pass # really, we need to ignore this unconditionally!
+
+        time.sleep(0.2)
+        return ret
+
+    
+    #
+    # --------------------------------------------------------------------------------
+    # get_auth_token_file_path
+    #
+    @staticmethod
+    def get_auth_token_file_path():
+        auth_token_path = os.environ.get('BSC_AUTH_TOKEN_PATH')
+        if auth_token_path is None:
+            auth_token_path = '/opt/sdnplatform'
+        auth_token_path += '/auth_token'
+        return auth_token_path
+    
+    #
+    # --------------------------------------------------------------------------------
+    # play_config_lines
+    #
+    def play_config_lines(self, src_text):
+        """
+        The complete collection of lines to replay are in src_text.
+        In the future, this would provide for a way to first identify
+        what needs to be removed, then apply what needs to be added.
+
+        Some smart diffing from the exiting running-config would
+        be needed to support that.   The stanza groups would need to
+        be collected, the diff'd
+        """
+        print "Updating running-config ..."
+
+        num_lines_played = 0
+        # scan the lines looking for the version number.
+        #
+        version = None
+        for line in src_text.splitlines():
+            m = re.match("(\s*)(\w+)\s*", line) # only match non-blank lines
+            if m:
+                if m.group(0).startswith('version '):
+                    line_parts = line.split()
+                    if line_parts > 1:
+                        version = line_parts[1]
+                        break
+
+        # construct the command to run.
+        command = ['env']
+        if version:
+            command.append('CLI_COMMAND_VERSION=%s' % version)
+        command.append('CLI_STARTING_MODE=config')
+        command.append('CLI_SUPPRESS_WARNING=True')
+
+        if os.path.exists('/opt/sdnplatform/cli/bin/cli'):
+            # controller VM
+            command.append('/opt/sdnplatform/cli/bin/cli')
+            command.append('--init')
+        else:
+            # developer setup
+            base = os.path.dirname(__file__)
+            command.append(os.path.join(base, 'cli.py'))
+            command.append('--init')
+
+        # create a subprocess for the configuration, then push
+        # each of the lines into that subprocess.
+        p = subprocess.Popen(command,
+                             stdin=subprocess.PIPE, 
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT,
+                             bufsize=1)
+        postprocesslines=[]
+        for line in src_text.splitlines(1):
+            m = re.match("(\s*)(\w+)\s*", line) # only match non-blank lines
+            if m:
+                if 'tenant' or 'router' in line:  #special handling for routing rule commands VNS-226
+                    postprocesslines.append(line)
+                p.stdin.write(line)
+                num_lines_played += 1
+        for line in postprocesslines:
+            p.stdin.write(line)
+            num_lines_played += 1
+        p.stdin.close()
+        output = p.stdout.read()
+        if output and (self.debug or self.debug_backtrace or self.description):  
+            print output
+        p.stdout.close()
+        return "Num lines applied: %s\n" % num_lines_played
+
+    #
+    # --------------------------------------------------------------------------------
+    # path_concat
+    #  Concatenate a suffix path to a prefix, making the guarantee that the
+    #  suffix will always be "under" the prefix. the suffix is normalized,
+    #  then any prefix up-dirs ("..") are removed.
+    #
+    def path_concat(self, prefix, path):
+        suffix = posixpath.normpath(path.lstrip('/').rstrip('/'))
+        (head, tail) = os.path.split(suffix)
+        tails = [tail]
+        while head:
+            (head, tail) = os.path.split(head)
+            tails.insert(0, tail)
+        drop = ''
+        while tails[0] == '..':
+            drop = os.path.join(drop, tails.pop(0))
+        if drop != '':
+            self.note("Ignoring %s prefix" % drop)
+        for t in tails:
+            prefix = os.path.join(prefix, t)
+        return prefix
+
+    #
+    # --------------------------------------------------------------------------------
+    # implement_copy
+    #  startup-config and update-config are simply abbreviations for 
+    #  config://startup-config and config://update_config
+    #
+    def implement_copy(self, words):
+        if not words or len(words) > 3:
+            print "Syntax: copy <src> <dst>"
+            print "where <src> and <dst> can be"
+            print "  running-config startup-config update-config"
+            print "  config://<name-of-config-in-db> - A-Za-z0-9_-.@ "
+            print "  <url> - starting with either tftp://, ftp://, http:// or file://"
+            return
+        if len(words) == 1:
+            src = words[0]
+            dst = "terminal"
+        elif len(words) == 2:
+            (src, dst) = (words[0], words[1])
+
+        # Complete as required.
+        # NOTE: No completion for upgrade-config as only our scripts should be using it
+        if "running-config".startswith(src):
+            src = "running-config"
+        elif "startup-config".startswith(src):
+            src = "startup-config"
+        if "running-config".startswith(dst):
+            dst = "running-config"
+        elif "startup-config".startswith(dst):
+            dst = "startup-config"
+        elif "terminal".startswith(dst):
+            dst = "terminal"
+
+        if src == dst:
+            print "src and dst for copy command cannot be equal"
+            return
+
+        # get from the source first
+        src_text = ""
+
+        # map any abbreviations
+        abbreviations = {'startup-config': 'config://startup-config',
+                         'upgrade-config': 'config://upgrade-config'
+                        }
+        src = abbreviations.get(src, src)
+        data = None
+
+        if src == "running-config": # get running
+            src_text = run_config.implement_show_running_config([]) + "\n"
+        elif src.startswith("config://"): # get local file
+            m = re.search(self.local_name_pattern, src)
+            if m:
+                data = self.store.get_user_data_table(m.group(1), "latest")
+                if data and len(data) > 0:
+                    src_text = self.store.get_user_data_file(data[0]['full_name'])
+            else:
+                print self.error_msg("src name does not match %s" % self.local_name_pattern)
+                return
+        elif src.startswith("ftp") or src.startswith("http"): # get URL
+            src_text = self.store.get_text_from_url(src)
+        elif src.startswith("file://"):
+            #src_file = self.saved_configs_dirname + posixpath.normpath(src[7:]).lstrip('/').rstrip('/')
+            src_file = self.path_concat(self.saved_configs_dirname, src[7:])
+            if src_file == "":
+                return self.error_msg("src %s could not be " 
+                                      "interpreted as a valid source for a file" % src)
+            try:
+                src_text = self.store.get_text_from_url("file://" + src_file)
+            except Exception, e:
+                return self.error_msg(src + ":" + str(e))
+        else:
+            return self.error_msg("Unknown configuration")
+
+        message = ""
+        if len(words) > 2:
+            message = " ".join(words[2:]).strip('"')
+
+        #
+        # map any abbreviations
+        dst = abbreviations.get(dst, dst)
+
+        # now copy to dest
+        if dst == "running-config":
+            return self.play_config_lines(src_text)
+        elif dst == "terminal":
+            return src_text # returning src_text here allow '|' to work
+        elif dst.startswith("config://"):
+            m = re.search(self.local_name_pattern, dst)
+            if m:
+                store_result = self.store.set_user_data_file(m.group(1), src_text)
+                if store_result:
+                    result = json.loads(store_result)
+                else:
+                    return self.error_msg("rest store result not json format")
+                if 'status' in result and result['status'] == 'success':
+                    return None
+                elif 'message' not in result:
+                    return self.error_msg("rest store result doesn't contain error message")
+                else:
+                    return self.error_msg(result['message'])
+            else:
+                return self.error_msg("dst name does not match %s" % self.local_name_pattern)
+        elif dst.startswith("ftp") or dst.startswith("http"):
+            self.store.copy_text_to_url(dst, src_text, message)
+        elif dst.startswith("file://"):
+            dst_file = self.path_concat(self.saved_configs_dirname, dst[7:])
+            dst_dir = '/'.join(dst_file.split('/')[:-1])
+            if not os.path.exists(dst_dir):
+                try:
+                    os.makedirs(dst_dir)
+                except Exception as e:
+                    return self.error_msg("in creating destination directory: %s [%s]"
+                                          % (str(e), dst_dir))
+            if not os.path.isdir(dst_dir):
+                return self.error_msg("destination directory is not a "
+                                      "valid directory: %s" % dst_dir)
+            with open(dst_file, 'w') as f:
+                try:
+                    f.write(src_text)
+                except Exception as e:
+                    return self.error_msg("in saving config file: %s [%s]" %
+                                          (str(e), dst_file))
+        elif dst == 'trash':
+            if data:
+                result = self.store.delete_user_data_file(data[0]['full_name'])
+                if 'status' in result and result['status'] == 'success':
+                    return None
+                elif 'message' not in result:
+                    return self.error_msg("rest store result doesn't contain error message")
+                else:
+                    return self.error_msg(result['message'])
+        else:
+            print self.error_msg("source file retrieved,"
+                                 "but could not copy to destination %s" % dst)
+        return
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_conf_object_type
+    #   Completion function for a named object, returns names of
+    #   available obj_types
+    #
+    def cp_conf_object_type(self, words, text):
+        if words[0] in mi.obj_types and len(words) == 1:
+            return utif.add_delim(objects_starting_with(words[0], text), ' ')
+        self.print_completion_help("<cr>")
+        return []
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_conf_field
+    #  Handle if we've got a bunch of fields being concatenated,
+    #  e.g., priority 42 src-port 80
+    #
+    def cp_conf_field(self, obj_type, words, text):
+        if len(words) % 2 == 1: 
+            latest_field_name = words[-1]
+                    
+            field_info = mi.obj_type_info_dict[obj_type]['fields'].get(latest_field_name, None)
+            # if there was no shallow match of text, do deep match of xrefs if any
+            if field_info is None:
+                if obj_type in mi.alias_obj_type_xref:
+                    if latest_field_name in mi.alias_obj_type_xref[obj_type]:
+                        field_info = mi.obj_type_info_dict[latest_field_name]['fields']['id']
+
+            if field_info:
+                completion_text = "< %s >: " % field_info['verbose-name']
+                completion_text += field_info.get('help_text', "")
+                self.print_completion_help(completion_text)
+
+
+            # return choices based on the types
+            if mi.is_field_boolean(obj_type, latest_field_name):
+                return utif.add_delib([x for x in ["True", "False"] if x.startswith(text)],
+                                      ' ')
+
+            # Use the 'Values:' prefix in the help_text as a way
+            # of enumerating the different choices
+            if field_info.get('help_text', "").startswith('Values:'):
+                values = field_info.get('help_text').replace("Values:", "")
+                return utif.add_delim([x for x in values.replace(" ","").split(',')
+                                      if x.startswith(text)], ' ')
+
+            #
+            # special cases:
+            if obj_type == 'vns-interface-rule' and latest_field_name == 'mac':
+                return utif.add_delim(objects_starting_with('host', text), ' ')
+            elif obj_type == 'vns-interface-rule' and latest_field_name == 'switch':
+                return utif.add_delim(objects_starting_with('switch', text), ' ')
+        else:
+            # we've got an even number of field-value pairs, so just give the list
+            # of fields for this obj_type
+            return utif.add_fields(
+                    self.fields_for_current_submode_starting_with(text),
+                    ' ')
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns methods.
+    #
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_obj_type
+    #  return True for an obj_type associated with vns, intended to identify
+    #  tables which are or aren't available in debug mode 
+    #
+    @staticmethod
+    def vns_obj_type(obj_type):
+        if obj_type in [ 'vns-interface', 'vns-access-list-entry', 'vns-access-list',
+                         'vns-interface-access-list', 'vns-interface-rule',
+                         'vns-access-group', 'vns-interfaces', 'host-vns-interface']:
+            return True
+        return False
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_debug_obj_type
+    #  return True if the obj_type is available in the non-debug mode
+    #
+    def vns_debug_obj_type(self, obj_type):
+        if self.debug:
+            return True
+        if self.in_config_submode("config-vns-") and obj_type == 'vns-access-list-entry':
+            return False
+        return not self.vns_obj_type(obj_type)
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_debug_show_commands
+    #  return True if the show command vns option is availabe in the current debug mode
+    #
+    def vns_debug_show_commands(self, show_command):
+        if self.debug:
+            return True
+        if self.in_config_submode() and show_command == 'do_show_vns_interface_rule':
+            return True
+        if self.in_config_vns_if_mode() and show_command == 'do_show_vns_access_group':
+            return True
+        if show_command == 'do_show_vns':
+            return True
+        return not self.vns_obj_type(show_command.replace('_', '-').replace('do-show-', '', 1))
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_find_name
+    #  Return True when found, False otherwise
+    #
+    def vns_find_name(self, name):
+        try:
+            self.get_object_from_store("vns-definition", name)
+            return True
+        except Exception, e:
+            pass
+        return False
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_find_and_set_name
+    #  Return True when the name is known, as a side effect, set self.vns_name
+    #  Invalid names are managed by the model, see VnsNameValidator
+    #
+    def vns_find_and_set_name(self, words):
+        if len(words) == 0:
+            print self.error_msg("vns <name> required")
+            return False
+        elif len(words) > 1:
+            print self.error_msg("Additional text after vns name ignored")
+        name = words[0]
+        if self.vns_find_name(name):
+            return True
+        return False
+        
+    #
+    # --------------------------------------------------------------------------------
+    # vns_find_and_set_existing_name
+    #  Return True when the name is known, as a side effect, set self.vns_name
+    #  And display an error message concerning the failure.
+    #
+    def vns_find_and_set_existing_name(self, words):
+        if self.vns_find_and_set_name(words):
+            return True
+        if len(words) > 0:
+            print self.error_msg("Not Found: vns '%s'" % words[0])
+        return False
+        
+    #
+    # --------------------------------------------------------------------------------
+    # vns_find_or_add_name
+    #  Return True when either the vns name currently exists, or of a create
+    #  for the vns name succeeded.
+    #
+    def vns_find_or_add_name(self, words):
+        if self.vns_find_and_set_name(words):
+            return True
+        name = words[0]
+        errors = None
+        ident = {mi.pk("vns-definition"): name }
+        try:
+            self.rest_create_object("vns-definition", ident)
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, 'vns-definition')
+            print self.rest_error_dict_to_message(errors)
+            return False
+
+        return True
+   
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_all_ids
+    #
+    def vns_all_ids(self):
+        return [x['id'] for x in self.get_table_from_store("vns-definition")]
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_convert_table_id
+    #  return a list of two entries, the first is the vns name, the second is the
+    #  updated column value
+    #
+    def vns_convert_table_id(self, obj_type, row, id):
+        fields = row[id].split('|')
+        if len(fields) == 1:
+            # Just in case there's an error in the table
+            return [fields[0], "<error>"]
+        if len(fields) == 2:
+            return fields
+        elif len(fields) == 3:
+            if obj_type == 'host-vns-interface':
+                return [fields[1], fields[2]]
+            elif obj_type == 'vns-access-list-entry':
+                row['vns-access-list'] = fields[1]
+                return [fields[0], fields[2]]
+            else:
+                print self.error_msg("3: vns_convert_table_id case %s" % obj_type)
+        elif len(fields) == 4:
+            if obj_type == 'vns-interface-access-list':
+                # XXX ought to validate
+                if row['vns-access-list'].split('|')[1] != fields[2]:
+                    print self.error_msg('vns-interface-access-list inconsistent %s and id %d' % \
+                                         (row['vns-access-list'], row[id]))
+                row['vns-access-list'] = fields[2]
+                row['vns-interface'] = fields[1]
+                return [fields[0], fields[2]]
+            else:
+                print self.error_msg("4: vns_convert_table_id case %s" % obj_type)
+        else:
+            print self.error_msg("vns_convert_table_id: length %d not managed" % len(fields))
+    #
+    # --------------------------------------------------------------------------------
+    # vns_table_id_to_vns_column
+    #
+    #  vns related tables in the model have unique id's created by concatenating the
+    #  vns name with other fields.  For those tables, separate the vns id's from the
+    #  associated fields, and transform the vns association into its own column.
+    #
+    #  obj_type is the name of the table.
+    #
+    #  for the vns_interface, the vns name is extracted from several fields,
+    #  validated, updated to exclude the vns name, then a new column is added
+    #
+    def vns_table_id_to_vns_column(self, obj_type, entries):
+        id = mi.pk(obj_type)
+        for row in entries:
+            if row[id]:
+                type_info = mi.obj_type_info_dict[obj_type]['fields'][id]['type']
+                if type_info == 'compound-key':
+                    mi.split_compound_into_dict(obj_type, id, row)
+                else:
+                    convert_id = self.vns_convert_table_id(obj_type, row, id)
+                    row['vns'] = convert_id[0]
+                    row[id] = convert_id[1]
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_foreign_key_to_base_name
+    #  For foreign key's which vns wants to 'show', convert the
+    #  foriegn key to the last entry for the field, and display
+    #  that entry
+    #
+    def vns_foreign_key_to_base_name(self, obj_type, entries):
+        foreign_keys = mi.obj_type_foreign_keys(obj_type)
+        for row in entries:
+            # convert the rule id into the rule suffix
+            for foreign_key in foreign_keys:
+                if foreign_key in row and row[foreign_key].find('|'):
+                    fields = row[foreign_key].split('|')
+                    row[foreign_key] = fields[-1]
+
+    #
+    # --------------------------------------------------------------------------------
+    # vns_join_host_fields
+    #  For vns-interfaces new fields are joined from the host table.
+    #
+    def vns_join_host_fields(self, obj_type, entries):
+        if obj_type == 'vns-interface':
+            #
+            host_dap_dict = self.create_attachment_dict()
+            host_ip_dict = self.create_ip_dict()
+            #
+            vns_interface_key = mi.pk('vns-interface')
+            #
+            # for vns-interface, currently vlan is shown in the output,
+            # and this must be joined from the host's table.  Again, it
+            # is better to collect the complee host table, then create
+            # a host dictionary
+
+            hosts_rows_dict = create_obj_type_dict('host', 'mac')
+
+            #
+            # re-index host_rows_dict based not on mac, but on attachment point,
+            #  which is the sum of the switch+port.  the objective here is to
+            #  identify the number of items on a specific-switch port.
+            #
+            ap_dict = {} # indexed by dpid|port
+            for (mac, values) in host_dap_dict.items():
+                for value in values:
+                    key = "%s|%s" % (value['switch'], value['ingress-port'])
+                    if not key in ap_dict:
+                        ap_dict[key] = 0
+                    ap_dict[key] += 1
+            #
+            # the ap_dict counts the number of mac's associated with an ap.
+            # sort the host_rows_dict based on the lowest ap in each group.
+            #
+            for (mac, value) in host_dap_dict.items():
+                new_value = sorted(value,
+                                   key=lambda k:ap_dict["%s|%s" % (
+                                                        k['switch'],
+                                                        k['ingress-port'])],
+                                   cmp=lambda x,y: int(x) - int(y))
+                # add a tag to the dictionary of the first list item
+                # when the ap_dict's entry's count is 1.
+                first = new_value[0]
+                if ap_dict['%s|%s' % (first['switch'], first['ingress-port'])] == 1:
+                    new_value[0]['prime'] = True
+                host_dap_dict[mac] = new_value
+                    
+            for row in entries:
+                fields = row['id'].split('/')
+                if not 'rule' in row:
+                    row['rule'] = fields[0]
+                if len(fields) != 2:
+                    continue # silently ignore any id's not containing hosts
+                host = fields[1]
+
+                row['mac'] = host
+                host_dict = {'mac' : host}
+                row['attachment-points'] = self.get_attachment_points(
+                                                   host_dict,
+                                                   host_dap_dict)
+                row['ips'] = self.get_ip_addresses(host_dict, host_ip_dict)
+
+                host_row = hosts_rows_dict.get(host, None)
+                if host_row and len(host_row) == 1 and 'vlan' in host_row[0]:
+                    row['vlan'] = host_row[0]['vlan']
+  
+    #
+    # --------------------------------------------------------------------------------
+    # vns_join_switch_fields
+    #  For vns-interfaces with entries arising from switch interface rules,
+    #  join in the switch and port.
+    #
+    def vns_join_switch_fields(self, vns_name, entries):
+        #
+        # store all the rules associated with a specific vns,
+        # index them by the primary key.
+        key = mi.pk('vns-interface-rule')
+        if vns_name == None:
+            # vns_name == None, this means 'all'
+            vns_ifr_dict = create_obj_type_dict('vns-interface-rule',
+                                                key)
+        else:
+            search_key = self.unique_key_from_non_unique([vns_name])
+            vns_ifr_dict = create_obj_type_dict('vns-interface-rule',
+                                                key,
+                                                key,
+                                                search_key)
+        for entry in entries:
+            if 'rule' in entry:
+                rule = entry['rule']
+                if rule in vns_ifr_dict:
+                    entry['switch'] = vns_ifr_dict[rule][0].get('switch', "")
+                    entry['ports'] = vns_ifr_dict[rule][0].get('ports', "")
+
+    #
+    # end of vns methods.
+    # --------------------------------------------------------------------------------
+    #
+
+    #
+    #
+    # --------------------------------------------------------------------------------
+    # debug_obj_type
+    #  Return True when the object is available, in self.debug mode, more objects
+    #  are available.
+    #
+    def debug_obj_type(self, obj_type):
+        if self.debug:
+            return True
+        if mi.is_obj_type_source_debug_only(obj_type):
+            return False
+        if self.vns_debug_obj_type(obj_type):
+            if not obj_type in mi.alias_obj_types:
+                return True
+        return False
+
+    #
+    # generic parsing routines
+    # 
+
+    #
+    # --------------------------------------------------------------------------------
+    # completion_reset
+    #
+    def completion_reset(self):
+        self.last_line = None
+        self.last_options = None
+        self.completion_cache = True
+        self.last_completion_char = readline.get_completion_type()
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # completer
+    #  This is the main function that is called in order to complete user input
+    #
+    def completer(self, text, state):
+        question_mark = ord('?')
+        if readline.get_completion_type() == question_mark:
+            if len(readline.get_line_buffer()) == 0:
+                #
+                # manage printing of help text during command completion
+                help_text = self.help_splash(None, text)
+                if help_text != "":
+                    self.print_completion_help(help_text)
+                    return
+        
+        try:
+            origline = readline.get_line_buffer()
+            # See if we have a cached reply already
+            if (self.completion_cache and origline == self.last_line and 
+                self.last_completion_char == readline.get_completion_type() and
+                self.last_options):
+
+                if state < len(self.last_options):
+                    return self.last_options[state]
+                else:
+                    # apparently, for the linux VM choice don't print 
+                    if self.last_options and \
+                      len(self.last_options) > 1 and \
+                      self.last_completion_char == ord('\t'):
+                        choices_text = self.choices_text_builder(self.last_options)
+                        self.print_completion_help(choices_text)
+
+                    if self.completion_skip:
+                        self.completion_cache = False
+                        self.completion_skip = False
+                    return None
+
+            self.completion_reset()
+
+            # parse what user has typed so far
+
+            begin = readline.get_begidx()
+            end = readline.get_endidx()
+
+            # Find which command we're in for a semicolon-separated list of single commands
+            # LOOK! This doesn't handle cases where an earlier command in the line changed
+            # the mode so the completion for later commands in the line should be different.
+            # For example, if you typed "enable; conf" it won't detect that it should be
+            # able to complete "conf" to "configure" because the enable command has not been
+            # executed yet, so you're not in enable mode yet. Handling that case would be
+            # non-trivial I think, at least with the current CLI framework.
+            command_begin = 0
+            command_end = 0
+            while True:
+                command_end = self.find_with_quoting(origline, ';', start_index=command_begin)
+                if command_end < 0:
+                    command_end = len(origline)
+                    break
+                if begin >= command_begin and end <= command_end:
+                    break
+                command_begin = command_end + 1
+            
+            # Skip past any leading whitespace in the command
+            while command_begin < begin and origline[command_begin].isspace():
+                command_begin += 1
+            
+            words = origline[command_begin:end].split()
+            
+            # remove last term if it is the one being matched
+            if begin != end:
+                words.pop()
+
+            # LOOK! there are at least three places that try to parse the valid options:
+            # 1. When actually handling a command
+            # 2. When trying to show completions (here)
+            # 3. When displaying help
+
+            # complete the first word in a command line            
+            if not words or begin == command_begin:
+                options = self.commands_for_current_mode_starting_with(text, completion = True)
+                if self.in_config_mode():
+                    for item in self.obj_types_for_config_mode_starting_with(text):
+                        self.append_when_missing(options, item)
+                if self.in_config_submode():
+                    for item in self.fields_for_current_submode_starting_with(text):
+                        self.append_when_missing(options, item)
+                options = [x if x.endswith(' ') else x + ' '  for x in sorted(options)]
+            # Complete the 2nd word or later
+            else:
+                commands = self.commands_for_current_mode_starting_with(words[0])
+                obj_types = self.obj_types_for_config_mode_starting_with(words[0]) if self.in_config_mode() else []
+                fields = self.fields_for_current_submode_starting_with(words[0]) if self.in_config_submode() else []
+                if len(commands) + len(obj_types) + len(fields) > 1:
+                    if len(fields) > 1:
+                        fields = [words[0]] if words[0] in fields else []
+                    if len(commands) > 1:
+                        commands = [words[0]] if words[0] in commands else []
+                    if len(obj_types) > 1:
+                        obj_types = [words[0]] if words[0] in obj_types else []
+                
+                if len(fields) == 1:
+                    options = self.cp_conf_field(self.get_current_mode_obj_type(), words, text)
+                elif len(obj_types) == 1:
+                    options = self.cp_conf_object_type(obj_types + words[1:], text)
+                elif len(commands) == 1: 
+                    try:
+                        # options[0] is expanded while words[0] is not
+                        method = self.completion_method_from_name(commands[0]) 
+                        if method:
+                            options = method(words, text, readline.get_completion_type())
+                            if not options:
+                                # no match
+                                return None
+                        else:
+                            if readline.get_completion_type() == question_mark:
+                                options = command.do_command_completion_help(words, text)
+                            else:
+                                options = command.do_command_completion(words, text)
+                            #else:
+                                #if options:
+                                    #print syntax_help
+                                #else:
+                                    #pass
+                                    #self.print_completion_help(syntax_help)
+                            
+                    except AttributeError:
+                        if self.debug or self.debug_backtrace:
+                            traceback.print_exc()
+                        return None
+
+                else:
+                    options = None
+                    
+        except Exception, e:
+            if self.debug or self.debug_backtrace:
+                traceback.print_exc()
+            # errors in connect are caught silently, complain here
+            # TODO - Maybe we should log this in a file we can review
+            # at a later date?
+        
+        try:
+            if options:
+                self.last_line = origline
+                self.last_options = options
+                self.last_completion_char = readline.get_completion_type()
+                return options[state]
+        except IndexError:
+            return None
+
+        return None
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_alias
+    #  Manage alias creation for an obj_type, only manage one alias for each of the
+    #  targets, although that requirement exists so that a single alias
+    #  can be displayed for output from (show) commands
+    #
+    #  Note that setting the alias to its current value currently causes the
+    #  alias to be created (ie: there's no specific search to find the item)
+    #
+    def handle_alias(self, obj_type, alias_obj_type, alias_value):
+
+        if alias_value in self.reserved_words:
+            return self.error_msg("alias value %s is a reserved word (%s)" % 
+                                  (alias_value, ', '.join(self.reserved_words)))
+        #
+        # allow the use of 'alias' when only one alias entry
+        # exists for the obj_type.  only-one ought to be typical.
+        # this may need to be removed after a compatability period.
+        if alias_obj_type == 'alias':
+            # there should be only one alias table for this obj_type
+            aliases = mi.alias_obj_type_xref[obj_type]
+            if len(aliases) != 1:
+                print self.error_msg("Internal more than one alias choice")
+            alias_obj_type = aliases[0]
+
+        obj = self.get_current_mode_obj()
+        alias_key = mi.pk(alias_obj_type)
+
+        #
+        # create row for table with foreign key
+        # find the name of the field which is the foreign key...
+        foreign_field =  mi.alias_obj_type_field(alias_obj_type)
+        if not foreign_field:
+            print self.error_msg("internal handle_alias: alias_obj_type_field")
+            return None
+
+        #
+        # delete the current alias if it exists
+        try:
+            exists = self.get_object_from_store(alias_obj_type, alias_value)
+            if len(exists):
+                self.rest_delete_object(alias_obj_type, alias_value)
+        except:
+            pass
+
+        try:
+            create_dict = { alias_key : alias_value, foreign_field : obj }
+            self.rest_create_object(alias_obj_type, create_dict)
+            errors = None
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, alias_obj_type)
+
+        if errors:
+            return self.error_msg("could not create %s for %s (%s): %s" %
+                                  (alias_obj_type, alias_value, obj_type,
+                                 self.rest_error_dict_to_message(errors)))
+        #
+        # remove other existing alias for the same foreign key
+        # find any other alias for this config object, then remove them
+        #
+        try:
+            rows = self.get_table_from_store(alias_obj_type,
+                                             foreign_field,
+                                             obj,
+                                             "exact")
+        except Exception, e:
+            errors = self.rest_error_to_dict(e, alias_obj_type)
+            print self.rest_error_dict_to_message(errors)
+            rows = []
+        #
+        #
+        for row in rows:
+            #
+            # skip the entry which was just inserted
+            if row[alias_key] == alias_value and row[foreign_field] == obj:
+                continue
+            try:
+                self.rest_delete_object(alias_obj_type, row[alias_key])
+                self.warning("removed other alias '%s' for %s '%s'" %
+                             (row[alias_key], foreign_field, row[foreign_field]))
+            except:
+                pass
+
+        return None
+        
+
+    #
+    # --------------------------------------------------------------------------------
+    # update_foreign_key
+    #  Given an obj_type, its primary key name, and the old and new
+    #  id values, find any associated tables which have foreign keys
+    #  associated with this table, and update the foreign key so that
+    #  the table again points to a valid id.
+    #
+    #  its unlikely, although not impossible, for the foreign key
+    #  update to need to cascade.
+    #
+    def update_foreign_key(self, obj_type, obj_key, old_id, new_id):
+        if obj_type in mi.foreign_key_xref and \
+           obj_key in mi.foreign_key_xref[obj_type]:
+            for (fk_obj_type, fk_name) in mi.foreign_key_xref[obj_type][obj_key]:
+                #
+                # find any affected rows
+                try:
+                    rows = self.get_table_from_store(fk_obj_type,
+                                                     fk_name,
+                                                     old_id,
+                                                     "exact")
+                except:
+                    rows = []
+
+                key = mi.pk(fk_obj_type)
+                for row in rows:
+                    self.warning("updating %s key %s field %s to %s" % \
+                                (fk_obj_type, row[key], fk_name, new_id))
+                    try:
+                        self.rest_update_object(fk_obj_type,
+                                                key,
+                                                row[key],
+                                                { fk_name : new_id })
+                        errors = None
+                    except Exception, e:
+                        errors = self.rest_error_to_dict(e, fk_obj_type)
+
+                    if errors:
+                        print self.rest_error_dict_to_message(errors)
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_field
+    #
+    # handle_field calls itself recursively to parse fields and build
+    # a field dict. It then passes the field dict to one rest call.
+    #
+    def handle_field(self, words, accumulated_data=None):
+        if accumulated_data is None:
+            accumulated_data = {}
+        if len(words) < 2:
+            return self.error_msg("incorrect number of args (must be <field> <value>)")
+        obj_type = self.get_current_mode_obj_type()
+        obj = self.get_current_mode_obj()
+        last_word = 2
+        field = words[0]
+        value = words[1]
+        
+        # complete the field if needed
+        field_choices = self.fields_for_current_submode_starting_with(words[0])
+        # LOOK!: robv: Fix to work with a field names which is a prefix of another
+        if len(field_choices) > 1:
+            for field_choice in field_choices:
+                if field_choice == words[0]:
+                    field_choices = [field_choice]
+                    break
+        if len(field_choices) > 1:
+            return "Multiple matches for field name %s." % field
+        if len(field_choices) == 0:
+            return self.error_msg("%s has no field named %s." % (obj_type, field))
+        field = field_choices[0]
+
+        #
+        # handle special case alias's which aren't understood via xref
+        # (this is because vns-interface-rule doesn't foreignKey neigther
+        #  switch or mac references to the switch/host tables)
+        #  
+        if obj_type == 'vns-interface-rule' and field == 'switch':
+            if not self.DPID_RE.match(value):
+                alias_value = alias_lookup('switch-alias', value)
+                if alias_value:
+                    value = alias_value
+                else:
+                    return "Syntax: Unknown switch alias '%s'; Specify switch as DPID or alias" % value
+        if obj_type == 'vns-interface-rule' and field == 'mac':
+            if not self.MAC_RE.match(value):
+                alias_value = alias_lookup('host-alias', value)
+                if alias_value:
+                    value = alias_value
+                else:
+                    return "Syntax: Unknown host alias '%s'; Specify host as MAC or alias" % value
+                
+        #
+        # Replace common type values with expected types, for example true or false
+        #  for True/False. 
+        if mi.is_field_boolean(self.get_current_mode_obj_type(), field):
+            if value.lower() == 'false':
+                value = 'False'
+            elif value.lower() == 'true':
+                value = 'True'
+        # 
+        elif mi.is_hex_allowed(obj_type, field) and self.HEX_RE.match(value):
+            value = str(int(value, 16))
+        #
+        # Look up any validation or value changing callouts...
+        validate = mi.field_validation(self.get_current_mode_obj_type(), field)
+        if validate:
+            validate_error = validate(obj_type, field, value)
+            if validate_error:
+                return validate_error
+
+        accumulated_data[field] = value
+
+        ret_val = None
+
+        if len(words) > last_word:
+            # more to munch
+            ret_val = self.handle_field(words[last_word:], accumulated_data)
+        else:
+            # munched everything, now update
+            obj_key = mi.pk(obj_type)
+
+            prepare_update = mi.obj_type_prepare_row_update(obj_type)
+            if prepare_update:
+                accumulated_data = prepare_update(obj_type, obj_key, obj,
+                                                  accumulated_data)
+                # in case the obj_type's key is updated
+                obj = accumulated_data[obj_key]
+
+            #
+            # Note: if all the fields for a row are all manually reverted
+            # to a default value, perhaps the row ought to be deleted.
+            errors = None
+            try:
+                self.rest_update_object(obj_type, obj_key, obj, accumulated_data)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, obj_type)
+
+            if errors:
+                ret_val = self.rest_error_dict_to_message(errors)
+            else:
+                #
+                # if the primary key was part of the update. find relatred
+                # tables and update the foreign key.  XXX perhaps this is
+                # the rest api's problem?
+                #
+                if obj_key in accumulated_data and \
+                   accumulated_data[obj_key] != obj:
+
+                    self.update_foreign_key(obj_type, obj_key, obj,
+                                            accumulated_data[obj_key])
+                    #
+                    # delete the old key.
+                    self.rest_delete_object(obj_type, obj)
+
+                    #
+                    # move the the current id
+                    self.set_current_mode_obj(accumulated_data[obj_key])
+
+        return ret_val
+
+    #
+    # --------------------------------------------------------------------------------
+    # convert_hex_to_decimal
+    #  Review the contents of all the values, looking for hex
+    #  valued fields.  When a hex value is identified, change
+    #  it to decimal when 'is_hex_allowed' is true.
+    #
+    def convert_hex_to_decimal(self, obj_type, field_dict):
+        for key in field_dict.keys():
+            if mi.is_hex_allowed(obj_type, key) and \
+               self.HEX_RE.match(field_dict[key]):
+                field_dict[key] = int(field_dict[key], 16)
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_obj_type
+    #  In config mode, this handles if first word is an object-type
+    #  (ex: "flow-entry catch-web")
+    #
+    def handle_obj_type(self, words):
+        if len(words) < 2:
+            return "Syntax: %s <key>: where key is an id of %s" % (words[0], words[0])
+
+        (obj_type, obj_name) = (words[0], words[1])
+
+        obj_name = convert_alias_to_object_key(obj_type, obj_name)
+        # First check if this is something we can actually configure
+        if obj_type not in mi.obj_types:
+            return self.error_msg("unknown command or object.")
+
+        # Next, find the object
+        #  Deal with any changes to the lookup name based on the 'concatenation'
+        #  of the config mode name to the named identifer.
+        #
+        found_obj = self.get_obj_of_type(obj_type, obj_name) 
+
+        if found_obj == None:
+            # need to create object, obj_data is the rest api dictionary used
+            # to create the new row.
+            obj_data = { mi.pk(obj_type): obj_name }
+
+            if self.in_config_submode():
+                # add in all the key value from modes in the stack
+                # LOOK! this is brittle as it depends on the name of 
+                # the mode matching the name of the attribute.
+                #
+                obj_data = self.mode_stack_to_rest_dict(obj_data)
+
+                # 
+                self.convert_hex_to_decimal(obj_type, obj_data)
+
+                # make sure all the foreign keys are populated
+                #
+                for key in mi.obj_type_foreign_keys(obj_type):
+                    if not key in obj_data:
+                        print self.error_msg("foreign key '%s' missing from mode stack %s" %
+                                             (key, obj_data))
+
+            prepare_update = mi.obj_type_prepare_row_update(obj_type)
+            if prepare_update:
+                obj_data = prepare_update(obj_type,
+                                          mi.pk(obj_type), obj_name,
+                                          obj_data)
+
+            # create the object
+            errors = None
+            try:
+                self.rest_create_object(obj_type, obj_data)
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, obj_type)
+
+            if errors:
+                return self.rest_error_dict_to_message(errors)
+
+            # get it back, populating found_obj
+            found_obj = self.get_obj_of_type(obj_type, obj_name) 
+            
+        # push on the submode for the object 
+        # LOOK! assumes all object commands drop you into a submode...
+        if found_obj:
+            sub_mode = "config-%s" % obj_type
+            self.push_mode(sub_mode, obj_type, obj_name)
+
+            # hand off the rest of the line to handle_field
+            if len(words) > 2:
+                return self.handle_field(words[2:])
+        else:
+            return self.error_msg("No %s with %s = %s" %
+                                  (obj_type, mi.pk(obj_type), obj_name))
+
+    #
+    # --------------------------------------------------------------------------------
+    # print_completion_help
+    #
+    def print_completion_help(self, completion_help_text):
+        origline = readline.get_line_buffer()
+        end = readline.get_endidx()
+        cur_command = origline[0:end]
+
+        help_text = "\n%s\n%s%s" % ( completion_help_text, 
+                                    self.prompt, 
+                                    cur_command)
+        self.completion_skip = True
+        sys.stdout.write(help_text)
+        
+    #
+    # --------------------------------------------------------------------------------
+    # get_ip_from_switch_dpid_or_alias
+    #    Returns the IP associated with the switch if it exists
+    #    or the original string if it's not a dpid or alias.
+    #
+    def get_ip_from_switch_dpid_or_alias(self, alias):
+        dpid = convert_alias_to_object_key("switches", alias)
+        if self.DPID_RE.match(dpid):
+            query_dict = { 'dpid' : dpid }
+            row = rest_to_model.get_model_from_url('switches', query_dict)
+            if len(row) >= 1:
+                if not 'ip-address' in row[0] or row[0].get('ip-address') == '':
+                    return self.error_msg("switch %s currently not connected "
+                                          % alias)
+                return row[0].get('ip-address')
+        return alias
+
+    #
+    # --------------------------------------------------------------------------------
+    # implement_write
+    #
+    def implement_write(self, words):
+        if len(words) == 1:
+            if "memory".startswith(words[0]):
+                return self.implement_copy(["running-config", "startup-config"])
+            elif "erase".startswith(words[0]):
+                print "This will clear the startup-config and set it to be empty."
+                resp = raw_input("Are you sure that want to proceed? [n]")
+                if resp and "yes".startswith(resp.lower()):
+                    print "Erasing startup config ..."
+                    result = self.store.delete_user_data_file("startup-config/time/len/version")
+                    if 'status' in result and result['status'] == 'success':
+                        return None
+                    elif 'message' not in result:
+                        return self.error_msg("rest store result doesn't contain error message")
+                    else:
+                        return self.error_msg(result['message'])
+                else:
+                    print "Command aborted by user: write erase"
+                return
+            elif "terminal".startswith(words[0]):
+                return self.implement_copy(["running-config", "terminal"])
+        return "Syntax: write < terminal | memory | erase>"
+
+    #
+    # --------------------------------------------------------------------------------
+    # 
+    
+    @staticmethod
+    def set_clock_action(data):
+        time_values = data['time'].split(':')
+        if len(time_values) != 3:
+            raise error.CommandError('Invalid time; must be HH:MM:SS')
+        hour = int(time_values[0])
+        minute = int(time_values[1])
+        second = int(time_values[2])
+        
+        MONTH_NAMES =  ('January', 'February', 'March', 'April', 'May', 'June',
+                        'July', 'August', 'September', 'October', 'November', 'December')
+
+        day_of_month = int(data['day-of-month'])
+        month_name = data['month']
+        if month_name not in MONTH_NAMES:
+            raise error.CommandError('Invalid month name (e.g. January, May, July)')
+        month = MONTH_NAMES.index(month_name) + 1
+        year = int(data['year'])
+        
+        date_time_info = {
+            'year': year,
+            'month': month,
+            'day': day_of_month,
+            'hour': hour,
+            'minute': minute,
+            'second': second
+        }
+        url = 'http://%s/rest/v1/system/clock/local' % cli.controller
+        result = cli.store.rest_post_request(url, date_time_info)
+        date_time_info = json.loads(result)
+        clock_string = SDNSh.get_clock_string(date_time_info, False)
+        return clock_string
+    
+    #
+    # --------------------------------------------------------------------------------
+    # get_misconfigured_default_gateway
+    #  
+    @staticmethod
+    def get_misconfigured_default_gateway():
+        """
+        Determine if the controller is configured with a default gateway
+        setting that doesn't match (i.e. is not on the same subnet)
+        any of the interfaces configured with static IP addresses.
+        This is used by the begin_default_gateway_check_action and
+        end_default_gateway_check_action actions that check if a command
+        results in a misconfigured default gateway setting and, if so,
+        emit an error message.
+        If the default gateway is misconfigured, the return value is the
+        default gateway value. Otherwise, the return value is None.
+        """
+        # First figure out which controller-node we're working with.
+        # This is a little kludgy right now. We check the mode stack
+        # looking for a controller node element.
+        controller_id = cli.get_nested_mode_obj('controller-node')
+        if not controller_id:
+            raise error.CommandDescriptionError('check_default_gateway_action must be called from a (possibly nested) controller node config mode')
+        
+        controller = cli.get_object_from_store('controller-node', controller_id)
+        if not controller:
+            # This shouldn't really happen unless someone/thing has mucked with the
+            # controller object out from under this instance of the CLI
+            # but just to be safe...
+            raise error.CommandInvocationError('Current controller settings have been deleted.')
+        
+        # Check if the controller node is configured with a default gateway.
+        # If not, then there's no possible misconfiguration and we're done.
+        default_gateway = controller.get('default-gateway')
+        if default_gateway == '':
+            return
+        
+        # There is a default gateway configured, so we need to check if there's
+        # an interface that matches (i.e. is on the same subnet as) the default
+        # gateway
+        interfaces = cli.rest_query_objects('controller-interface', {'controller': controller_id})
+        for interface in interfaces:
+            mode = interface.get('mode')
+            if mode == 'static':
+                ip = interface.get('ip')
+                netmask = interface.get('netmask')
+                if (ip != '') and (netmask != '') and same_subnet(default_gateway, ip, netmask):
+                    return None
+
+        return default_gateway
+        
+    #
+    # --------------------------------------------------------------------------------
+    # check_default_gateway_action
+    #  
+    @staticmethod
+    def begin_default_gateway_check_action():
+        """
+        This is an action proc for the data-driven command module that is used
+        in conjunction with the end_default_gateway_check_action to check if a
+        CLI command results in an improperly configured default gateway setting.
+        Currently the backend code that maps the network/interface settings
+        for the controller to the /etc/network/interfaces file will only
+        apply the default gateway setting if it's on the same subnet as an
+        interface that's configured with a static IP address/netmask.
+        So if there's no interface that matches the default gateway (either
+        because it's configured to use DHCP or the subnet doesn't match)
+        then the default gateway setting will be ignored and we want to warn
+        the user about the misconfiguration. The check should be performed
+        on any configuration change that could affect this check. This includes:
+        
+        1) setting the default gateway
+        2) setting the mode of an interface to DHCP
+        3) setting/resetting the ip/netmask of an interface
+        4) deleting an interface
+        
+        We only want to emit the warning if the default gateway was previously
+        not misconfigured and the current command resulted in a misconfiguration,
+        so we want to check for a misconfiguration before applying the command
+        and then check again after the settings have been updated. The
+        begin_default_gateway_check_action is the action that is performed before
+        the settings are updated and the corresponding end_default_gateway_check_action
+        action is the one that is performed after the settings are updated.
+        
+        LOOK!: Ideally we should be doing this check in the sdncon code instead
+        of here in the CLI code. That way the warning would also be returned
+        for clients that are changing these settings directly via the REST
+        API instead of via the CLI. But there isn't a really good mechanism
+        currently for the REST API to return a warning but still apply the
+        config change.
+        """
+        # Stash away if the gateway setting was already misconfigured at the
+        # beginning of the current command. 
+        # LOOK! This is a bit kludgy to stash this away in the CLI object.
+        # When the command module action API is changed to allow access to the
+        # context, this code should be updated to stash the value in the context
+        # instead of the CLI.
+        cli.begin_misconfigured_default_gateway = SDNSh.get_misconfigured_default_gateway()
+
+    @staticmethod
+    def end_default_gateway_check_action():
+        """
+        This is an action proc for the data-driven command module that is used
+        in conjunction with the begin_default_gateway_check_action to check if a
+        CLI command results in an improperly configured default gateway setting.
+        Check the doc comments for begin_default_gateway_check_action for more
+        details about how the two actions are intended to be used.
+        """
+        end_misconfigured_default_gateway = SDNSh.get_misconfigured_default_gateway()
+        if (end_misconfigured_default_gateway and
+            (end_misconfigured_default_gateway != cli.begin_misconfigured_default_gateway)):
+            return  ('The controller is configured with a default gateway setting (%s), that\n'
+                     'is not on the same subnet as any of the interfaces configured to use a\n'
+                     'static IP address. The default gateway setting will be ignored.' %
+                     end_misconfigured_default_gateway)
+ 
+ 
+    #
+    # --------------------------------------------------------------------------------
+    # load_time_zone_list
+    #  Use the rest api to collect all the known time zones
+    #
+    @staticmethod
+    def load_time_zone_list():
+        if not cli.time_zone_list:
+            url = "http://%s/rest/v1/system/timezones/all" % cli.controller
+            cli.time_zone_list = cli.rest_simple_request_to_dict(url)
+ 
+    #
+    # --------------------------------------------------------------------------------
+    # time_zone_completion
+    #
+    @staticmethod
+    def time_zone_completion(words, text, completions):
+        SDNSh.load_time_zone_list()
+        completion_dict = {}
+        tz_completions = []
+        for tz in cli.time_zone_list:
+            if tz.lower().startswith(text.lower()):
+                tz_completions.append(tz)
+                for index in range(len(text), len(tz)):
+                    if tz[index] == '/':
+                        tz = tz[:index+1]
+                        break
+                completion_dict[tz] = 'Timezone Choice'
+        
+        if len(completion_dict) >= 1:
+            completions.update(completion_dict)
+    
+    #
+    # --------------------------------------------------------------------------------
+    # time_zone_validation
+    #
+    @staticmethod
+    def time_zone_validation(typedef, value):
+        SDNSh.load_time_zone_list()
+        if value not in cli.time_zone_list:
+            raise error.ArgumentValidationError('Invalid time zone')
+    
+    #
+    # --------------------------------------------------------------------------------
+    # cp_clock
+    #
+    @staticmethod
+    def cp_clock(words, text, completion_char):
+        return command.do_command_completion(words, text)
+                
+    #
+    # --------------------------------------------------------------------------------
+    # do_clock
+    #
+    @staticmethod
+    def do_clock(words):
+        return command.do_command(['clock'] + words)
+    
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_clock
+    #
+    def cp_show_clock(self, words, text, completion_char):
+        if len(words) == 1 and 'detail'.startswith(text.lower()):
+            return ['detail']
+    
+    
+    @staticmethod
+    def get_clock_string(time_info, detail = None):
+        # The tz item contains the abbreviated time zone string (e.g. PST, EST)
+        # This is different from the full time zone string (e.g. America/Los_Angeles)
+        # which we get from the controller-node object below when we're showing
+        # detail info.
+        tz = time_info['tz']
+        del time_info['tz']
+        dt = datetime.datetime(**time_info)
+        if detail:
+            time_info['tz'] = tz
+        
+        # Arista-style format
+        #show_result = dt.strftime('%c')
+        
+        # Cisco-style format
+        clock_string = dt.strftime('%H:%M:%S '+ tz + ' %a %b %d %Y')
+        
+        return clock_string
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_clock
+    #
+    @staticmethod
+    def do_show_clock(words):
+        syntax_help = "Syntax: show clock [detail]"
+        
+        if len(words) == 0:
+            detail = False
+        elif len(words) == 1:
+            if not 'detail'.startswith(words[0].lower()):
+                return syntax_help
+            detail = True
+        else:
+            return syntax_help
+
+        url = "http://%s/rest/v1/system/clock/local/" % cli.controller
+        time_info = cli.rest_simple_request_to_dict(url)
+        clock_string = SDNSh.get_clock_string(time_info, detail)
+        return clock_string
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_show_vns
+    #
+    def cp_show_vns(self, words, text, completion_char):
+        if len(words) == 1:
+            return objects_starting_with('vns-definition', text)
+        elif len(words) == 2:
+            return [x for x in
+                    [ 'interface', 'mac-address-table', 'interface-rules',  \
+                       'access-lists', 'running-config', 'switch', 'flow' ]
+                    if x.startswith(text)]
+        elif len(words) == 3 and 'switch'.startswith(words[2]):
+            return objects_starting_with("switch", text)
+        elif (len(words) >= 3) and (words[2] == 'flow'):
+            return self.cp_show_vns_flow(words, text)
+        else:
+            self.print_completion_help("<cr>")
+
+    #
+    # --------------------------------------------------------------------------------
+    # show_vns_definition_running_config
+    # Display the vns-definition -- the interface rules for the vns.
+    #
+    def show_vns_definition_running_config(self, config, vns_name,tenant=None,indent=0):
+        if tenant==None and vns_name!='all':
+            vns_id='default|'+vns_name
+        else:
+            vns_id=tenant +'|'+vns_name
+        try:
+            vns = self.get_object_from_store('vns-definition', vns_id)
+        except:
+            return self.error_msg('no vns named %s' % vns_name)
+
+        config.append(' ' *2*indent + "vns-definition %s\n" % vns_name)
+        run_config.running_config_vns_details(config, vns, indent+1)
+
+        vns_rules = None
+        try:
+            vns_rules = self.get_table_from_store('vns-interface-rule',
+                                                  'vns', vns_id, "exact")
+        except Exception:
+            pass
+        
+        if vns_rules:
+            run_config.running_config_vns_if_rule(config,
+                                                  vns_rules,indent+1)
+
+    #
+    # --------------------------------------------------------------------------------
+    # show_vns_running_config
+    #  In the larger 'running-config' for vns, the complete vns tables are read
+    #  since the complete 'running-config' will display all the data from the
+    #  fields.  Here, the tables are searched only for specific vns entries.
+    #
+    #  The procedure's name is choosen carefully, since its not intended to
+    #  part of any of show command, completion, or command processing
+    #
+    def show_vns_running_config(self, vns_name, tenant=None, indent=0):
+        config=[]
+        preconfig=[' '*2*indent +"vns %s\n" % vns_name]
+        if tenant==None and vns_name!='all':
+            vns_name='default|'+vns_name
+        if tenant!=None:
+            vns_name=tenant+'|'+vns_name
+        try:
+            self.get_object_from_store('vns-definition', vns_name)
+        except:
+            return self.error_msg('no vns named %s' % vns_name)
+        vns_acls = []
+        try:
+            vns_acls = self.get_table_from_store('vns-access-list',
+                                                 'vns', vns_name, 'exact')
+        except Exception, e:
+            pass
+
+        for acl in vns_acls:
+            # note use of key initialized above
+
+            vns_acl_entries = None
+            try:
+                vns_acl_entries = self.get_table_from_store('vns-access-list-entry',
+                                                            'vns-access-list',
+                                                            acl['id'],
+                                                            'exact')
+            except Exception:
+                pass
+            run_config.running_config_vns_acl(config, vns_name, acl, vns_acl_entries,indent+1)
+
+        vns_interface_acl = None
+        try:
+            vns_interface_acl = self.get_table_from_store('vns-interface-access-list')
+        except Exception:
+            pass
+
+        for vns_if in run_config.running_config_active_vns_interfaces(vns_name, vns_interface_acl):
+            config.append(' ' *2*(indent+1) + "interface %s\n" % vns_if)
+            run_config.running_config_vns_if_and_access_group(config,
+                                                              vns_name,
+                                                              vns_if,
+                                                              vns_interface_acl,indent+2)
+        if len(config) > 0:
+            config = preconfig + config
+        return ''.join(config)
+
+    #generate tenant xxx running config
+    def show_tenant_running_config(self, config, tenant_name):
+        try:
+                tenants = self.get_object_from_store('tenant', tenant_name)
+        except:
+                return self.error_msg('no tenant named %s' % tenant_name)
+    
+        config.append("!\ntenant %s\n" % tenant_name)
+        run_config.running_config_tenant_details(config,tenants)
+
+        try:
+            vnses = self.get_table_from_store('vns-definition','tenant',tenant_name,"exact")
+        except Exception:
+            vnses = {}
+            pass
+        try:
+            virtual_routers = self.get_table_from_store('virtualrouter','tenant', tenant_name, "exact")
+        except Exception:
+            virtual_routers = {}
+            pass
+
+        for vns in vnses:
+            vns_name=vns['vnsname']
+            self.show_vns_definition_running_config(config, vns_name, tenant=tenant_name,indent=1)
+            config += self.show_vns_running_config(vns_name, tenant=tenant_name,indent=1)
+            
+        for virtual_router in virtual_routers:
+            virtual_router_name=virtual_router['vrname']
+            virtual_router_id=virtual_router['id']
+            config.append("  router %s\n" % virtual_router_name)
+            run_config.running_config_tenant_router_details(config,virtual_router,indent=1)
+            try:
+                vr_interfaces = self.get_table_from_store('virtualrouter-interface','virtual-router', virtual_router_id, "exact")
+            except Exception:
+                vr_interfaces = {}
+            pass
+            try:
+                vr_routes = self.get_table_from_store('virtualrouter-routingrule','virtual-router', virtual_router_id, "exact")
+            except Exception:
+                vr_routes = {}
+            pass
+            try:
+                vr_gwpools = self.get_table_from_store('virtualrouter-gwpool','virtual-router', virtual_router_id, "exact")
+            except Exception:
+                vr_gwpools = {}
+            pass
+
+            for vr_interface in vr_interfaces:
+                run_config.running_config_router_interface_details(config,vr_interface,indent=2)
+            for vr_route in vr_routes:
+                run_config.running_config_router_rule_details(config,vr_route,indent=2)
+            for vr_gwpool in vr_gwpools:
+                run_config.running_config_router_gwpool_details(config,vr_gwpool,indent=2)
+      
+    #
+    # --------------------------------------------------------------------------------
+    # switch_port_match
+    #  Return True when the port matches a port specirfication "pattern"
+    #
+    #  The port specification of an interface rule is a command separated list,
+    #  which can contain a tail of "-<d>".  That tail describes a range.
+    #  With a port range, determine whether or not the 'port' parameter
+    #  is a match.
+    #
+    def switch_port_match(self, port, pattern):
+        # XXX validate port is something which ends in a number?
+        for field in pattern.split(','):
+            m = re.match(r'^([A-Za-z0-9-]*?)(\d+)-(\d+)$', pattern)
+            if not m:
+                if field == port:
+                    return True
+                continue
+            prefix = m.group(1)
+            startport = int(m.group(2))
+            endport = int(m.group(3))
+            if not port.startswith(prefix):
+                continue
+            tail = port[len(prefix):]
+            if not self.DIGITS_RE.match(tail):
+                print self.error_msg("port name tail %s must be all digits" % tail)
+                continue
+            m = re.search(r'(\d+)$', port)
+            if not m:
+                continue
+            port = m.group(1)
+            if int(port) >= int(startport) and int(port) <= int(endport):
+                return True
+            else:
+                print self.error_msg("port %s out of port-spec range %s-%s" %
+                                     (port, startport, endport))
+        return False
+
+    #
+    # ---------------------------------------------------------------------------
+    # cp_show_event_history
+    #  Command completion for the following command to see
+    #  last <n> events of <name> events
+    #  Used in "show event-history <name> [ last <n> ]"
+    #
+    def cp_show_event_history(self, words, text, completion_char):
+        options = ['attachment-point', 
+                   'packet-in',
+                   'topology-link',
+                   'topology-switch',
+                   'topology-cluster',
+                   # Add more event history options above this line
+                   # Add the same item in do_show_event_history() below also
+                  ]
+        completion_help = ''
+        for op in options:
+            ev_help = '%s  show %s events\n' % (op, op)
+            completion_help = completion_help + ev_help
+
+        # syntax: show event-history <name> [ last <n> ]
+        if (len(words) == 1) and text=='':
+            self.print_completion_help(completion_help)
+            return options
+        elif (len(words) == 1):
+            return [op for op in options if op.startswith(text)]
+        elif (len(words) == 2):
+            if text == '':
+                self.print_completion_help("last  Show lastest <n> events\n" +
+                                           "<cr>  Enter")
+                return ['last', '<cr>']
+            elif "last".startswith(text):
+                return ["last"]
+        elif (len(words) == 3):
+            self.print_completion_help("<number>  Enter number of latest events to display (1-10000)")
+            return range(0, 10000)
+        else:
+            self.print_completion_help('<cr>')
+
+    #
+    # --------------------------------------------------------------------------
+    # do_show_event_history
+    #
+    # Show the event history of the specified events
+    # Syntax: show event-history <event-history-name> [last <count>]
+    # <event-history-name> is words[0], <count> is words[2]
+    #
+    def do_show_event_history(self, words):
+        self.debug_msg("do-show-event-history words: %s" % words)
+
+        # Check syntax of the command
+        syntax = self.syntax_msg('show event-history <name> [ last <n> ]')
+        options = ['attachment-point', 
+                   'packet-in',
+                   'topology-link',
+                   'topology-switch',
+                   'topology-cluster',
+                   # Add more event history options above this line
+                   # Add the same item in do_cp_event_history() above also
+                  ]
+        if (words[0] not in options):
+            yield("Event history name %s not found" % words[0])
+            return
+        if (len(words) >= 3) and (words[1] != 'last'):
+            yield(syntax)
+            return
+        if (len(words) == 2) or (len(words) > 4):
+            yield(syntax)
+            return
+        if (len(words) >= 3) and (not words[2].isdigit()):
+            yield(syntax)
+            return
+        if (len(words) >= 3) and (words[2].isdigit()):
+            count = int(words[2])
+            if (count < 1) or (count > 10000):
+                yield("Number of events must be between 1 and 10000")
+                return
+
+        last_n_count = 1024 # default
+        if (len(words) >= 3):
+            last_n_count = words[2]
+        ev_hist_name = words[0]
+        ev_hist_field_name = 'ev-hist-' + ev_hist_name
+        url = 'http://%s/rest/v1/event-history/%s/%s' % \
+                               (self.controller, ev_hist_name, last_n_count)
+        ev_hist = self.rest_simple_request_to_dict(url)
+        #ev_hist - json.dumps(ev_hist)
+        events = ev_hist['events']
+        tableData = []
+        for ev in events:
+            info      = ev['info']
+            base_info = ev['base_info']
+            info.update(base_info)
+            tableData.append(info)
+        # Prepare the date for CLI display
+        tableData = self.pp.format_table(tableData, ev_hist_field_name)
+        yield("\n")
+        yield(tableData)
+
+    #
+    # -------------------------------------------------------------------------------
+    # cp_show_vns
+    #  Command completion for the following command
+    #  Used in "show vns { <vns-name> | all } flow [ brief | full-detail | detail | summary ]
+    #
+    def cp_show_vns_flow(self, words, text, completion_char):
+        cmd1 = 'brief        show flow information in brief format'
+        cmd2 = 'detail       show detailed flow information'
+        cmd3 = 'full-detail  show full details of flow information'
+        cmd4 = 'summary      show summarized flow information'
+
+        syntax = self.syntax_msg('show vns {<vns-name> | all} flow [ brief | detail | full-detail | summary ]')
+        if (len(words) == 3) and text=='':
+            self.print_completion_help(cmd1+'\n'+cmd2+'\n'+cmd3+'\n'+cmd4)
+            return ['brief', 'detail', 'full-detail', 'summary', '<cr>' ]
+        elif (len(words) == 3) and ('detail'.startswith(text)):
+            return ['detail']
+        elif (len(words) == 3) and ('full-detail'.startswith(text)):
+            return ['full-detail']
+        elif (len(words) == 3) and ('summary'.startswith(text)):
+            return ['summary']
+        elif (len(words) == 3) and ('brief'.startswith(text)):
+            return ['brief']
+        elif (len(words) == 4) and (words[3] not in ['brief', 'detail', 'full-detail', 'summary']):
+            self.print_completion_help(syntax)
+        elif (len(words) >= 3) and (text != ''):
+            self.print_completion_help(syntax)
+        else:
+            self.print_completion_help('<cr>')
+
+    #
+    # --------------------------------------------------------------------------------
+    # show_vns_flow_annotated
+    #
+    # For a given vns-name, show all the active flows in that vns 
+    # or
+    # for show active-flows in all vnses, categorized by vns
+    # Used in "show vns { <vns-name> | all } flow [ brief | full-detail | detail | summary ]
+    # flow records are annotated in the sdnplatform with vns name
+    #
+    def show_vns_flow_annotated(self, words):
+
+        syntax = self.syntax_msg('show vns {<vns-name> | all} flow [ brief | detail | full-detail |summary ]')
+        if (len(words) == 3) and (words[2] not in ['brief', 'details', 'full-detail', 'summary']):
+            print syntax
+            return
+
+        if (len(words) > 3):
+            print syntax
+            return
+        
+        # all = False is this used anywhere
+        
+        vns = words[0]
+        
+        option = 'none'
+        if (len(words) == 3):
+            option = words[2]        
+
+        # Get all the flows in the network
+        annotated_flow_data = {}
+        url = 'http://%s/rest/v1/vns/realtimestats/flow/%s' % (self.controller, vns)
+        annotated_flow_data = self.rest_simple_request_to_dict(url)
+        #print "Data=%s" % json.dumps(annotated_flow_data, sort_keys=True, indent=4)
+        # annotated_flow_data response is in the following format:
+        # Data={
+        #   "vnsCount": 1, 
+        #   "vnsFlowMap": {
+        #            "two": {
+        #                "flowCount": 10, 
+        #                "flowList": [
+        #                     {
+        #                       "dpid": "00:00:00:00:00:00:00:0f", 
+        #                       "flowEntry": {
+        #                          "actions": [
+        #                               {
+
+        # vnsCount = annotated_flow_data["vnsCount"]
+        vnsFlowMap = annotated_flow_data["vnsFlowMap"]
+        vnsAddressSpaceMap = annotated_flow_data["vnsAddressSpaceMap"]
+        
+        if (option == "brief"):
+            table_field_ordering = "vns_flow"
+        elif (option == "detail"):
+            table_field_ordering = "details"
+        elif (option == "full-detail"):
+            table_field_ordering = "undefined" # prints everything!
+        elif (option == "summary"):
+            table_field_ordering = "summary"            
+        else:
+            table_field_ordering = "default"        
+        
+        summaryTable = [] # used for holding the data for "summary" option
+        for vnsName in vnsFlowMap:
+            if (option == 'brief') or (option == "summary"):
+                flow_tuple_list = []
+                briefFlowCnt = 0
+            # Table Data will hold all the flow entries, one list element per row of output
+            # It is reinitilized for each VNS   
+            tableData  = []
+            vnsFlowCnt = vnsFlowMap[vnsName]["flowCount"]                    
+            vnsFlowList = vnsFlowMap[vnsName]["flowList"]
+            for vnsFlowEntry in vnsFlowList:                
+                flowEntry = vnsFlowEntry["flowEntry"]
+                dpid      = vnsFlowEntry["dpid"]
+                if (option == "brief") or (option == "summary"):                    
+                    src_mac   = flowEntry['match']['dataLayerDestination']
+                    dst_mac   = flowEntry['match']['dataLayerSource']
+                    vlan      = flowEntry['match']['dataLayerVirtualLan']
+                    etherType = flowEntry['match']['dataLayerType']
+                    flowList  = []
+                    flowList.append(src_mac)
+                    flowList.append(dst_mac)
+                    flowList.append(vlan)
+                    flowList.append(etherType)
+                    if flowList in flow_tuple_list:
+                        # duplicate flow (due to same flow entry on multiple switches along the path, 
+                        # skip it if the option if brief or summary
+                        continue
+                    else:
+                        flow_tuple_list.append(flowList)
+                        briefFlowCnt += 1
+                #print "DPID = %s" % dpid
+                #print " New Data = %s" % json.dumps(flowEntry, indent=4)
+                if (option != "summary"):
+                    tableEntry = {}
+                    tableEntry[dpid] = []
+                    tableEntry[dpid].append(flowEntry)
+                    tableEntry = self.add_dpid_to_data(tableEntry)
+                    tableEntry = self.fix_realtime_flows(tableEntry)
+                    #print "Table Entry : %s" % json.dumps(tableEntry, indent=4)
+                    tableData.append(tableEntry[0])
+            #print "*** Table Data: %s" % json.dumps(tableData[0], indent=4)
+            #printf tenant + vnsname
+            names=vnsName.split('|')
+            tenant=names[0]
+            vns=names[1]
+            if (option == "brief"):
+                yield("\nTenant %s VNS %s (address-space %s) flows (count: %s)" % (tenant, vns, vnsAddressSpaceMap[vnsName], briefFlowCnt))
+            elif (option != "summary"):
+                yield("\nTenant %s VNS %s (address-space %s) flow entries (count: %s)" % (tenant, vns, vnsAddressSpaceMap[vnsName], vnsFlowCnt))
+            # Print flow data for one vns, unless option is summary
+            if (option == "summary"):
+                summaryData = dict()
+#                summaryData['tenant']       =tenant
+                summaryData["vnsName"]      = vns
+                summaryData["flowEntryCnt"] = vnsFlowCnt
+                summaryData["vnsFlowCnt"]   = briefFlowCnt
+                summaryTable.append(summaryData)
+            else:
+                yield("\n") 
+                # print "*** TD = %s" % tableData
+                tableData = self.pp.format_table(tableData, "realtime_flow", table_field_ordering)
+                yield(tableData)
+                
+        if (option == "summary"):            
+            # print "*** ST %s" % summaryTable
+            yield("\n")
+            summaryTable = self.pp.format_table(summaryTable, "realtime_flow", table_field_ordering)            
+            yield(summaryTable)
+        print(" ") 
+        return
+  
+    #
+    # --------------------------------------------------------------------------------
+    # show_vns_switch_ports
+    #  For some vns-name, collect all the interfaces, and from that,
+    #  collect all the attachment points.  The objective here is to
+    #  name all the switch's and ports associated with a vns
+    #
+    def show_vns_switch_ports(self, words):
+        if len(words) < 1:
+            return
+
+        # words:  [ vns_name, 'switch', switch_name ]
+        vns_name = words[0]
+        switch = None
+        if len(words) > 2:
+            switch = convert_alias_to_object_key('switch', words[2])
+        port = None
+        if len(words) > 3:
+            port = words[3]
+
+        vns_interface_key = mi.pk('vns-interface')
+        if vns_name == 'all':
+            vns_ifs = create_obj_type_dict('vns-interface',
+                                           vns_interface_key,
+                                           'id')
+            vns_rules = create_obj_type_dict('vns-interface-rule',
+                                             mi.pk('vns-interface-rule'),
+                                             'id',)
+        else:
+            vns_ifs = create_obj_type_dict('vns-interface',
+                                           vns_interface_key,
+                                           'vns',
+                                           vns_name)
+            vns_rules = create_obj_type_dict('vns-interface-rule',
+                                             mi.pk('vns-interface-rule'),
+                                             'vns',
+                                             vns_name)
+        host_dap_dict = self.create_attachment_dict()
+
+        bsp = {}  # _b_vs _s_witch _p_ort
+        for ifs in vns_ifs:
+            fields = ifs.split('|')
+            # all these fields must have two parts.
+            if len(fields) != 3:
+                continue
+            # choose between switch based rules and mac/ip based rules
+            rule = 'default'
+            vns_name = vns_ifs[ifs][0]['vns']
+            switch_rule = None
+            if fields[1] != 'default':
+                rule = vns_ifs[ifs][0]['rule']
+                if not rule in vns_rules:
+                    continue
+                if_rule = vns_rules[rule][0]
+                if 'switch' in if_rule:
+                    switch_rule = if_rule['switch']
+            else:
+                if_rule = { 'mac' : 'defaultLie' } # for default rules
+
+            # There's two major classes of rules: host and switch
+            # Use existance of a 'switch' to differentiate between the two.
+            if switch_rule:
+                # if_rule/switch are both set, part after the '/' is the port
+                if fields[2].find('/') < 0:
+                    # skip Eth<n> general interface
+                    continue
+                #
+                # Prefix this port with a plus sign, which will be recognized
+                # in the printing code as already describing an openflow port name
+                port = '+' + fields[2].split('/')[1]
+                tenant_vns=vns_name.split('|')
+                tenant_name=tenant_vns[0]
+                vns_real_name=tenant_vns[1] 
+                key = "%s|%s|%s|%s" % (tenant_name,vns_real_name, switch, port)
+
+                if not key in bsp:
+                    bsp[key] = {
+                            'tenant'      : tenant_name,
+                            'vns'         : vns_real_name,
+                            'switch'      : switch_rule,
+                            'port'        : port,
+                            'reason'      : ["Rule:%s" % rule.split('|')[-1], fields[1]],
+                    }
+                else:
+                    pass # should only be one.
+            else:
+                # the second part (fields[1]) is the interface-long name,
+                items = fields[2].split('/')
+                if len(items) == 1:
+                    if items[0].startswith('VEth'):
+                        if not 'mac' in rule:
+                            continue
+                        mac = if_rule['mac']
+                    elif items[0].startswith('Eth'):
+                        self.debug_msg('should have been a switch in if_rule')
+                        continue
+                    else:
+                        self.debug_msg('item length of 1')
+                        continue
+                else:
+                    mac = items[1]
+                    if not re.match(r'^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$', mac):
+                        print 'Not a mac address: %s' % mac
+                # currently just use the mac to find the attachment points.
+                if mac in host_dap_dict:
+                    for attachment_point in host_dap_dict[mac]:
+                        # if switch is named, skip any which don't match
+                        if switch and attachment_point['switch'] != switch:
+                            continue
+                        if port and attachment_point['ingress-port'] != port:
+                            continue
+
+                        tenant_vns=vns_name.split('|')
+                        tenant_name=tenant_vns[0]
+                        vns_real_name=tenant_vns[1] 
+                        key = "%s|%s|%s|%s" % (tenant_name,
+                                            vns_real_name,
+                                            attachment_point['switch'],
+                                            attachment_point['ingress-port'])
+                        if not key in bsp:
+                            bsp[key] = {
+                                    'tenant' : tenant_name,
+                                    'vns'    : vns_real_name,
+                                    'switch' : attachment_point['switch'],
+                                    'port'   : utif.try_int(attachment_point['ingress-port']),
+                                    'reason' : ["Rule:%s" % rule.split('|')[-1], mac]
+                                    }
+                        else:
+                            self.append_when_missing(bsp[key]['reason'],
+                                                    "Rule:%s" % rule.split('|')[-1])
+                            self.append_when_missing(bsp[key]['reason'], mac)
+
+        sort = [bsp[x] for x in sorted(bsp.keys(),
+                                       cmp=lambda a,b: cmp(utif.try_int(a.split('|')[2]),
+                                                           utif.try_int(b.split('|')[2]))
+                                           if a.split('|')[1] == b.split('|')[1]
+                                           else cmp(b.split('|')[1],a.split('|')[1]))]
+
+        return self.display_obj_type_rows('vns-switch-ports', sort)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # show_switch_ports_vns
+    #
+    def show_switch_ports_vns(self, words):
+        switch = None
+        if len(words) > 1 and words[0] != 'all':
+            switch = words[0]
+            #
+            # switch alias conversion
+            value = alias_lookup('switch-alias', switch)
+            if value:
+                switch = value
+
+        #
+        # dictionary from the vns side, indexed by host.
+        vns_ifs_dict = create_obj_type_dict('vns-interface',
+                                            mi.pk('vns-interface'))
+        #
+        # dictionary of the interface-rules, by rule
+        vns_rules = create_obj_type_dict('vns-interface-rule',
+                                         mi.pk('vns-interface-rule'))
+        #
+        # from the list of hosts, identify the attachment points
+        host_dap_dict = self.create_attachment_dict()
+
+        #
+        # there can be multiple attachment points for each of the
+        # hosts.  iterate over the hosts,  find all the attachment points,
+        # manage an association for the entries
+        spb = {}  # _s_witch _p_ort _b_vs
+        for ifs in vns_ifs_dict:
+            fields = vns_ifs_dict[ifs][0]['id'].split('|')
+            # all these fields must have two parts.
+            if len(fields) != 2:
+                continue
+            # id parts are vns|interface
+            vns_name = fields[0]
+
+            # choose between switch based rules and mac/ip based rules
+            rule = 'default'
+
+            switch_rule = None
+            mac_rule = None
+            rule_fields = [rule]
+            if vns_name == 'default':
+                if fields[1].find('/') >= 0:
+                    mac_rule = fields[1].split('/')[1]
+            else:
+                if not 'rule' in vns_ifs_dict[ifs][0]:
+                    continue
+                rule = vns_ifs_dict[ifs][0]['rule']
+                rule_fields = rule.split('|')
+                if_rule = vns_rules[rule][0]
+                if 'switch' in if_rule:
+                    if switch and if_rule['switch'] != switch:
+                        continue
+                    switch_rule = if_rule['switch'] # switch may be None.
+                elif 'mac' in if_rule:
+                    mac_rule = if_rule['mac']
+                elif 'ip-subnet' in if_rule:
+                    mac_rule = if_rule['ip-subnet']
+                elif 'tags' in if_rule:
+                    mac_rule = if_rule['tags']
+                elif 'vlans' in if_rule:
+                    mac_rule = if_rule['vlans']
+            if mac_rule:
+                if not mac_rule in host_dap_dict:
+                    self.debug_msg("Unknown attachment point for %s" % mac_rule)
+                    continue
+
+                for attachment_point in host_dap_dict[mac_rule]:
+                    key = "%s|%s" % (attachment_point['switch'],
+                                      attachment_point['ingress-port'])
+                    if switch and attachment_point['switch'] != switch:
+                        continue
+
+                    if not key in spb:
+                        spb[key] = {
+                                'switch' : attachment_point['switch'],
+                                'port'   : utif.try_int(attachment_point['ingress-port']),
+                                'vns'    : {vns_name : 1},
+                                'reason' : ["Rule:%s" % rule_fields[-1], mac_rule]
+                                }
+                    else:
+                        if vns_name in spb[key]['vns']:
+                            spb[key]['vns'][vns_name] += 1
+                        else:
+                            spb[key]['vns'][vns_name] = 1
+                        self.append_when_missing(spb[key]['reason'],
+                                                 "Rule:%s" % rule_fields[-1])
+                        self.append_when_missing(spb[key]['reason'], mac_rule)
+            if switch_rule:
+                if fields[1].find('/') >= 0:
+                    #
+                    # Prefix this port with a plus sign, which will be recognized
+                    # in the printing code as already describing an openflow port name
+                    port = '+' + fields[1].split('/')[1]
+                    key = "%s|%s" % (switch_rule, port)
+
+                    if not key in spb:
+                        spb[key] = {
+                                'switch' : switch_rule,
+                                'port'   : port,
+                                'vns'    : {vns_name : 1},
+                                'reason' : ["Rule:%s" % rule_fields[-1], fields[1]]
+                        }
+
+        sort = [spb[x] for x in sorted(spb.keys(),
+                                        cmp=lambda a,b: cmp(utif.try_int(a.split('|')[1]),
+                                                            utif.try_int(b.split('|')[1]))
+                                            if a.split('|')[0] == b.split('|')[0]
+                                            else cmp(b.split('|')[0],a.split('|')[0]))]
+
+        return self.display_obj_type_rows('switch-ports-vns', sort)
+                                          # [spb[x] for x in sorted(spb.keys())])
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_vns
+    #
+    def do_show_vns(self, words):
+        choices = ['interface', 'mac-address-table',
+                   'interface-rules', 'access-lists', 'running-config', 'switch', 'flow' ]
+        if words == None or len(words) > 2:
+            if words[1] not in ['switch', 'flow']:
+                return self.syntax_msg('show vns <vns-name> [ %s ] ' %
+                                       ' | '.join(choices))
+        if len(words) in [3, 4]:
+            if words[1] == 'switch':
+                return self.show_vns_switch_ports(words)
+            elif words[1] == 'flow':
+                return self.show_vns_flow_annotated(words)
+            else:
+                return self.syntax_msg('show vns <vns-name> [ %s ] ' %
+                                       ' | '.join(choices))
+        elif len(words) == 2:
+            # words[0] ought to an existing vns
+            # Allow show vns all flow [detail]
+            if (not self.vns_find_name(words[0])) and (words[1] != 'flow'):
+                return self.error_msg("show vns '%s': vns Not Found" % words[0])
+
+            vns_key = self.prefix_search_key([words[0]])
+            selection = utif.full_word_from_choices(words[1], choices)
+            if not selection:
+                return self.syntax_msg('show vns <vns-name> [ %s ' %
+                                       ' | '.join(choices))
+            if selection == 'interface':
+                return self.find_and_display_vns_interface(words[0], words[2:])
+            elif selection == 'mac-address-table':
+                # the id for the host-vns-interface table has the host as the 'prefix',
+                # preventing searching based on the prefix.  the vns is not even a foreign
+                # key, which means the complete table must be read, then the vns association
+                # must be determined, and then matched
+                return self.display_vns_mac_address_table(words[0], words[2:])
+            elif selection == 'interface-rules':
+                return self.do_show_object(['vns-interface-rule', vns_key], "<no_key>")
+            elif selection == 'access-lists':
+                return self.do_show_object(['vns-access-list-entry', vns_key], "<no_key>")
+            elif selection == 'running-config':
+                return self.show_vns_running_config(words[0])
+            elif selection == 'switch':
+                return self.show_vns_switch_ports(words)
+            elif selection == 'flow':
+                return self.show_vns_flow_annotated(words)
+        elif len(words) == 1:
+            return self.do_show_object(["vns-definition", words[0]])
+        else:
+            return self.do_show_object(["vns-definition"])
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_vns_interface_rule
+    #  do_show_object is used to construct the output for the table search.
+    #  However, since a vns prefix key search is used to display the table,
+    #  and since do_show_object behaves differently when displaying tables
+    #  depending on whether the table is a key search or not, the 'with_search_key'
+    #  parameter is set to "with_key" when the caller included an additional
+    #  prefix for (key) for the rule, and otherwise '<no_key>' is used when
+    #  the caller wants the complete interface-rule table for a single vns
+    #  (which obvioulsy also implies a key search for 'vns|' prefied rules.
+    #
+    def do_show_vns_interface_rule(self, words):
+        with_search_key = "<no_key>"
+        if self.vns_name() is None:
+            if len(words) > 0:
+                search_object = ["vns-interface-rule", words[0]]
+            else:
+                search_object = ["vns-interface-rule"] 
+        elif len(words) > 0:
+            with_search_key = '-'.join(words)
+            words.insert(0, self.vns_name())
+            search_object = ["vns-interface-rule", 
+                             self.unique_key_from_non_unique(words)]
+        else:
+            search_object = ["vns-interface-rule",
+                             self.prefix_search_key([self.vns_name()]) ] 
+            obj_type = 'vns-interface-rule'
+
+            # --- this ought to be promoted to be used more ..
+            s_dict = {}
+            # for all foreign keys in this obj_type
+            mode_dict = self.mode_stack_to_rest_dict({})
+
+            # for fk in mi.obj_type_foreign_keys(obj_type):
+            for kf in mi.compound_key_fields(obj_type, mi.pk(obj_type)):
+                if mi.is_foreign_key(obj_type, kf):
+                    (ref_ot, ref_fn) = mi.foreign_key_references(obj_type, kf)
+                    if ref_ot in mode_dict:
+                        s_dict[kf] = mode_dict[ref_ot]
+
+            # for (n,v) in self.mode_stack_to_rest_dict({}).items():
+                # for (fk_ot, fk_fn) in mi.foreign_key_xref[n][mi.pk(n)]:
+                    # print n, fk_ot, fk_fn
+                    # if fk_ot == obj_type:
+                        # s_dict[fk_fn] = v
+            entries = self.store.rest_query_objects(obj_type, s_dict)
+            return self.display_obj_type_rows(obj_type, entries, with_search_key)
+        return self.do_show_object(search_object, with_search_key)
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_is_alias
+    #  Used in cp_no to determine if the particular request is an alias completion
+    #
+    def cp_is_alias(self, words, text):
+        if not self.in_config_submode() or len(words) != 2:
+            return False
+        obj_type = self.get_current_mode_obj_type()
+        # LOOK! robv: Tweaked this from the commented out version below
+        return obj_type in mi.alias_obj_type_xref
+ 
+
+    #
+    # --------------------------------------------------------------------------------
+    # cascade_delete
+    #  Delete interior objects' rows related via foreign keys
+    #
+    def cascade_delete(self, obj_type, id_value):
+        global modi
+
+        obj_key = mi.pk(obj_type)
+        if obj_type in mi.foreign_key_xref and \
+           obj_key in mi.foreign_key_xref[obj_type]:
+            for (fk_obj_type, fk_name) in mi.foreign_key_xref[obj_type][obj_key]:
+                if mi.is_cascade_delete_enabled(fk_obj_type):
+                    #
+                    # find any affected rows
+                    try:
+                        rows = self.get_table_from_store(fk_obj_type,
+                                                         fk_name,
+                                                         id_value,
+                                                         "exact")
+                    except Exception, e:
+                        if self.debug or self.debug_backtrace:
+                            errors = self.rest_error_to_dict(e, fk_obj_type)
+                            print self.rest_error_dict_to_message(errors)
+                        rows = []
+
+                    # determine whether the foreign key can have a null
+                    # value, in which case the row doesn't have to be deleted,
+                    # just updated the foreign key to `None'.
+                    if mi.is_force_delete_enabled(fk_obj_type):
+                        delete = True
+                    elif mi.is_null_allowed(fk_obj_type, fk_name):
+                        delete = False
+                    else:
+                        delete = True
+
+                    key = mi.pk(fk_obj_type)
+                    for row in rows:
+                        try:
+                            if delete:
+                                self.rest_delete_object(fk_obj_type, row[key])
+                            else: # update
+                                self.rest_update_object(fk_obj_type, key, row[key], 
+                                                        { fk_name : None } )
+                            errors = None
+                        except Exception, e:
+                            errors = self.rest_error_to_dict(e,
+                                                             fk_obj_type + " "
+                                                             + row[key])
+                        if errors:
+                            return self.rest_error_dict_to_message(errors)
+                        self.debug_msg("cascade delete: %s: %s" % \
+                                       (fk_obj_type, ', '.join(row[key].split('|'))))
+                        if delete:
+                            self.cascade_delete(fk_obj_type, row[key])
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_no
+    #  Delete rows from a table, or update a field.  For fields which
+    #  have defaults, 'no' referts the field to its default value.
+    #
+    def do_no(self, words):
+        # format is no < obj_type > < id >
+        if not self.in_config_mode():
+            if len(words) < 1 or words[0] != 'debug':
+                return self.error_msg("'no' command only valid in config mode")
+        obj_type = self.get_current_mode_obj_type()
+        option = words[0]
+        #
+        # manage deletion of complete rows in obj_types'
+        #
+        if option in self.obj_types_for_config_mode_starting_with():
+            if not len(words) > 1:
+                return self.error_msg("<id> must be specified for the object to delete")
+            item = convert_alias_to_object_key(option, words[1])
+ 
+            try:
+                self.rest_delete_object(option, item)
+                errors = None
+            except Exception, e:
+                errors = self.rest_error_to_dict(e, option + " " + item)
+            #
+            # cascade delete?
+            if not errors:
+                self.cascade_delete(option, item)
+        #
+        # manage removal/set-to-default of values in fields of an obj_type
+        #
+        elif option in self.fields_for_current_submode_starting_with(option):
+            #
+            # replace the obj_type with the alias obj_type when for
+            # fields called 'alias' when the obj_type has one alias 
+            if obj_type in mi.alias_obj_type_xref:
+                aliases = mi.alias_obj_type_xref[obj_type]
+                if option in aliases:
+                    obj_type = option
+                if len(aliases) == 1 and option == 'alias':
+                    obj_type = aliases[0]
+            if len(aliases) != 1:
+                print self.error_msg("Internal 'no' more than one alias choice")
+                if len(words) < 2:
+                    return "Syntax: no %s <value>" % option
+                item = words[1]
+                try:
+                    self.rest_delete_object(obj_type, item)
+                    errors = None
+                except Exception, e:
+                    errors = self.rest_error_to_dict(e, obj_type + " " + item)
+                return self.rest_error_dict_to_message(errors)
+ 
+            key = mi.pk(obj_type)
+            #
+            # note: field_default_value returns None when no default is
+            # provided.  its not clear whether default values are always
+            # provided for fields which don't accept null values.
+            #
+            default_value = mi.field_default_value(obj_type, option)
+
+            if mi.is_null_allowed(obj_type, option) and default_value:
+                self.warning("'%s' accepts null and had a default "
+                             "value; %s is set to the default value '%s" %
+                             (obj_type, option, default_value))
+
+            errors = self.rest_update_object(obj_type,
+                                             key,
+                                             self.get_current_mode_obj(),
+                                             {option:default_value})
+            # fall through to return
+        elif self.in_config_vns_acl_mode() and self.ACL_RE.match(option):
+            return self.do_vns_no(['access-list-entry'] + words)
+        #elif self.in_config_controller_interface_mode() and 'firewall'.startswith(option):
+        #    return self.do_no_firewall(words)
+        else:
+            try:
+                command_words = ['no'] + words
+                # Just try to execute the command. It will either succeed or
+                # throw an exception
+                return command.do_command(command_words)
+            except urllib2.HTTPError, e:
+                raise e
+            except Exception, e:
+                if self.debug or self.debug_backtrace:
+                    traceback.print_exc()
+                return self.error_msg("'%s' must be either a valid object type or a field" %
+                                  option)
+
+        # when errors == None, rest_error_dict_to_message returns None.
+        return self.rest_error_dict_to_message(errors)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # implement_ping
+    #    Performs a traceroute to a switch or host.
+    #    Input can either be a DPID, switch alias, or host (IP or domain).
+    def implement_ping(self, data):
+        
+        count = '-c %d ' % data.get('count', 5)
+        if not 'ip-address' in data:
+            yield('Can\'t determine ping target')
+            return
+
+        ip_host = data['ip-address']
+        if self.DPID_RE.match(ip_host):
+            ip_host = self.get_ip_from_switch_dpid_or_alias(ip_host)
+
+        cmd = 'ping %s%s' % (count, self.shell_escape(ip_host))
+        for item in self.generate_subprocess_output(cmd):
+            yield item
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # implement_traceroute
+    #    Performs a traceroute to a switch or host.
+    #    Input can either be a DPID, switch alias, or host (IP or domain).
+    def implement_traceroute(self, data):
+
+        if not 'ip-address' in data:
+            yield('Can\'t determine traceroute target')
+            return
+
+        ip_host = data['ip-address']
+        if self.DPID_RE.match(ip_host):
+            ip_host = self.get_ip_from_switch_dpid_or_alias(ip_host)
+
+        cmd = 'traceroute %s' % self.shell_escape(ip_host)
+        for item in self.generate_subprocess_output(cmd):
+            yield item
+
+ 
+    #
+    # --------------------------------------------------------------------------------
+    # do_no_firewall
+    #
+    #def do_no_firewall(self, words):
+    #    return self.do_firewall(words[1:], True)
+        
+
+    #
+    # --------------------------------------------------------------------------------
+    # firewall_rule_add_rule_to_entries
+    #
+    def firewall_rule_add_rule_to_entries(self, entries):
+        for entry in entries:
+            entry['rule'] = run_config.firewall_rule(entry)
+        return entries
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # get_firewall_rules
+    #  Returns a list of strings describing the firewall rules for a particular
+    #  controller-node name.
+    #
+    def get_firewall_rules(self, node):
+        key = mi.pk('firewall-rule')
+        key_value = self.unique_key_from_non_unique([node])
+        entries = self.get_table_from_store('firewall-rule', key, key_value)
+
+        return self.firewall_rule_add_rule_to_entries(entries)
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_show_firewall
+    #  Depends on get_firewall_rules to add 'rule' to entries so that
+    #  the 'firewall-rule' table can display the rule's value in a
+    #  easily identified syntax.
+    #
+    def do_show_firewall(self, words):
+        return self.display_obj_type_rows('firewall-rule',
+                                          self.get_firewall_rules(self.get_current_mode_obj()))
+
+    # --------------------------------------------------------------------------------
+    # handle_command
+    #
+    def handle_command(self, command_word, words):
+        if type(command_word) == str:
+            method = self.command_method_from_name(command_word)
+            if method:
+                return method(words)
+        # XXX It would be better to only call do_command if it
+        # was clear that this command actually existed.
+        return command.do_command([command_word] + words)
+
+
+    #
+    # --------------------------------------------------------------------------------
+    # find_with_quoting
+    #
+    #  Assumes start_index is not inside a quoted string.
+    #
+    @staticmethod
+    def find_with_quoting(line, find_char, reverse=False, start_index=0):
+        in_quoted_arg = False
+        line_length = len(line)
+        i = start_index
+        found_index = -1;
+        while i < line_length:
+            c = line[i]
+            if c in "\"'":
+                if not in_quoted_arg:
+                    quote_char = c
+                    in_quoted_arg = True
+                elif c == quote_char:
+                    in_quoted_arg = False
+                # otherwise leave in_quoted_arg True
+            elif c == "\\" and in_quoted_arg:
+                i += 1
+            elif (c == find_char) and not in_quoted_arg:
+                found_index = i
+                if not reverse:
+                    break
+            i += 1
+            
+        return found_index
+    
+    #
+    # --------------------------------------------------------------------------------
+    # split_with_quoting
+    #
+    @staticmethod
+    def split_with_quoting(line, separators=" \t"):
+        word_list = []
+        current_word = ""
+        in_quoted_arg = False
+        line_length = len(line)
+        i = 0
+        while i < line_length:
+            c = line[i]
+            i += 1
+            if c in "\"'":
+                if not in_quoted_arg:
+                    in_quoted_arg = True
+                    quote_char = c
+                elif c == quote_char:
+                    in_quoted_arg = False
+                    word_list.append(current_word)
+                    current_word = ""
+                else:
+                    current_word += c
+            elif c == "\\" and in_quoted_arg:
+                if i < line_length:
+                    c = line[i]
+                    current_word += c
+                    i += 1
+            elif (c in separators) and not in_quoted_arg:
+                if current_word:
+                    word_list.append(current_word)
+                    current_word = ""
+            else:
+                current_word += c
+                
+        if current_word:
+            word_list.append(current_word)
+        
+        return word_list
+    
+    #
+    # --------------------------------------------------------------------------------
+    # quote_item
+    #  Some of the new model columns available as choices to select have the '|' 
+    #  character as a separator.  For these choices to word, they need to be
+    #  quoted
+    #
+    @staticmethod
+    def quote_item(obj_type, item):
+        if item.find("|") >= 0:
+            return  '"' + str(item) + '"' 
+        else:
+            return str(item)
+
+    #
+    # --------------------------------------------------------------------------------
+    # 
+    def replay(self, file, verbose = True, command_replay = False):
+        # Only replay the STR values, since the code ought to
+        # stuff back the JSON values.
+        play = open(file)
+        rest_line_format = re.compile(r'^REST ([^ ]*)(  *)([^ ]*)(  *)(.*)$')
+        cmd_line_format = re.compile(r'^COMMAND (.*)$')
+        skip_command = True
+        for line in play.read().split('\n'):
+            # the format ought to be url<space>[STR|JSON]<space> ...
+            match = rest_line_format.match(line)
+            if match:
+                if match.group(3) == 'STR':
+                    if verbose:
+                        print 'REST STR', match.group(1)
+                    url_cache.save_url(match.group(1), match.group(5), 1000000)
+                elif match.group(3) == 'JSON':
+                    if verbose:
+                        print 'REST JSON', match.group(1)
+                    entries = json.loads(match.group(5))
+                    url_cache.save_url(match.group(1), entries, 1000000)
+                else:
+                    print 'REST REPLAY NOT STR|JSON'
+            elif len(line):
+                match = cmd_line_format.match(line)
+                if command_replay and match:
+                    # skip the first command since it ought to be the replay enablement
+                    if skip_command:
+                        if verbose:
+                            print 'SKIP COMMAND %s' % match.group(1)
+                        skip_command = False
+                    else:
+                        line = self.split_with_quoting(match.group(1))
+                        if verbose:
+                            print 'COMMAND %s' % line
+                        output = self.handle_multipart_line(line[0])
+                        if output != None:
+                            print output
+                else:
+                    print 'no MATCH +%s+' % line
+        play.close()
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_single_line
+    #
+    def handle_single_line(self, line):
+        ret_val = None
+        if len(line) > 0 and line[0]=="!": # skip comments
+            return
+        words = self.split_with_quoting(line)
+        if not words:
+            return
+        #
+        self.completion_reset()
+
+        # Look for the replay keyword, use the first two tokens if the replay
+        # keyword is in the first part of the command.
+        if self.debug and len(words) >= 2:
+            if words[0] == 'replay':
+                # replay the file, remove the first two keywords
+                self.replay(words[1], command_replay = len(words) == 2)
+                if len(words) == 2:
+                    return
+                words = words[2:]
+
+        # the first word of a line is either:
+        # - a command - dependent on mode (show anywhere but configure only in enable)
+        # - an object type - if we're in a config mode (either config or config submode)
+        # - a field for an object - if we're in a config submode
+        matches = [(x, "command") for x in self.commands_for_current_mode_starting_with(words[0])]
+        matches.extend([(x, "config object") for x in self.obj_types_for_config_mode_starting_with(words[0])])
+        matches.extend([(x, "field") for x in self.fields_for_current_submode_starting_with(words[0])])
+        # LOOK!: robv Fix to work with field names where one name is a prefix of another
+        if len(matches) > 1:
+            for match_tuple in matches:
+                if match_tuple[0] == words[0]:
+                    matches = [match_tuple]
+                    break
+        if len(matches) == 1:
+            match = matches[0]
+            # Replace the (possibly) abbreviated argument with the full name.
+            # This is so that the handlers don't need to all handle abbreviations.
+            if type(match[0]) == str:
+                words[0] = match[0]
+
+            if match[1] == "field":
+                ret_val = self.handle_field(words)
+            elif match[1] == "config object":
+                ret_val = self.handle_obj_type(words)
+            else:
+                ret_val = self.handle_command(words[0], words[1:])
+                #ret_val = self.handle_command(match[0], words[1:])
+        elif len(matches) > 1:
+            ret_val = self.error_msg("%s is ambiguous\n" % words[0])
+            for m in matches:
+                ret_val += "%s (%s)\n" % m
+        else:
+            ret_val = self.error_msg("Unknown command: %s\n" % words[0])
+
+        url_cache.command_finished(words)
+        return ret_val
+
+    #
+    # --------------------------------------------------------------------------------
+    # generate_pipe_output
+    #
+    def generate_pipe_output(self, p, output):
+        fl = fcntl.fcntl(p.stdout, fcntl.F_GETFL)
+        fcntl.fcntl(p.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+
+        for item in output:
+            try:
+                p.stdin.write(item)
+            except IOError:
+                break
+
+            try:
+                out_item = p.stdout.read()
+                yield out_item
+            except IOError:
+                pass
+            
+        p.stdin.close()
+
+        fcntl.fcntl(p.stdout, fcntl.F_SETFL, fl)
+        while True:
+            out_item = p.stdout.read()
+            if (out_item):
+                yield out_item
+            else:
+                p.stdout.close()
+                break
+        p.wait()
+
+    #
+    # --------------------------------------------------------------------------------
+    # write_to_pipe
+    #
+    def write_to_pipe(self, p, output):
+        for item in output:
+            try:
+                p.stdin.write(item)
+            except IOError:
+                break
+        p.stdin.close()
+        p.wait()
+            
+    #
+    # --------------------------------------------------------------------------------
+    # shell_escape
+    #  Return a string, quoting the complete string, and correctly prefix any
+    #  quotes within the string.
+    #
+    def shell_escape(self, arg):
+        return "'" + arg.replace("'", "'\\''") + "'"
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_pipe_and_redirect
+    #
+    def handle_pipe_and_redirect(self, pipe_cmds, redirect_target, output):
+        # if redirect target is tftp/ftp/http/file, then we should actually stick
+        # curl at the end of the pipe_cmds so it gets handled below
+        if redirect_target:
+            if redirect_target.startswith("tftp") or redirect_target.startswith("ftp") or \
+               redirect_target.startswith("http") or redirect_target.startswith("file"):
+                redirect_target = self.shell_escape(redirect_target)
+                # add so it can be used below
+                if pipe_cmds == None:
+                    pipe_cmds = ""
+                else:
+                    pipe_cmds += " | "
+
+                if redirect_target.startswith("ftp"): # shell_escape added quote
+                    pipe_cmds += " curl -T - %s" % self.shell_escape(redirect_target)
+                else:
+                    pipe_cmds += " curl -X PUT -d @- %s" % self.shell_escape(redirect_target)
+
+        if pipe_cmds:
+            new_pipe_cmd_list = []
+            for pipe_cmd in [x.strip() for x in pipe_cmds.split('|')]:
+                # doing it this way let us handles spaces in the patterns
+                # as opposed to using split/join which would compress space
+                new_pipe_cmd = pipe_cmd
+                m = re.search('^(\w+)(.*)$', pipe_cmd) 
+                if m: 
+                    first_tok = m.group(1)
+                    rest_of_cmd = m.group(2).strip()
+                    if first_tok.startswith("in"):
+                        new_pipe_cmd = "grep -e " + rest_of_cmd
+                    elif first_tok.startswith("ex"):
+                        new_pipe_cmd = "grep -v -e" + rest_of_cmd
+                    elif first_tok.startswith("begin"):
+                        new_pipe_cmd =  "awk '/%s/,0'" % rest_of_cmd
+                new_pipe_cmd_list.append(new_pipe_cmd)
+
+            new_pipe_cmds = "|".join(new_pipe_cmd_list)
+            if new_pipe_cmds:
+                if redirect_target:
+                    p = subprocess.Popen(new_pipe_cmds, 
+                                         shell=True, 
+                                         stdin=subprocess.PIPE, 
+                                         stdout=subprocess.PIPE,
+                                         stderr=subprocess.STDOUT)
+                    output = self.generate_pipe_output(p, output)
+                else:
+                    p = subprocess.Popen(new_pipe_cmds, 
+                                         shell=True, 
+                                         stdin=subprocess.PIPE)
+                    self.write_to_pipe(p, output)
+                    output = None
+
+        # only handle local file here as http/ftp were handled above via pipe
+        if redirect_target:
+            if redirect_target.startswith("config://"):
+                m = re.search(self.local_name_pattern, redirect_target)
+                if m:
+                    join_output = ''.join(iter(output))
+                    store_result = self.store.set_user_data_file(m.group(1), join_output)
+                    if store_result:
+                        result = json.loads(store_result)
+                    else:
+                        return self.error_msg("rest store result not json format")
+                    if 'status' in result and result['status'] == 'success':
+                        return None
+                    elif 'message' not in result:
+                        return self.error_msg("rest store result doesn't contain error message")
+                    else:
+                        return self.error_msg(result['message'])
+                else:
+                    print self.error_msg("invalid name-in-db (%s)\n" % redirect_target)
+            else:
+                return output
+
+        return None
+
+    #
+    # --------------------------------------------------------------------------------
+    # generate_command_output
+    #
+    @staticmethod
+    def generate_command_output(ret_val):
+        if (isinstance(ret_val, str) or \
+            isinstance(ret_val, buffer) or \
+            isinstance(ret_val, bytearray) or \
+            isinstance(ret_val, unicode)):
+
+            # yield ret_val
+            if len(ret_val) and ret_val[-1] == '\n':
+                ret_val = ret_val[:-1]
+            for line in ret_val.split('\n'):
+                yield line + '\n'
+        elif ret_val != None:
+            for item in ret_val:
+                yield item
+
+    #
+    # --------------------------------------------------------------------------------
+    # generate_line_output
+    #
+    # This is a generator that will generate the output of the 
+    # command either as a string, or by iterating over a returned
+    # iterable.  This way, a subcommand can return an iterable to 
+    # lazily evaluate large amounts of output
+    #
+    def generate_line_output(self, line, dont_ask):
+        while line:
+            subline_index = self.find_with_quoting(line, ';')
+            if subline_index < 0:
+                subline_index = len(line)
+            subline = line[:subline_index]
+            line = line[subline_index+1:]
+            ret_val = self.handle_single_line(subline)
+            cnt = 1
+            total_cnt = 0
+
+            (col_width, screen_length) = self.pp.get_terminal_size()
+            if type(self.length) == int:
+                screen_length = self.length
+
+            for item in self.generate_command_output(ret_val):
+                if not dont_ask:
+                    incr = 1 + (max((len(item.rstrip()) - 1), 0) / col_width)
+                    if screen_length and cnt + incr >= screen_length:
+                        raw_input('-- hit return to continue, %s) --' % total_cnt)
+                        cnt = 0
+                    cnt += incr
+                    total_cnt += incr
+                yield item
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_multipart_line
+    #
+    # this is the outermost handler that should print
+    #
+    def handle_multipart_line(self, line):
+        pipe_cmds = None
+        redirect_target = None
+        output = None
+
+        # pattern is:
+        # single line [; single line]* [| ...] [> {conf|ftp|http}]
+
+        # first take off the potential redirect part then the pipe cmds
+        redirect_index = self.find_with_quoting(line, '>', True)
+        if redirect_index >= 0:
+            redirect_target = line[redirect_index+1:].strip()
+            line = line[:redirect_index].strip()
+        pipe_index = self.find_with_quoting(line, '|')
+        if pipe_index >= 0:
+            pipe_cmds = line[pipe_index+1:].strip()
+            line = line[:pipe_index].strip()
+        # remaining text is single lines separated by ';' - handle them
+        output = self.generate_line_output(line, pipe_cmds or redirect_target)
+
+        # now output everything
+        if pipe_cmds or redirect_target:
+            output = self.handle_pipe_and_redirect(pipe_cmds, redirect_target, output)
+
+        if output != None:
+            for line in output:
+                print line.rstrip()
+
+    #
+    # --------------------------------------------------------------------------------
+    # cp_watch
+    #
+    def cp_watch(self, words, text, completion_char):
+        if completion_char == ord('?'):
+            if len(words) > 1:
+                command.do_command_completion_help(words[1:], text)
+            else:
+                self.print_completion_help(self.help_splash([], text))
+            return
+        if len(words) == 1:
+            items = self.commands_for_current_mode_starting_with(text)
+            return utif.add_delim(items, ' ')
+        else:   
+            return command.do_command_completion(words[1:], text)
+
+    #
+    # --------------------------------------------------------------------------------
+    # do_watch
+    #   only called to display help
+    #
+    def do_watch(self, words):
+        return 'watch: repeat indicated command after watch keyword'
+
+    #
+    # --------------------------------------------------------------------------------
+    # handle_watch_command
+    #
+    # handle this here because this is a CLI-only command
+    # LOOK! This could be using curses, but that has some complications with 
+    # potentially messing up the terminal.  This is cheap but downside
+    # is it uses up the scrollbuffer...
+    #
+    def handle_watch_command(self, line):
+        #
+        words = line.split()
+        if len(words) == 0:
+            return self.syntax_msg('watch: command to watch missing')
+            
+        if len(words) and words[0] == 'watch':
+            return self.error_msg('watch command not supported for watch')
+
+        while True: # must control-C to get out of this
+            output = self.handle_multipart_line(line) 
+            if output:
+                os.system("clear")
+                print "Executing %s " % line
+                print output
+            else:
+                print "Executing %s " % line
+            time.sleep(2)
+
+    #
+    #
+    # --------------------------------------------------------------------------------
+    # loop
+    #  this is just dispatching the command and handling errors
+    #
+    def loop(self):
+        command.action_invoke('wait-for-controller', (5))
+
+        if self.controller:
+            try:
+                version_url = 'http://%s/rest/v1/system/version' % self.controller
+                version = self.rest_simple_request_to_dict(version_url)
+            except Exception, e:
+                version = [{'controller' : 'REST API FAILURE\n'}]
+
+            print "default controller: %s, %s" % (self.controller, 
+                                                  version[0]['controller'])
+            #
+            # vns feature enablement.
+            #  when vns is enabled, call a init procedure
+            #
+            if onos == 0:
+                self.netvirt_feature_enabled()
+
+        while self.run:
+            # Get command line - this will use the command completion above
+            try:
+                #rest_to_model.validate_switch()
+                url_cache.clear_cached_urls()
+                line = raw_input(self.prompt)
+                if self.batch:
+                    print line
+                m = re.search('^watch (.*)$', line) 
+                if m:
+                    self.handle_watch_command(m.group(1))
+                else:
+                    self.handle_multipart_line(line)
+            except KeyboardInterrupt:
+                self.completion_reset()
+                print "\nInterrupt."
+            except EOFError:
+                print "\nExiting."
+                return
+            except urllib2.HTTPError, e:
+                errors = self.rest_error_to_dict(e)
+                print self.error_msg("%s" % self.rest_error_dict_to_message(errors))
+            except urllib2.URLError, e:
+                print self.error_msg("communicating with REST API server on %s " 
+                                     "- Network error: %s" %
+                                     (self.controller, e.reason))
+            except Exception, e:
+                print "\nError running command '%s'.\n" % line
+                if self.debug or self.debug_backtrace:
+                    traceback.print_exc()
+
+
+#
+# --------------------------------------------------------------------------------
+# Initialization crazyness to make it work across platforms. Many platforms don't include
+# GNU readline (e.g. mac os x) and we need to compensate for this
+
+try:
+    import readline
+except ImportError:
+    try:
+        import pyreadline as readline
+    except ImportError:
+        print "Can't find any readline equivalent - aborting."
+else:
+    if 'libedit' in readline.__doc__:
+        # needed for Mac, please fix Apple
+        readline.parse_and_bind ("bind ^I rl_complete")
+    else:
+        readline.parse_and_bind("tab: complete")
+        readline.parse_and_bind("?: possible-completions")
+
+  
+#
+# --------------------------------------------------------------------------------
+# Run the shell
+
+def main():
+    global cli
+    # Uncomment the next two lines to enable remote debugging with PyDev
+    # LOOK! Should have logic here that enables/disables the pydevd stuff
+    # automatically without requiring uncommenting (and, more importantly,
+    # remembering to recomment before committing).
+    # (e.g. checking environment variable or something like that)
+    #python_path = os.environ.get('PYTHONPATH', '')
+    #if 'pydev.debug' in python_path:
+    try:
+        import pydevd
+        pydevd.settrace()
+    except Exception, e:
+        pass
+
+    # Process '--init' argument since it  gates progress to rest of processing
+    # as this is a special argument, it is required to be first argument (if used)
+    check_ready_file = True
+    if len(sys.argv) > 1:
+        if sys.argv[1] == '--init':
+            check_ready_file = False
+    
+    # Do not start CLI till the systemn is ready
+    # (allow user to ^C and get to SDNSh for debug etc)
+    not_ready_file = '/opt/sdnplatform/run/starting'
+    if check_ready_file:
+        try:
+            while True:
+                if os.path.exists(not_ready_file):
+                    with open(not_ready_file, "r") as f:
+                        message = f.read()
+                        if len(message):
+                            print message,
+                        else:
+                            print 'Controller not yet ready ... waiting 5 sec'
+                    time.sleep(5)
+                else:
+                    break
+        except:
+            if os.path.exists(not_ready_file):
+                resp = raw_input('Controller is not yet ready. Do you still want to continue to the CLI? [n]')
+                if resp and "yes".startswith(resp.lower()):
+                    print 'Continuing with CLI despite initialization error ...'
+                else:
+                    print 'Aborting Controller CLI login.'
+                    time.sleep(1)
+                    return
+
+    # Start CLI
+    cli = SDNSh()
+    cli.init()
+    cli.loop()              
+
+if __name__ == '__main__':
+    main()
