diff --git a/packaging/windows/py2exeWalkthroughPython26.txt b/packaging/windows/py2exeWalkthroughPython26.txt
index 7ad865c0..2762699e 100644
--- a/packaging/windows/py2exeWalkthroughPython26.txt
+++ b/packaging/windows/py2exeWalkthroughPython26.txt
@@ -33,6 +33,7 @@ psycopg2 ... http://www.stickpeople.com/projects/python/win-psycopg/psycopg2-2.2
 (py)pokereval v138 ... http://sourceforge.net/projects/fpdb/files/fpdb/pypoker-eval-win32/pokereval-138.win32.exe/download
 (Note: There are no official windows builds, this installer is built from source.  A walkthrough is in the same directory as this walkthrough.
 
+
 1.2/ MySQL 
 
 Install the following file:
@@ -67,6 +68,26 @@ with this line:
 1.3.4/ Save and exit
 
 
+1.4/ Patch py2exe to stop popup runtime error message
+
+see http://www.py2exe.org/index.cgi/StderrLog for technical info.
+
+1.4.1/
+
+dos> write C:\Python26\Lib\site-packages\py2exe\boot_common.py
+
+replace:
+                    atexit.register(alert, 0,
+                                    "See the logfile '%s' for details" % fname,
+                                    "Errors occurred")
+with:
+                    #atexit.register(alert, 0,
+                    #                "See the logfile '%s' for details" % fname,
+                    #                "Errors occurred")
+
+1.4.2/ save and exit
+
+
 
 Step 2 Setup GTK
 -----------------
diff --git a/pyfpdb/GuiRingPlayerStats.py b/pyfpdb/GuiRingPlayerStats.py
index 86ba1aad..f061322e 100644
--- a/pyfpdb/GuiRingPlayerStats.py
+++ b/pyfpdb/GuiRingPlayerStats.py
@@ -58,7 +58,7 @@ onlinehelp = {'Game':_('Type of Game'),
               'Saw_F':_('% Saw Flop vs hands dealt'),
               'SawSD':_('Saw Show Down / River'),
               'WtSDwsF':_('Went To Show Down When Saw Flop'),
-              'W$SD':_('Amount Won when Show Down seen'),
+              'W$SD':_('% Won some money at showdown'),
               'FlAFq':_('Flop Aggression\n% Bet or Raise after seeing Flop'),
               'TuAFq':_('Turn Aggression\n% Bet or Raise after seeing Turn'),
               'RvAFq':_('River Aggression\n% Bet or Raise after seeing River'),
diff --git a/pyfpdb/RushNotesAux.py b/pyfpdb/RushNotesAux.py
new file mode 100644
index 00000000..312de6d5
--- /dev/null
+++ b/pyfpdb/RushNotesAux.py
@@ -0,0 +1,333 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""RushNotesAux.py
+
+            EXPERIMENTAL - USE WITH CARE
+            
+Auxilliary process to push HUD data into the FullTilt player notes XML
+This will allow a rudimentary "HUD" in rush games
+
+The existing notes file will be altered by this function
+"""
+#    Copyright 2010,  "Gimick" of the FPDB project  fpdb.sourceforge.net
+#
+#This program is free software: you can redistribute it and/or modify
+#it under the terms of the GNU Affero General Public License as published by
+#the Free Software Foundation, version 3 of the License.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU Affero General Public License
+#along with this program. If not, see .
+#In the "official" distribution you can find the license in agpl-3.0.txt.
+
+########################################################################
+
+##########for each hand processed, attempts to create update for player notes in FullTilt
+##########based upon the AW howto notes written by Ray E. Barker (nutomatic) at fpdb.sourceforge.net
+##########Huge thanks to Ray for his guidance and encouragement to create this !!
+
+#
+#debugmode will write logfiles for the __init__ and update_data methods
+# writes into ./pyfpdb/~Rushdebug.*
+#
+debugmode = False
+
+#    Standard Library modules
+import os
+import sys
+from xml.dom import minidom 
+from datetime import datetime
+from time import *
+
+#    FreePokerDatabase modules
+from Mucked import Aux_Window
+from Mucked import Seat_Window
+from Mucked import Aux_Seats
+import Stats
+import Card
+
+#
+# overload minidom methods to fix bug where \n is parsed as " ".
+# described here: http://bugs.python.org/issue7139
+#
+
+def _write_data(writer, data, isAttrib=False):
+    "Writes datachars to writer."
+    if isAttrib:
+        data = data.replace("\r", "
").replace("\n", "
")
+        data = data.replace("\t", "	")
+    writer.write(data)
+minidom._write_data = _write_data
+
+def writexml(self, writer, indent="", addindent="", newl=""):
+    # indent = current indentation
+    # addindent = indentation to add to higher levels
+    # newl = newline string
+    writer.write(indent+"<" + self.tagName)
+
+    attrs = self._get_attributes()
+    a_names = attrs.keys()
+    a_names.sort()
+
+    for a_name in a_names:
+        writer.write(" %s=\"" % a_name)
+        _write_data(writer, attrs[a_name].value, isAttrib=True)
+        writer.write("\"")
+    if self.childNodes:
+        writer.write(">%s"%(newl))
+        for node in self.childNodes:
+            node.writexml(writer,indent+addindent,addindent,newl)
+        writer.write("%s%s>%s" % (indent,self.tagName,newl))
+    else:
+        writer.write("/>%s"%(newl))
+# For an introduction to overriding instance methods, see
+#   http://irrepupavel.com/documents/python/instancemethod/
+instancemethod = type(minidom.Element.writexml)
+minidom.Element.writexml = instancemethod(
+    writexml, None, minidom.Element)
+
+
+
+class RushNotes(Aux_Window):
+
+    def __init__(self, hud, config, params):
+
+        self.hud = hud
+        self.config = config
+        
+        #
+        # following line makes all the site params magically available (thanks Ray!)        
+        #
+        site_params_dict = self.hud.config.get_site_parameters(self.hud.site)
+        
+        heroname = site_params_dict['screen_name']
+        sitename = site_params_dict['site_name']
+        notepath = site_params_dict['site_path']  # this is a temporary hijack of site-path
+        self.heroid = self.hud.db_connection.get_player_id(self.config, sitename, heroname)
+        self.notefile = notepath + "/" + heroname + ".xml"
+        self.rushtables = ("Mach 10", "Lightning", "Celerity", "Flash", "Zoom")
+
+        if not os.path.isfile(self.notefile):
+            self.active = False
+            return
+        else:
+            self.active = True
+
+        #
+        # read in existing notefile and backup with date/time in name
+        # todo change to not use dom
+        #
+        now = datetime.now()
+        notefilebackup = self.notefile + ".backup." + now.strftime("%Y%m%d%H%M%S")
+        xmlnotefile = minidom.parse(self.notefile)        
+        outputfile = open(notefilebackup, 'w')
+        xmlnotefile.writexml(outputfile)
+        outputfile.close()
+        xmlnotefile.unlink
+
+        #
+        # Create a fresh queue file with skeleton XML
+        #
+        self.queuefile = self.notefile + ".queue"
+        queuedom = minidom.Document()
+
+        pld=queuedom.createElement("PLAYERDATA")
+        queuedom.appendChild(pld)
+
+        nts=queuedom.createElement("NOTES")
+        pld.appendChild(nts)
+
+        nte = queuedom.createElement("NOTE")
+        nte = queuedom.createTextNode("\n")
+        nts.insertBefore(nte,None)
+
+        outputfile = open(self.queuefile, 'w')
+        queuedom.writexml(outputfile)
+        outputfile.close()
+        queuedom.unlink
+
+        if (debugmode):
+            #initialise logfiles
+            debugfile=open("~Rushdebug.init", "w")
+            debugfile.write("conf="+str(config)+"\n")
+            debugfile.write("spdi="+str(site_params_dict)+"\n")
+            debugfile.write("para="+str(params)+"\n")
+            debugfile.write("hero="+heroname+" "+str(self.heroid)+"\n")
+            debugfile.write("back="+notefilebackup+"\n")
+            debugfile.write("queu="+self.queuefile+"\n")
+            debugfile.close()
+
+            open("~Rushdebug.data", "w").close()
+
+
+    def update_data(self, new_hand_id, db_connection):
+        #this method called once for every hand processed
+        # self.hud.stat_dict contains the stats information for this hand
+
+        if not self.active:
+            return
+
+        if (debugmode):
+            debugfile=open("~Rushdebug.data", "a")
+            debugfile.write(new_hand_id+"\n")
+            now = datetime.now()
+            debugfile.write(now.strftime("%Y%m%d%H%M%S")+ " update_data begins"+ "\n")
+            debugfile.write("hero="+str(self.heroid)+"\n")
+            #debugfile.write(str(self.hud.stat_dict)+"\n")
+            debugfile.write("table="+self.hud.table.name+"\n")
+            debugfile.write("players="+str(self.hud.stat_dict.keys())+"\n")
+            debugfile.write("db="+str(db_connection)+"\n")
+
+        if self.hud.table.name not in self.rushtables:
+            return
+        #
+        # Grab a list of player id's
+        #
+        handplayers = self.hud.stat_dict.keys()  
+
+        #
+        # build a dictionary of stats text for each player in the hand (excluding the hero)
+        # xmlqueuedict contains {playername : stats text}
+        #
+        xmlqueuedict = {}
+        for playerid in handplayers:
+            # ignore hero, no notes available for hero at Full Tilt
+            if playerid == self.heroid: continue
+
+            playername=unicode(str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'playername')[1]))
+            # Use index[3] which is a short description
+            n=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'n')[3] + " ")
+            vpip=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'vpip')[3] + " ")
+            pfr=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'pfr')[3] + " ")
+            three_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'three_B')[3] + " ")
+            cbet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'cbet')[3] + " ")
+            fbbsteal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_BB_steal')[3] + " ")
+
+            steal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'steal')[3] + " ")
+            ffreq1=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'ffreq1')[3] + " ")
+            agg_freq=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'agg_freq')[3] + " ")
+            BBper100=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'BBper100')[3])
+            if BBper100[6] == "-": BBper100=BBper100[0:6] + "(" + BBper100[7:] + ")"
+
+
+            #
+            # grab villain known starting hands
+            # only those where they VPIP'd, so limp in the BB will not be shown
+            # sort by hand strength.  Output will show position too,
+            #  so KK.1 is KK from late posn etc.
+            # ignore non-rush hands (check against known rushtablenames)
+            #  cards decoding is hard-coded for holdem, so that's tuff atm
+            # three categories of known hands are shown:
+            #    agression preflop hands
+            #    non-aggression preflop hands
+            #    bigblind called to defend hands
+            #
+            # This isn't perfect, but it isn't too bad a starting point
+            #
+
+            PFcall="PFcall"
+            PFaggr="PFaggr"
+            PFdefend="PFdefend"
+
+            c = db_connection.get_cursor()
+            c.execute(("SELECT handId, position, startCards, street0Aggr, tableName " +
+                        "FROM hands, handsPlayers " +
+                        "WHERE handsplayers.handId = hands.id " +
+                        "AND street0VPI = 1 " +
+                        "AND startCards > 0 " +
+                        "AND playerId = %d " +
+                        "ORDER BY startCards DESC " +
+                        ";")
+                         % int(playerid))
+
+            for (qid, qposition, qstartcards, qstreet0Aggr, qtablename) in c.fetchall():
+                if (debugmode):
+                    debugfile.write("pid, hid, pos, cards, aggr, table player"+
+                                    str(playerid)+"/"+str(qid)+"/"+str(qposition)+"/"+
+                                    str(qstartcards)+"/"+str(qstreet0Aggr)+"/"+
+                                    str(qtablename)+"/"+str(playername)+
+                                    "\n")
+
+                humancards = Card.decodeStartHandValue("holdem", qstartcards)
+                
+                if qtablename not in self.rushtables:
+                    pass
+                elif qposition == "B" and qstreet0Aggr == False:
+                    PFdefend=PFdefend+"/"+humancards
+                elif qstreet0Aggr == True:
+                    PFaggr=PFaggr+"/"+humancards+"."+qposition
+                else:
+                    PFcall=PFcall+"/"+humancards+"."+qposition
+            c.close
+
+            #
+            # build up final text package (top/tail with ~fpdb~ ~ends~
+            # for later search/replace by Merge module
+            #
+            xmlqueuedict[playername] = ("~fpdb~" + "\n" +
+                                        n + vpip + pfr + three_B + fbbsteal + "\n" +
+                                        steal + cbet + ffreq1 + "\n" +
+                                        agg_freq + BBper100 + "\n" +
+                                        PFcall+"\n"+PFaggr+"\n"+PFdefend +"\n"
+                                        "~ends~")
+
+        if (debugmode):
+            now = datetime.now()
+            debugfile.write(now.strftime("%Y%m%d%H%M%S")+" villain data has been processed" + "\n")
+            debugfile.write(str(xmlqueuedict)+"\n")
+
+        #
+        # delaying processing of xml until now.  Grab current queuefile contents and
+        # read each existing NOTE element in turn, if matched to a player in xmlqueuedict
+        # update their text in the xml and delete the dictionary item
+        # 
+        xmlnotefile = minidom.parse(self.queuefile)
+        notelist = xmlnotefile.getElementsByTagName('NOTE')
+        
+        for noteentry in notelist:                              #for each note in turn
+            noteplayer = noteentry.getAttribute("PlayerId")     #extract the playername from xml
+            if noteplayer in xmlqueuedict:                      # does that player exist in the queue?
+                noteentry.setAttribute("Text",xmlqueuedict[noteplayer])
+                del xmlqueuedict[noteplayer]                    #remove from list, does not need to be added later on
+
+        #
+        #create entries for new players (those remaining in the dictionary)
+        #
+        if len(xmlqueuedict) > 0:
+            playerdata=xmlnotefile.lastChild #move to the PLAYERDATA node (assume last one in the list)
+            notesnode=playerdata.childNodes[0] #Find NOTES node 
+
+            for newplayer in xmlqueuedict:
+                newentry = xmlnotefile.createElement("NOTE")
+                newentry.setAttribute("PlayerId", newplayer)
+                newentry.setAttribute("Text", xmlqueuedict[newplayer])
+                notesnode.insertBefore(newentry,None)
+                newentry = xmlnotefile.createTextNode("\n")
+                notesnode.insertBefore(newentry,None)
+
+        if (debugmode):
+            now = datetime.now()
+            debugfile.write(now.strftime("%Y%m%d%H%M%S")+" xml pre-processing complete"+ "\n")
+
+        #
+        # OverWrite existing xml file with updated DOM and cleanup
+        #
+        updatednotes = open(self.queuefile, 'w')
+        xmlnotefile.writexml(updatednotes)
+        updatednotes.close()
+
+        xmlnotefile.unlink
+
+        if (debugmode):
+            now = datetime.now()
+            debugfile.write(now.strftime("%Y%m%d%H%M%S")+" dom written, process finished"+ "\n")
+            debugfile.close()
+
+
+
+
+
diff --git a/pyfpdb/RushNotesMerge.py b/pyfpdb/RushNotesMerge.py
new file mode 100755
index 00000000..7bfec3df
--- /dev/null
+++ b/pyfpdb/RushNotesMerge.py
@@ -0,0 +1,183 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""RushNotesMerge.py
+
+            EXPERIMENTAL - USE WITH CARE
+
+Merge .queue file with hero's note to generate fresh .merge file
+
+normal usage 
+$> ./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/heroname.xml"
+
+The generated file can then replace heroname.xml (if all is well).
+
+
+"""
+#    Copyright 2010,  "Gimick" of the FPDB project  fpdb.sourceforge.net
+#
+#This program is free software: you can redistribute it and/or modify
+#it under the terms of the GNU Affero General Public License as published by
+#the Free Software Foundation, version 3 of the License.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU Affero General Public License
+#along with this program. If not, see .
+#In the "official" distribution you can find the license in agpl-3.0.txt.
+
+########################################################################
+
+
+#    Standard Library modules
+import os
+import sys
+from xml.dom import minidom 
+
+#
+# overload minidom methods to fix bug where \n is parsed as " ".
+# described here: http://bugs.python.org/issue7139
+#
+
+def _write_data(writer, data, isAttrib=False):
+    "Writes datachars to writer."
+    if isAttrib:
+        data = data.replace("\r", "
").replace("\n", "
")
+        data = data.replace("\t", "	")
+    writer.write(data)
+minidom._write_data = _write_data
+
+def writexml(self, writer, indent="", addindent="", newl=""):
+    # indent = current indentation
+    # addindent = indentation to add to higher levels
+    # newl = newline string
+    writer.write(indent+"<" + self.tagName)
+
+    attrs = self._get_attributes()
+    a_names = attrs.keys()
+    a_names.sort()
+
+    for a_name in a_names:
+        writer.write(" %s=\"" % a_name)
+        _write_data(writer, attrs[a_name].value, isAttrib=True)
+        writer.write("\"")
+    if self.childNodes:
+        writer.write(">%s"%(newl))
+        for node in self.childNodes:
+            node.writexml(writer,indent+addindent,addindent,newl)
+        writer.write("%s%s>%s" % (indent,self.tagName,newl))
+    else:
+        writer.write("/>%s"%(newl))
+# For an introduction to overriding instance methods, see
+#   http://irrepupavel.com/documents/python/instancemethod/
+instancemethod = type(minidom.Element.writexml)
+minidom.Element.writexml = instancemethod(
+    writexml, None, minidom.Element)
+
+
+
+statqueue=0
+statupdated=0
+statadded=0
+
+def cleannote(textin):
+    if textin.find("~fpdb~") == -1: return textin
+    if textin.find("~ends~") == -1: return textin
+    if textin.find("~fpdb~") > textin.find("~ends~"): return textin
+    return textin[0:textin.find("~fpdb~")] + textin[textin.find("~ends~")+6:]
+# get out now if parameter not passed
+try: 
+    sys.argv[1] <> ""
+except: 
+    print "A parameter is required, quitting now"
+    print "normal usage is something like:"
+    print '$> ./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myhero.xml"'
+    quit()
+
+if not os.path.isfile(sys.argv[1]):
+    print "Hero notes file not found, quitting"
+    print "normal usage is something like:"
+    print '$> ./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myhero.xml"'
+    quit()
+
+if not os.path.isfile((sys.argv[1]+".queue")):
+    print "Nothing found to merge, quitting"
+    print "Did the HUD not get started during the last session?"
+    print "Has the HUD been stopped and started without merging?"
+    quit()
+
+print "***************************************************************"
+print "IMPORTANT: *** Before running this merge: ***"
+print "Closedown the FullTiltClient and wait for it to completely stop"
+print "If FullTiltClient was running, run the merge again once it"
+print "has stopped completely"
+print "***************************************************************"
+print
+print "read from: ", sys.argv[1]
+print "merge with: ", sys.argv[1]+".queue"
+
+#read queue and turn into a dict
+queuedict = {}
+xmlqueue = minidom.parse(sys.argv[1]+".queue")
+notelist = xmlqueue.getElementsByTagName('NOTE')
+        
+for noteentry in notelist:                            
+    noteplayer = noteentry.getAttribute("PlayerId")  
+    notetext = noteentry.getAttribute("Text")
+    queuedict[noteplayer] = notetext  
+    statqueue = statqueue + 1
+
+#read existing player note file
+
+xmlnotefile = minidom.parse(sys.argv[1])
+notelist = xmlnotefile.getElementsByTagName('NOTE')
+
+#
+#for existing players, empty out existing fpdbtext and refill
+#        
+for noteentry in notelist: 
+    noteplayer = noteentry.getAttribute("PlayerId")
+    if noteplayer in queuedict:        
+        existingnote = noteentry.getAttribute("Text")
+        newnote=cleannote(existingnote)
+        newnote = newnote + queuedict[noteplayer]
+        noteentry.setAttribute("Text",newnote)
+        statupdated = statupdated + 1
+        del queuedict[noteplayer]                  
+
+#
+#create entries for new players (those remaining in the dictionary)
+#
+if len(queuedict) > 0:
+    playerdata=xmlnotefile.lastChild #move to the PLAYERDATA node (assume last one in the list)
+    notesnode=playerdata.childNodes[1] #Find NOTES node 
+
+for newplayer in queuedict:
+    newentry = xmlnotefile.createElement("NOTE")
+    newentry.setAttribute("PlayerId", newplayer)
+    newentry.setAttribute("Text", queuedict[newplayer])              
+    notesnode.insertBefore(newentry,None)
+    newentry = xmlnotefile.createTextNode("\n")
+    notesnode.insertBefore(newentry,None)
+    statadded=statadded+1
+                
+#print xmlnotefile.toprettyxml()
+
+mergednotes = open(sys.argv[1]+".merged", 'w')
+xmlnotefile.writexml(mergednotes)
+mergednotes.close()
+
+xmlnotefile.unlink
+
+print "Merged file has been written to: ", sys.argv[1]+".merged"
+print ""
+print "number in queue: ", statqueue
+print "existing players updated: ", statupdated
+print "new players added: ", statadded
+print "\n"
+print "Use a viewer to check the contents of the merge file."
+print "If you are happy, carry out the following steps:"
+print "1 Rename or delete the existing notes file (normally .xml"
+print "2 Rename the .merged file to become the new notes file"
diff --git a/pyfpdb/RushNotesReadMe.txt b/pyfpdb/RushNotesReadMe.txt
new file mode 100644
index 00000000..43475536
--- /dev/null
+++ b/pyfpdb/RushNotesReadMe.txt
@@ -0,0 +1,194 @@
+aux to write fpdb data to player notes on Full Tilt
+---------------------------------------------------
+
+by Gimick 30th Dec 2010
+
+RushNotesAux - auxillary processed attached to the full tilt hud 
+                builds up fpdb notes "queue" for each villain met while the autoimport is running
+                uses HUD aggregation stats to do this
+
+RushNotesMerge - stand alone process to merge the existing ftp notes, together with queue
+                 produced by Aux.
+                the output file can then be renamed to become the new ftp notes file
+
+Important info:
+The Merge process can only be run when ftp client is shutdown
+ - otherwise ftp overwrites the xml on exit.
+
+Restarting the autoimport will empty the notes"queue" so avoid restarting
+ autoimport until the previous notes "queue" has been merged.  You will
+ lose all the queued notes, but these will be regenerated the next time
+ the villian is at your table, so it isn't the end of the world.
+
+Existing ftp notes _SHOULD_ be preserved, but this isn't guaranteed, 
+ you have been warned!
+ 
+Existing colour codings should be preserved, 
+ this process does not change or set colourcodings.
+
+Copies of the live ftp notes file should be preserved everytime
+  RushNotesAux (i.e. the HUD is started)
+
+The AW is hard-coded with just the table names of Micro Rush Poker, 
+  and should ignore all other hands.
+
+What might not work?
+--------------------
+
+This isn't tested with Windows, and probably won't work, feedback welcome.
+Hasn't been tested for co-existance with other sites, feedback welcome.
+Whenever FTP change their notes file format, this will all break rather spectacularly,
+    you have been warned!
+    
+Getting started:
+---------------
+
+1. Set the Hero aggregation to alltime.  hero_stat_range="A" 
+ This overcomes a sqlite "bug" which has nothing to do with auxillary windows
+  not doing this will slow processing down to about 1 hand per minute.
+
+2. Set the site_path to be the folder containing the FTP notes xml file
+(on wine this is normally site_path="/home/blah/.wine/Program Files/Full Tilt Poker/")
+
+
+Wire-up the aux process:
+-----------------------
+
+ 
+
+
+or whatever works for you.
+
+
+Play some poker
+---------------
+
+Start Autoimport, and rearrange the on-screen stats out of the way
+    (the full HUD must run, killing the HUD kills the AW updates)
+
+Play whatever you want
+
+Stop the autoimport
+
+Exit the Full tilt poker client (ensure it has fully stopped with ps -A)
+
+execute the following:
+
+./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myname.xml"
+
+A revised notes file (blah.merge) should automagically appear in the full tilt root directory.
+If you are happy with it, replace the existing (myname.xml file)
+
+
+Since the updates aren't real time, it would be ok to play the rush
+    session with fpdb inactive, but before quitting any of the tables, 
+    start the HUD and wait for it to catch-up processing all the hands played.
+
+
+Summary
+-------
+
+This is very rough and ready, but it does what I set-out to achieve.  
+
+All feedback welcome, and if this is useful as a basis for general notes
+ processing in future, then thats great.
+
+As I find bugs and make improvements, I will push to git.
+
+
+Much more information below:
+----------------------------
+
+Background
+----------
+
+When playing rush poker, some sort of rudimentary HUD would answer simple questions 
+like "is this allin overbet being made by a nit, or a maniac".  Although some 
+notes may have been made previously, some statistics would help to backup the decision.
+
+Currently fpdb cannot support rush because the HUD is always 1 hand or more 
+behind the current action.
+
+The only way to do this at the moment is to switch to GuiPlayerStats and make a quick 
+enquiry by player name.  However, this effectively times you out of all other 
+action if multitabling.
+
+Full Tilt situation
+-------------------
+
+Full Tilt notes are stored in xml format ("hero.xml").  Previously these could 
+be updated while the game was in progress, however, FullTilt now cache the
+notes and write them out when the application exits.  This makes it impossible
+to use the notes as a real-time HUD, and therefore real-time huds are now
+forced to screen-scrape or poke around in the client memory.
+
+Accepting this a limitation, this implementation updates the notes only once
+the FullTilt client has been closed.  Obviously, the villain HUD stats are only
+as at the end of the last session, however, it is hoped this is significantly
+better than having nothing at all.  As the hero's hand history increases, the
+notes should progressively mature in accuracy.
+
+Preamble
+--------
+
+Note that this implementation was written purely to be "good enough" to work
+for the author, and is not intended as package or production quality.  It 
+is contributed as a starting point for others, or for experimental use.
+
+Thanks to Ray Barker who gave a great deal of help throughout.
+
+
+The implementation
+-------------------
+
+RushNotesAux is an fpdb auxilliary process, and is called for every hand
+processed by autoimport.  Each villain has a note prepared based on the current
+fpdb data, and this note (in XML format) is stored in a queue file.
+
+Auxilliary windows were chosen because 
+a) the author has limited fpdb and programming skill
+b) the auxillary windows handler is well documented and supported
+c) any code created has access to the full range of stats with little or no extra work
+d) runs within the HUD, so the aggregation parameters are already available
+
+
+Limitations
+-----------
+
+The notes are only regenerated if a hand is played against the villain.  The 
+process does not "bulk load" notes based upon all the player stats in FPDB.
+
+It is hoped that due to the relatively large hand volume and relatively small
+ player pools, this limitation will be largely overcome after a few sessions
+although there will obviously be a number of players with no fpdb note. 
+
+The aggregation parameters used for the notes are based upon the HUD parameters.
+ (with the exception of the hand-ranges, which uses its' own criteria (see source)
+
+Stopping and starting the HUD will erase the previously created notes queue file.
+
+The HUD must run, so the individual player popups need to be manually relocated.
+
+Although hard-coded for micro RUSH tablenames, the auxilliary window  could
+probably happily update notes of all cash and tournament players.
+
+Process overview
+----------------
+
+1/ The HUD process is started.  
+1.1/ when the first hand is received, h fresh holding file is created, and 
+a copy of the current live xml note file is created as a security backup.
+2/ For every hand played, the auxillary window is called
+3/ Based upon the players in the hand, fpdb will be interrogated
+and key stats are formatted in xml-style and written out to a holding file.
+4/ At the end of the session, the HUD is stopped and the poker client closed
+
+5/ The user can then review the contents of the holding file.
+6/ A process is begun to "merge" the holding file into the existing player notes
+7/ A new "merged" file is created.  The process attempts to preserve any
+existing notes, but this cannot be guaranteed.
+8/ The user can review this merged file, and if they are happy, 
+they replace the existing note file.
+9/ Note that this process never updates the live notes file in situ, but
+there is a risk that something goes wrong, and that existing notes could be destroyed.
+