diff --git a/pom.xml b/pom.xml
index 100b16589429bd146d1770ca425b4cb735aea8eb..bc0158879cc86ca568cd7b6d25d78c2a65c657c8 100755
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,12 @@
       <type>jar</type>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.python</groupId>
+      <artifactId>jython-standalone</artifactId>
+      <version>2.7.0</version>
+      <type>jar</type>
+    </dependency>
     <dependency>
       <groupId>javax</groupId>
       <artifactId>javaee-api</artifactId>
diff --git a/src/main/java/no/nibio/vips/model/JythonModel.java b/src/main/java/no/nibio/vips/model/JythonModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..a14860538656b097474eea9ebe720098900caa9a
--- /dev/null
+++ b/src/main/java/no/nibio/vips/model/JythonModel.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
+ * 
+ * This file is part of VIPSCommon.
+ * VIPSCommon is free software: you can redistribute it and/or modify
+ * it under the terms of the NIBIO Open Source License as published by 
+ * NIBIO, either version 1 of the License, or (at your option) any
+ * later version.
+ * 
+ * VIPSCommon 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
+ * NIBIO Open Source License for more details.
+ * 
+ * You should have received a copy of the NIBIO Open Source License
+ * along with VIPSCommon.  If not, see <http://www.nibio.no/licenses/>.
+ * 
+ */
+
+package no.nibio.vips.model;
+
+import org.python.util.PythonInterpreter;
+
+/**
+ * When implementing a model using Jython (Python on the Java Virtual Machine),
+ * you must extend this class.
+ * 
+ * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a>
+ * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
+ */
+public abstract class JythonModel{
+    
+    public JythonModel()
+    {
+        // Adding possible paths to the python module
+        PythonInterpreter interpreter = new PythonInterpreter();
+        interpreter.exec("import sys");
+        // Adding path to the containing JAR (if any) or code source
+        String jarPath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
+        // For some reason weird prefixes and suffixes are added to the path. We try to 
+        // remove them. This removal might ned to be revised when new deployment situations occur
+        jarPath = jarPath.replaceFirst("file:", "").replace("!", "");
+        interpreter.exec("sys.path.append('" + jarPath + "python')");
+        //interpreter.exec("print sys.path");
+    }
+    
+    /**
+     * Assumes the python modules are found under the [jarPath]/python folder
+     * @param moduleName
+     * @param className
+     * @return 
+     */
+    protected Model getPythonModel(String moduleName, String className){
+        JythonObjectFactory f = new JythonObjectFactory(
+                Model.class, moduleName, className
+        );
+        return (Model) f.createObject();
+    }
+}
diff --git a/src/main/java/no/nibio/vips/model/JythonObjectFactory.java b/src/main/java/no/nibio/vips/model/JythonObjectFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..88dad9c58d07e565273fe021c67ad9cbfa351afa
--- /dev/null
+++ b/src/main/java/no/nibio/vips/model/JythonObjectFactory.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
+ * 
+ * This file is part of VIPSCommon.
+ * VIPSCommon is free software: you can redistribute it and/or modify
+ * it under the terms of the NIBIO Open Source License as published by 
+ * NIBIO, either version 1 of the License, or (at your option) any
+ * later version.
+ * 
+ * VIPSCommon 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
+ * NIBIO Open Source License for more details.
+ * 
+ * You should have received a copy of the NIBIO Open Source License
+ * along with VIPSCommon.  If not, see <http://www.nibio.no/licenses/>.
+ * 
+ */
+
+package no.nibio.vips.model;
+
+/**
+ * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a>
+ * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
+ */
+import java.util.Properties;
+import org.python.core.Py;
+import org.python.core.PyObject;
+import org.python.core.PySystemState;
+
+/**
+ * Jython Object Factory using PySystemState
+ * Found here: http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html#more-efficient-version-of-loosely-coupled-object-factory
+ */
+public class JythonObjectFactory {
+
+ private final Class interfaceType;
+ private final PyObject klass;
+
+ // Constructor obtains a reference to the importer, module, and the class name
+ public JythonObjectFactory(PySystemState state, Class interfaceType, String moduleName, String className) {
+     this.interfaceType = interfaceType;
+     PyObject importer = state.getBuiltins().__getitem__(Py.newString("__import__"));
+     PyObject module = importer.__call__(Py.newString(moduleName));
+     klass = module.__getattr__(className);
+     //System.err.println("module=" + module + ",class=" + klass);
+ }
+
+ // This constructor passes through to the other constructor
+ public JythonObjectFactory(Class interfaceType, String moduleName, String className) {
+     this(new PySystemState(), interfaceType, moduleName, className);
+ }
+
+ // All of the followng methods return
+ // a coerced Jython object based upon the pieces of information
+ // that were passed into the factory. The differences are
+ // between them are the number of arguments that can be passed
+ // in as arguents to the object.
+
+ public Object createObject() {
+     return klass.__call__().__tojava__(interfaceType);
+ }
+
+
+ public Object createObject(Object arg1) {
+     return klass.__call__(Py.java2py(arg1)).__tojava__(interfaceType);
+ }
+
+ public Object createObject(Object arg1, Object arg2) {
+     return klass.__call__(Py.java2py(arg1), Py.java2py(arg2)).__tojava__(interfaceType);
+ }
+
+ public Object createObject(Object arg1, Object arg2, Object arg3)
+ {
+     return klass.__call__(Py.java2py(arg1), Py.java2py(arg2),
+         Py.java2py(arg3)).__tojava__(interfaceType);
+ }
+
+ public Object createObject(Object args[], String keywords[]) {
+     PyObject convertedArgs[] = new PyObject[args.length];
+     for (int i = 0; i < args.length; i++) {
+         convertedArgs[i] = Py.java2py(args[i]);
+     }
+
+     return klass.__call__(convertedArgs, keywords).__tojava__(interfaceType);
+ }
+
+ public Object createObject(Object... args) {
+     return createObject(args, Py.NoKeywords);
+ }
+
+ /**
+ * Adds user.dir into python.path to make Jython look for python modules in working directory in all cases
+ * (both standalone and not standalone modes)
+ * @param props
+ * @return props
+ */
+private Properties setDefaultPythonPath(Properties props) {
+    String pythonPathProp = props.getProperty("python.path");
+    String new_value;
+    if (pythonPathProp==null)
+    {
+        new_value  = System.getProperty("user.dir");
+    } else {
+        new_value = pythonPathProp +java.io.File.pathSeparator + System.getProperty("user.dir") + java.io.File.pathSeparator;
+    }
+    props.setProperty("python.path",new_value);
+    return props;
+}
+ 
+}