diff --git a/bin/minindn b/bin/minindn
index 51a4c52..7e451aa 100755
--- a/bin/minindn
+++ b/bin/minindn
@@ -13,6 +13,7 @@
 import os.path, time
 import optparse
 import datetime
+from os.path import expanduser
 
 from ndn.nlsr import Nlsr, NlsrConfigGenerator
 
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()
