diff --git a/bin/minindnedit b/bin/minindnedit
new file mode 100755
index 0000000..c0ff708
--- /dev/null
+++ b/bin/minindnedit
@@ -0,0 +1,1732 @@
+#!/usr/bin/python
+
+"""
+MiniCCNxEdit: a simple network editor for MiniCCNx
+
+Based on miniedit by:
+Bob Lantz, April 2010
+Gregory Gee, July 2013
+
+Carlos Cabral, Jan 2013
+Caio Elias, Nov 2014
+
+"""
+
+MINIEDIT_VERSION = '2.2.0.1'
+
+from optparse import OptionParser
+from Tkinter import *
+from ttk import Notebook
+from tkMessageBox import showinfo, showerror, showwarning
+from subprocess import call
+import tkFont
+import csv
+import tkFileDialog
+import tkSimpleDialog
+import re
+import json
+from distutils.version import StrictVersion
+import os
+import sys
+from functools import partial
+
+import pdb
+
+if 'PYTHONPATH' in os.environ:
+    sys.path = os.environ[ 'PYTHONPATH' ].split( ':' ) + sys.path
+
+# someday: from ttk import *
+
+from mininet.log import info, error, debug, output, setLogLevel
+from mininet.net import Mininet, VERSION
+from mininet.util import ipStr, netParse, ipAdd, quietRun
+from mininet.util import buildTopo
+from mininet.util import custom, customConstructor
+from mininet.term import makeTerm, cleanUpScreens
+from mininet.node import Controller, RemoteController, NOX, OVSController
+from mininet.node import CPULimitedHost, Host, Node
+from mininet.node import OVSKernelSwitch, OVSSwitch, UserSwitch
+from mininet.link import TCLink, Intf, Link
+from mininet.cli import CLI
+from mininet.moduledeps import moduleDeps, pathCheck
+from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
+from mininet.topolib import TreeTopo
+
+print 'MiniCCNxEdit running...' #+VERSION
+MININET_VERSION = re.sub(r'[^\d\.]', '', VERSION)
+if StrictVersion(MININET_VERSION) > StrictVersion('2.0'):
+    from mininet.node import IVSSwitch
+
+TOPODEF = 'none'
+TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ),
+          'linear': LinearTopo,
+          'reversed': SingleSwitchReversedTopo,
+          'single': SingleSwitchTopo,
+          'none': None,
+          'tree': TreeTopo }
+LINKDEF = 'default'
+LINKS = { 'default': Link,
+          'tc': TCLink }
+HOSTDEF = 'proc'
+HOSTS = { 'proc': Host,
+          'rt': custom( CPULimitedHost, sched='rt' ),
+          'cfs': custom( CPULimitedHost, sched='cfs' ) }
+
+class LegacyRouter( Node ):
+
+    def __init__( self, name, inNamespace=True, **params ):
+        Node.__init__( self, name, inNamespace, **params )
+
+    def config( self, **_params ):
+        if self.intfs:
+            self.setParam( _params, 'setIP', ip='0.0.0.0' )
+        r = Node.config( self, **_params )
+        self.cmd('sysctl -w net.ipv4.ip_forward=1')
+        return r
+
+class CustomDialog(object):
+
+        # TODO: Fix button placement and Title and window focus lock
+        def __init__(self, master, title):
+            self.top=Toplevel(master)
+
+            self.bodyFrame = Frame(self.top)
+            self.bodyFrame.grid(row=0, column=0, sticky='nswe')
+            self.body(self.bodyFrame)
+
+            #return self.b # initial focus
+            buttonFrame = Frame(self.top, relief='ridge', bd=3, bg='lightgrey')
+            buttonFrame.grid(row=1 , column=0, sticky='nswe')
+
+            okButton = Button(buttonFrame, width=8, text='OK', relief='groove',
+                       bd=4, command=self.okAction)
+            okButton.grid(row=1, column=0, sticky=E)
+
+            canlceButton = Button(buttonFrame, width=8, text='Cancel', relief='groove',
+                        bd=4, command=self.cancelAction)
+            canlceButton.grid(row=1, column=1, sticky=W)
+
+        def body(self, master):
+            self.rootFrame = master
+
+        def apply(self):
+            self.top.destroy()
+
+        def cancelAction(self):
+            self.top.destroy()
+
+        def okAction(self):
+            self.apply()
+            self.top.destroy()
+
+class HostDialog(CustomDialog):
+
+        def __init__(self, master, title, prefDefaults, isRouter):
+
+            self.prefValues = prefDefaults
+            self.result = None
+            self.isRouter = isRouter
+            self.title = title
+
+            CustomDialog.__init__(self, master, title)
+
+        def body(self, master):
+            self.rootFrame = master
+            n = Notebook(self.rootFrame)
+            self.propFrame = Frame(n)
+            self.fibFrame = Frame(n)
+            n.add(self.propFrame, text='Properties')
+            n.add(self.fibFrame, text='FIB Entries')
+            n.pack()
+
+            ### TAB 1
+            # Field for Hostname
+            Label(self.propFrame, text="Hostname:").grid(row=0, sticky=E)
+            self.hostnameEntry = Entry(self.propFrame)
+            self.hostnameEntry.grid(row=0, column=1)
+            if 'hostname' in self.prefValues:
+                self.hostnameEntry.insert(0, self.prefValues['hostname'])
+
+            # Field for CPU
+            Label(self.propFrame, text="Amount CPU:").grid(row=2, sticky=E)
+            self.cpuEntry = Entry(self.propFrame)
+            self.cpuEntry.grid(row=2, column=1)
+            Label(self.propFrame, text="%").grid(row=2, column=2, sticky=W)
+            if 'cpu' in self.prefValues:
+                self.cpuEntry.insert(0, str(self.prefValues['cpu']))
+
+            # Field for Memory
+            Label(self.propFrame, text="Amount MEM:").grid(row=3, sticky=E)
+            self.memEntry = Entry(self.propFrame)
+            self.memEntry.grid(row=3, column=1)
+            Label(self.propFrame, text="%").grid(row=3, column=2, sticky=W)
+            if 'mem' in self.prefValues:
+                self.memEntry.insert(0, str(self.prefValues['mem']))
+
+            # Field for Cache
+            Label(self.propFrame, text="Amount CACHE:").grid(row=4, sticky=E)
+            self.cacheEntry = Entry(self.propFrame)
+            self.cacheEntry.grid(row=4, column=1)
+            Label(self.propFrame, text="KBytes").grid(row=4, column=2, sticky=W)
+            if 'cache' in self.prefValues:
+                self.cacheEntry.insert(0, str(self.prefValues['cache']))
+
+            # Start command
+            #print self.isRouter
+            if self.isRouter == 'False':
+                    Label(self.propFrame, text="Start Command:").grid(row=5, sticky=E)
+                    self.startEntry = Entry(self.propFrame)
+                    self.startEntry.grid(row=5, column=1, sticky='nswe', columnspan=3)
+                    Label(self.propFrame, text="[full path]").grid(row=5, column=2, sticky=W)
+                    if 'startCommand' in self.prefValues:
+                        self.startEntry.insert(0, str(self.prefValues['startCommand']))
+            else:
+                self.startEntry= Entry(self.propFrame)
+
+            ### TAB 2
+            # FIB Entries
+            self.fibEntries = 0
+            Label(self.fibFrame, text="FIB Entry:").grid(row=0, column=0, sticky=E)
+            self.fibButton = Button( self.fibFrame, text='Add', command=self.addEntry)
+            self.fibButton.grid(row=0, column=1)
+
+            self.fibFrame = VerticalScrolledTable(self.fibFrame, rows=0, columns=2, title='FIB Entries')
+            self.fibFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
+            self.fibTableFrame = self.fibFrame.interior
+            self.fibTableFrame.addRow(value=['Prefix','Next Hop'], readonly=True)
+
+            fibList = []
+            if 'fibEntries' in self.prefValues:
+                fibList = self.prefValues['fibEntries']
+            for fibEntr in fibList:
+                if isinstance( fibEntr, tuple ):
+                    self.fibTableFrame.addRow(value=fibEntr)
+                else:
+                    self.fibTableFrame.addRow(value=[fibEntr,''])
+
+        def addEntry( self ):
+            self.fibTableFrame.addRow()
+
+        def apply(self):
+            fibEntries = []
+            for row in range(self.fibTableFrame.rows):
+                if (len(self.fibTableFrame.get(row, 0)) > 0 and row > 0):
+                    if(len(self.fibTableFrame.get(row, 1)) > 0):
+                        fibEntries.append((self.fibTableFrame.get(row, 0), self.fibTableFrame.get(row, 1)))
+                    else:
+                        fibEntries.append(self.fibTableFrame.get(row, 0))
+
+            results = {'cpu': self.cpuEntry.get(),
+                       'cache': self.cacheEntry.get(),
+                       'mem': self.memEntry.get(),
+                       'hostname':self.hostnameEntry.get(),
+                       'startCommand':self.startEntry.get(),
+                       'fibEntries':fibEntries}
+            self.result = results
+
+class VerticalScrolledTable(LabelFrame):
+    """A pure Tkinter scrollable frame that actually works!
+
+    * Use the 'interior' attribute to place widgets inside the scrollable frame
+    * Construct and pack/place/grid normally
+    * This frame only allows vertical scrolling
+
+    """
+    def __init__(self, parent, rows=2, columns=2, title=None, *args, **kw):
+        LabelFrame.__init__(self, parent, text=title, padx=5, pady=5, *args, **kw)
+
+        # create a canvas object and a vertical scrollbar for scrolling it
+        vscrollbar = Scrollbar(self, orient=VERTICAL)
+        vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
+        canvas = Canvas(self, bd=0, highlightthickness=0,
+                        yscrollcommand=vscrollbar.set)
+        canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
+        vscrollbar.config(command=canvas.yview)
+
+        # reset the view
+        canvas.xview_moveto(0)
+        canvas.yview_moveto(0)
+
+        # create a frame inside the canvas which will be scrolled with it
+        self.interior = interior = TableFrame(canvas, rows=rows, columns=columns)
+        interior_id = canvas.create_window(0, 0, window=interior,
+                                           anchor=NW)
+
+        # track changes to the canvas and frame width and sync them,
+        # also updating the scrollbar
+        def _configure_interior(event):
+            # update the scrollbars to match the size of the inner frame
+            size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
+            canvas.config(scrollregion="0 0 %s %s" % size)
+            if interior.winfo_reqwidth() != canvas.winfo_width():
+                # update the canvas's width to fit the inner frame
+                canvas.config(width=interior.winfo_reqwidth())
+        interior.bind('<Configure>', _configure_interior)
+
+        def _configure_canvas(event):
+            if interior.winfo_reqwidth() != canvas.winfo_width():
+                # update the inner frame's width to fill the canvas
+                canvas.itemconfigure(interior_id, width=canvas.winfo_width())
+        canvas.bind('<Configure>', _configure_canvas)
+
+        return
+
+class TableFrame(Frame):
+    def __init__(self, parent, rows=2, columns=2):
+
+        Frame.__init__(self, parent, background="black")
+        self._widgets = []
+        self.rows = rows
+        self.columns = columns
+        for row in range(rows):
+            current_row = []
+            for column in range(columns):
+                label = Entry(self, borderwidth=0)
+                label.grid(row=row, column=column, sticky="wens", padx=1, pady=1)
+                current_row.append(label)
+            self._widgets.append(current_row)
+
+    def set(self, row, column, value):
+        widget = self._widgets[row][column]
+        widget.insert(0, value)
+
+    def get(self, row, column):
+        widget = self._widgets[row][column]
+        return widget.get()
+
+    def addRow( self, value=None, readonly=False ):
+        #print "Adding row " + str(self.rows +1)
+        current_row = []
+        for column in range(self.columns):
+            label = Entry(self, borderwidth=0)
+            label.grid(row=self.rows, column=column, sticky="wens", padx=1, pady=1)
+            if value is not None:
+                label.insert(0, value[column])
+            if (readonly == True):
+                label.configure(state='readonly')
+            current_row.append(label)
+        self._widgets.append(current_row)
+        self.update_idletasks()
+        self.rows += 1
+
+class LinkDialog(tkSimpleDialog.Dialog):
+
+        def __init__(self, parent, title, linkDefaults):
+
+            self.linkValues = linkDefaults
+
+            tkSimpleDialog.Dialog.__init__(self, parent, title)
+
+        def body(self, master):
+
+            self.var = StringVar(master)
+            Label(master, text="Bandwidth:").grid(row=0, sticky=E)
+            self.e1 = Entry(master)
+            self.e1.grid(row=0, column=1)
+            Label(master, text="[1-1000] Mbps").grid(row=0, column=2, sticky=W)
+            if 'bw' in self.linkValues:
+                self.e1.insert(0,str(self.linkValues['bw']))
+
+            Label(master, text="Delay:").grid(row=1, sticky=E)
+            self.e2 = Entry(master)
+            self.e2.grid(row=1, column=1)
+            Label(master, text="[0-1000] ms").grid(row=1, column=2, sticky=W)
+            if 'delay' in self.linkValues:
+                self.e2.insert(0, self.linkValues['delay'])
+
+            Label(master, text="Loss:").grid(row=2, sticky=E)
+            self.e3 = Entry(master)
+            self.e3.grid(row=2, column=1)
+            Label(master, text="%").grid(row=2, column=2, sticky=W)
+            if 'loss' in self.linkValues:
+                self.e3.insert(0, str(self.linkValues['loss']))
+
+            return self.e1 # initial focus
+
+        def apply(self):
+            self.result = {}
+            if (len(self.e1.get()) > 0):
+                self.result['bw'] = int(self.e1.get())
+            if (len(self.e2.get()) > 0):
+                self.result['delay'] = self.e2.get()
+            if (len(self.e3.get()) > 0):
+                self.result['loss'] = int(self.e3.get())
+
+class ToolTip(object):
+
+    def __init__(self, widget):
+        self.widget = widget
+        self.tipwindow = None
+        self.id = None
+        self.x = self.y = 0
+
+    def showtip(self, text):
+        "Display text in tooltip window"
+        self.text = text
+        if self.tipwindow or not self.text:
+            return
+        x, y, cx, cy = self.widget.bbox("insert")
+        x = x + self.widget.winfo_rootx() + 27
+        y = y + cy + self.widget.winfo_rooty() +27
+        self.tipwindow = tw = Toplevel(self.widget)
+        tw.wm_overrideredirect(1)
+        tw.wm_geometry("+%d+%d" % (x, y))
+        try:
+            # For Mac OS
+            tw.tk.call("::tk::unsupported::MacWindowStyle",
+                       "style", tw._w,
+                       "help", "noActivates")
+        except TclError:
+            pass
+        label = Label(tw, text=self.text, justify=LEFT,
+                      background="#ffffe0", relief=SOLID, borderwidth=1,
+                      font=("tahoma", "8", "normal"))
+        label.pack(ipadx=1)
+
+    def hidetip(self):
+        tw = self.tipwindow
+        self.tipwindow = None
+        if tw:
+            tw.destroy()
+
+class MiniEdit( Frame ):
+
+    "A simple network editor for MiniCCNx."
+
+    def __init__( self, parent=None, cheight=600, cwidth=1000, template_file='miniccnx.conf' ):
+
+        self.template_file = template_file
+
+        Frame.__init__( self, parent )
+        self.action = None
+        self.appName = 'MiniccnxEdit'
+        self.fixedFont = tkFont.Font ( family="DejaVu Sans Mono", size="14" )
+
+        # Style
+        self.font = ( 'Geneva', 9 )
+        self.smallFont = ( 'Geneva', 7 )
+        self.bg = 'white'
+
+        # Title
+        self.top = self.winfo_toplevel()
+        self.top.title( self.appName )
+
+        # Menu bar
+        self.createMenubar()
+
+        # Editing canvas
+        self.cheight, self.cwidth = cheight, cwidth
+        self.cframe, self.canvas = self.createCanvas()
+
+        # Toolbar
+        self.controllers = {}
+
+        # Toolbar
+        self.images = miniEditImages()
+        self.buttons = {}
+        self.active = None
+        self.tools = ( 'Select', 'Host', 'LegacyRouter', 'NetLink' )
+        self.customColors = { 'LegacyRouter': 'darkGreen', 'Host': 'blue' }
+        self.toolbar = self.createToolbar()
+
+        # Layout
+        self.toolbar.grid( column=0, row=0, sticky='nsew')
+        self.cframe.grid( column=1, row=0 )
+        self.columnconfigure( 1, weight=1 )
+        self.rowconfigure( 0, weight=1 )
+        self.pack( expand=True, fill='both' )
+
+        # About box
+        self.aboutBox = None
+
+        # Initialize node data
+        self.nodeBindings = self.createNodeBindings()
+        self.nodePrefixes = { 'LegacyRouter': 'r', 'Host': 'h'}
+        self.widgetToItem = {}
+        self.itemToWidget = {}
+
+        # Initialize link tool
+        self.link = self.linkWidget = None
+
+        # Selection support
+        self.selection = None
+
+        # Keyboard bindings
+        self.bind( '<Control-q>', lambda event: self.quit() )
+        self.bind( '<KeyPress-Delete>', self.deleteSelection )
+        self.bind( '<KeyPress-BackSpace>', self.deleteSelection )
+        self.focus()
+
+        #Mouse bindings
+        self.bind( '<Button-1>', lambda event: self.clearPopups )
+
+        self.hostPopup = Menu(self.top, tearoff=0)
+        self.hostPopup.add_command(label='Host Options', font=self.font, command=self.hostDetails)
+        #self.hostPopup.add_separator()
+        #self.hostPopup.add_command(label='Properties', font=self.font, command=self.hostDetails )
+
+        self.legacyRouterPopup = Menu(self.top, tearoff=0)
+        self.legacyRouterPopup.add_command(label='Router Options', font=self.font, command=self.hostDetails)
+
+        self.linkPopup = Menu(self.top, tearoff=0)
+        self.linkPopup.add_command(label='Link Options', font=self.font, command=self.linkDetails)
+        #self.linkPopup.add_separator()
+        #self.linkPopup.add_command(label='Properties', font=self.font, command=self.linkDetails )
+
+        # Event handling initalization
+        self.linkx = self.linky = self.linkItem = None
+        self.lastSelection = None
+
+        # Model initialization
+        self.links = {}
+        self.hostOpts = {}
+        self.switchOpts = {}
+        self.routerOpts = {}
+        self.hostCount = 0
+        self.routerCount = 0
+        self.net = None
+
+        # Close window gracefully
+        Wm.wm_protocol( self.top, name='WM_DELETE_WINDOW', func=self.quit )
+
+    def quit( self ):
+        "Stop our network, if any, then quit."
+        #sself.stop()
+        Frame.quit( self )
+
+    def createMenubar( self ): # MODIFICADO - OK
+        "Create our menu bar."
+
+        font = self.font
+
+        mbar = Menu( self.top, font=font )
+        self.top.configure( menu=mbar )
+
+        fileMenu = Menu( mbar, tearoff=False )
+        mbar.add_cascade( label="File", font=font, menu=fileMenu )
+        fileMenu.add_command( label="New", font=font, command=self.newTopology )
+        fileMenu.add_command( label="Open", font=font, command=self.loadTopology )
+        fileMenu.add_command( label="Save", font=font, command=self.saveTopology )
+        fileMenu.add_command( label="Generate", font=font, command=self.doGenerate )
+        fileMenu.add_separator()
+        fileMenu.add_command( label='Quit', command=self.quit, font=font )
+
+        editMenu = Menu( mbar, tearoff=False )
+        mbar.add_cascade( label="Edit", font=font, menu=editMenu )
+        editMenu.add_command( label="Cut", font=font,
+                              command=lambda: self.deleteSelection( None ) )
+
+        # Application menu
+        appMenu = Menu( mbar, tearoff=False )
+        mbar.add_cascade( label=self.appName, font=font, menu=appMenu )
+        appMenu.add_command( label='About Mini-CCNx', command=self.about,
+                             font=font)
+        #appMenu.add_separator()
+        #appMenu.add_command( label='Quit', command=self.quit, font=font )
+
+    # Canvas - TUDO IGUAL - OK
+
+    def createCanvas( self ):
+        "Create and return our scrolling canvas frame."
+        f = Frame( self )
+
+        canvas = Canvas( f, width=self.cwidth, height=self.cheight,
+                         bg=self.bg )
+
+        # Scroll bars
+        xbar = Scrollbar( f, orient='horizontal', command=canvas.xview )
+        ybar = Scrollbar( f, orient='vertical', command=canvas.yview )
+        canvas.configure( xscrollcommand=xbar.set, yscrollcommand=ybar.set )
+
+        # Resize box
+        resize = Label( f, bg='white' )
+
+        # Layout
+        canvas.grid( row=0, column=1, sticky='nsew')
+        ybar.grid( row=0, column=2, sticky='ns')
+        xbar.grid( row=1, column=1, sticky='ew' )
+        resize.grid( row=1, column=2, sticky='nsew' )
+
+        # Resize behavior
+        f.rowconfigure( 0, weight=1 )
+        f.columnconfigure( 1, weight=1 )
+        f.grid( row=0, column=0, sticky='nsew' )
+        f.bind( '<Configure>', lambda event: self.updateScrollRegion() )
+
+        # Mouse bindings
+        canvas.bind( '<ButtonPress-1>', self.clickCanvas )
+        canvas.bind( '<B1-Motion>', self.dragCanvas )
+        canvas.bind( '<ButtonRelease-1>', self.releaseCanvas )
+
+        return f, canvas
+
+    def updateScrollRegion( self ):
+        "Update canvas scroll region to hold everything."
+        bbox = self.canvas.bbox( 'all' )
+        if bbox is not None:
+            self.canvas.configure( scrollregion=( 0, 0, bbox[ 2 ],
+                                   bbox[ 3 ] ) )
+
+    def canvasx( self, x_root ):
+        "Convert root x coordinate to canvas coordinate."
+        c = self.canvas
+        return c.canvasx( x_root ) - c.winfo_rootx()
+
+    def canvasy( self, y_root ):
+        "Convert root y coordinate to canvas coordinate."
+        c = self.canvas
+        return c.canvasy( y_root ) - c.winfo_rooty()
+
+    # Toolbar
+
+    def activate( self, toolName ): #IGUAL - OK
+        "Activate a tool and press its button."
+        # Adjust button appearance
+        if self.active:
+            self.buttons[ self.active ].configure( relief='raised' )
+        self.buttons[ toolName ].configure( relief='sunken' )
+        # Activate dynamic bindings
+        self.active = toolName
+
+
+    def createToolTip(self, widget, text): #NOVA - CRIA HINTS E TIPS
+        toolTip = ToolTip(widget)
+        def enter(event):
+            toolTip.showtip(text)
+        def leave(event):
+            toolTip.hidetip()
+        widget.bind('<Enter>', enter)
+        widget.bind('<Leave>', leave)
+
+    def createToolbar( self ): #MODIFICADO - OK
+        "Create and return our toolbar frame."
+
+        toolbar = Frame( self )
+
+        # Tools
+        for tool in self.tools:
+            cmd = ( lambda t=tool: self.activate( t ) )
+            b = Button( toolbar, text=tool, font=self.smallFont, command=cmd)
+            if tool in self.images:
+                b.config( height=35, image=self.images[ tool ] )
+                self.createToolTip(b, str(tool))
+                # b.config( compound='top' )
+            b.pack( fill='x' )
+            self.buttons[ tool ] = b
+        self.activate( self.tools[ 0 ] )
+
+        # Spacer
+        Label( toolbar, text='' ).pack()
+
+        # abaixo copiado Mini-CCNx para criar botao Generate
+
+        for cmd, color in [ ( 'Generate', 'darkGreen' ) ]:
+            doCmd = getattr( self, 'do' + cmd )
+            b = Button( toolbar, text=cmd, font=self.smallFont,
+                        fg=color, command=doCmd )
+            b.pack( fill='x', side='bottom' )
+
+        return toolbar
+
+    def doGenerate( self ): #COPIA Mini-CCNx - GERA TEMPLATE
+        "Generate template."
+        self.activate( 'Select' )
+        for tool in self.tools:
+            self.buttons[ tool ].config( state='disabled' )
+
+        self.buildTemplate()
+
+        for tool in self.tools:
+            self.buttons[ tool ].config( state='normal' )
+
+        toplevel = Toplevel()
+        label1 = Label(toplevel, text="Template file generated successfully", height=0, width=30)
+        label1.pack()
+        b=Button(toplevel, text="Ok", width=5, command=toplevel.destroy)
+        b.pack(side='bottom', padx=0,pady=0)
+
+    def parseFibEntries ( self, fibEntries ):
+        "Parse FIB Entries for write"
+        result=''
+
+        for fibEntry in fibEntries:
+                entry = ','.join(map(str, fibEntry))
+                result += entry + ' '
+
+        return result
+
+    def buildTemplate( self ): #COPIA Mini-CCNx para criar Template
+        "Generate template"
+
+        template = open(self.template_file, 'w')
+
+        # hosts
+        template.write('[hosts]\n')
+        for widget in self.widgetToItem:
+            name = widget[ 'text' ]
+            tags = self.canvas.gettags( self.widgetToItem[ widget ] )
+            #print self.hostOpts[name]
+            if 'Host' in tags:
+                hOpts=self.hostOpts[name]
+                template.write(name + ': ')
+                if 'startCommand' in hOpts:
+                        template.write(hOpts['startCommand'] + ' ')
+                else:
+                        template.write('_ ')
+                if 'cache' in hOpts:
+                        template.write('cache=' + hOpts['cache'] + ' ')
+                if 'cpu' in hOpts:
+                        cpu=float(hOpts['cpu'])/100
+                        template.write('cpu=' + repr(cpu) + ' ')
+                if 'mem' in hOpts:
+                        mem=float(hOpts['mem'])/100
+                        template.write('mem=' + repr(mem) + ' ')
+                if 'fibEntries' in hOpts:
+                        customFib = self.parseFibEntries(hOpts['fibEntries'])
+                        template.write(customFib)
+                template.write('\n')
+
+        # switches/routers
+        template.write('[routers]\n')
+
+        for router in self.routerOpts.values():
+
+            hasOpt='False'
+            routerName=router['hostname']
+            #nodetype=router['nodetype']
+            #nodenum=router['nodenum']
+
+            rOpts=self.routerOpts[routerName]
+
+            template.write(routerName + ': ')
+
+            if 'cpu' in rOpts:
+                cpu=float(rOpts['cpu'])/100
+                template.write('cpu=' + repr(cpu) + ' ')
+                hasOpt='True'
+            if 'mem' in rOpts:
+                mem=float(rOpts['mem'])/100
+                template.write('mem=' + repr(mem) + ' ')
+                hasOpt='True'
+            if 'cache' in rOpts:
+                template.write('cache=' + rOpts['cache'] + ' ')
+                hasOpt='True'
+            if 'fibEntries' in rOpts:
+                customFib = self.parseFibEntries(rOpts['fibEntries'])
+                template.write(customFib)
+                hasOpt='True'
+            if hasOpt == 'False':
+                template.write('_')
+
+            template.write('\n')
+
+        # Make links
+        template.write('[links]\n')
+        for link in self.links.values():
+             dst=link['dest']
+             src=link['src']
+             linkopts=link['linkOpts']
+             linktype=link['type']
+
+             srcName, dstName = src[ 'text' ], dst[ 'text' ]
+             template.write(srcName + ':' + dstName + ' ')
+             if 'bw' in linkopts:
+                     template.write('bw=' + str(linkopts['bw']) + ' ' )
+             if 'loss' in linkopts:
+                     template.write('loss=' + repr(linkopts['loss']) + ' ' )
+             if 'delay' in linkopts:
+                     template.write('delay=' + str(linkopts['delay']))
+
+             template.write('\n')
+
+        template.close()
+
+    def addNode( self, node, nodeNum, x, y, name=None):
+        "Add a new node to our canvas."
+
+        if 'LegacyRouter' == node:
+            self.routerCount += 1
+        if 'Host' == node:
+            self.hostCount += 1
+        if name is None:
+            name = self.nodePrefixes[ node ] + nodeNum
+        self.addNamedNode(node, name, x, y)
+
+    def addNamedNode( self, node, name, x, y):
+        "Add a new node to our canvas."
+        c = self.canvas
+        icon = self.nodeIcon( node, name )
+        item = self.canvas.create_window( x, y, anchor='c', window=icon,
+                                          tags=node )
+        self.widgetToItem[ icon ] = item
+        self.itemToWidget[ item ] = icon
+        icon.links = {}
+
+    def convertJsonUnicode(self, input):
+        "Some part of Mininet don't like Unicode"
+        if isinstance(input, dict):
+            return {self.convertJsonUnicode(key): self.convertJsonUnicode(value) for key, value in input.iteritems()}
+        elif isinstance(input, list):
+            return [self.convertJsonUnicode(element) for element in input]
+        elif isinstance(input, unicode):
+            return input.encode('utf-8')
+        else:
+            return input
+
+    def loadTopology( self ):
+        "Load command."
+        c = self.canvas
+
+        myFormats = [
+            ('Miniccnx Topology','*.mnccnx'),
+            ('All Files','*'),
+        ]
+        f = tkFileDialog.askopenfile(filetypes=myFormats, mode='rb')
+        if f == None:
+            return
+        self.newTopology()
+        loadedTopology = self.convertJsonUnicode(json.load(f))
+
+        # Load hosts
+        hosts = loadedTopology['hosts']
+        for host in hosts:
+            nodeNum = host['number']
+            hostname = 'h'+nodeNum
+            if 'hostname' in host['opts']:
+                hostname = host['opts']['hostname']
+            else:
+                host['opts']['hostname'] = hostname
+            if 'nodeNum' not in host['opts']:
+                host['opts']['nodeNum'] = int(nodeNum)
+            x = host['x']
+            y = host['y']
+            self.addNode('Host', nodeNum, float(x), float(y), name=hostname)
+
+            # Fix JSON converting tuple to list when saving
+            if 'privateDirectory' in host['opts']:
+                newDirList = []
+                for privateDir in host['opts']['privateDirectory']:
+                    if isinstance( privateDir, list ):
+                        newDirList.append((privateDir[0],privateDir[1]))
+                    else:
+                        newDirList.append(privateDir)
+                host['opts']['privateDirectory'] = newDirList
+            self.hostOpts[hostname] = host['opts']
+            icon = self.findWidgetByName(hostname)
+            icon.bind('<Button-3>', self.do_hostPopup )
+
+        # Load routers
+        routers = loadedTopology['routers']
+        for router in routers:
+            nodeNum = router['number']
+            hostname = 'r'+nodeNum
+            #print router
+            if 'nodeType' not in router['opts']:
+                router['opts']['nodeType'] = 'legacyRouter'
+            if 'hostname' in router['opts']:
+                hostname = router['opts']['hostname']
+            else:
+                router['opts']['hostname'] = hostname
+            if 'nodeNum' not in router['opts']:
+                router['opts']['nodeNum'] = int(nodeNum)
+            x = router['x']
+            y = router['y']
+            if router['opts']['nodeType'] == "legacyRouter":
+                self.addNode('LegacyRouter', nodeNum, float(x), float(y), name=hostname)
+                icon = self.findWidgetByName(hostname)
+                icon.bind('<Button-3>', self.do_legacyRouterPopup )
+            self.routerOpts[hostname] = router['opts']
+
+        # Load links
+        links = loadedTopology['links']
+        for link in links:
+            srcNode = link['src']
+            src = self.findWidgetByName(srcNode)
+            sx, sy = self.canvas.coords( self.widgetToItem[ src ] )
+
+            destNode = link['dest']
+            dest = self.findWidgetByName(destNode)
+            dx, dy = self.canvas.coords( self.widgetToItem[ dest ]  )
+
+            self.link = self.canvas.create_line( sx, sy, dx, dy, width=4,
+                                             fill='blue', tag='link' )
+            c.itemconfig(self.link, tags=c.gettags(self.link)+('data',))
+            self.addLink( src, dest, linkopts=link['opts'] )
+            self.createDataLinkBindings()
+            self.link = self.linkWidget = None
+
+        f.close
+
+    def findWidgetByName( self, name ):
+        for widget in self.widgetToItem:
+            if name ==  widget[ 'text' ]:
+                return widget
+
+    def newTopology( self ):
+        "New command."
+        for widget in self.widgetToItem.keys():
+            self.deleteItem( self.widgetToItem[ widget ] )
+        self.hostCount = 0
+        self.routerCount = 0
+        self.links = {}
+        self.hostOpts = {}
+        self.routerOpts = {}
+
+    def saveTopology( self ):
+        "Save command."
+        myFormats = [
+            ('Miniccnx Topology','*.mnccnx'),
+            ('All Files','*'),
+        ]
+
+        savingDictionary = {}
+        fileName = tkFileDialog.asksaveasfilename(filetypes=myFormats ,title="Save the topology as...")
+        if len(fileName ) > 0:
+            # Save Application preferences
+            savingDictionary['version'] = '2'
+
+            # Save routers and Hosts
+            hostsToSave = []
+            routersToSave = []
+
+            for widget in self.widgetToItem:
+                name = widget[ 'text' ]
+                tags = self.canvas.gettags( self.widgetToItem[ widget ] )
+                x1, y1 = self.canvas.coords( self.widgetToItem[ widget ] )
+                if 'LegacyRouter' in tags:
+                    nodeNum = self.routerOpts[name]['nodeNum']
+                    nodeToSave = {'number':str(nodeNum),
+                                  'x':str(x1),
+                                  'y':str(y1),
+                                  'opts':self.routerOpts[name] }
+                    routersToSave.append(nodeToSave)
+                elif 'Host' in tags:
+                    nodeNum = self.hostOpts[name]['nodeNum']
+                    nodeToSave = {'number':str(nodeNum),
+                                  'x':str(x1),
+                                  'y':str(y1),
+                                  'opts':self.hostOpts[name] }
+                    hostsToSave.append(nodeToSave)
+                else:
+                    raise Exception( "Cannot create mystery node: " + name )
+            savingDictionary['hosts'] = hostsToSave
+            savingDictionary['routers'] = routersToSave
+
+            # Save Links
+            linksToSave = []
+            for link in self.links.values():
+                src = link['src']
+                dst = link['dest']
+                linkopts = link['linkOpts']
+
+                srcName, dstName = src[ 'text' ], dst[ 'text' ]
+                linkToSave = {'src':srcName,
+                              'dest':dstName,
+                              'opts':linkopts}
+                if link['type'] == 'data':
+                    linksToSave.append(linkToSave)
+            savingDictionary['links'] = linksToSave
+
+            # Save Application preferences
+            #savingDictionary['application'] = self.appPrefs
+
+            try:
+                f = open(fileName, 'wb')
+                f.write(json.dumps(savingDictionary, sort_keys=True, indent=4, separators=(',', ': ')))
+            except Exception as er:
+                print er
+            finally:
+                f.close()
+
+    # Generic canvas handler
+    #
+    # We could have used bindtags, as in nodeIcon, but
+    # the dynamic approach used here
+    # may actually require less code. In any case, it's an
+    # interesting introspection-based alternative to bindtags.
+
+    def canvasHandle( self, eventName, event ):
+        "Generic canvas event handler"
+        if self.active is None:
+            return
+        toolName = self.active
+        handler = getattr( self, eventName + toolName, None )
+        if handler is not None:
+            handler( event )
+
+    def clickCanvas( self, event ):
+        "Canvas click handler."
+        self.canvasHandle( 'click', event )
+
+    def dragCanvas( self, event ):
+        "Canvas drag handler."
+        self.canvasHandle( 'drag', event )
+
+    def releaseCanvas( self, event ):
+        "Canvas mouse up handler."
+        self.canvasHandle( 'release', event )
+
+    # Currently the only items we can select directly are
+    # links. Nodes are handled by bindings in the node icon.
+
+    def findItem( self, x, y ):
+        "Find items at a location in our canvas."
+        items = self.canvas.find_overlapping( x, y, x, y )
+        if len( items ) == 0:
+            return None
+        else:
+            return items[ 0 ]
+
+    # Canvas bindings for Select, Host, Router and Link tools
+
+    def clickSelect( self, event ):
+        "Select an item."
+        self.selectItem( self.findItem( event.x, event.y ) )
+
+    def deleteItem( self, item ):
+        "Delete an item."
+        # Don't delete while network is running
+        if self.buttons[ 'Select' ][ 'state' ] == 'disabled':
+            return
+        # Delete from model
+        if item in self.links:
+            self.deleteLink( item )
+        if item in self.itemToWidget:
+            self.deleteNode( item )
+        # Delete from view
+        self.canvas.delete( item )
+
+    def deleteSelection( self, _event ):
+        "Delete the selected item."
+        if self.selection is not None:
+            self.deleteItem( self.selection )
+        self.selectItem( None )
+
+    def clearPopups(self):
+        print 'Entrou funcao clear_popups'
+
+            if isHostPopup == True:
+                print 'Hostpopup = true'
+                    self.hostPopup.unpost
+                isHostPopup = False
+        #if isRouterPopup == True
+        #if isLinkPopup == True
+
+    def nodeIcon( self, node, name ):
+        "Create a new node icon."
+        icon = Button( self.canvas, image=self.images[ node ],
+                       text=name, compound='top' )
+        # Unfortunately bindtags wants a tuple
+        bindtags = [ str( self.nodeBindings ) ]
+        bindtags += list( icon.bindtags() )
+        icon.bindtags( tuple( bindtags ) )
+        return icon
+
+    def newNode( self, node, event ):
+        "Add a new node to our canvas."
+        c = self.canvas
+        x, y = c.canvasx( event.x ), c.canvasy( event.y )
+        name = self.nodePrefixes[ node ]
+
+        if 'LegacyRouter' == node:
+            self.routerCount += 1
+            name = self.nodePrefixes[ node ] + str( self.routerCount )
+            self.routerOpts[name] = {}
+            self.routerOpts[name]['nodeNum']=self.routerCount
+            self.routerOpts[name]['hostname']=name
+            self.routerOpts[name]['nodeType']='legacyRouter'
+
+        if 'Host' == node:
+            self.hostCount += 1
+            name = self.nodePrefixes[ node ] + str( self.hostCount )
+            self.hostOpts[name] = {'sched':'host'}
+            self.hostOpts[name]['nodeNum']=self.hostCount
+            self.hostOpts[name]['hostname']=name
+
+        icon = self.nodeIcon( node, name )
+        item = self.canvas.create_window( x, y, anchor='c', window=icon,
+                                          tags=node )
+        self.widgetToItem[ icon ] = item
+        self.itemToWidget[ item ] = icon
+        self.selectItem( item )
+        icon.links = {}
+        if 'LegacyRouter' == node:
+            icon.bind('<Button-3>', self.do_legacyRouterPopup )
+        if 'Host' == node:
+            icon.bind('<Button-3>', self.do_hostPopup )
+
+    def clickHost( self, event ):
+        "Add a new host to our canvas."
+        self.newNode( 'Host', event )
+
+    def clickLegacyRouter( self, event ):
+        "Add a new router to our canvas."
+        self.newNode( 'LegacyRouter', event )
+
+    def dragNetLink( self, event ):
+        "Drag a link's endpoint to another node."
+        if self.link is None:
+            return
+        # Since drag starts in widget, we use root coords
+        x = self.canvasx( event.x_root )
+        y = self.canvasy( event.y_root )
+        c = self.canvas
+        c.coords( self.link, self.linkx, self.linky, x, y )
+
+    def releaseNetLink( self, _event ):
+        "Give up on the current link."
+        if self.link is not None:
+            self.canvas.delete( self.link )
+        self.linkWidget = self.linkItem = self.link = None
+
+    # Generic node handlers
+
+    def createNodeBindings( self ):
+        "Create a set of bindings for nodes."
+        bindings = {
+            '<ButtonPress-1>': self.clickNode,
+            '<B1-Motion>': self.dragNode,
+            '<ButtonRelease-1>': self.releaseNode,
+            '<Enter>': self.enterNode,
+            '<Leave>': self.leaveNode
+        }
+        l = Label()  # lightweight-ish owner for bindings
+        for event, binding in bindings.items():
+            l.bind( event, binding )
+        return l
+
+    def selectItem( self, item ):
+        "Select an item and remember old selection."
+        self.lastSelection = self.selection
+        self.selection = item
+
+    def enterNode( self, event ):
+        "Select node on entry."
+        self.selectNode( event )
+
+    def leaveNode( self, _event ):
+        "Restore old selection on exit."
+        self.selectItem( self.lastSelection )
+
+    def clickNode( self, event ):
+        "Node click handler."
+        if self.active is 'NetLink':
+            self.startLink( event )
+        else:
+            self.selectNode( event )
+        return 'break'
+
+    def dragNode( self, event ):
+        "Node drag handler."
+        if self.active is 'NetLink':
+            self.dragNetLink( event )
+        else:
+            self.dragNodeAround( event )
+
+    def releaseNode( self, event ):
+        "Node release handler."
+        if self.active is 'NetLink':
+            self.finishLink( event )
+
+    # Specific node handlers
+
+    def selectNode( self, event ):
+        "Select the node that was clicked on."
+        item = self.widgetToItem.get( event.widget, None )
+        self.selectItem( item )
+
+    def dragNodeAround( self, event ):
+        "Drag a node around on the canvas."
+        c = self.canvas
+        # Convert global to local coordinates;
+        # Necessary since x, y are widget-relative
+        x = self.canvasx( event.x_root )
+        y = self.canvasy( event.y_root )
+        w = event.widget
+        # Adjust node position
+        item = self.widgetToItem[ w ]
+        c.coords( item, x, y )
+        # Adjust link positions
+        for dest in w.links:
+            link = w.links[ dest ]
+            item = self.widgetToItem[ dest ]
+            x1, y1 = c.coords( item )
+            c.coords( link, x, y, x1, y1 )
+        self.updateScrollRegion()
+
+    def createDataLinkBindings( self ):
+        "Create a set of bindings for nodes."
+        # Link bindings
+        # Selection still needs a bit of work overall
+        # Callbacks ignore event
+
+        def select( _event, link=self.link ):
+            "Select item on mouse entry."
+            self.selectItem( link )
+
+        def highlight( _event, link=self.link ):
+            "Highlight item on mouse entry."
+            self.selectItem( link )
+            self.canvas.itemconfig( link, fill='green' )
+
+        def unhighlight( _event, link=self.link ):
+            "Unhighlight item on mouse exit."
+            self.canvas.itemconfig( link, fill='blue' )
+            #self.selectItem( None )
+
+        self.canvas.tag_bind( self.link, '<Enter>', highlight )
+        self.canvas.tag_bind( self.link, '<Leave>', unhighlight )
+        self.canvas.tag_bind( self.link, '<ButtonPress-1>', select )
+        self.canvas.tag_bind( self.link, '<Button-3>', self.do_linkPopup )
+
+    def startLink( self, event ):
+        "Start a new link."
+        if event.widget not in self.widgetToItem:
+            # Didn't click on a node
+            return
+
+        w = event.widget
+        item = self.widgetToItem[ w ]
+        x, y = self.canvas.coords( item )
+        self.link = self.canvas.create_line( x, y, x, y, width=4,
+                                             fill='blue', tag='link' )
+        self.linkx, self.linky = x, y
+        self.linkWidget = w
+        self.linkItem = item
+
+    def finishLink( self, event ):
+        "Finish creating a link"
+        if self.link is None:
+            return
+        source = self.linkWidget
+        c = self.canvas
+        # Since we dragged from the widget, use root coords
+        x, y = self.canvasx( event.x_root ), self.canvasy( event.y_root )
+        target = self.findItem( x, y )
+        dest = self.itemToWidget.get( target, None )
+        if ( source is None or dest is None or source == dest
+                or dest in source.links or source in dest.links ):
+            self.releaseNetLink( event )
+            return
+        # For now, don't allow hosts to be directly linked
+        stags = self.canvas.gettags( self.widgetToItem[ source ] )
+        dtags = self.canvas.gettags( target )
+        if (('Host' in stags and 'Host' in dtags)):
+            self.releaseNetLink( event )
+            return
+
+        # Set link type
+        linkType='data'
+
+        self.createDataLinkBindings()
+        c.itemconfig(self.link, tags=c.gettags(self.link)+(linkType,))
+
+        x, y = c.coords( target )
+        c.coords( self.link, self.linkx, self.linky, x, y )
+        self.addLink( source, dest, linktype=linkType )
+
+        # We're done
+        self.link = self.linkWidget = None
+
+    # Menu handlers
+
+    def about( self ):
+        "Display about box."
+        about = self.aboutBox
+        if about is None:
+            bg = 'white'
+            about = Toplevel( bg='white' )
+            about.title( 'About' )
+            info = self.appName + ': a simple network editor for MiniCCNx - based on Miniedit'
+            warning = 'Development version - not entirely functional!'
+            #version = 'MiniEdit '+MINIEDIT_VERSION
+            author = 'Carlos Cabral, Jan 2013'
+            author2 = 'Caio Elias, Nov 2014'
+            author3 = 'Originally by: Bob Lantz <rlantz@cs>, April 2010'
+            enhancements = 'Enhancements by: Gregory Gee, Since July 2013'
+            www = 'http://gregorygee.wordpress.com/category/miniedit/'
+            line1 = Label( about, text=info, font='Helvetica 10 bold', bg=bg )
+            line2 = Label( about, text=warning, font='Helvetica 9', bg=bg )
+            line3 = Label( about, text=author, font='Helvetica 9', bg=bg )
+            line4 = Label( about, text=author2, font='Helvetica 9', bg=bg )
+            line5 = Label( about, text=author3, font='Helvetica 9', bg=bg )
+            line6 = Label( about, text=enhancements, font='Helvetica 9', bg=bg )
+            line7 = Entry( about, font='Helvetica 9', bg=bg, width=len(www), justify=CENTER )
+
+            line7.insert(0, www)
+            line7.configure(state='readonly')
+            line1.pack( padx=20, pady=10 )
+            line2.pack(pady=10 )
+            line3.pack(pady=10 )
+            line4.pack(pady=10 )
+            line5.pack(pady=10 )
+            line6.pack(pady=10 )
+            line7.pack(pady=10 )
+            hide = ( lambda about=about: about.withdraw() )
+            self.aboutBox = about
+            # Hide on close rather than destroying window
+            Wm.wm_protocol( about, name='WM_DELETE_WINDOW', func=hide )
+        # Show (existing) window
+        about.deiconify()
+
+    def createToolImages( self ):
+        "Create toolbar (and icon) images."
+
+    def hostDetails( self, _ignore=None ):
+        if ( self.selection is None or
+             self.net is not None or
+             self.selection not in self.itemToWidget ):
+            return
+        widget = self.itemToWidget[ self.selection ]
+        name = widget[ 'text' ]
+        tags = self.canvas.gettags( self.selection )
+
+        #print tags
+        if 'Host' in tags:
+
+                prefDefaults = self.hostOpts[name]
+                hostBox = HostDialog(self, title='Host Details', prefDefaults=prefDefaults, isRouter='False')
+                self.master.wait_window(hostBox.top)
+                if hostBox.result:
+                    newHostOpts = {'nodeNum':self.hostOpts[name]['nodeNum']}
+
+                    if len(hostBox.result['startCommand']) > 0:
+                        newHostOpts['startCommand'] = hostBox.result['startCommand']
+                    if hostBox.result['cpu']:
+                        newHostOpts['cpu'] = hostBox.result['cpu']
+                    if hostBox.result['mem']:
+                        newHostOpts['mem'] = hostBox.result['mem']
+                    if len(hostBox.result['hostname']) > 0:
+                        newHostOpts['hostname'] = hostBox.result['hostname']
+                        name = hostBox.result['hostname']
+                        widget[ 'text' ] = name
+                    if len(hostBox.result['cache']) > 0:
+                        newHostOpts['cache'] = hostBox.result['cache']
+                    if len(hostBox.result['fibEntries']) > 0:
+                        newHostOpts['fibEntries'] = hostBox.result['fibEntries']
+                    self.hostOpts[name] = newHostOpts
+
+                    print 'New host details for ' + name + ' = ' + str(newHostOpts)
+
+        elif 'LegacyRouter' in tags:
+
+                prefDefaults = self.routerOpts[name]
+                hostBox = HostDialog(self, title='Router Details', prefDefaults=prefDefaults, isRouter='True')
+                self.master.wait_window(hostBox.top)
+                if hostBox.result:
+                    newRouterOpts = {'nodeNum':self.routerOpts[name]['nodeNum']}
+
+                    if hostBox.result['cpu']:
+                        newRouterOpts['cpu'] = hostBox.result['cpu']
+                    if hostBox.result['mem']:
+                        newRouterOpts['mem'] = hostBox.result['mem']
+                    if len(hostBox.result['hostname']) > 0:
+                        newRouterOpts['hostname'] = hostBox.result['hostname']
+                        name = hostBox.result['hostname']
+                        widget[ 'text' ] = name
+                    if len(hostBox.result['cache']) > 0:
+                        newRouterOpts['cache'] = hostBox.result['cache']
+                    if len(hostBox.result['fibEntries']) > 0:
+                        newRouterOpts['fibEntries'] = hostBox.result['fibEntries']
+                    self.routerOpts[name] = newRouterOpts
+
+                    print 'New host details for ' + name + ' = ' + str(newRouterOpts)
+
+    def linkDetails( self, _ignore=None ):
+        if ( self.selection is None or
+             self.net is not None):
+            return
+        link = self.selection
+
+        linkDetail =  self.links[link]
+        src = linkDetail['src']
+        dest = linkDetail['dest']
+        linkopts = linkDetail['linkOpts']
+        linkBox = LinkDialog(self, title='Link Details', linkDefaults=linkopts)
+        if linkBox.result is not None:
+            linkDetail['linkOpts'] = linkBox.result
+            print 'New link details = ' + str(linkBox.result)
+
+    # Model interface
+    #
+    # Ultimately we will either want to use a topo or
+    # mininet object here, probably.
+
+    def addLink( self, source, dest, linktype='data', linkopts={} ):
+        "Add link to model."
+        source.links[ dest ] = self.link
+        dest.links[ source ] = self.link
+        self.links[ self.link ] = {'type' :linktype,
+                                   'src':source,
+                                   'dest':dest,
+                                   'linkOpts':linkopts}
+
+    def deleteLink( self, link ):
+        "Delete link from model."
+        pair = self.links.get( link, None )
+        if pair is not None:
+            source=pair['src']
+            dest=pair['dest']
+            del source.links[ dest ]
+            del dest.links[ source ]
+            stags = self.canvas.gettags( self.widgetToItem[ source ] )
+            dtags = self.canvas.gettags( self.widgetToItem[ dest ] )
+            ltags = self.canvas.gettags( link )
+
+        if link is not None:
+            del self.links[ link ]
+
+    def deleteNode( self, item ):
+        "Delete node (and its links) from model."
+
+        widget = self.itemToWidget[ item ]
+        tags = self.canvas.gettags(item)
+
+        for link in widget.links.values():
+            # Delete from view and model
+            self.deleteItem( link )
+        del self.itemToWidget[ item ]
+        del self.widgetToItem[ widget ]
+
+    def do_linkPopup(self, event):
+        # display the popup menu
+        if ( self.net is None ):
+            try:
+                self.linkPopup.tk_popup(event.x_root, event.y_root)
+            finally:
+                # make sure to release the grab (Tk 8.0a1 only)
+                self.linkPopup.grab_release()
+
+    def do_legacyRouterPopup(self, event):
+        # display the popup menu
+        if ( self.net is None ):
+            try:
+                self.legacyRouterPopup.tk_popup(event.x_root, event.y_root)
+            finally:
+                # make sure to release the grab (Tk 8.0a1 only)
+                self.legacyRouterPopup.grab_release()
+
+    def do_hostPopup(self, event):
+        # display the popup menu
+        if ( self.net is None ):
+                try:
+                    self.hostPopup.tk_popup(event.x_root, event.y_root)
+                    isHostPopup = True
+                finally:
+                    # make sure to release the grab (Tk 8.0a1 only)
+                    self.hostPopup.grab_release()
+
+    def xterm( self, _ignore=None ):
+        "Make an xterm when a button is pressed."
+        if ( self.selection is None or
+             self.net is None or
+             self.selection not in self.itemToWidget ):
+            return
+        name = self.itemToWidget[ self.selection ][ 'text' ]
+        if name not in self.net.nameToNode:
+            return
+        term = makeTerm( self.net.nameToNode[ name ], 'Host', term=self.appPrefs['terminalType'] )
+        if StrictVersion(MININET_VERSION) > StrictVersion('2.0'):
+            self.net.terms += term
+        else:
+            self.net.terms.append(term)
+
+    def iperf( self, _ignore=None ):
+        "Make an xterm when a button is pressed."
+        if ( self.selection is None or
+             self.net is None or
+             self.selection not in self.itemToWidget ):
+            return
+        name = self.itemToWidget[ self.selection ][ 'text' ]
+        if name not in self.net.nameToNode:
+            return
+        self.net.nameToNode[ name ].cmd( 'iperf -s -p 5001 &' )
+
+    """ BELOW HERE IS THE TOPOLOGY IMPORT CODE """
+
+    def parseArgs( self ):
+        """Parse command-line args and return options object.
+           returns: opts parse options dict"""
+
+        if '--custom' in sys.argv:
+            index = sys.argv.index( '--custom' )
+            if len( sys.argv ) > index + 1:
+                filename = sys.argv[ index + 1 ]
+                self.parseCustomFile( filename )
+            else:
+                raise Exception( 'Custom file name not found' )
+
+        desc = ( "The %prog utility creates Miniccnx network from the\n"
+                 "command line. It can create parametrized topologies,\n"
+                 "invoke the Miniccnx CLI, and run tests." )
+
+        usage = ( '%prog [options] [template_file]\n'
+                  '\nIf no template_file is given, generated template will be written to the file miniccnx.conf in the current directory.\n'
+                  'Type %prog -h for details)' )
+
+        opts = OptionParser( description=desc, usage=usage )
+
+        addDictOption( opts, TOPOS, TOPODEF, 'topo' )
+        addDictOption( opts, LINKS, LINKDEF, 'link' )
+
+        opts.add_option( '--custom', type='string', default=None,
+                         help='read custom topo and node params from .py' +
+                         'file' )
+
+        self.options, self.args = opts.parse_args()
+        # We don't accept extra arguments after the options
+        if self.args:
+             if len(self.args) > 1:
+                     opts.print_help()
+                     exit()
+             else:
+                     self.template_file=self.args[0]
+
+    def setCustom( self, name, value ):
+        "Set custom parameters for MininetRunner."
+        if name in ( 'topos', 'switches', 'hosts', 'controllers' ):
+            # Update dictionaries
+            param = name.upper()
+            globals()[ param ].update( value )
+        elif name == 'validate':
+            # Add custom validate function
+            self.validate = value
+        else:
+            # Add or modify global variable or class
+            globals()[ name ] = value
+
+    def parseCustomFile( self, fileName ):
+        "Parse custom file and add params before parsing cmd-line options."
+        customs = {}
+        if os.path.isfile( fileName ):
+            execfile( fileName, customs, customs )
+            for name, val in customs.iteritems():
+                self.setCustom( name, val )
+        else:
+            raise Exception( 'could not find custom file: %s' % fileName )
+
+    def importTopo( self ):
+        print 'topo='+self.options.topo
+        if self.options.topo == 'none':
+            return
+        self.newTopology()
+        topo = buildTopo( TOPOS, self.options.topo )
+        link = customConstructor( LINKS, self.options.link )
+        importNet = Mininet(topo=topo, build=False, link=link)
+        importNet.build()
+
+        c = self.canvas
+        rowIncrement = 100
+        currentY = 100
+
+        # Add switches
+        print 'switches:'+str(len(importNet.switches))
+        columnCount = 0
+        for switch in importNet.switches:
+            name = switch.name
+            self.switchOpts[name] = {}
+            self.switchOpts[name]['nodeNum']=self.switchCount
+            self.switchOpts[name]['hostname']=name
+            self.switchOpts[name]['switchType']='default'
+            self.switchOpts[name]['controllers']=[]
+
+            x = columnCount*100+100
+            self.addNode('Switch', self.switchCount,
+                 float(x), float(currentY), name=name)
+            icon = self.findWidgetByName(name)
+            icon.bind('<Button-3>', self.do_switchPopup )
+
+            if columnCount == 9:
+                columnCount = 0
+                currentY = currentY + rowIncrement
+            else:
+                columnCount =columnCount+1
+
+        currentY = currentY + rowIncrement
+        # Add hosts
+        print 'hosts:'+str(len(importNet.hosts))
+        columnCount = 0
+        for host in importNet.hosts:
+            name = host.name
+            self.hostOpts[name] = {'sched':'host'}
+            self.hostOpts[name]['nodeNum']=self.hostCount
+            self.hostOpts[name]['hostname']=name
+            #self.hostOpts[name]['ip']=host.IP()
+
+            x = columnCount*100+100
+            self.addNode('Host', self.hostCount,
+                 float(x), float(currentY), name=name)
+            icon = self.findWidgetByName(name)
+            icon.bind('<Button-3>', self.do_hostPopup )
+            if columnCount == 9:
+                columnCount = 0
+                currentY = currentY + rowIncrement
+            else:
+                columnCount =columnCount+1
+
+        print 'links:'+str(len(topo.links()))
+        #[('h1', 's3'), ('h2', 's4'), ('s3', 's4')]
+        for link in topo.links():
+            print str(link)
+            srcNode = link[0]
+            src = self.findWidgetByName(srcNode)
+            sx, sy = self.canvas.coords( self.widgetToItem[ src ] )
+
+            destNode = link[1]
+            dest = self.findWidgetByName(destNode)
+            dx, dy = self.canvas.coords( self.widgetToItem[ dest]  )
+
+            params = topo.linkInfo( srcNode, destNode )
+            print 'Link Parameters='+str(params)
+
+            self.link = self.canvas.create_line( sx, sy, dx, dy, width=4,
+                                             fill='blue', tag='link' )
+            c.itemconfig(self.link, tags=c.gettags(self.link)+('data',))
+            self.addLink( src, dest, linkopts=params )
+            self.createDataLinkBindings()
+            self.link = self.linkWidget = None
+
+        importNet.stop()
+
+def miniEditImages():
+    "Create and return images for MiniEdit."
+
+    # Image data. Git will be unhappy. However, the alternative
+    # is to keep track of separate binary files, which is also
+    # unappealing.
+
+    return {
+        'Select': BitmapImage(
+            file='/usr/include/X11/bitmaps/left_ptr' ),
+
+        'LegacyRouter': PhotoImage( data=r"""
+            R0lGODlhMgAYAPcAAAEBAXZ8gQNAgL29vQNctjl/xVSa4j1dfCF+
+            3QFq1DmL3wJMmAMzZZW11dnZ2SFrtyNdmTSO6gIZMUKa8gJVqEOH
+            zR9Pf5W74wFjxgFx4jltn+np6Eyi+DuT6qKiohdtwwUPGWiq6ymF
+            4LHH3Rh11CV81kKT5AMoUA9dq1ap/mV0gxdXlytRdR1ptRNPjTt9
+            vwNgvwJZsX+69gsXJQFHjTtjizF0tvHx8VOm9z2V736Dhz2N3QM2
+            acPZ70qe8gFo0HS19wVRnTiR6hMpP0eP1i6J5iNlqAtgtktjfQFu
+            3TNxryx4xAMTIzOE1XqAh1uf5SWC4AcfNy1XgQJny93n8a2trRh3
+            12Gt+VGm/AQIDTmByAF37QJasydzvxM/ayF3zhdLf8zLywFdu4i5
+            6gFlyi2J4yV/1w8wUo2/8j+X8D2Q5Eee9jeR7Uia7DpeggFt2QNP
+            m97e3jRong9bpziH2DuT7aipqQoVICmG45vI9R5720eT4Q1hs1er
+            /yVVhwJJktPh70tfdbHP7Xev5xs5V7W1sz9jhz11rUVZcQ9WoCVV
+            hQk7cRdtwWuw9QYOFyFHbSBnr0dznxtWkS18zKfP9wwcLAMHCwFF
+            iS5UeqGtuRNNiwMfPS1hlQMtWRE5XzGM5yhxusLCwCljnwMdOFWh
+            7cve8pG/7Tlxp+Tr8g9bpXF3f0lheStrrYu13QEXLS1ppTV3uUuR
+            1RMjNTF3vU2X4TZupwRSolNne4nB+T+L2YGz4zJ/zYe99YGHjRdD
+            cT95sx09XQldsgMLEwMrVc/X3yN3yQ1JhTRbggsdMQNfu9HPz6Wl
+            pW2t7RctQ0GFyeHh4dvl8SBZklCb5kOO2kWR3Vmt/zdjkQIQHi90
+            uvPz8wIVKBp42SV5zbfT7wtXpStVfwFWrBVvyTt3swFz5kGBv2+1
+            /QlbrVFjdQM7d1+j54i67UmX51qn9i1vsy+D2TuR5zddhQsjOR1t
+            u0GV6ghbsDVZf4+76RRisent8Xd9hQFBgwFNmwJLlcPDwwFr1z2T
+            5yH5BAEAAAAALAAAAAAyABgABwj/AAEIHEiQYJY7Qwg9UsTplRIb
+            ENuxEiXJgpcz8e5YKsixY8Essh7JcbbOBwcOa1JOmJAmTY4cHeoI
+            abJrCShI0XyB8YRso0eOjoAdWpciBZajJ1GuWcnSZY46Ed5N8hPA
+            TqEBoRB9gVJsxRlhPwHI0kDkVywcRpGe9LF0adOnMpt8CxDnxg1o
+            9lphKoEACoIvmlxxvHOKVg0n/Tzku2WoVoU2J1P6WNkSrtwADuxC
+            G/MOjwgRUEIjGG3FhaOBzaThiDSCil27G8Isc3LLjZwXsA6YYJmD
+            jhTMmseoKQIFDx7RoxHo2abnwygAlUj1mV6tWjlelEpRwfd6gzI7
+            VeJQ/2vZoVaDUqigqftXpH0R46H9Kl++zUo4JnKq9dGvv09RHFhc
+            IUMe0NiFDyql0OJUHWywMc87TXRhhCRGiHAccvNZUR8JxpDTH38p
+            9HEUFhxgMSAvjbBjQge8PSXEC6uo0IsHA6gAAShmgCbffNtsQwIJ
+            ifhRHX/TpUUiSijlUk8AqgQixSwdNBjCa7CFoVggmEgCyRf01WcF
+            CYvYUgB104k4YlK5HONEXXfpokYdMrXRAzMhmNINNNzB9p0T57Ag
+            yZckpKKPGFNgw06ZWKR10jTw6MAmFWj4AJcQQkQQwSefvFeGCemM
+            IQggeaJywSQ/wgHOAmJskQEfWqBlFBEH1P/QaGY3QOpDZXA2+A6m
+            7hl3IRQKGDCIAj6iwE8yGKC6xbJv8IHNHgACQQybN2QiTi5NwdlB
+            pZdiisd7vyanByOJ7CMGGRhgwE+qyy47DhnBPLDLEzLIAEQjBtCh
+            RmVPNWgpr+Be+Nc9icARww9TkIEuDAsQ0O7DzGIQzD2QdDEJHTsI
+            AROc3F7qWQncyHPPHN5QQAAG/vjzw8oKp8sPPxDH3O44/kwBQzLB
+            xBCMOTzzHEMMBMBARgJvZJBBEm/4k0ACKydMBgwYoKNNEjJXbTXE
+            42Q9jtFIp8z0Dy1jQMA1AGziz9VoW7310V0znYDTGMQgwUDXLDBO
+            2nhvoTXbbyRk/XXL+pxWkAT8UJ331WsbnbTSK8MggDZhCTOMLQkc
+            jvXeSPedAAw0nABWWARZIgEDfyTzxt15Z53BG1PEcEknrvgEelhZ
+            MDHKCTwI8EcQFHBBAAFcgGPLHwLwcMIo12Qxu0ABAQA7
+            """),
+
+        'Host': PhotoImage( data=r"""
+            R0lGODlhIAAYAPcAMf//////zP//mf//Zv//M///AP/M///MzP/M
+            mf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9m
+            Zv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8A
+            M/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zM
+            AMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz
+            /8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/
+            zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZ
+            mZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkz
+            ZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/
+            M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZ
+            AGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA
+            /2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPM
+            zDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNm
+            mTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMA
+            ZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDM
+            MwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBm
+            AAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAM+4AAN0A
+            ALsAAKoAAIgAAHcAAFUAAEQAACIAABEAAADuAADdAAC7AACqAACI
+            AAB3AABVAABEAAAiAAARAAAA7gAA3QAAuwAAqgAAiAAAdwAAVQAA
+            RAAAIgAAEe7u7t3d3bu7u6qqqoiIiHd3d1VVVURERCIiIhEREQAA
+            ACH5BAEAAAAALAAAAAAgABgAAAiNAAH8G0iwoMGDCAcKTMiw4UBw
+            BPXVm0ixosWLFvVBHFjPoUeC9Tb+6/jRY0iQ/8iVbHiS40CVKxG2
+            HEkQZsyCM0mmvGkw50uePUV2tEnOZkyfQA8iTYpTKNOgKJ+C3AhO
+            p9SWVaVOfWj1KdauTL9q5UgVbFKsEjGqXVtP40NwcBnCjXtw7tx/
+            C8cSBBAQADs=
+        """ ),
+
+        'NetLink': PhotoImage( data=r"""
+            R0lGODlhFgAWAPcAMf//////zP//mf//Zv//M///AP/M///MzP/M
+            mf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9m
+            Zv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8A
+            M/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zM
+            AMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz
+            /8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/
+            zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZ
+            mZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkz
+            ZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/
+            M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZ
+            AGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA
+            /2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPM
+            zDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNm
+            mTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMA
+            ZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDM
+            MwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBm
+            AAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAM+4AAN0A
+            ALsAAKoAAIgAAHcAAFUAAEQAACIAABEAAADuAADdAAC7AACqAACI
+            AAB3AABVAABEAAAiAAARAAAA7gAA3QAAuwAAqgAAiAAAdwAAVQAA
+            RAAAIgAAEe7u7t3d3bu7u6qqqoiIiHd3d1VVVURERCIiIhEREQAA
+            ACH5BAEAAAAALAAAAAAWABYAAAhIAAEIHEiwoEGBrhIeXEgwoUKG
+            Cx0+hGhQoiuKBy1irChxY0GNHgeCDAlgZEiTHlFuVImRJUWXEGEy
+            lBmxI8mSNknm1Dnx5sCAADs=
+        """ )
+    }
+
+def addDictOption( opts, choicesDict, default, name, helpStr=None ):
+    """Convenience function to add choices dicts to OptionParser.
+       opts: OptionParser instance
+       choicesDict: dictionary of valid choices, must include default
+       default: default choice key
+       name: long option name
+       help: string"""
+    if default not in choicesDict:
+        raise Exception( 'Invalid  default %s for choices dict: %s' %
+                         ( default, name ) )
+    if not helpStr:
+        helpStr = ( '|'.join( sorted( choicesDict.keys() ) ) +
+                    '[,param=value...]' )
+    opts.add_option( '--' + name,
+                     type='string',
+                     default = default,
+                     help = helpStr )
+
+if __name__ == '__main__':
+    setLogLevel( 'info' )
+    app = MiniEdit()
+    """ import topology if specified """
+    app.parseArgs()
+    app.importTopo()
+
+    global isHostPopup
+    global isRouterPopup
+    global isLinkPopup
+
+    app.mainloop()
