diff --git a/cli/prettyprint.py b/cli/prettyprint.py
new file mode 100755
index 0000000..47f119b
--- /dev/null
+++ b/cli/prettyprint.py
@@ -0,0 +1,529 @@
+#
+# 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.
+#
+
+#
+# PRETTYPRINT
+#
+# This module contains classes that help formatting text for the CLI,
+# including tables, individual records etc.
+# 
+# Formatting information is stored in table_info, a dict of dicts.
+
+import model_info_list
+import os
+import array
+import datetime
+import utif
+import re
+import fmtcnv
+
+class PrettyPrinter():
+    table_info = None   # Annotated table format. This is a dict of dicts. Set by cli.
+
+    def __init__(self, bs):
+        self.sdnsh = bs
+        self.table_info = {}
+        self.format_version = {}
+        self.format_added_modules = {}
+
+        self.add_format('MODEL',
+                        'model_info',
+                        model_info_list.model_info_dict)
+
+
+    def add_format(self, name, origin, format_dict):
+        """
+        Add a format to the saved formats, from the dictionary
+        with 'name'.   The 'name' can help identify the source
+        for this format when errors arise
+        """
+
+        # very interesting items in a format are the field_orderings,
+        # and the fields description.   It could make sense to only
+        # allow specific items from the fields, to prevent field-output
+        # formatting from using uninnteded database fields.
+        for (format_name, format) in format_dict.items():
+            if not format_name in self.table_info:
+                self.table_info[format_name] = { }
+            # combine details: top level items
+            for (item_name, item_value) in format.items():
+                if item_name == 'fields':
+                    if not item_name in self.table_info[format_name]:
+                        self.table_info[format_name][item_name] = {}
+                    for (term_name, term_value) in item_value.items():
+                        if not term_name in self.table_info[format_name][item_name]:
+                            self.table_info[format_name][item_name][term_name] = {}
+                        self.table_info[format_name][item_name][term_name].update(term_value)
+                if item_name == 'field-orderings':
+                    if not item_name in self.table_info[format_name]:
+                        self.table_info[format_name][item_name] = {}
+                    self.table_info[format_name][item_name].update(item_value)
+            #
+            # save the name of the source for this format
+            if not 'self' in self.table_info[format_name]:
+                self.table_info[format_name]['self'] = name
+            if not 'origin' in self.table_info[format_name]:
+                self.table_info[format_name]['origin'] = origin
+            #
+            # Add the 'Idx' field if it's not there.
+            if format_name in self.table_info:
+                if not 'fields' in self.table_info[format_name]:
+                    self.table_info[format_name]['fields'] = {}
+                if not 'Idx' in self.table_info[format_name]['fields']:
+                    self.table_info[format_name]['fields']['Idx'] = {
+                            'verbose-name' : '#',
+                            'type' : 'CharField'
+                        }
+
+
+    def add_module_name(self, version, module):
+        """
+        Save some state about the version/module
+        """
+        if version not in self.format_version:
+            self.format_version[version] = [module]
+        else:
+            self.format_version[version].append(module)
+
+
+    def add_formats_from_module(self, version, module):
+        self.add_module_name(version, module)
+        for name in dir(module):
+            if re.match(r'.*_FORMAT$', name):
+                if module.__name__ not in self.format_added_modules:
+                    self.format_added_modules[module.__name__] = [name]
+                if name not in self.format_added_modules[module.__name__]:
+                    self.format_added_modules[module.__name__].append(name)
+                self.add_format(name, module.__name__, getattr(module, name))
+
+
+    # Utility Functions
+    def get_field_info(self, obj_type_info, field_name):
+        return obj_type_info['fields'].get(field_name, None)
+
+
+    def format_to_alias_update(self, display_format, update):
+        """
+        Given a format, find all the formatters, and for each
+        formatter, determine which aliases need to be updated.
+        """
+        if display_format not in self.table_info:
+            # this will fail soon enough when final output is attempted
+            return
+        format_dict = self.table_info[display_format]
+        if not 'fields' in format_dict:
+            return
+
+        for (field_name, field_dict) in format_dict['fields'].items():
+            if 'formatter' in field_dict:
+                fmtcnv.formatter_to_alias_update(field_dict['formatter'], update)
+            elif 'entry_formatter' in field_dict:
+                fmtcnv.formatter_to_alias_update(field_dict['entry-formatter'], update)
+        return update
+
+
+    def formats(self):
+        return self.table_info.keys()
+
+    def format_details(self):
+        """
+        Return a table of formats suitable as a format_table parameter
+        """
+        return [ { 'format'      : x,
+                   'format dict' : self.table_info[x]['self'],
+                   'origin'      : self.table_info[x]['origin'] }
+
+                  for x in self.formats()]
+
+
+    def format_as_header(self, field):
+        # LOOK! could prob do something fancy to handle camelCapStrings or underscore_strings
+        return field[0].capitalize() + field[1:]
+
+
+    def get_header_for_field(self, obj_type_info, field_name):
+        field_info = self.get_field_info(obj_type_info, field_name)
+        if not field_info:
+            return self.format_as_header(field_name)
+        default_header = self.format_as_header(field_name)
+        return field_info.get('verbose-name', default_header)
+
+
+    def format_table(self, data_list, display_format = None, field_ordering="default"):
+        """
+        Takes in list of dicts and generates nice table, e.g.
+
+        id slice_id MAC Address       ip    Switch ID    
+        ------------------------------------------------
+        1  1        00:00:00:00:01:03 10013 150861407404
+        2  2        00:00:00:00:01:01 10011 150861407404
+        3  1        00:00:00:00:02:03 10023 150866955514
+
+        @param data_list - a list of dicts
+        @param format describes the format of the output table to display
+        @param field_ordering is the field_ordering identifier in the model,
+          there can be multiple ("default", "brief", "detailed")
+       
+        """
+
+        #
+        # first, determine a list of fields to be printed, then using that list,
+        # determine the fields width of each field, including calling any formatting
+        # function, then format the result
+        #
+        # during the format computation, replace the value with the 'formatted value'
+        # to prevent multiple calls to the same formatting funcition
+        #
+        if not data_list or not type(data_list) == list:
+            if type(data_list) == dict and "error_type" in data_list:
+                return data_list.get("description", "Internal error")
+            return "None."
+
+        format_info = self.table_info.get(display_format, None)
+
+        if self.sdnsh.description:
+            if format_info == None:
+                print 'format_table: missing format %s' % display_format
+            else:
+                format_from = format_info.get('self', '')
+                print 'format_table: %s %s %d entries' % (
+                        display_format, format_from, len(data_list))
+
+        field_widths = {}
+        field_headers = {}
+        fields_to_print = []
+
+        #
+        # do the 'figur'n for which fields will get printed.
+        #
+        # to determine the length, call the formatting function, and replace the
+        # value for that field with the updated value; then 'cypher the length.
+        #
+        # note that field_widths.keys() are all the possible fields
+        # check if the headers makes any field wider and set fields_to_print
+        #
+        if format_info:
+            if 'field-orderings' in format_info:
+                fields_to_print = format_info['field-orderings'].get(field_ordering, [])
+            if len(fields_to_print) == 0: # either no field_orderings or couldn't find specific
+                fields_to_print = format_info['fields'].keys()
+            for f in fields_to_print:
+                header = self.get_header_for_field(format_info, f)
+                field_headers[f] = header
+                field_widths[f] = max(len(header), field_widths.get(f, 0))
+            # LOOK! not done now... add in extra fields discovered in data_list if desired
+            # right now, fields_to_print is a projection on the data
+        else:
+            # get fields_to_print from the field names in data_list,
+            # which is (intended to be) a list of dictionaries
+            all_fields = utif.unique_list_from_list(sum([x.keys()
+                                                        for x in data_list], []))
+            fields_to_print = sorted(all_fields)
+
+        if self.sdnsh.description:
+            print 'format_table: field order "%s" fields %s' % \
+                   (field_ordering, fields_to_print)
+
+        #
+        # generate a fields_to_print ordered list with field_widths for each
+        # by going through all data and then using field_ordering if avail.
+        #
+        row_index = 0
+        for row in data_list:
+            row_index += 1
+            if not 'Idx' in row:
+                row['Idx'] = row_index
+            for key in fields_to_print:
+            #for (k,v) in row.items():
+                if format_info:
+                    # don't worry about header here - do that soon below
+                    info = self.get_field_info(format_info, key)
+                    if info and info.get('formatter'):
+                        row[key] = str(info['formatter'](row.get(key, ''), row))
+                        w = len(row[key])
+                    else:
+                        w = len(str(row.get(key, '')))
+                else:
+                    field_headers[key] = self.format_as_header(key)
+                    w = max(len(str(row[key])), len(field_headers[key]))
+                field_widths[key] = max(w, field_widths.get(key, 0))
+
+        #
+        # generate the format_str and header lines based on fields_to_print
+        #
+        format_str_per_field = []
+        for f in fields_to_print:
+            format_str_per_field.append("%%(%s)-%ds" % (f, field_widths[f]))
+
+        row_format_str = " ".join(format_str_per_field) + "\n"
+
+        #
+        # finally print! only caveat is to handle sparse data with a blank_dict
+        # let result be a list, and append new strings to generate the final result,
+        # (for better python performance)
+        #
+        result= []
+        result.append(" ".join(format_str_per_field) % field_headers + "\n")
+        result.append("|".join(["-"*field_widths[f] for f in fields_to_print]) + "\n") # I <3 python too
+
+        blank_dict = dict([(f,"") for f in fields_to_print])
+        for row in data_list:
+            result.append(row_format_str % dict(blank_dict, **row))
+        
+        return ''.join(result)
+
+
+    def format_entry(self, data, display_format=None, field_ordering="default", debug=False):
+        """
+        Takes in parsed JSON object, generates nice single entry printout,
+        intended for 'details' display
+
+        @param data list of dictionaries, values for output
+        @param format name of format description to use for printing
+        @param field_ordering list of field to print
+        @param debug print values of compound keys
+        """
+        if not data:
+            return "None."
+        elif type(data) == dict and "error_type" in data:
+            return data.get("description", "Internal error")
+    
+        format_info = self.table_info.get(display_format, None)
+
+        # Print. Pretty please.
+        if format_info:
+            fields = format_info['fields']
+        else:
+            fields = dict([[x, {}] for x in data.keys()])
+            format_info = { 'fields' : fields }
+            if self.sdnsh.description:
+                print "format_entry: Missing format ", display_format, fields
+
+        # Find widest data field name
+        label_w = len( max(data, key=lambda x:len(x)) )
+        if format_info:
+            verbose_len = max([len(self.get_header_for_field(format_info, x)) for x in fields.keys()])
+            # This isn't exactly right, the verbose names for the fields ought to be replaced first
+            label_w = max(verbose_len, label_w)
+        label_str = "%%-%ds :" % label_w
+
+        # Use format_info for this table to order fields if possible
+        fields_to_print = None
+        if format_info:
+            if 'field-orderings' in format_info:
+                fields_to_print = format_info['field-orderings'].get(field_ordering, [])
+            else:
+                if self.sdnsh.description:
+                    print 'Error: internal: %s field ordering %s not present for %s' % \
+                          (display_format, field_ordering, format_info)
+            if fields_to_print == None or len(fields_to_print) == 0:
+                # either no field_orderings or couldn't find specific
+                fields_to_print = format_info['fields'].keys()
+        else:
+            fields_to_print = sorted(fields.keys())
+
+        result = ""
+        tmp_merged_dict = dict([(f,"") for f in fields_to_print], **data)
+        blank_dict = dict([(f,"") for f in fields_to_print])
+
+        # first print the requested fields
+        all_fields_in_correct_order = list(fields_to_print)
+        # then the remaining fields
+        all_fields_in_correct_order.extend([x for x in fields.keys()
+                                            if x not in fields_to_print])
+        # give all the formatter's a shot, save the updates
+        updated = {}
+        for e in all_fields_in_correct_order:
+            if format_info:
+                info = self.get_field_info(format_info, e)
+                if not info:
+                    continue
+                if 'entry-formatter' in info:
+                    updated[e] = info['entry-formatter'](
+                                    tmp_merged_dict.get(e, ''), tmp_merged_dict)
+                elif 'formatter' in info:
+                    updated[e] = info['formatter'](
+                                    tmp_merged_dict.get(e, ''), tmp_merged_dict)
+
+        tmp_merged_dict.update(updated)
+
+        data.update(updated)
+        all_fields_in_correct_order = filter(lambda x: x in data,
+                                             all_fields_in_correct_order)
+        for e in all_fields_in_correct_order:
+            if format_info:
+                info = self.get_field_info(format_info, e)
+                if not debug and info and 'help_text' in info and info['help_text'][0] == '#':
+                    # sdnsh._is_compound_key(), please skip display of compound key
+                    continue
+            result += (label_str % self.get_header_for_field(format_info, e)+" "+
+                       str(tmp_merged_dict[e]) + "\n");
+        
+        return result[:-1]
+
+    def get_terminal_size(self):
+        def ioctl_GWINSZ(fd):
+            try:
+                import fcntl, termios, struct, os
+                cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
+                                                     '1234'))
+            except:
+                return None
+            return cr
+        cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
+        if not cr:
+            try:
+                fd = os.open(os.ctermid(), os.O_RDONLY)
+                cr = ioctl_GWINSZ(fd)
+                os.close(fd)
+            except:
+                pass
+        if not cr:
+            try:
+                cr = (os.environ['LINES'], os.environ['COLUMNS'])
+            except:
+                cr = (24, 80)
+
+        if (cr[1] == 0 or cr[0] == 0):
+            return (80, 24)
+
+        return int(cr[1]), int(cr[0])
+
+    def format_time_series_graph(self, data, obj_type=None, field_ordering="default"):
+        if not data:
+            return "None."
+        elif type(data) == dict and "error_type" in data:
+            return data.get("description", "Internal error")
+
+        obj_type_info = self.table_info.get(obj_type, None)
+
+        if self.sdnsh.description:
+            print "format_time_series_graph", obj_type, obj_type_info
+        yunits = None
+        ylabel = "Value"
+        if (obj_type_info):
+            ylabel = obj_type_info['fields']['value']['verbose-name']
+            if 'units' in obj_type_info['fields']['value']:
+                yunits = obj_type_info['fields']['value']['units']
+
+
+        miny = None
+        maxy = None
+        minx = None
+        maxx = None
+
+        for (x,y) in data:
+            if miny == None or y < miny:
+                miny = y
+            if maxy == None or y > maxy:
+                maxy = y
+            if minx == None or x < minx:
+                minx = x
+            if maxx == None or x > maxx:
+                maxx = x
+
+        if (yunits == '%'):
+            maxy = 100
+
+        if isinstance(maxy, float) and maxy < 10.0:
+            axisyw = len('%.5f' % maxy)
+        else:
+            axisyw = len('%s' % maxy)
+        
+        (twidth, theight) = self.get_terminal_size()
+
+        width = twidth-axisyw
+        height = theight-5
+
+        ybucket = float(maxy)/height;
+
+        xbucket = (maxx-minx)/width;
+        if (xbucket == 0):
+            minx = maxx - 1800000
+            maxx += 1800000
+            xbucket = maxx/width;
+
+        graph = array.array('c')
+        graph.fromstring(' ' * (width * height))
+        for (x,y) in data:
+            if (ybucket == 0):
+                yc = height
+            else:
+                yc = int(round((maxy-y)/ybucket))
+            if (xbucket == 0):
+                xy = width
+            else:
+                xc = int(round((x-minx)/xbucket))
+
+            if (yc < 0):
+                yc = 0
+            if (yc >= height):
+                yc = height-1
+            if (xc < 0):
+                xc = 0
+            if (xc >= width):
+                xc = width-1
+
+            #print (xc,yc, x, y, yc*width + xc)
+            for i in range(yc,height):
+                graph[i*width + xc] = '#'
+
+        b = '%s\n' % (ylabel)
+
+        if isinstance(maxy, float) and maxy < 10.0:
+            form = '%%%d.5f|%%s\n'
+        else:
+            form = '%%%ds|%%s\n'
+
+        for i in range(0,height-1):
+            ylabel = maxy - i*ybucket
+            if not isinstance(maxy, float) or maxy >= 10.0:
+                ylabel = int(round(ylabel))
+            b += (form % axisyw) % \
+                (ylabel, 
+                 ''.join(graph[i*width:(i+1)*width-1]))
+        b += (form % axisyw) % \
+            (0, ''.join(graph[(height-1)*width:height*width-1]).replace(' ', '_'))
+
+        b += '%s' % (' ' * axisyw)
+        d = ' ' * axisyw
+
+        olddate = None
+        interval = (maxx - minx)/(width/7.0)
+        for i in range(0, width/7):
+            curtimestamp = minx + interval*i
+           
+            if i == width/7-1:
+                df = (' ' * (width % 7)) + " %m/%d^"
+                tf = (' ' * (width % 7)) + " %H:%M^"
+                curtimestamp = maxx
+            else:
+                df = "^%m/%d "
+                tf = "^%H:%M "
+
+            curtime = datetime.datetime.fromtimestamp(curtimestamp/1000.0)
+            date = curtime.strftime(df)
+            b += curtime.strftime(tf)
+            if (date != olddate):
+                olddate = date
+                d += date
+            else:
+                d += ' ' * 7
+
+        b += '\n%s\n' % d
+        b += '%s%sTime' % (' ' * axisyw, ' ' * (width/2-2))
+
+        return b
