+    def ReadConfigurationFile(self):
+
+        self.auiConfigurations = {}
+        self.expansionState = [0, 1]
+
+        config = GetConfig()
+        val = config.Read('ExpansionState')
+        if val:
+            self.expansionState = eval(val)
+
+        val = config.Read('AUIPerspectives')
+        if val:
+            self.auiConfigurations = eval(val)
+        
+
+    def BuildMenuBar(self):
+
+        # Make a File menu
+        self.mainmenu = wx.MenuBar()
+        menu = wx.Menu()
+        item = menu.Append(-1, '&Redirect Output',
+                           'Redirect print statements to a window',
+                           wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU, self.OnToggleRedirect, item)
+ 
+        exitItem = wx.MenuItem(menu, -1, 'E&xit\tCtrl-Q', 'Get the heck outta here!')
+        exitItem.SetBitmap(images.catalog['exit'].getBitmap())
+        menu.AppendItem(exitItem)
+        self.Bind(wx.EVT_MENU, self.OnFileExit, exitItem)
+        wx.App.SetMacExitMenuItemId(exitItem.GetId())
+        self.mainmenu.Append(menu, '&File')
+
+        # Make a Demo menu
+        menu = wx.Menu()
+        for indx, item in enumerate(_treeList[:-1]):
+            menuItem = wx.MenuItem(menu, -1, item[0])
+            submenu = wx.Menu()
+            for childItem in item[1]:
+                mi = submenu.Append(-1, childItem)
+                self.Bind(wx.EVT_MENU, self.OnDemoMenu, mi)
+            menuItem.SetBitmap(images.catalog[_demoPngs[indx+1]].getBitmap())
+            menuItem.SetSubMenu(submenu)
+            menu.AppendItem(menuItem)
+        self.mainmenu.Append(menu, '&Demo')
+
+        # Make an Option menu
+        # If we've turned off floatable panels then this menu is not needed
+        if ALLOW_AUI_FLOATING:
+            menu = wx.Menu()
+            auiPerspectives = self.auiConfigurations.keys()
+            auiPerspectives.sort()
+            perspectivesMenu = wx.Menu()
+            item = wx.MenuItem(perspectivesMenu, -1, DEFAULT_PERSPECTIVE, "Load startup default perspective", wx.ITEM_RADIO)
+            self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item)
+            perspectivesMenu.AppendItem(item)
+            for indx, key in enumerate(auiPerspectives):
+                if key == DEFAULT_PERSPECTIVE:
+                    continue
+                item = wx.MenuItem(perspectivesMenu, -1, key, "Load user perspective %d"%indx, wx.ITEM_RADIO)
+                perspectivesMenu.AppendItem(item)
+                self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item)
+
+            menu.AppendMenu(wx.ID_ANY, "&AUI Perspectives", perspectivesMenu)
+            self.perspectives_menu = perspectivesMenu
+
+            item = wx.MenuItem(menu, -1, 'Save Perspective', 'Save AUI perspective')
+            item.SetBitmap(images.catalog['saveperspective'].getBitmap())
+            menu.AppendItem(item)
+            self.Bind(wx.EVT_MENU, self.OnSavePerspective, item)
+
+            item = wx.MenuItem(menu, -1, 'Delete Perspective', 'Delete AUI perspective')
+            item.SetBitmap(images.catalog['deleteperspective'].getBitmap())
+            menu.AppendItem(item)
+            self.Bind(wx.EVT_MENU, self.OnDeletePerspective, item)
+
+            menu.AppendSeparator()
+
+            item = wx.MenuItem(menu, -1, 'Restore Tree Expansion', 'Restore the initial tree expansion state')
+            item.SetBitmap(images.catalog['expansion'].getBitmap())
+            menu.AppendItem(item)
+            self.Bind(wx.EVT_MENU, self.OnTreeExpansion, item)
+
+            self.mainmenu.Append(menu, '&Options')
+        
+        # Make a Help menu
+        menu = wx.Menu()
+        findItem = wx.MenuItem(menu, -1, '&Find\tCtrl-F', 'Find in the Demo Code')
+        findItem.SetBitmap(images.catalog['find'].getBitmap())
+        findNextItem = wx.MenuItem(menu, -1, 'Find &Next\tF3', 'Find Next')
+        findNextItem.SetBitmap(images.catalog['findnext'].getBitmap())
+        menu.AppendItem(findItem)
+        menu.AppendItem(findNextItem)
+        menu.AppendSeparator()
+
+        shellItem = wx.MenuItem(menu, -1, 'Open Py&Shell Window\tF5',
+                                'An interactive interpreter window with the demo app and frame objects in the namesapce')
+        shellItem.SetBitmap(images.catalog['pyshell'].getBitmap())
+        menu.AppendItem(shellItem)
+        inspToolItem = wx.MenuItem(menu, -1, 'Open &Widget Inspector\tF6',
+                                   'A tool that lets you browse the live widgets and sizers in an application')
+        inspToolItem.SetBitmap(images.catalog['inspect'].getBitmap())
+        menu.AppendItem(inspToolItem)        
+        menu.AppendSeparator()
+        helpItem = menu.Append(-1, '&About wxPython Demo', 'wxPython RULES!!!')
+        wx.App.SetMacAboutMenuItemId(helpItem.GetId())
+
+        self.Bind(wx.EVT_MENU, self.OnOpenShellWindow, shellItem)
+        self.Bind(wx.EVT_MENU, self.OnOpenWidgetInspector, inspToolItem)
+        self.Bind(wx.EVT_MENU, self.OnHelpAbout, helpItem)
+        self.Bind(wx.EVT_MENU, self.OnHelpFind,  findItem)
+        self.Bind(wx.EVT_MENU, self.OnFindNext,  findNextItem)
+        self.Bind(wx.EVT_FIND, self.OnFind)
+        self.Bind(wx.EVT_FIND_NEXT, self.OnFind)
+        self.Bind(wx.EVT_FIND_CLOSE, self.OnFindClose)
+        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateFindItems, findItem)
+        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateFindItems, findNextItem)
+        self.mainmenu.Append(menu, '&Help')
+        self.SetMenuBar(self.mainmenu)
+
+        if False:
+            # This is another way to set Accelerators, in addition to
+            # using the '\t<key>' syntax in the menu items.
+            aTable = wx.AcceleratorTable([(wx.ACCEL_ALT,  ord('X'), exitItem.GetId()),
+                                          (wx.ACCEL_CTRL, ord('H'), helpItem.GetId()),
+                                          (wx.ACCEL_CTRL, ord('F'), findItem.GetId()),
+                                          (wx.ACCEL_NORMAL, wx.WXK_F3, findnextItem.GetId()),
+                                          (wx.ACCEL_NORMAL, wx.WXK_F9, shellItem.GetId()),
+                                          ])
+            self.SetAcceleratorTable(aTable)
+            
+
+    #---------------------------------------------    
+    def RecreateTree(self, evt=None):
+        # Catch the search type (name or content)
+        searchMenu = self.filter.GetMenu().GetMenuItems()
+        fullSearch = searchMenu[1].IsChecked()
+            
+        if evt:
+            if fullSearch:
+                # Do not`scan all the demo files for every char
+                # the user input, use wx.EVT_TEXT_ENTER instead
+                return
+
+        expansionState = self.tree.GetExpansionState()
+
+        current = None
+        item = self.tree.GetSelection()
+        if item:
+            prnt = self.tree.GetItemParent(item)
+            if prnt:
+                current = (self.tree.GetItemText(item),
+                           self.tree.GetItemText(prnt))
+                    
+        self.tree.Freeze()
+        self.tree.DeleteAllItems()
+        self.root = self.tree.AddRoot("wxPython Overview")
+        self.tree.SetItemImage(self.root, 0)
+        self.tree.SetItemPyData(self.root, 0)
+
+        treeFont = self.tree.GetFont()
+        catFont = self.tree.GetFont()
+
+        # The old native treectrl on MSW has a bug where it doesn't
+        # draw all of the text for an item if the font is larger than
+        # the default.  It seems to be clipping the item's label as if
+        # it was the size of the same label in the default font.
+        if 'wxMSW' not in wx.PlatformInfo or wx.GetApp().GetComCtl32Version() >= 600:
+            treeFont.SetPointSize(treeFont.GetPointSize()+2)
+            treeFont.SetWeight(wx.BOLD)
+            catFont.SetWeight(wx.BOLD)
+            
+        self.tree.SetItemFont(self.root, treeFont)
+        
+        firstChild = None
+        selectItem = None
+        filter = self.filter.GetValue()
+        count = 0
+        
+        for category, items in _treeList:
+            count += 1
+            if filter:
+                if fullSearch:
+                    items = self.searchItems[category]
+                else:
+                    items = [item for item in items if filter.lower() in item.lower()]
+            if items:
+                child = self.tree.AppendItem(self.root, category, image=count)
+                self.tree.SetItemFont(child, catFont)
+                self.tree.SetItemPyData(child, count)
+                if not firstChild: firstChild = child
+                for childItem in items:
+                    image = count
+                    if DoesModifiedExist(childItem):
+                        image = len(_demoPngs)
+                    theDemo = self.tree.AppendItem(child, childItem, image=image)
+                    self.tree.SetItemPyData(theDemo, count)
+                    self.treeMap[childItem] = theDemo
+                    if current and (childItem, category) == current:
+                        selectItem = theDemo
+                        
+                    
+        self.tree.Expand(self.root)
+        if firstChild:
+            self.tree.Expand(firstChild)
+        if filter:
+            self.tree.ExpandAll()
+        elif expansionState:
+            self.tree.SetExpansionState(expansionState)
+        if selectItem:
+            self.skipLoad = True
+            self.tree.SelectItem(selectItem)
+            self.skipLoad = False
+        
+        self.tree.Thaw()
+        self.searchItems = {}
+
+
+    def OnSearchMenu(self, event):
+
+        # Catch the search type (name or content)
+        searchMenu = self.filter.GetMenu().GetMenuItems()
+        fullSearch = searchMenu[1].IsChecked()
+        
+        if fullSearch:
+            self.OnSearch()
+        else:
+            self.RecreateTree()
+            
+
+    def OnSearch(self, event=None):
+
+        value = self.filter.GetValue()
+        if not value:
+            self.RecreateTree()
+            return
+
+        wx.BeginBusyCursor()
+        
+        for category, items in _treeList:
+            self.searchItems[category] = []
+            for childItem in items:
+                if SearchDemo(childItem, value):
+                    self.searchItems[category].append(childItem)
+
+        wx.EndBusyCursor()
+        self.RecreateTree()            
+
+
+    def SetTreeModified(self, modified):
+        item = self.tree.GetSelection()
+        if modified:
+            image = len(_demoPngs)
+        else:
+            image = self.tree.GetItemPyData(item)
+        self.tree.SetItemImage(item, image)
+        
+