diff --git a/examples/consoles.py b/examples/consoles.py
new file mode 100644
index 0000000..ea2e28d
--- /dev/null
+++ b/examples/consoles.py
@@ -0,0 +1,456 @@
+#!/usr/bin/python
+
+"""
+consoles.py: bring up a bunch of miniature consoles on a virtual network
+
+This demo shows how to monitor a set of nodes by using
+Node's monitor() and Tkinter's createfilehandler().
+
+We monitor nodes in a couple of ways:
+
+- First, each individual node is monitored, and its output is added
+  to its console window
+
+- Second, each time a console window gets iperf output, it is parsed
+  and accumulated. Once we have output for all consoles, a bar is
+  added to the bandwidth graph.
+
+The consoles also support limited interaction:
+
+- Pressing "return" in a console will send a command to it
+
+- Pressing the console's title button will open up an xterm
+
+Bob Lantz, April 2010
+
+"""
+
+import re
+
+from Tkinter import Frame, Button, Label, Text, Scrollbar, Canvas, Wm, READABLE
+
+from mininet.log import setLogLevel
+from mininet.topolib import TreeNet
+from mininet.term import makeTerms, cleanUpScreens
+from mininet.util import quietRun
+
+class Console( Frame ):
+    "A simple console on a host."
+
+    def __init__( self, parent, net, node, height=10, width=32, title='Node' ):
+        Frame.__init__( self, parent )
+
+        self.net = net
+        self.node = node
+        self.prompt = node.name + '# '
+        self.height, self.width, self.title = height, width, title
+
+        # Initialize widget styles
+        self.buttonStyle = { 'font': 'Monaco 7' }
+        self.textStyle = {
+            'font': 'Monaco 7',
+            'bg': 'black',
+            'fg': 'green',
+            'width': self.width,
+            'height': self.height,
+            'relief': 'sunken',
+            'insertbackground': 'green',
+            'highlightcolor': 'green',
+            'selectforeground': 'black',
+            'selectbackground': 'green'
+        }
+
+        # Set up widgets
+        self.text = self.makeWidgets( )
+        self.bindEvents()
+        self.sendCmd( 'export TERM=dumb' )
+
+        self.outputHook = None
+
+    def makeWidgets( self ):
+        "Make a label, a text area, and a scroll bar."
+
+        def newTerm( net=self.net, node=self.node, title=self.title ):
+            "Pop up a new terminal window for a node."
+            net.terms += makeTerms( [ node ], title )
+        label = Button( self, text=self.node.name, command=newTerm,
+                        **self.buttonStyle )
+        label.pack( side='top', fill='x' )
+        text = Text( self, wrap='word', **self.textStyle )
+        ybar = Scrollbar( self, orient='vertical', width=7,
+                          command=text.yview )
+        text.configure( yscrollcommand=ybar.set )
+        text.pack( side='left', expand=True, fill='both' )
+        ybar.pack( side='right', fill='y' )
+        return text
+
+    def bindEvents( self ):
+        "Bind keyboard and file events."
+        # The text widget handles regular key presses, but we
+        # use special handlers for the following:
+        self.text.bind( '<Return>', self.handleReturn )
+        self.text.bind( '<Control-c>', self.handleInt )
+        self.text.bind( '<KeyPress>', self.handleKey )
+        # This is not well-documented, but it is the correct
+        # way to trigger a file event handler from Tk's
+        # event loop!
+        self.tk.createfilehandler( self.node.stdout, READABLE,
+                                   self.handleReadable )
+
+    # We're not a terminal (yet?), so we ignore the following
+    # control characters other than [\b\n\r]
+    ignoreChars = re.compile( r'[\x00-\x07\x09\x0b\x0c\x0e-\x1f]+' )
+
+    def append( self, text ):
+        "Append something to our text frame."
+        text = self.ignoreChars.sub( '', text )
+        self.text.insert( 'end', text )
+        self.text.mark_set( 'insert', 'end' )
+        self.text.see( 'insert' )
+        outputHook = lambda x, y: True  # make pylint happier
+        if self.outputHook:
+            outputHook = self.outputHook
+        outputHook( self, text )
+
+    def handleKey( self, event ):
+        "If it's an interactive command, send it to the node."
+        char = event.char
+        if self.node.waiting:
+            self.node.write( char )
+
+    def handleReturn( self, event ):
+        "Handle a carriage return."
+        cmd = self.text.get( 'insert linestart', 'insert lineend' )
+        # Send it immediately, if "interactive" command
+        if self.node.waiting:
+            self.node.write( event.char )
+            return
+        # Otherwise send the whole line to the shell
+        pos = cmd.find( self.prompt )
+        if pos >= 0:
+            cmd = cmd[ pos + len( self.prompt ): ]
+        self.sendCmd( cmd )
+
+    # Callback ignores event
+    def handleInt( self, _event=None ):
+        "Handle control-c."
+        self.node.sendInt()
+
+    def sendCmd( self, cmd ):
+        "Send a command to our node."
+        if not self.node.waiting:
+            self.node.sendCmd( cmd )
+
+    def handleReadable( self, _fds, timeoutms=None ):
+        "Handle file readable event."
+        data = self.node.monitor( timeoutms )
+        self.append( data )
+        if not self.node.waiting:
+            # Print prompt
+            self.append( self.prompt )
+
+    def waiting( self ):
+        "Are we waiting for output?"
+        return self.node.waiting
+
+    def waitOutput( self ):
+        "Wait for any remaining output."
+        while self.node.waiting:
+            # A bit of a trade-off here...
+            self.handleReadable( self, timeoutms=1000)
+            self.update()
+
+    def clear( self ):
+        "Clear all of our text."
+        self.text.delete( '1.0', 'end' )
+
+
+class Graph( Frame ):
+
+    "Graph that we can add bars to over time."
+
+    def __init__( self, parent=None, bg = 'white', gheight=200, gwidth=500,
+                  barwidth=10, ymax=3.5,):
+
+        Frame.__init__( self, parent )
+
+        self.bg = bg
+        self.gheight = gheight
+        self.gwidth = gwidth
+        self.barwidth = barwidth
+        self.ymax = float( ymax )
+        self.xpos = 0
+
+        # Create everything
+        self.title, self.scale, self.graph = self.createWidgets()
+        self.updateScrollRegions()
+        self.yview( 'moveto', '1.0' )
+
+    def createScale( self ):
+        "Create a and return a new canvas with scale markers."
+        height = float( self.gheight )
+        width = 25
+        ymax = self.ymax
+        scale = Canvas( self, width=width, height=height,
+                        background=self.bg )
+        opts = { 'fill': 'red' }
+        # Draw scale line
+        scale.create_line( width - 1, height, width - 1, 0, **opts )
+        # Draw ticks and numbers
+        for y in range( 0, int( ymax + 1 ) ):
+            ypos = height * (1 - float( y ) / ymax )
+            scale.create_line( width, ypos, width - 10, ypos, **opts )
+            scale.create_text( 10, ypos, text=str( y ), **opts )
+        return scale
+
+    def updateScrollRegions( self ):
+        "Update graph and scale scroll regions."
+        ofs = 20
+        height = self.gheight + ofs
+        self.graph.configure( scrollregion=( 0, -ofs,
+                              self.xpos * self.barwidth, height ) )
+        self.scale.configure( scrollregion=( 0, -ofs, 0, height ) )
+
+    def yview( self, *args ):
+        "Scroll both scale and graph."
+        self.graph.yview( *args )
+        self.scale.yview( *args )
+
+    def createWidgets( self ):
+        "Create initial widget set."
+
+        # Objects
+        title = Label( self, text='Bandwidth (Gb/s)', bg=self.bg )
+        width = self.gwidth
+        height = self.gheight
+        scale = self.createScale()
+        graph = Canvas( self, width=width, height=height, background=self.bg)
+        xbar = Scrollbar( self, orient='horizontal', command=graph.xview )
+        ybar = Scrollbar( self, orient='vertical', command=self.yview )
+        graph.configure( xscrollcommand=xbar.set, yscrollcommand=ybar.set,
+                         scrollregion=(0, 0, width, height ) )
+        scale.configure( yscrollcommand=ybar.set )
+
+        # Layout
+        title.grid( row=0, columnspan=3, sticky='new')
+        scale.grid( row=1, column=0, sticky='nsew' )
+        graph.grid( row=1, column=1, sticky='nsew' )
+        ybar.grid( row=1, column=2, sticky='ns' )
+        xbar.grid( row=2, column=0, columnspan=2, sticky='ew' )
+        self.rowconfigure( 1, weight=1 )
+        self.columnconfigure( 1, weight=1 )
+        return title, scale, graph
+
+    def addBar( self, yval ):
+        "Add a new bar to our graph."
+        percent = yval / self.ymax
+        c = self.graph
+        x0 = self.xpos * self.barwidth
+        x1 = x0 + self.barwidth
+        y0 = self.gheight
+        y1 = ( 1 - percent ) * self.gheight
+        c.create_rectangle( x0, y0, x1, y1, fill='green' )
+        self.xpos += 1
+        self.updateScrollRegions()
+        self.graph.xview( 'moveto', '1.0' )
+
+    def clear( self ):
+        "Clear graph contents."
+        self.graph.delete( 'all' )
+        self.xpos = 0
+
+    def test( self ):
+        "Add a bar for testing purposes."
+        ms = 1000
+        if self.xpos < 10:
+            self.addBar( self.xpos / 10 * self.ymax  )
+            self.after( ms, self.test )
+
+    def setTitle( self, text ):
+        "Set graph title"
+        self.title.configure( text=text, font='Helvetica 9 bold' )
+
+
+class ConsoleApp( Frame ):
+
+    "Simple Tk consoles for Mininet."
+
+    menuStyle = { 'font': 'Geneva 7 bold' }
+
+    def __init__( self, net, parent=None, width=4 ):
+        Frame.__init__( self, parent )
+        self.top = self.winfo_toplevel()
+        self.top.title( 'Mininet' )
+        self.net = net
+        self.menubar = self.createMenuBar()
+        cframe = self.cframe = Frame( self )
+        self.consoles = {}  # consoles themselves
+        titles = {
+            'hosts': 'Host',
+            'switches': 'Switch',
+            'controllers': 'Controller'
+        }
+        for name in titles:
+            nodes = getattr( net, name )
+            frame, consoles = self.createConsoles(
+                cframe, nodes, width, titles[ name ] )
+            self.consoles[ name ] = Object( frame=frame, consoles=consoles )
+        self.selected = None
+        self.select( 'hosts' )
+        self.cframe.pack( expand=True, fill='both' )
+        cleanUpScreens()
+        # Close window gracefully
+        Wm.wm_protocol( self.top, name='WM_DELETE_WINDOW', func=self.quit )
+
+        # Initialize graph
+        graph = Graph( cframe )
+        self.consoles[ 'graph' ] = Object( frame=graph, consoles=[ graph ] )
+        self.graph = graph
+        self.graphVisible = False
+        self.updates = 0
+        self.hostCount = len( self.consoles[ 'hosts' ].consoles )
+        self.bw = 0
+
+        self.pack( expand=True, fill='both' )
+
+    def updateGraph( self, _console, output ):
+        "Update our graph."
+        m = re.search( r'(\d+) Mbits/sec', output )
+        if not m:
+            return
+        self.updates += 1
+        self.bw += .001 * float( m.group( 1 ) )
+        if self.updates >= self.hostCount:
+            self.graph.addBar( self.bw )
+            self.bw = 0
+            self.updates = 0
+
+    def setOutputHook( self, fn=None, consoles=None ):
+        "Register fn as output hook [on specific consoles.]"
+        if consoles is None:
+            consoles = self.consoles[ 'hosts' ].consoles
+        for console in consoles:
+            console.outputHook = fn
+
+    def createConsoles( self, parent, nodes, width, title ):
+        "Create a grid of consoles in a frame."
+        f = Frame( parent )
+        # Create consoles
+        consoles = []
+        index = 0
+        for node in nodes:
+            console = Console( f, self.net, node, title=title )
+            consoles.append( console )
+            row = index / width
+            column = index % width
+            console.grid( row=row, column=column, sticky='nsew' )
+            index += 1
+            f.rowconfigure( row, weight=1 )
+            f.columnconfigure( column, weight=1 )
+        return f, consoles
+
+    def select( self, groupName ):
+        "Select a group of consoles to display."
+        if self.selected is not None:
+            self.selected.frame.pack_forget()
+        self.selected = self.consoles[ groupName ]
+        self.selected.frame.pack( expand=True, fill='both' )
+
+    def createMenuBar( self ):
+        "Create and return a menu (really button) bar."
+        f = Frame( self )
+        buttons = [
+            ( 'Hosts', lambda: self.select( 'hosts' ) ),
+            ( 'Switches', lambda: self.select( 'switches' ) ),
+            ( 'Controllers', lambda: self.select( 'controllers' ) ),
+            ( 'Graph', lambda: self.select( 'graph' ) ),
+            ( 'Ping', self.ping ),
+            ( 'Iperf', self.iperf ),
+            ( 'Interrupt', self.stop ),
+            ( 'Clear', self.clear ),
+            ( 'Quit', self.quit )
+        ]
+        for name, cmd in buttons:
+            b = Button( f, text=name, command=cmd, **self.menuStyle )
+            b.pack( side='left' )
+        f.pack( padx=4, pady=4, fill='x' )
+        return f
+
+    def clear( self ):
+        "Clear selection."
+        for console in self.selected.consoles:
+            console.clear()
+
+    def waiting( self, consoles=None ):
+        "Are any of our hosts waiting for output?"
+        if consoles is None:
+            consoles = self.consoles[ 'hosts' ].consoles
+        for console in consoles:
+            if console.waiting():
+                return True
+        return False
+
+    def ping( self ):
+        "Tell each host to ping the next one."
+        consoles = self.consoles[ 'hosts' ].consoles
+        if self.waiting( consoles ):
+            return
+        count = len( consoles )
+        i = 0
+        for console in consoles:
+            i = ( i + 1 ) % count
+            ip = consoles[ i ].node.IP()
+            console.sendCmd( 'ping ' + ip )
+
+    def iperf( self ):
+        "Tell each host to iperf to the next one."
+        consoles = self.consoles[ 'hosts' ].consoles
+        if self.waiting( consoles ):
+            return
+        count = len( consoles )
+        self.setOutputHook( self.updateGraph )
+        for console in consoles:
+            console.node.cmd( 'iperf -sD' )
+        i = 0
+        for console in consoles:
+            i = ( i + 1 ) % count
+            ip = consoles[ i ].node.IP()
+            console.sendCmd( 'iperf -t 99999 -i 1 -c ' + ip )
+
+    def stop( self, wait=True ):
+        "Interrupt all hosts."
+        consoles = self.consoles[ 'hosts' ].consoles
+        for console in consoles:
+            console.handleInt()
+        if wait:
+            for console in consoles:
+                console.waitOutput()
+        self.setOutputHook( None )
+        # Shut down any iperfs that might still be running
+        quietRun( 'killall -9 iperf' )
+
+    def quit( self ):
+        "Stop everything and quit."
+        self.stop( wait=False)
+        Frame.quit( self )
+
+
+# Make it easier to construct and assign objects
+
+def assign( obj, **kwargs ):
+    "Set a bunch of fields in an object."
+    obj.__dict__.update( kwargs )
+
+class Object( object ):
+    "Generic object you can stuff junk into."
+    def __init__( self, **kwargs ):
+        assign( self, **kwargs )
+
+
+if __name__ == '__main__':
+    setLogLevel( 'info' )
+    network = TreeNet( depth=2, fanout=4 )
+    network.start()
+    app = ConsoleApp( network, width=4 )
+    app.mainloop()
+    network.stop()
