Index: sasview/README.txt
===================================================================
--- sasview/README.txt	(revision 9533593bd68a5d03ddc7e4bfede0191634e13336)
+++ sasview/README.txt	(revision 40c69b31c6a5bf3b6cf8a44c498be9bb0de4d646)
@@ -255,9 +255,27 @@
 
    2.2- Installing from source
-        - Get the code from GitHub at https://github.com/SasView/sasview.git
-          for this release version use: https://github.com/SasView/sasview/releases
-          - run 'python setup.py install' under the 'sasview-x.x.x' folder
+        - Get the source code
+          - to follow the current development version from source control use
+              git clone https://github.com/SasView/sasview.git
+              git clone https://github.com/bumps/bumps.git
+	  - to install a specific version
+
+        - Build, install and run a specific release
+          - make sure the requirements below are already installed
+          - retrieve the source from https://github.com/SasView/sasview/releases
+          - open a command line window in the 'sasview-x.x.x' directory
+          - run 'python setup.py install'
           - run 'python sasview.py' under the 'sasview' folder.
-          
+
+        - Build, install and run the current development version
+          - clone the source from git; also clone bumps, which is developed in parallel
+              git clone https://github.com/SasView/sasview.git
+              git clone https://github.com/bumps/bumps.git
+          - open a command line window in the 'sasview' directory
+          - run 'python setup.py build'
+          - run 'python run.py'; this runs from the source directories, so you
+            don't have to rebuild every time you make a change, unless you are
+            changing the C++ model files
+
         - The following modules are required (version numbers are what are used
           in the windows release build):
Index: sasview/sasview.py
===================================================================
--- sasview/sasview.py	(revision 199bb42b1d8cc0dd3885c291e634d038962b5550)
+++ sasview/sasview.py	(revision 85130cb3582eef4c433e40ac08435fe6040abbf1)
@@ -69,8 +69,13 @@
 
 import wx
+
 try:
     logging.info("Wx version: %s" % wx.__version__)
 except:
     logging.error("Wx version: error reading version")
+
+import wxcruft
+wxcruft.call_later_fix()
+#wxcruft.trace_new_id()
 
 # The below will make sure that sasview application uses the matplotlib font
Index: sasview/wxcruft.py
===================================================================
--- sasview/wxcruft.py	(revision 6f16e25ca8391464dfcea6ba0d48d6b3702d148e)
+++ sasview/wxcruft.py	(revision 6f16e25ca8391464dfcea6ba0d48d6b3702d148e)
@@ -0,0 +1,165 @@
+import inspect
+import wx
+from wx import Timer
+import wx._misc
+
+def call_later_fix():
+    # TODO: test if we need the fix
+    wx.CallLater = CallLater
+    wx.FutureCall = FutureCall
+    wx.PyTimer = PyTimer
+
+def trace_new_id():
+    wx.NewId = NewId
+
+def NewId():
+    id = wx._misc.NewId()
+    path, line, function = _get_caller()
+    if path == "sas/guiframe/utils.py":
+        # Special case: NewId is being called via an IdList request; we
+        # want to which widget triggered the request, not that it was
+        # triggered via IdList.
+        path, line, function = _get_caller(2)
+        tag = " via IdList"
+    elif path.endswith("/wxcruft.py"):
+        # Special case: NewId is being called via CallLater; we want to
+        # know where the CallLater was invoked.
+        path, line, function = _get_caller(1)
+        tag = " via CallLater"
+    else:
+        tag = ""
+    print "NewId %d from %s(%d):%s%s"%(id, path, line, function, tag)
+    return id
+
+def _get_caller(distance=0):
+    frame = inspect.stack()[distance+2]
+    path = frame[1]
+    index = path.find('/sas/')
+    if index == -1: index = path.find('\\sas\\')
+    return path[index+1:], frame[2], frame[3]
+
+
+
+# ==========================================================================
+# Hacked versions of CallLater and PyTimer so that the main GUI loop doesn't
+# eat wx ids.
+# Changed lines are marked #PAK
+# ==========================================================================
+
+# For backwards compatibility with 2.4
+class PyTimer(Timer):
+    def __init__(self, notify, *args, **kw):  #PAK
+        Timer.__init__(self, *args, **kw)     #PAK
+        self.notify = notify
+
+    def Notify(self):
+        if self.notify:
+            self.notify()
+
+
+class CallLater:
+    """
+    A convenience class for `wx.Timer`, that calls the given callable
+    object once after the given amount of milliseconds, passing any
+    positional or keyword args.  The return value of the callable is
+    availbale after it has been run with the `GetResult` method.
+
+    If you don't need to get the return value or restart the timer
+    then there is no need to hold a reference to this object.
+
+    :see: `wx.CallAfter`
+    """
+
+    __RUNNING = set()
+
+    def __init__(self, millis, callableObj, *args, **kwargs):
+        # print "=================== entering CallLater constructor"
+        assert callable(callableObj), "callableObj is not callable"
+        self.millis = millis
+        self.callable = callableObj
+        self.SetArgs(*args, **kwargs)
+        self.runCount = 0
+        self.running = False
+        self.hasRun = False
+        self.result = None
+        self.timer = None
+        self.id = wx.NewId()  # PAK
+        self.Start()
+
+
+    def Start(self, millis=None, *args, **kwargs):
+        """
+        (Re)start the timer
+        """
+        self.hasRun = False
+        if millis is not None:
+            self.millis = millis
+        if args or kwargs:
+            self.SetArgs(*args, **kwargs)
+        self.Stop()
+        self.timer = PyTimer(self.Notify, id=self.id)  # PAK
+        self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
+        self.running = True
+        self.__RUNNING.add(self)
+    Restart = Start
+
+
+    def Stop(self):
+        """
+        Stop and destroy the timer.
+        """
+        if self.timer is not None:
+            self.timer.Stop()
+            self.timer = None
+        self.__RUNNING.discard(self)
+
+
+    def GetInterval(self):
+        if self.timer is not None:
+            return self.timer.GetInterval()
+        else:
+            return 0
+
+
+    def IsRunning(self):
+        return self.timer is not None and self.timer.IsRunning()
+
+
+    def SetArgs(self, *args, **kwargs):
+        """
+        (Re)set the args passed to the callable object.  This is
+        useful in conjunction with Restart if you want to schedule a
+        new call to the same callable object but with different
+        parameters.
+        """
+        self.args = args
+        self.kwargs = kwargs
+
+
+    def HasRun(self):
+        return self.hasRun
+
+
+    def GetResult(self):
+        return self.result
+
+
+    def Notify(self):
+        """
+        The timer has expired so call the callable.
+        """
+        if self.callable and getattr(self.callable, 'im_self', True):
+            self.runCount += 1
+            self.running = False
+            self.result = self.callable(*self.args, **self.kwargs)
+        self.hasRun = True
+        if not self.running:
+            # if it wasn't restarted, then cleanup
+            wx.CallAfter(self.Stop)
+
+    Interval = property(GetInterval)
+    Result = property(GetResult)
+
+
+class FutureCall(CallLater):
+    """A compatibility alias for `CallLater`."""
