diff --git a/.gitignore b/.gitignore
index 22219f7fe9afb6ff871c5825a414082460ec5632..f8e8e0f986c463627b7e19e70a1893e9587129dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 *.*~
 *~
 *.html
+/moose
diff --git a/moose-core/.gitignore b/moose-core/.gitignore
index c3622c5460d8d401119f1067cd3e364eb6f22786..6208aede5114ca1007ed37ca018466eb50b37e60 100644
--- a/moose-core/.gitignore
+++ b/moose-core/.gitignore
@@ -58,7 +58,7 @@ tags
 *.i*86
 *.x86_64
 *.hex
-moose
+/moose
 
 CMakeCache.txt
 CMakeFiles
@@ -132,3 +132,4 @@ Session.vim
 *~
 *.clean
 
+/VERSION
diff --git a/moose-core/pymoose/CMakeLists.txt b/moose-core/pymoose/CMakeLists.txt
index 83397de45054b7cc470f3c144ec6632ad3978c05..b2887ee7b3b78b8810df4e9b9e98d796ba52eda8 100644
--- a/moose-core/pymoose/CMakeLists.txt
+++ b/moose-core/pymoose/CMakeLists.txt
@@ -43,10 +43,10 @@ set_target_properties(_moose PROPERTIES
     SUFFIX ".so"
     )
 
-#if(NOT(PYTHON_SO_EXTENSION STREQUAL ""))
-#    set_target_properties(_moose PROPERTIES
-#    SUFFIX ${PYTHON_SO_EXTENSION})
-#endif()
+if(NOT(PYTHON_SO_EXTENSION STREQUAL ""))
+    set_target_properties(_moose PROPERTIES
+    SUFFIX ${PYTHON_SO_EXTENSION})
+endif()
 
 # see issue #80
 if(HDF5_LIBRARY_DIRS)
diff --git a/moose-core/python/moose/SBML/readSBML.py b/moose-core/python/moose/SBML/readSBML.py
index 801d3681ec23536b60dce134f2faa67480c70571..5747765be0fa07ee7de5ca40547e1ad4b162590a 100644
--- a/moose-core/python/moose/SBML/readSBML.py
+++ b/moose-core/python/moose/SBML/readSBML.py
@@ -23,7 +23,7 @@ import sys
 import os.path
 import collections
 import moose
-from validation import validateModel
+from .validation import validateModel
 
 '''
    TODO in
@@ -1133,4 +1133,4 @@ if __name__ == "__main__":
             if read:
                 print(" Model read to moose path "+ modelpath)
             else:
-                print(" could not read  SBML to MOOSE")
\ No newline at end of file
+                print(" could not read  SBML to MOOSE")
diff --git a/moose-core/python/moose/SBML/writeSBML.py b/moose-core/python/moose/SBML/writeSBML.py
index bcfaf2eb2824b52337fd8b058f7b2dd5ba4d5fc8..7bf1727e3d0533fb0f69b6c1ef72fbdcdc4248c6 100644
--- a/moose-core/python/moose/SBML/writeSBML.py
+++ b/moose-core/python/moose/SBML/writeSBML.py
@@ -23,7 +23,7 @@ import re
 from collections import Counter
 
 import moose
-from validation import validateModel
+from .validation import validateModel
 from moose.chemUtil.chemConnectUtil import *
 from moose.chemUtil.graphUtils import *
 
diff --git a/moose-core/python/moose/moose.py b/moose-core/python/moose/moose.py
new file mode 100644
index 0000000000000000000000000000000000000000..0957638de1ae7915966a5a6f877d831d021a519b
--- /dev/null
+++ b/moose-core/python/moose/moose.py
@@ -0,0 +1,507 @@
+# moose.py ---
+# This is the primary moose module. It wraps _moose.so and adds some
+# utility functions.
+
+# Filename: moose.py
+# Author: Subhasis Ray
+# Maintainer: Dilawar Singh, Harsha Rani, Upi Bhalla
+
+from __future__ import print_function
+from contextlib import closing
+import warnings
+import platform
+import pydoc
+import os
+from io import StringIO
+from collections import defaultdict
+from . import _moose
+from ._moose import *
+import __main__ as main
+from .genesis import writeKkit
+from . import SBML
+sequence_types = ['vector<double>',
+                  'vector<int>',
+                  'vector<long>',
+                  'vector<unsigned int>',
+                  'vector<float>',
+                  'vector<unsigned long>',
+                  'vector<short>',
+                  'vector<Id>',
+                  'vector<ObjId>']
+
+known_types = ['void',
+               'char',
+               'short',
+               'int',
+               'unsigned int',
+               'double',
+               'float',
+               'long',
+               'unsigned long',
+               'string',
+               'vec',
+               'melement'] + sequence_types
+
+# SBML related functions.
+
+
+def mooseReadSBML(filepath, loadpath, solver='ee'):
+    """Load SBML model.
+
+    keyword arguments: \n
+
+    filepath -- filepath to be loaded \n
+    loadpath -- Root path for this model e.g. /model/mymodel \n
+    solver   -- Solver to use (default 'ee' ) \n
+
+    """
+    return SBML.readSBML.mooseReadSBML( filepath, loadpath, solver )
+
+
+def mooseWriteSBML(modelpath, filepath, sceneitems={}):
+    """Writes loaded model under modelpath to a file in SBML format.
+
+    keyword arguments:\n
+
+    modelpath -- model path in moose e.g /model/mymodel \n
+    filepath -- Path of output file. \n
+    sceneitems -- dictlist (UserWarning: user need not worry about this) \n
+                    layout position is saved in Annotation field of all the moose Object (pool,Reaction,enzyme)\n
+                    If this function is called from \n
+                        -- GUI, the layout position of moose object is passed \n
+                        -- command line, \n
+                            ---if genesis/kkit model is loaded then layout position is taken from the file \n
+                            --- else, auto-coordinates is used for layout position and passed
+
+    """
+    return SBML.writeSBML.mooseWriteSBML(modelpath, filepath, sceneitems)
+
+
+def mooseWriteKkit(modelpath, filepath,sceneitems={}):
+    """Writes  loded model under modelpath to a file in Kkit format.
+
+    keyword arguments:\n
+
+    modelpath -- model path in moose \n
+    filepath -- Path of output file.
+    """
+    return writeKkit.mooseWriteKkit(modelpath, filepath,sceneitems)
+
+
+def moosedeleteChemSolver(modelpath):
+    """ deletes solver on all the compartment and its children.
+        This is neccesary while created a new moose object on a pre-existing modelpath,\n
+        this should be followed by mooseaddChemSolver for add solvers on to compartment to simulate else
+        default is Exponential Euler (ee)
+    """
+    return chemUtil.add_Delete_ChemicalSolver.moosedeleteChemSolver(modelpath)
+
+
+def mooseaddChemSolver(modelpath, solver):
+    """ Add solver on chemical compartment and its children for calculation
+
+    keyword arguments:\n
+
+    modelpath -- model path that is loaded into moose \n
+    solver -- "Exponential Euler" (ee) (default), \n
+              "Gillespie"         ("gssa"), \n
+              "Runge Kutta"       ("gsl")
+
+    """
+    return chemUtil.add_Delete_ChemicalSolver.mooseaddChemSolver(modelpath, solver)
+
+################################################################
+# Wrappers for global functions
+################################################################
+
+
+def pwe():
+    """Print present working element. Convenience function for GENESIS
+    users. If you want to retrieve the element in stead of printing
+    the path, use moose.getCwe()
+
+    """
+    pwe_ = _moose.getCwe()
+    print(pwe_.getPath())
+    return pwe_
+
+
+def le(el=None):
+    """List elements under `el` or current element if no argument
+    specified.
+
+    Parameters
+    ----------
+    el : str/melement/vec/None
+        The element or the path under which to look. If `None`, children
+         of current working element are displayed.
+
+    Returns
+    -------
+    List of path of child elements
+
+    """
+    if el is None:
+        el = getCwe()
+    elif isinstance(el, str):
+        if not exists(el):
+            raise ValueError('no such element')
+        el = element(el)
+    elif isinstance(el, vec):
+        el = el[0]
+    print('Elements under', el.path)
+    for ch in el.children:
+        print(ch.path)
+    return [child.path for child in el.children]
+
+ce = setCwe  # ce is a GENESIS shorthand for change element.
+
+
+def syncDataHandler(target):
+    """Synchronize data handlers for target.
+
+    Parameters
+    ----------
+    target : melement/vec/str
+        Target element or vec or path string.
+
+    Raises
+    ------
+    NotImplementedError
+        The call to the underlying C++ function does not work.
+
+    Notes
+    -----
+    This function is defined for completeness, but currently it does not work.
+
+    """
+    raise NotImplementedError('The implementation is not working for IntFire - goes to invalid objects. \
+First fix that issue with SynBase or something in that line.')
+    if isinstance(target, str):
+        if not _moose.exists(target):
+            raise ValueError('%s: element does not exist.' % (target))
+        target = vec(target)
+        _moose.syncDataHandler(target)
+
+
+def showfield(el, field='*', showtype=False):
+    """Show the fields of the element `el`, their data types and
+    values in human readable format. Convenience function for GENESIS
+    users.
+
+    Parameters
+    ----------
+    el : melement/str
+        Element or path of an existing element.
+
+    field : str
+        Field to be displayed. If '*' (default), all fields are displayed.
+
+    showtype : bool
+        If True show the data type of each field. False by default.
+
+    Returns
+    -------
+    None
+
+    """
+    if isinstance(el, str):
+        if not exists(el):
+            raise ValueError('no such element')
+        el = element(el)
+    if field == '*':
+        value_field_dict = getFieldDict(el.className, 'valueFinfo')
+        max_type_len = max(len(dtype) for dtype in value_field_dict.values())
+        max_field_len = max(len(dtype) for dtype in value_field_dict.keys())
+        print('\n[', el.path, ']')
+        for key, dtype in sorted(value_field_dict.items()):
+            if dtype == 'bad' or key == 'this' or key == 'dummy' or key == 'me' or dtype.startswith(
+                    'vector') or 'ObjId' in dtype:
+                continue
+            value = el.getField(key)
+            if showtype:
+                typestr = dtype.ljust(max_type_len + 4)
+                # The following hack is for handling both Python 2 and
+                # 3. Directly putting the print command in the if/else
+                # clause causes syntax error in both systems.
+                print(typestr, end=' ')
+            print(key.ljust(max_field_len + 4), '=', value)
+    else:
+        try:
+            print(field, '=', el.getField(field))
+        except AttributeError:
+            pass  # Genesis silently ignores non existent fields
+
+
+def showfields(el, showtype=False):
+    """Convenience function. Should be deprecated if nobody uses it.
+
+    """
+    warnings.warn(
+        'Deprecated. Use showfield(element, field="*", showtype=True) instead.',
+        DeprecationWarning)
+    showfield(el, field='*', showtype=showtype)
+
+# Predefined field types and their human readable names
+finfotypes = [('valueFinfo', 'value field'),
+              ('srcFinfo', 'source message field'),
+              ('destFinfo', 'destination message field'),
+              ('sharedFinfo', 'shared message field'),
+              ('lookupFinfo', 'lookup field')]
+
+
+def listmsg(el):
+    """Return a list containing the incoming and outgoing messages of
+    `el`.
+
+    Parameters
+    ----------
+    el : melement/vec/str
+        MOOSE object or path of the object to look into.
+
+    Returns
+    -------
+    msg : list
+        List of Msg objects corresponding to incoming and outgoing
+        connections of `el`.
+
+    """
+    obj = element(el)
+    ret = []
+    for msg in obj.inMsg:
+        ret.append(msg)
+    for msg in obj.outMsg:
+        ret.append(msg)
+    return ret
+
+
+def showmsg(el):
+    """Print the incoming and outgoing messages of `el`.
+
+    Parameters
+    ----------
+    el : melement/vec/str
+        Object whose messages are to be displayed.
+
+    Returns
+    -------
+    None
+
+    """
+    obj = element(el)
+    print('INCOMING:')
+    for msg in obj.msgIn:
+        print(
+            msg.e2.path,
+            msg.destFieldsOnE2,
+            '<---',
+            msg.e1.path,
+            msg.srcFieldsOnE1)
+    print('OUTGOING:')
+    for msg in obj.msgOut:
+        print(
+            msg.e1.path,
+            msg.srcFieldsOnE1,
+            '--->',
+            msg.e2.path,
+            msg.destFieldsOnE2)
+
+
+def getfielddoc(tokens, indent=''):
+    """Return the documentation for field specified by `tokens`.
+
+    Parameters
+    ----------
+    tokens : (className, fieldName) str
+        A sequence whose first element is a MOOSE class name and second
+        is the field name.
+
+    indent : str
+        indentation (default: empty string) prepended to builtin
+        documentation string.
+
+    Returns
+    -------
+    docstring : str
+        string of the form
+        `{indent}{className}.{fieldName}: {datatype} - {finfoType}\n{Description}\n`
+
+    Raises
+    ------
+    NameError
+        If the specified fieldName is not present in the specified class.
+    """
+    assert(len(tokens) > 1)
+    classname = tokens[0]
+    fieldname = tokens[1]
+    while True:
+        try:
+            classelement = _moose.element('/classes/' + classname)
+            for finfo in classelement.children:
+                for fieldelement in finfo:
+                    baseinfo = ''
+                    if classname != tokens[0]:
+                        baseinfo = ' (inherited from {})'.format(classname)
+                    if fieldelement.fieldName == fieldname:
+                        # The field elements are
+                        # /classes/{ParentClass}[0]/{fieldElementType}[N].
+                        finfotype = fieldelement.name
+                        return '{indent}{classname}.{fieldname}: type={type}, finfotype={finfotype}{baseinfo}\n\t{docs}\n'.format(
+                            indent=indent, classname=tokens[0],
+                            fieldname=fieldname,
+                            type=fieldelement.type,
+                            finfotype=finfotype,
+                            baseinfo=baseinfo,
+                            docs=fieldelement.docs)
+            classname = classelement.baseClass
+        except ValueError:
+            raise NameError('`%s` has no field called `%s`'
+                            % (tokens[0], tokens[1]))
+
+
+def toUnicode(v, encoding='utf8'):
+    # if isinstance(v, str):
+        # return v
+    try:
+        return v.decode(encoding)
+    except (AttributeError, UnicodeEncodeError):
+        return str(v)
+
+
+def getmoosedoc(tokens, inherited=False):
+    """Return MOOSE builtin documentation.
+
+    Parameters
+    ----------
+    tokens : (className, [fieldName])
+        tuple containing one or two strings specifying class name
+        and field name (optional) to get documentation for.
+
+    inherited: bool (default: False)
+        include inherited fields.
+
+    Returns
+    -------
+    docstring : str
+        Documentation string for class `className`.`fieldName` if both
+        are specified, for the class `className` if fieldName is not
+        specified. In the latter case, the fields and their data types
+        and finfo types are listed.
+
+    Raises
+    ------
+    NameError
+        If class or field does not exist.
+
+    """
+    indent = '    '
+    with closing(StringIO()) as docstring:
+        if not tokens:
+            return ""
+        try:
+            class_element = _moose.element('/classes/%s' % (tokens[0]))
+        except ValueError:
+            raise NameError('name \'%s\' not defined.' % (tokens[0]))
+        if len(tokens) > 1:
+            docstring.write(toUnicode(getfielddoc(tokens)))
+        else:
+            docstring.write(toUnicode('%s\n' % (class_element.docs)))
+            append_finfodocs(tokens[0], docstring, indent)
+            if inherited:
+                mro = eval('_moose.%s' % (tokens[0])).mro()
+                for class_ in mro[1:]:
+                    if class_ == _moose.melement:
+                        break
+                    docstring.write(toUnicode(
+                        '\n\n#Inherited from %s#\n' % (class_.__name__)))
+                    append_finfodocs(class_.__name__, docstring, indent)
+                    if class_ == _moose.Neutral:    # Neutral is the toplevel moose class
+                        break
+        return docstring.getvalue()
+
+
+def append_finfodocs(classname, docstring, indent):
+    """Append list of finfos in class name to docstring"""
+    try:
+        class_element = _moose.element('/classes/%s' % (classname))
+    except ValueError:
+        raise NameError('class \'%s\' not defined.' % (classname))
+    for ftype, rname in finfotypes:
+        docstring.write(toUnicode('\n*%s*\n' % (rname.capitalize())))
+        try:
+            finfo = _moose.element('%s/%s' % (class_element.path, ftype))
+            for field in finfo.vec:
+                docstring.write(toUnicode(
+                    '%s%s: %s\n' % (indent, field.fieldName, field.type)))
+        except ValueError:
+            docstring.write(toUnicode('%sNone\n' % (indent)))
+
+
+# the global pager is set from pydoc even if the user asks for paged
+# help once. this is to strike a balance between GENESIS user's
+# expectation of control returning to command line after printing the
+# help and python user's expectation of seeing the help via more/less.
+pager = None
+
+
+def doc(arg, inherited=True, paged=True):
+    """Display the documentation for class or field in a class.
+
+    Parameters
+    ----------
+    arg : str/class/melement/vec
+        A string specifying a moose class name and a field name
+        separated by a dot. e.g., 'Neutral.name'. Prepending `moose.`
+        is allowed. Thus moose.doc('moose.Neutral.name') is equivalent
+        to the above.
+        It can also be string specifying just a moose class name or a
+        moose class or a moose object (instance of melement or vec
+        or there subclasses). In that case, the builtin documentation
+        for the corresponding moose class is displayed.
+
+    paged: bool
+        Whether to display the docs via builtin pager or print and
+        exit. If not specified, it defaults to False and
+        moose.doc(xyz) will print help on xyz and return control to
+        command line.
+
+    Returns
+    -------
+    None
+
+    Raises
+    ------
+    NameError
+        If class or field does not exist.
+
+    """
+    # There is no way to dynamically access the MOOSE docs using
+    # pydoc. (using properties requires copying all the docs strings
+    # from MOOSE increasing the loading time by ~3x). Hence we provide a
+    # separate function.
+    global pager
+    if paged and pager is None:
+        pager = pydoc.pager
+    tokens = []
+    text = ''
+    if isinstance(arg, str):
+        tokens = arg.split('.')
+        if tokens[0] == 'moose':
+            tokens = tokens[1:]
+    elif isinstance(arg, type):
+        tokens = [arg.__name__]
+    elif isinstance(arg, melement) or isinstance(arg, vec):
+        text = '%s: %s\n\n' % (arg.path, arg.className)
+        tokens = [arg.className]
+    if tokens:
+        text += getmoosedoc(tokens, inherited=inherited)
+    else:
+        text += pydoc.getdoc(arg)
+    if pager:
+        pager(text)
+    else:
+        print(text)
+
+
+#
+# moose.py ends here