Index: issm/trunk-jpl/src/m/classes/toolkits.py
===================================================================
--- issm/trunk-jpl/src/m/classes/toolkits.py	(revision 27427)
+++ issm/trunk-jpl/src/m/classes/toolkits.py	(revision 27458)
@@ -1,12 +1,12 @@
+from fielddisplay import fielddisplay
+from iluasmoptions import iluasmoptions
 from IssmConfig import IssmConfig
-from mumpsoptions import mumpsoptions
-from iluasmoptions import iluasmoptions
-from fielddisplay import fielddisplay
 from issmgslsolver import issmgslsolver
 from issmmumpssolver import issmmumpssolver
+from mumpsoptions import mumpsoptions
 
 
 class toolkits(object):
-    """TOOLKITS class definition
+    """toolkits class definition
 
     Usage:
@@ -14,5 +14,48 @@
     """
 
-    def __init__(self): #{{{
+    def __init__(self, *args):  # {{{
+        self.DefaultAnalysis = None
+        self.RecoveryAnalysis = None
+
+        nargs = len(args)
+        if nargs == 0:
+            self.setdefaultparameters()
+        elif nargs == 1:
+            # TODO: Replace the following with constructor
+            self.setdefaultparameters()
+        else:
+            raise Exception('constructor not supported')
+    # }}}
+
+    def __repr__(self):  # {{{
+        s = "List of toolkits options per analysis:\n\n"
+        for analysis in list(vars(self).keys()):
+            s += "{}\n".format(fielddisplay(self, analysis, ''))
+
+        return s
+    # }}}
+
+    def addoptions(self, analysis, *args):  # {{{
+        """addoptions - add analysis to md.toolkits.analysis
+
+        Optional third parameter adds toolkits options to analysis.
+        
+        Usage:
+            md.toolkits = addoptions(md.toolkits, 'StressbalanceAnalysis', FSoptions())
+            md.toolkits = addoptions(md.toolkits, 'StressbalanceAnalysis')
+        """
+
+        # Create dynamic property if property does not exist yet
+        if not hasattr(self, analysis):
+            setattr(self, analysis, None)
+
+        # Add toolkits options to analysis
+        if len(args) == 1:
+            setattr(self, analysis, args[0])
+
+        return self
+    # }}}
+
+    def setdefaultparameters(self):  # {{{
         # Default toolkits
         if IssmConfig('_HAVE_PETSC_')[0]:
@@ -28,52 +71,53 @@
                 self.DefaultAnalysis = issmgslsolver()
             else:
-                raise IOError("ToolkitsFile error: need at least Mumps or Gsl to define issm solver type")
+                raise IOError('ToolkitsFile error: need at least MUMPS or GSL to define ISSM solver type, no default solver assigned')
 
         # Use same solver for Recovery mode
         self.RecoveryAnalysis = self.DefaultAnalysis
 
-        # The other properties are dynamic
-    #}}}
+        return self
+    # }}}
 
-    def __repr__(self): #{{{
-        s = "List of toolkits options per analysis:\n\n"
-        for analysis in list(vars(self).keys()):
-            s += "{}\n".format(fielddisplay(self, analysis, ''))
+    def checkconsistency(self, md, solution, analyses):  # {{{
+        supported_analyses = [
+            'DefaultAnalysis',
+            'RecoveryAnalysis',
+            'StressbalanceAnalysis',
+            'GLheightadvectionAnalysis',
+            'MasstransportAnalysis',
+            'ThermalAnalysis',
+            'EnthalpyAnalysis',
+            'AdjointBalancethicknessAnalysis',
+            'BalancethicknessAnalysis',
+            'Balancethickness2Analysis',
+            'BalancethicknessSoftAnalysis',
+            'BalancevelocityAnalysis',
+            'DamageEvolutionAnalysis',
+            'LoveAnalysis',
+            'EsaAnalysis',
+            'SealevelchangeAnalysis',
+            'FreeSurfaceBaseAnalysis',
+            'FreeSurfaceTopAnalysis',
+            'LevelsetAnalysis',
+            'DebrisAnalysis',
+            'L2ProjectionBaseAnalysis',
+            'ExtrudeFromBaseAnalysis',
+            'ExtrudeFromTopAnalysis'
+        ]
+        analyses = list(vars(self).keys())
+        for analysis in analyses:
+            if analysis not in supported_analyses:
+                md.checkmessage('md.toolkits.{} not supported yet'.format(analysis))
 
-        return s
-    #}}}
-
-    def addoptions(self, analysis, *args): #{{{
-        # Usage example:
-        #    md.toolkits = addoptions(md.toolkits, 'StressbalanceAnalysis', FSoptions())
-        #    md.toolkits = addoptions(md.toolkits, 'StressbalanceAnalysis')
-
-        # Create dynamic property if property does not exist yet
-        if not hasattr(self, analysis):
-            setattr(self, analysis, None)
-
-        # Add toolkits options to analysis
-        if len(args) == 1:
-            setattr(self, analysis, args[0])
-
-        return self
-    #}}}
-
-    def checkconsistency(self, md, solution, analyses): #{{{
-        # TODO:
-        # - Implement something closer to a switch as in 
-        # src/m/classes/toolkits.m?
-        #
-        for analysis in list(vars(self).keys()):
             if not getattr(self, analysis):
-                md.checkmessage("md.toolkits.{} is empty".format(analysis))
+                md.checkmessage('md.toolkits.{} is empty'.format(analysis))
 
         return md
-    #}}}
+    # }}}
 
-    def ToolkitsFile(self, filename): #{{{
-        """TOOLKITSFILE - build toolkits file
+    def ToolkitsFile(self, filename):  # {{{
+        """ToolkitsFile - build toolkits file
 
-        Build a PETSc compatible options file, from the toolkits model field + return options string.
+        Build a PETSc compatible options file, from the toolkits model field and return options string.
         This file will also be used when the toolkit used is 'issm' instead of 'petsc'.
 
@@ -86,8 +130,8 @@
             fid = open(filename, 'w')
         except IOError as e:
-            raise IOError("ToolkitsFile error: could not open {}' for writing due to".format(filename), e)
+            raise IOError('ToolkitsFile error: could not open {} for writing due to {}'.format(filename), e)
 
         # Write header
-        fid.write("%s%s%s\n" % ('%Toolkits options file: ', filename, ' written from Python toolkits array'))
+        fid.write('{}{}{}\n'.format('%Toolkits options file: ', filename, ' written from Python toolkits array'))
 
         # Start writing options
@@ -96,5 +140,6 @@
 
             # First write analysis
-            fid.write("\n+{}\n".format(analysis))  # Append a + to recognize it's an analysis enum
+            fid.write('\n+{}\n'.format(analysis))  # Append a + to recognize it's an analysis enum
+
             # Now, write options
             for optionname, optionvalue in list(options.items()):
@@ -102,14 +147,14 @@
                 if not optionvalue:
                     # This option has only one argument
-                    fid.write("-{}\n".format(optionname))
+                    fid.write('-{}\n'.format(optionname))
                 else:
                     # Option with value. Value can be string or scalar.
                     if isinstance(optionvalue, (bool, int, float)):
-                        fid.write("-{} {}\n".format(optionname, optionvalue))
+                        fid.write('-{} {}\n'.format(optionname, optionvalue))
                     elif isinstance(optionvalue, str):
-                        fid.write("-{} {}\n".format(optionname, optionvalue))
+                        fid.write('-{} {}\n'.format(optionname, optionvalue))
                     else:
-                        raise TypeError("ToolkitsFile error: option '{}' is not well formatted.".format(optionname))
+                        raise TypeError('ToolkitsFile error: option {} is not well formatted'.format(optionname))
 
         fid.close()
-    #}}}
+    # }}}
