diff --git a/.gitignore b/.gitignore
index 3d8fc6e..99782a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,39 @@
+# IDE
+.idea
+*.iml
+.project
+.settings
+.vscode
+*.code-workspace
+**/.sts4-cache
+
+# Go Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Kubernetes Secrets
+docker-secret.yaml
+
+# Kubernetes ServiceAccount (customized with username)
+build.yaml
+service.yaml
+
+# NodeJS
+node_modules/
+package-lock.json
+
+# Swift
+Packages/
+
+# OpenWhisk project-specific
 openwhisk-src
 .wskprops
-
-*.iml
-.idea
-.vscode
-**/.sts4-cache
diff --git a/README.md b/README.md
index 2903649..0f4a2eb 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@
 * [java-action-archetype](java-action-archetype/README.md) This archetype helps to generate the Java Action template project.
 * [node-local](node-local/README.md) allows testing individual OpenWhisk functions locally, using only node.js. This is ideal if you are writing node.js functions to run in OpenWhisk, but need to emulate some of OpenWhisk's behavior in creating `params` and expecting promises.
 * [maven-java](maven-java/README.md) allows testing OpenWhisk Java Actions. This shows how to package the function dependencies e.g. external jar.
+* [knative-build](knative-build/README.md) contains Knative Build Templates along with modified versions of their respective OpenWhisk Action Runtimes that can be used to Build and Serve Knative compatible applications on Kubernetes.
 
 ## Travis builds
 
diff --git a/knative-build/runtimes/javascript/app.js b/knative-build/runtimes/javascript/app.js
index 3f0eb26..b4714d3 100644
--- a/knative-build/runtimes/javascript/app.js
+++ b/knative-build/runtimes/javascript/app.js
@@ -16,7 +16,7 @@
  */
 var dbg = require('./utils/debug');
 var DEBUG = new dbg();
-DEBUG.trace("Hello World from NodeJS runtime");
+DEBUG.trace("NodeJS runtime initializing...");
 DEBUG.dumpObject(process.env, "process.env");
 
 // __OW_ALLOW_CONCURRENT: see docs/concurrency.md
@@ -27,11 +27,6 @@
         'requestBodyLimit': "48mb"
 };
 
-var runtime_platform = {
-    openwhisk: 'openwhisk',
-    knative: 'knative',
-};
-
 var bodyParser = require('body-parser');
 var express    = require('express');
 
@@ -53,83 +48,52 @@
 app.use(bodyParser.json({ limit: config.requestBodyLimit }));
 
 // identify the target Serverless platform
+const platformFactory = require('./platform/platform.js');
+const factory = new platformFactory(app, config, service);
 var targetPlatform = process.env.__OW_RUNTIME_PLATFORM;
 
 // default to "openwhisk" platform initialization if not defined
-if( typeof targetPlatform === "undefined") {
-    console.error("__OW_RUNTIME_PLATFORM is undefined; defaulting to 'openwhisk' ...");
-    targetPlatform = runtime_platform.openwhisk;
+// TODO export isvalid() from platform, if undefined this is OK to default, but if not valid value then error out
+if(typeof targetPlatform === "undefined") {
+    targetPlatform = platformFactory.PLATFORM_OPENWHISK;
+    console.log("__OW_RUNTIME_PLATFORM is undefined; defaulting to 'openwhisk' ...");
+}
+
+if(!platformFactory.isSupportedPlatform(targetPlatform)){
+    console.error("__OW_RUNTIME_PLATFORM ("+targetPlatform+") is not supported by the runtime.");
+    process.exit(9);
 }
 
 /**
  * Register different endpoint handlers depending on target PLATFORM and its expected behavior.
- * In addition, register request pre-processors and/or response post-processors as needed.
+ * In addition, register request pre-processors and/or response post-processors as needed
+ * to move data where the platform and function author expects it to be.
  */
-if (targetPlatform === runtime_platform.openwhisk ) {
-    app.post('/init', wrapEndpoint(service.initCode));
-    app.post('/run', wrapEndpoint(service.runCode));
-} else if (targetPlatform === runtime_platform.knative) {
-    var platformFactory = require('./platform/platform.js');
-    var platform = new platformFactory("knative", service, config);
-    platform.registerHandlers(app, platform)
+
+var platformImpl = factory.createPlatformImpl(targetPlatform);
+
+if(typeof platformImpl !== "undefined"){
+
+    platformImpl.registerHandlers(app, platformImpl);
+
+    // short-circuit any requests to invalid routes (endpoints) that we have no handlers for.
+    app.use(function (req, res, next) {
+        res.status(500).json({error: "Bad request."});
+    });
+
+    /**
+     * Register a default error handler. This effectively only gets called when invalid JSON is received
+     * (JSON Parser) and we do not wish the default handler to error with a 400 and send back HTML in the
+     * body of the response.
+     */
+    app.use(function (err, req, res, next) {
+        console.log(err.stackTrace);
+        res.status(500).json({error: "Bad request."});
+    });
+
+    service.start(app);
+
 } else {
-    console.error("Environment variable '__OW_RUNTIME_PLATFORM' has an unrecognized value ("+targetPlatform+").");
-}
-
-// short-circuit any requests to invalid routes (endpoints) that we have no handlers for.
-app.use(function (req, res, next) {
-    res.status(500).json({error: "Bad request."});
-});
-
-// register a default error handler. This effectively only gets called when invalid JSON is received (JSON Parser)
-// and we do not wish the default handler to error with a 400 and send back HTML in the body of the response.
-app.use(function (err, req, res, next) {
-    console.log(err.stackTrace);
-    res.status(500).json({error: "Bad request."});
-});
-
-service.start(app);
-
-/**
- * Wraps an endpoint written to return a Promise into an express endpoint,
- * producing the appropriate HTTP response and closing it for all controllable
- * failure modes.
- *
- * The expected signature for the promise value (both completed and failed)
- * is { code: int, response: object }.
- *
- * @param ep a request=>promise function
- * @returns an express endpoint handler
- */
-function wrapEndpoint(ep) {
-    DEBUG.functionStart("wrapping: " + ep.name);
-    DEBUG.functionEnd("returning wrapper: " + ep.name);
-    return function (req, res) {
-        try {
-            ep(req).then(function (result) {
-                res.status(result.code).json(result.response);
-                DEBUG.dumpObject(result,"result");
-                DEBUG.dumpObject(res,"response");
-                DEBUG.functionEndSuccess("wrapper for: " + ep.name);
-            }).catch(function (error) {
-                if (typeof error.code === "number" && typeof error.response !== "undefined") {
-                    res.status(error.code).json(error.response);
-                } else {
-                    console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
-                    res.status(500).json({ error: "Internal error." });
-                }
-                DEBUG.dumpObject(error,"error");
-                DEBUG.dumpObject(res,"response");
-                DEBUG.functionEndError(error, "wrapper for: " + ep.name);
-            });
-        } catch (e) {
-            // This should not happen, as the contract for the endpoints is to
-            // never (externally) throw, and wrap failures in the promise instead,
-            // but, as they say, better safe than sorry.
-            console.error("[wrapEndpoint]", "exception caught", e.message);
-            res.status(500).json({ error: "Internal error (exception)." });
-            DEBUG.dumpObject(error,"error");
-            DEBUG.functionEndError(error, ep.name);
-        }
-    }
+    console.error("Failed to initialize __OW_RUNTIME_PLATFORM ("+targetPlatform+").");
+    process.exit(10);
 }
diff --git a/knative-build/runtimes/javascript/platform/knative.js b/knative-build/runtimes/javascript/platform/knative.js
new file mode 100644
index 0000000..fb8f9b0
--- /dev/null
+++ b/knative-build/runtimes/javascript/platform/knative.js
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var dbg = require('../utils/debug');
+var DEBUG = new dbg();
+
+const OW_ENV_PREFIX = "__OW_";
+
+/**
+ * Pre-process the incoming
+ */
+function preProcessInitData(env, initdata, valuedata, activationdata) {
+    DEBUG.functionStart();
+    try {
+        // Set defaults to use INIT data not provided on the request
+        // Look first to the process (i.e., Container's) environment variables.
+        var main = (typeof env.__OW_ACTION_MAIN === 'undefined') ? "main" : env.__OW_ACTION_MAIN;
+        // TODO: Throw error if CODE is NOT defined!
+        var code = (typeof env.__OW_ACTION_CODE === 'undefined') ? "" : env.__OW_ACTION_CODE;
+        var binary = (typeof env.__OW_ACTION_BINARY === 'undefined') ? false : env.__OW_ACTION_BINARY.toLowerCase() === "true";
+        // TODO: default to empty?
+        var actionName = (typeof env.__OW_ACTION_NAME === 'undefined') ? "" : env.__OW_ACTION_NAME;
+        var raw = (typeof env.__OW_ACTION_RAW === 'undefined') ? false : env.__OW_ACTION_RAW.toLowerCase() === "true";
+
+        DEBUG.dumpObject(actionName, "Action name");
+        DEBUG.dumpObject(main, "Action main");
+        DEBUG.dumpObject(code, "Action code");
+        DEBUG.dumpObject(binary, "Action binary");
+        DEBUG.dumpObject(raw, "Action Raw");
+
+        // Look for init data within the request (i.e., "stem cell" runtime, where code is injected by request)
+        if (typeof(initdata) !== "undefined") {
+            if (initdata.name && typeof initdata.name === 'string') {
+                actionName = initdata.name;
+            }
+            if (initdata.main && typeof initdata.main === 'string') {
+                main = initdata.main;
+            }
+            if (initdata.code && typeof initdata.code === 'string') {
+                code = initdata.code;
+            }
+            if (initdata.binary && typeof initdata.binary === 'boolean') {
+                // TODO: Throw error if BINARY is not 'true' or 'false'
+                binary = initdata.binary;
+            }
+            if (initdata.raw && typeof initdata.raw === 'boolean') {
+                // TODO: Throw error if RAW is not 'true' or 'false'
+                raw = initdata.raw;
+            }
+        }
+
+        // Move the init data to the request body under the "value" key.
+        // This will allow us to reuse the "openwhisk" /init route handler function
+        valuedata.main = main;
+        valuedata.code = code;
+        valuedata.binary = binary;
+        valuedata.raw = raw;
+
+        // Action name is a special case, as we have a key collision on "name" between init. data and request
+        // param. data (as they both appear within "body.value") so we must save it to its final location
+        // as the default Action name as part of the activation data
+        // NOTE: if action name is not present in the action data, we will set it regardless even if an empty string
+        if( typeof(activationdata) !== "undefined" ) {
+            if ( typeof(activationdata.action_name) === "undefined" ||
+                (typeof(activationdata.action_name) === "string" && activationdata.action_name.length == 0 )){
+                activationdata.action_name = actionName;
+            }
+        }
+
+        DEBUG.dumpObject(valuedata.main, "valuedata.main");
+        DEBUG.dumpObject(valuedata.code , "valuedata.code");
+        DEBUG.dumpObject(valuedata.binary, "valuedata.binary");
+        DEBUG.dumpObject(valuedata.raw, "valuedata.raw");
+
+    } catch(e){
+        console.error(e);
+        DEBUG.functionEndError(e.message);
+        throw("Unable to initialize the runtime: " + e.message);
+    }
+    DEBUG.functionEnd();
+}
+
+/**
+ * Pre-process the incoming http request data, moving it to where the
+ * route handlers expect it to be for an openwhisk runtime.
+ */
+function preProcessActivationData(env, activationdata) {
+    DEBUG.functionStart();
+    try {
+        // Note: we move the values here so that the "run()" handler does not have
+        // to move them again.
+        Object.keys(activationdata).forEach(
+            function (k) {
+                if (typeof activationdata[k] === 'string') {
+                    var envVariable = OW_ENV_PREFIX + k.toUpperCase();
+                    process.env[envVariable] = activationdata[k];
+                    DEBUG.dumpObject(process.env[envVariable], envVariable, "preProcessActivationData");
+                }
+            }
+        );
+    } catch(e){
+        console.error(e);
+        DEBUG.functionEndError(e.message);
+        throw("Unable to initialize the runtime: " + e.message);
+    }
+    DEBUG.functionEnd();
+}
+
+/**
+ * Pre-process HTTP request details, send them as parameters to the action input argument
+ * __ow_method, __ow_headers, __ow_path, __ow_user, __ow_body, and __ow_query
+ */
+function preProcessHTTPContext(req, valueData) {
+    DEBUG.functionStart();
+    try {
+        if (valueData.raw) {
+            if (typeof req.body.value === "string" && req.body.value !== undefined) {
+                valueData.__ow_body = req.body.value;
+            } else {
+                const body = Object.assign({}, req.body.value);
+                // delete main, binary, raw, and code from the body before sending it as an action argument
+                delete body.main;
+                delete body.code;
+                delete body.binary;
+                delete body.raw;
+                var bodyStr = JSON.stringify(body);
+                valueData.__ow_body = Buffer.from(bodyStr).toString("base64");;
+            }
+            valueData.__ow_query = req.query;
+        }
+
+        var namespace = "";
+        if (process.env[OW_ENV_PREFIX + "NAMESPACE"] !== undefined) {
+            namespace = process.env[OW_ENV_PREFIX + "NAMESPACE"];
+        }
+        valueData.__ow_user = namespace;
+        valueData.__ow_method = req.method;
+        valueData.__ow_headers = req.headers;
+        valueData.__ow_path = "";
+    } catch (e) {
+        console.error(e);
+        DEBUG.functionEndError(e.message);
+        throw ("Unable to initialize the runtime: " + e.message)
+    }
+    DEBUG.functionEnd()
+}
+
+
+/**
+ * Pre-process the incoming http request data, moving it to where the
+ * route handlers expect it to be for an openwhisk runtime.
+ */
+function preProcessRequest(req){
+    DEBUG.functionStart();
+    try{
+        // Get or create valid references to the various data we might encounter
+        // in a request such as Init., Activation and function parameter data.
+        let body = req.body || {};
+        let valueData = body.value || {};
+        let initData = body.init || {};
+        let activationData = body.activation || {};
+        let env = process.env || {};
+
+        // process initialization (i.e., "init") data
+        preProcessInitData(env, initData, valueData, activationData);
+
+        preProcessHTTPContext(req, valueData);
+
+        // Fix up pointers in case we had to allocate new maps
+        req.body = body;
+        req.body.value = valueData;
+        req.body.init = initData;
+        req.body.activation = activationData;
+
+        // process per-activation (i.e, "run") data
+        preProcessActivationData(env, activationData);
+
+    } catch(e){
+        console.error(e);
+        DEBUG.functionEndError(e.message);
+        // TODO: test this error is handled properly and results in an HTTP error response
+        throw("Unable to initialize the runtime: " + e.message);
+    }
+    DEBUG.functionEnd();
+}
+
+function postProcessResponse(result, res) {
+    DEBUG.functionStart();
+    // After getting the result back from an action, update the HTTP headers,
+    // status code, and body based on its result if it includes one or more of the
+    // following as top level JSON properties: headers, statusCode, body
+    let statusCode = result.code;
+    let headers = {};
+    let body = result.response;
+
+    // statusCode: default is 200 OK if body is not empty otherwise 204 No Content
+    if (result.response.statusCode !== undefined) {
+        statusCode = result.response.statusCode;
+        delete body['statusCode'];
+    }
+
+    // the default content-type for an HTTP response is application/json
+    // this default are overwritten with the action specified headers
+    if (result.response.headers !== undefined) {
+        headers = result.response.headers;
+        delete body['headers'];
+    }
+
+    // body: a string which is either a plain text, JSON object, or a base64 encoded string for binary data (default is "")
+    // body is considered empty if it is null, "", or undefined
+    if (result.response.body !== undefined) {
+        body = result.response.body;
+        delete body['main'];
+        delete body['code'];
+        delete body['binary'];
+    }
+
+    // statusCode: set it to 204 No Content if body is empty
+    if (statusCode === 200 && body === "") {
+        statusCode = 204;
+    }
+
+    res.header(headers).status(statusCode).json(body);
+    DEBUG.functionEnd();
+}
+
+
+function PlatformKnativeImpl(platformFactory) {
+    DEBUG.functionStart();
+    DEBUG.dumpObject(platformFactory, "platformFactory" );
+
+    var http_method = {
+        get: 'GET',
+        post: 'POST',
+        put: 'PUT',
+        delete: 'DELETE',
+    };
+
+    const DEFAULT_METHOD = [ 'POST' ];
+
+    // Provide access to common runtime services
+    var service = platformFactory.service;
+
+    // TODO: Should we use app.WrapEndpoint()?
+    this.run = function(req, res) {
+
+        try {
+
+            DEBUG.dumpObject(service.initialized(),"service.initialized()");
+
+            // Process request and process env. variables to provide them in the manner
+            // an OpenWhisk Action expects them, as well as enable additional Http features.
+            preProcessRequest(req);
+
+            service.initCode(req).then(function () {
+                service.runCode(req).then(function (result) {
+                    postProcessResponse(result, res)
+                });
+            }).catch(function (error) {
+                console.error(error);
+                if (typeof error.code === "number" && typeof error.response !== "undefined") {
+                    res.status(error.code).json(error.response);
+                } else {
+                    console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
+                    res.status(500).json({ error: "Internal error during function execution." });
+                }
+            });
+        } catch (e) {
+            res.status(500).json({error: "internal error during function initialization."})
+        }
+    };
+
+    this.registerHandlers = function(app, platform) {
+        var httpMethods = process.env.__OW_HTTP_METHODS;
+        // default to "[post]" HTTP method if not defined
+        if (typeof httpMethods === "undefined" || !Array.isArray(httpMethods)) {
+            console.error("__OW_HTTP_METHODS is undefined; defaulting to '[post]' ...");
+            httpMethods = DEFAULT_METHOD;
+        }
+        httpMethods.forEach(function (method) {
+            switch (method.toUpperCase()) {
+                case http_method.get:
+                    app.get('/', platform.run);
+                    break;
+                case http_method.post:
+                    app.post('/', platform.run);
+                    break;
+                case http_method.put:
+                    app.put('/', platform.run);
+                    break;
+                case http_method.delete:
+                    app.delete('/', platform.run);
+                    break;
+                default:
+                    console.error("Environment variable '__OW_HTTP_METHODS' has an unrecognized value (" + method + ").");
+            }
+        });
+    };
+    DEBUG.functionEnd();
+}
+
+module.exports = PlatformKnativeImpl;
diff --git a/knative-build/runtimes/javascript/platform/openwhisk.js b/knative-build/runtimes/javascript/platform/openwhisk.js
new file mode 100644
index 0000000..b72a35f
--- /dev/null
+++ b/knative-build/runtimes/javascript/platform/openwhisk.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var dbg = require('../utils/debug');
+var DEBUG = new dbg();
+
+function PlatformOpenWhiskImpl(platformFactory) {
+    DEBUG.functionStart();
+    DEBUG.dumpObject(platformFactory, "platformFactory");
+    // Provide access to common runtime services
+    var service = platformFactory.service;
+
+    this.registerHandlers = function(app, platform) {
+        app.post('/init', platformFactory.wrapEndpoint(service.initCode));
+        app.post('/run', platformFactory.wrapEndpoint(service.runCode));
+    };
+    DEBUG.functionEnd();
+}
+
+module.exports = PlatformOpenWhiskImpl;
diff --git a/knative-build/runtimes/javascript/platform/platform.js b/knative-build/runtimes/javascript/platform/platform.js
index acc73bb..2af5874 100644
--- a/knative-build/runtimes/javascript/platform/platform.js
+++ b/knative-build/runtimes/javascript/platform/platform.js
@@ -15,308 +15,150 @@
  * limitations under the License.
  */
 
+/**
+ * Runtime platform factory
+ *
+ * This module is a NodeJS compatible version of a factory that will
+ * produce an implementation module provides OpenWhisk Language
+ * Runtime functionality and is able to register endpoints/handlers
+ * allowing to host OpenWhisk Actions and process OpenWhisk Activations.
+ */
+
 var dbg = require('../utils/debug');
 var DEBUG = new dbg();
 
-const OW_ENV_PREFIX = "__OW_";
+// Export supported platform impls.
+const PLATFORM_OPENWHISK = 'openwhisk';
+const PLATFORM_KNATIVE =  'knative';
 
-/**
- * Pre-process the incoming
- */
-function preProcessInitData(env, initdata, valuedata, activationdata) {
-    DEBUG.functionStart();
-    try {
-        // Set defaults to use INIT data not provided on the request
-        // Look first to the process (i.e., Container's) environment variables.
-        var main = (typeof env.__OW_ACTION_MAIN === 'undefined') ? "main" : env.__OW_ACTION_MAIN;
-        // TODO: Throw error if CODE is NOT defined!
-        var code = (typeof env.__OW_ACTION_CODE === 'undefined') ? "" : env.__OW_ACTION_CODE;
-        var binary = (typeof env.__OW_ACTION_BINARY === 'undefined') ? false : env.__OW_ACTION_BINARY.toLowerCase() === "true";
-        // TODO: deault to empty?
-        var actionName = (typeof env.__OW_ACTION_NAME === 'undefined') ? "" : env.__OW_ACTION_NAME;
-        var raw = (typeof env.__OW_ACTION_RAW === 'undefined') ? false : env.__OW_ACTION_RAW.toLowerCase() === "true";
+const SUPPORTED_PLATFORMS = [
+    PLATFORM_OPENWHISK,
+    PLATFORM_KNATIVE
+];
 
-        DEBUG.dumpObject(actionName, "Action name");
-        DEBUG.dumpObject(main, "Action main");
-        DEBUG.dumpObject(code, "Action code");
-        DEBUG.dumpObject(binary, "Action binary");
-        DEBUG.dumpObject(raw, "Action Raw");
+module.exports = class PlatformFactory {
 
-        // Look for init data within the request (i.e., "stem cell" runtime, where code is injected by request)
-        if (typeof(initdata) !== "undefined") {
-            if (initdata.name && typeof initdata.name === 'string') {
-                actionName = initdata.name;
-            }
-            if (initdata.main && typeof initdata.main === 'string') {
-                main = initdata.main;
-            }
-            if (initdata.code && typeof initdata.code === 'string') {
-                code = initdata.code;
-            }
-            if (initdata.binary && typeof initdata.binary === 'boolean') {
-                // TODO: Throw error if BINARY is not 'true' or 'false'
-                binary = initdata.binary;
-            }
-            if (initdata.raw && typeof initdata.raw === 'boolean') {
-                // TODO: Throw error if RAW is not 'true' or 'false'
-                raw = initdata.raw;
-            }
+    /**
+     * Object constructor
+     * @param app NodeJS express application instance
+     * @param cfg Runtime configuration
+     * @@param svc Runtime services (default handlers)
+     */
+    constructor (app, cfg, svc) {
+        DEBUG.dumpObject(app,"app");
+        DEBUG.dumpObject(cfg,"cfg");
+        DEBUG.dumpObject(svc,"svc");
+        this._app = app;
+        this._service = svc;
+        this._config = cfg;
+    }
+
+    /**
+     * @returns {string[]} List of supported platforms by their string ID
+     */
+    static get SUPPORTED_PLATFORMS() {
+        return SUPPORTED_PLATFORMS;
+    }
+
+    static get PLATFORM_OPENWHISK() {
+        return PLATFORM_OPENWHISK;
+    }
+
+    static get PLATFORM_KNATIVE() {
+        return PLATFORM_KNATIVE;
+    }
+
+    get app(){
+        return this._app;
+    }
+
+    get service(){
+        return this._service;
+    }
+
+    get config(){
+        return this._config;
+    }
+
+    /**
+     * validate if a platform ID is a known, supported value
+     * @param id Platform Id
+     */
+    static isSupportedPlatform(id){
+        if (SUPPORTED_PLATFORMS.indexOf(id) > -1) {
+            return true;
         }
+        return false;
+    }
 
-        // Move the init data to the request body under the "value" key.
-        // This will allow us to reuse the "openwhisk" /init route handler function
-        valuedata.main = main;
-        valuedata.code = code;
-        valuedata.binary = binary;
-        valuedata.raw = raw;
-
-        // Action name is a special case, as we have a key collision on "name" between init. data and request
-        // param. data (as they both appear within "body.value") so we must save it to its final location
-        // as the default Action name as part of the activation data
-        // NOTE: if action name is not present in the action data, we will set it regardless even if an empty string
-        if( typeof(activationdata) !== "undefined" ) {
-            if ( typeof(activationdata.action_name) === "undefined" ||
-                (typeof(activationdata.action_name) === "string" && activationdata.action_name.length == 0 )){
-                activationdata.action_name = actionName;
-            }
+    /**
+     * Instantiate a platform implementation
+     * @param id Platform ID
+     * @returns {PlatformImpl} Platform instance (interface), as best can be done with NodeJS
+     */
+    // TODO remove "app" parameter once we have a valid openwhisk platformImpl.
+    createPlatformImpl(id){
+        DEBUG.functionStart();
+        DEBUG.dumpObject(id,"id");
+        // Load the appropriate implementation module and return reference to it
+        switch (id.toLowerCase()) {
+            case PLATFORM_KNATIVE:
+                const knPlatformImpl = require('./knative.js');
+                this._platformImpl = new knPlatformImpl(this);
+                break;
+            case PLATFORM_OPENWHISK:
+                const owPlatformImpl = require('./openwhisk.js');
+                this._platformImpl = new owPlatformImpl(this);
+                break;
+            default:
+                console.error("Platform ID is not a known value (" + id + ").");
         }
-
-        DEBUG.dumpObject(valuedata.main, "valuedata.main");
-        DEBUG.dumpObject(valuedata.code , "valuedata.code");
-        DEBUG.dumpObject(valuedata.binary, "valuedata.binary");
-        DEBUG.dumpObject(valuedata.raw, "valuedata.raw");
-
-    } catch(e){
-        console.error(e);
-        DEBUG.functionEndError(e.message);
-        throw("Unable to initialize the runtime: " + e.message);
-    }
-    DEBUG.functionEnd();
-}
-
-/**
- * Pre-process the incoming http request data, moving it to where the
- * route handlers expect it to be for an openwhisk runtime.
- */
-function preProcessActivationData(env, activationdata) {
-    DEBUG.functionStart();
-    try {
-        // Note: we move the values here so that the "run()" handler does not have
-        // to move them again.
-        Object.keys(activationdata).forEach(
-            function (k) {
-                if (typeof activationdata[k] === 'string') {
-                    var envVariable = OW_ENV_PREFIX + k.toUpperCase();
-                    process.env[envVariable] = activationdata[k];
-                    DEBUG.dumpObject(process.env[envVariable], envVariable, "preProcessActivationData");
-                }
-            }
-        );
-    } catch(e){
-        console.error(e);
-        DEBUG.functionEndError(e.message);
-        throw("Unable to initialize the runtime: " + e.message);
-    }
-    DEBUG.functionEnd();
-}
-
-
-/**
- * Pre-process HTTP request details, send them as parameters to the action input argument
- * __ow_method, __ow_headers, __ow_path, __ow_user, __ow_body, and __ow_query
- */
-function preProcessHTTPContext(req, valueData) {
-    DEBUG.functionStart()
-
-    try {
-        if (valueData.raw) {
-            if (typeof req.body.value === "string" && req.body.value !== undefined) {
-                valueData.__ow_body = req.body.value;
-            } else {
-                const body = Object.assign({}, req.body.value);
-                // delete main, binary, raw, and code from the body before sending it as an action argument
-                delete body.main;
-                delete body.code;
-                delete body.binary;
-                delete body.raw;
-                var bodyStr = JSON.stringify(body);
-                var bodyBase64 = Buffer.from(bodyStr).toString("base64");
-                valueData.__ow_body = bodyBase64;
-            }
-            valueData.__ow_query = req.query;
-        }
-
-        var namespace = "";
-        if (process.env[OW_ENV_PREFIX + "NAMESPACE"] !== undefined) {
-            namespace = process.env[OW_ENV_PREFIX + "NAMESPACE"];
-        }
-        valueData.__ow_user = namespace;
-        valueData.__ow_method = req.method;
-        valueData.__ow_headers = req.headers;
-        valueData.__ow_path = "";
-    } catch (e) {
-        console.error(e);
-        DEBUG.functionEndError(e.message);
-        throw ("Unable to initialize the runtime: " + e.message)
-    }
-    DEBUG.functionEnd()
-}
-
-
-/**
- * Pre-process the incoming http request data, moving it to where the
- * route handlers expect it to be for an openwhisk runtime.
- */
-function preProcessRequest(req){
-    DEBUG.functionStart();
-
-    try{
-        // Get or create valid references to the various data we might encounter
-        // in a request such as Init., Activation and function parameter data.
-        let body = req.body || {};
-        let valueData = body.value || {};
-        let initData = body.init || {};
-        let activationData = body.activation || {};
-        let env = process.env || {};
-
-        // process initialization (i.e., "init") data
-        preProcessInitData(env, initData, valueData, activationData);
-
-        preProcessHTTPContext(req, valueData);
-
-        // Fix up pointers in case we had to allocate new maps
-        req.body = body;
-        req.body.value = valueData;
-        req.body.init = initData;
-        req.body.activation = activationData;
-
-        // process per-activation (i.e, "run") data
-        preProcessActivationData(env, activationData);
-
-
-
-
-    } catch(e){
-        console.error(e);
-        DEBUG.functionEndError(e.message);
-        // TODO: test this error is handled properly and results in an HTTP error response
-        throw("Unable to initialize the runtime: " + e.message);
+        DEBUG.dumpObject(this._platformImpl,"platformImpl");
+        DEBUG.functionEnd();
+        return this._platformImpl;
     }
 
-    DEBUG.functionEnd();
-}
-
-function postProcessResponse(result, res) {
-    DEBUG.functionStart();
-
-    // After getting the result back from an action, update the HTTP headers,
-    // status code, and body based on its result if it includes one or more of the
-    // following as top level JSON properties: headers, statusCode, body
-    let statusCode = result.code;
-    let headers = {};
-    let body = result.response;
-
-    // statusCode: default is 200 OK if body is not empty otherwise 204 No Content
-    if (result.response.statusCode !== undefined) {
-        statusCode = result.response.statusCode;
-        delete body['statusCode'];
-    }
-
-    // the default content-type for an HTTP response is application/json
-    // this default are overwritten with the action specified headers
-    if (result.response.headers !== undefined) {
-        headers = result.response.headers;
-        delete body['headers'];
-    }
-
-    // body: a string which is either a plain text, JSON object, or a base64 encoded string for binary data (default is "")
-    // body is considered empty if it is null, "", or undefined
-    if (result.response.body !== undefined) {
-        body = result.response.body;
-        delete body['main'];
-        delete body['code'];
-        delete body['binary'];
-    }
-
-    // statusCode: set it to 204 No Content if body is empty
-    if (statusCode === 200 && body === "") {
-        statusCode = 204;
-    }
-
-    res.header(headers).status(statusCode).json(body);
-
-    DEBUG.functionEnd();
-}
-
-
-function PlatformFactory(id, svc, cfg) {
-
-    DEBUG.dumpObject(id, "Platform" );
-    DEBUG.dumpObject(svc, "Service" );
-    DEBUG.dumpObject(cfg, "Config" );
-
-    var service = svc;
-    //var config = cfg;  // TODO: use this to pass future config. information uniformly to any impl.
-    var isInitialized = false;
-
-    this.run = function(req, res) {
-
-        try {
-
-            preProcessRequest(req);
-            console.info("isInitialized="+isInitialized);
-
-            service.initCode(req).then(function () {
-                service.runCode(req).then(function (result) {
-                    postProcessResponse(result, res)
+    /**
+     * Wraps an endpoint written to return a Promise into an express endpoint,
+     * producing the appropriate HTTP response and closing it for all controllable
+     * failure modes.
+     *
+     * The expected signature for the promise value (both completed and failed)
+     * is { code: int, response: object }.
+     *
+     * @param ep a request=>promise function
+     * @returns an express endpoint handler
+     */
+    wrapEndpoint(ep) {
+        DEBUG.functionStart("wrapping: " + ep.name);
+        DEBUG.functionEnd("returning wrapper: " + ep.name);
+        return function (req, res) {
+            try {
+                ep(req).then(function (result) {
+                    res.status(result.code).json(result.response);
+                    DEBUG.dumpObject(result,"result");
+                    DEBUG.dumpObject(res,"response");
+                    DEBUG.functionEndSuccess("wrapper for: " + ep.name);
+                }).catch(function (error) {
+                    if (typeof error.code === "number" && typeof error.response !== "undefined") {
+                        res.status(error.code).json(error.response);
+                    } else {
+                        console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
+                        res.status(500).json({ error: "Internal error." });
+                    }
+                    DEBUG.dumpObject(error,"error");
+                    DEBUG.dumpObject(res,"response");
+                    DEBUG.functionEndError(error, "wrapper for: " + ep.name);
                 });
-            }).catch(function (error) {
-                console.error(error);
-                if (typeof error.code === "number" && typeof error.response !== "undefined") {
-                    res.status(error.code).json(error.response);
-                } else {
-                    console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
-                    res.status(500).json({ error: "Internal error." });
-                }
-            });
-        } catch (e) {
-            res.status(500).json({error: "internal error"})
-        }
-    }
-
-    var http_method = {
-        get: 'GET',
-        post: 'POST',
-        put: 'PUT',
-        delete: 'DELETE',
-    };
-
-    this.registerHandlers = function(app, platform) {
-        var httpMethods = process.env.__OW_HTTP_METHODS;
-        // default to "[post]" HTTP method if not defined
-        if (typeof httpMethods === "undefined" || !Array.isArray(httpMethods)) {
-            console.error("__OW_HTTP_METHODS is undefined; defaulting to '[post]' ...");
-            httpMethods = [http_method.post];
-        }
-        httpMethods.forEach(function (method) {
-            switch (method.toUpperCase()) {
-                case http_method.get:
-                    app.get('/', platform.run);
-                    break;
-                case http_method.post:
-                    app.post('/', platform.run);
-                    break;
-                case http_method.put:
-                    app.put('/', platform.run);
-                    break;
-                case http_method.delete:
-                    app.delete('/', platform.run);
-                    break;
-                default:
-                    console.error("Environment variable '__OW_HTTP_METHODS' has an unrecognized value (" + method + ").");
+            } catch (e) {
+                // This should not happen, as the contract for the endpoints is to
+                // never (externally) throw, and wrap failures in the promise instead,
+                // but, as they say, better safe than sorry.
+                console.error("[wrapEndpoint]", "exception caught", e.message);
+                res.status(500).json({ error: "Internal error (exception)." });
+                DEBUG.dumpObject(error,"error");
+                DEBUG.functionEndError(error, ep.name);
             }
-        });
+        }
     }
 };
-
-module.exports = PlatformFactory;
diff --git a/knative-build/runtimes/javascript/src/service.js b/knative-build/runtimes/javascript/src/service.js
index ab947e2..b0d335e 100644
--- a/knative-build/runtimes/javascript/src/service.js
+++ b/knative-build/runtimes/javascript/src/service.js
@@ -64,6 +64,18 @@
     }
 
     /**
+     * Indicates if we have been initialized which is determined by if we have
+     * created a NodeActionRunner.
+     * @returns {boolean}
+     */
+    this.initialized = function isIntialized(){
+        if( userCodeRunner === undefined ){
+            return false;
+        }
+        return true;
+    };
+
+    /**
      * Starts the server.
      *
      * @param app express app
diff --git a/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-init.http b/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-init.http
new file mode 100644
index 0000000..28b4957
--- /dev/null
+++ b/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-init.http
@@ -0,0 +1,13 @@
+POST http://localhost:8080/ HTTP/1.1
+content-type: application/json
+
+{
+  "init": {
+    "name" : "nodejs-helloworld-with-params",
+    "main" : "main",
+    "binary": false,
+    "code" : "function main(params) {return {payload: 'Hello ' + params.name + ' from ' + params.place +  '!'};}"
+  }
+}
+
+###
diff --git a/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-run.http b/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-run.http
new file mode 100644
index 0000000..7a88f2c
--- /dev/null
+++ b/knative-build/runtimes/javascript/tests/helloworldwithparams/payload-knative-run.http
@@ -0,0 +1,19 @@
+POST http://localhost:8080/ HTTP/1.1
+content-type: application/json
+
+{
+  "activation": {
+    "namespace": "default",
+    "action_name": "nodejs-helloworld-with-params",
+    "api_host": "",
+    "api_key": "",
+    "activation_id": "",
+    "deadline": "4102498800000"
+  },
+  "value": {
+    "name" : "Jill",
+    "place" : "OK"
+  }
+}
+
+###
