You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/03/08 22:57:36 UTC

[GitHub] mrutkows closed pull request #779: WIP: Add "trace" support, include -trace flag and -v for go test

mrutkows closed pull request #779: WIP: Add "trace" support, include -trace flag and -v for go test
URL: https://github.com/apache/incubator-openwhisk-wskdeploy/pull/779
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/.gitignore b/.gitignore
index d9864756..9fd9de2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,4 @@ build/
 
 #emacs
 *~
+bin/content.json
diff --git a/README.md b/README.md
index cd519baa..f4c81020 100644
--- a/README.md
+++ b/README.md
@@ -141,6 +141,22 @@ $ git branch --set-upstream-to origin/master  # track master from origin now
 
 You can now use `git push` to push changes to your repository and submit pull requests.
 
+### Developers should use "go deps" and "go build" not "go get"
+
+The Whisk deploy project is setup for development purposes and uses "go deps" for dependency management. We do NOT recommend using "go get" as this will use the latest dependencies for all imported GitHub repos. which is not supported.
+
+- See: [https://github.com/tools/godep](https://github.com/tools/godep)
+
+Specifically, for development please use:
+
+```
+$ git clone git@github.com:mrutkows/incubator-openwhisk-wskdeploy
+$ go build
+```
+
+for end-users, please use versioned releases of binaries.
+- [https://github.com/apache/incubator-openwhisk-wskdeploy/releases](https://github.com/apache/incubator-openwhisk-wskdeploy/releases)
+
 ### How to Cross Compile Binary with Gradle/Docker
 
 If you don't want to bother with go installation, build, git clone etc, and you can do it with Gradle/Docker.
@@ -174,7 +190,7 @@ Then, you will find the binaries and their compressed packages generated under t
 ### Building for Internationalization
 
 Please follow this process for building any changes to translatable strings:
-[How to generate the file i18n_resources.go for internationalization](https://github.com/apache/incubator-openwhisk-wskdeploy/blob/master/wski18n/README.md)
+- [How to generate the file i18n_resources.go for internationalization](https://github.com/apache/incubator-openwhisk-wskdeploy/blob/master/wski18n/README.md)
 
 <!-- ----------------------------------------------------------------------------- -->
 
@@ -204,7 +220,11 @@ while there, you can verify that your upstream repository is set correctly:
 
 #### Git clone RPC failed: HTTP 301
 
-This sometimes occurs using "go get" the wskdeploy code (which indirectly invokes "git clone"). You might get this error when downloading `incubator-openwhisk-wskdeploy`:
+This sometimes occurs using "go get" the wskdeploy code (which indirectly invokes "git clone"). 
+
+<b>Note: Using "go get" for development is unsupported; instead, please use "go deps" for dependency management.</b>
+
+You might get this error when downloading `incubator-openwhisk-wskdeploy`:
 
      Cloning into ''$GOAPTH/src/gopkg.in/yaml.v2'...
      error: RPC failed; HTTP 301 curl 22 The requested URL returned error: 301
diff --git a/cmd/root.go b/cmd/root.go
index 7225924b..c29eca12 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -111,6 +111,7 @@ func init() {
 	// with any other Whisk Deploy command e.g. undeploy, export, etc.
 	// TODO() Publish command, not completed
 	// TODO() Report command, not completed
+	// TODO() have a single function that conditionally (i.e., Trace=true) prints ALL Flags
 	RootCmd.PersistentFlags().StringVar(&utils.Flags.CfgFile, "config", "", wski18n.T(wski18n.ID_CMD_FLAG_CONFIG))
 	RootCmd.PersistentFlags().StringVarP(&utils.Flags.ProjectPath, "project", "p", ".", wski18n.T(wski18n.ID_CMD_FLAG_PROJECT))
 	RootCmd.PersistentFlags().StringVarP(&utils.Flags.ManifestPath, "manifest", "m", "", wski18n.T(wski18n.ID_CMD_FLAG_MANIFEST))
@@ -125,6 +126,9 @@ func init() {
 	RootCmd.PersistentFlags().StringVarP(&utils.Flags.Key, "key", "k", "", wski18n.T(wski18n.ID_CMD_FLAG_KEY_FILE))
 	RootCmd.PersistentFlags().StringVarP(&utils.Flags.Cert, "cert", "c", "", wski18n.T(wski18n.ID_CMD_FLAG_CERT_FILE))
 	RootCmd.PersistentFlags().BoolVarP(&utils.Flags.Managed, "managed", "", false, wski18n.T(wski18n.ID_CMD_FLAG_MANAGED))
+	RootCmd.PersistentFlags().StringVarP(&utils.Flags.ProjectName, "projectname", "", "", wski18n.T(wski18n.ID_CMD_FLAG_PROJECTNAME))
+	RootCmd.PersistentFlags().BoolVarP(&utils.Flags.Trace, "trace", "t", false, wski18n.T(wski18n.ID_CMD_FLAG_TRACE))
+	RootCmd.PersistentFlags().MarkHidden("trace")
 }
 
 // initConfig reads in config file and ENV variables if set.
@@ -148,6 +152,7 @@ func initConfig() {
 	}
 }
 
+// TODO() add Trace of runtimes found at apihost
 func setSupportedRuntimes(apiHost string) {
 	op, error := utils.ParseOpenWhisk(apiHost)
 	if error == nil {
@@ -158,12 +163,46 @@ func setSupportedRuntimes(apiHost string) {
 	}
 }
 
+func displayCommandUsingFilenameMessage(command string, filetype string, path string) {
+	msg := wski18n.T(wski18n.ID_MSG_COMMAND_USING_X_cmd_X_filetype_X_path_X,
+		map[string]interface{}{
+			wski18n.KEY_CMD:       command,
+			wski18n.KEY_FILE_TYPE: filetype,
+			wski18n.KEY_PATH:      path})
+	wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, msg)
+}
+
+func loadDefaultManifestFileFromProjectPath(command string, projectPath string) error {
+
+	if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYaml)); err == nil {
+		utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYaml)
+	} else if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYml)); err == nil {
+		utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYml)
+	} else {
+		stderr = wski18n.T(wski18n.ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X,
+			map[string]interface{}{wski18n.KEY_PATH: projectPath})
+		return wskderrors.NewErrorManifestFileNotFound(projectPath, stderr)
+	}
+	displayCommandUsingFilenameMessage(command, wski18n.MANIFEST_FILE, utils.Flags.ManifestPath)
+	return nil
+}
+
+func loadDefaultDeploymentFileFromProjectPath(command string, projectPath string) error {
+
+	if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYaml)); err == nil {
+		utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYaml)
+	} else if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYml)); err == nil {
+		utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYml)
+	}
+	displayCommandUsingFilenameMessage(command, wski18n.DEPLOYMENT_FILE, utils.Flags.ManifestPath)
+	return nil
+}
+
 func Deploy() error {
 
+	// Convey flags for verbose and trace to Go client
 	whisk.SetVerbose(utils.Flags.Verbose)
-	// Verbose mode is the only mode for wskdeploy to turn on all the debug messages,
-	// so set Verbose mode (and also debug mode) to true.
-	whisk.SetDebug(utils.Flags.Verbose)
+	whisk.SetDebug(utils.Flags.Trace)
 
 	project_Path := strings.TrimSpace(utils.Flags.ProjectPath)
 	if len(project_Path) == 0 {
@@ -171,29 +210,17 @@ func Deploy() error {
 	}
 	projectPath, _ := filepath.Abs(project_Path)
 
-	// TODO() identical code block below; please create function both can share
+	// If manifest filename is not provided, attempt to load default manifests from project path
 	if utils.Flags.ManifestPath == "" {
-		if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYaml)); err == nil {
-			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYaml)
-			stdout = wski18n.T(wski18n.ID_MSG_MANIFEST_DEPLOY_X_path_X,
-				map[string]interface{}{wski18n.KEY_PATH: utils.Flags.ManifestPath})
-		} else if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYml)); err == nil {
-			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYml)
-			stdout = wski18n.T(wski18n.ID_MSG_MANIFEST_DEPLOY_X_path_X,
-				map[string]interface{}{wski18n.KEY_PATH: utils.Flags.ManifestPath})
-		} else {
-			stderr = wski18n.T(wski18n.ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X,
-				map[string]interface{}{wski18n.KEY_PATH: projectPath})
-			return wskderrors.NewErrorManifestFileNotFound(projectPath, stderr)
+		if err := loadDefaultManifestFileFromProjectPath(wski18n.CMD_DEPLOY, projectPath); err != nil {
+			return err
 		}
-		whisk.Debug(whisk.DbgInfo, stdout)
 	}
 
 	if utils.Flags.DeploymentPath == "" {
-		if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYaml)); err == nil {
-			utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYaml)
-		} else if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYml)); err == nil {
-			utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYml)
+
+		if err := loadDefaultDeploymentFileFromProjectPath(wski18n.CMD_DEPLOY, projectPath); err != nil {
+			return err
 		}
 	}
 
@@ -208,7 +235,11 @@ func Deploy() error {
 		// master record of any dependency that has been downloaded
 		deployer.DependencyMaster = make(map[string]utils.DependencyRecord)
 
-		clientConfig, error := deployers.NewWhiskConfig(utils.Flags.CfgFile, utils.Flags.DeploymentPath, utils.Flags.ManifestPath, deployer.IsInteractive)
+		clientConfig, error := deployers.NewWhiskConfig(
+			utils.Flags.CfgFile,
+			utils.Flags.DeploymentPath,
+			utils.Flags.ManifestPath,
+			deployer.IsInteractive)
 		if error != nil {
 			return error
 		}
@@ -249,10 +280,9 @@ func Deploy() error {
 
 func Undeploy() error {
 
+	// Convey flags for verbose and trace to Go client
 	whisk.SetVerbose(utils.Flags.Verbose)
-	// Verbose mode is the only mode for wskdeploy to turn on all the debug messages, so the currenty Verbose mode
-	// also set debug mode to true.
-	whisk.SetDebug(utils.Flags.Verbose)
+	whisk.SetDebug(utils.Flags.Trace)
 
 	project_Path := strings.TrimSpace(utils.Flags.ProjectPath)
 	if len(project_Path) == 0 {
@@ -260,41 +290,17 @@ func Undeploy() error {
 	}
 	projectPath, _ := filepath.Abs(project_Path)
 
+	// If manifest filename is not provided, attempt to load default manifests from project path
 	if utils.Flags.ManifestPath == "" {
-		if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYaml)); err == nil {
-			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYaml)
-			stdout = wski18n.T(wski18n.ID_MSG_MANIFEST_UNDEPLOY_X_path_X,
-				map[string]interface{}{wski18n.KEY_PATH: utils.Flags.ManifestPath})
-		} else if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYml)); err == nil {
-			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYml)
-			stdout = wski18n.T(wski18n.ID_MSG_MANIFEST_UNDEPLOY_X_path_X,
-				map[string]interface{}{wski18n.KEY_PATH: utils.Flags.ManifestPath})
-		} else {
-			stderr = wski18n.T(wski18n.ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X,
-				map[string]interface{}{wski18n.KEY_PATH: projectPath})
-			return wskderrors.NewErrorManifestFileNotFound(projectPath, stderr)
+		if err := loadDefaultManifestFileFromProjectPath(wski18n.CMD_UNDEPLOY, projectPath); err != nil {
+			return err
 		}
-		wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, stdout)
 	}
 
 	if utils.Flags.DeploymentPath == "" {
-		if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYaml)); err == nil {
-			utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYaml)
-			// TODO() have a single function that conditionally (verbose) prints ALL Flags
-			dbgMsg := fmt.Sprintf("%s >> [%s]: [%s]",
-				wski18n.T(wski18n.ID_DEBUG_UNDEPLOYING_USING),
-				wski18n.DEPLOYMENT,
-				utils.Flags.DeploymentPath)
-			wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, dbgMsg)
-
-		} else if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYml)); err == nil {
-			utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYml)
-			// TODO() have a single function that conditionally (verbose) prints ALL Flags
-			dbgMsg := fmt.Sprintf("%s >> [%s]: [%s]",
-				wski18n.T(wski18n.ID_DEBUG_UNDEPLOYING_USING),
-				wski18n.DEPLOYMENT,
-				utils.Flags.DeploymentPath)
-			wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, dbgMsg)
+
+		if err := loadDefaultDeploymentFileFromProjectPath(wski18n.CMD_UNDEPLOY, projectPath); err != nil {
+			return err
 		}
 	}
 
diff --git a/deployers/deploymentreader.go b/deployers/deploymentreader.go
index a31addd5..ed31125b 100644
--- a/deployers/deploymentreader.go
+++ b/deployers/deploymentreader.go
@@ -20,6 +20,7 @@ package deployers
 import (
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/parsers"
+	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
 	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
@@ -77,7 +78,7 @@ func (reader *DeploymentReader) getPackageMap() map[string]parsers.Package {
 				wski18n.ID_DEBUG_PACKAGES_FOUND_UNDER_ROOT_X_path_X,
 				map[string]interface{}{
 					wski18n.KEY_PATH: reader.DeploymentDescriptor.Filepath})
-			wskprint.PrintlnOpenWhiskTrace(false, infoMsg)
+			wskprint.PrintlnOpenWhiskTrace(utils.Flags.Trace, infoMsg)
 			for packName, depPacks := range reader.DeploymentDescriptor.Packages {
 				depPacks.Packagename = packName
 				packMap[packName] = depPacks
@@ -90,7 +91,7 @@ func (reader *DeploymentReader) getPackageMap() map[string]parsers.Package {
 			map[string]interface{}{
 				wski18n.KEY_PATH: reader.DeploymentDescriptor.Filepath,
 				wski18n.KEY_NAME: reader.DeploymentDescriptor.GetProject().Name})
-		wskprint.PrintlnOpenWhiskTrace(false, infoMsg)
+		wskprint.PrintlnOpenWhiskTrace(utils.Flags.Trace, infoMsg)
 
 		for packName, depPacks := range reader.DeploymentDescriptor.GetProject().Packages {
 			depPacks.Packagename = packName
@@ -349,5 +350,5 @@ func displayEntityFoundInDeploymentTrace(entityType string, entityName string) {
 		map[string]interface{}{
 			wski18n.KEY_KEY:  entityType,
 			wski18n.KEY_NAME: entityName})
-	wskprint.PrintlnOpenWhiskTrace(true, infoMsg)
+	wskprint.PrintlnOpenWhiskTrace(utils.Flags.Trace, infoMsg)
 }
diff --git a/deployers/deploymentreader_test.go b/deployers/deploymentreader_test.go
index cc48f2ca..1c6e52c3 100644
--- a/deployers/deploymentreader_test.go
+++ b/deployers/deploymentreader_test.go
@@ -22,6 +22,8 @@ package deployers
 import (
 	"fmt"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
+	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
+	"github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 	"github.com/stretchr/testify/assert"
 	"reflect"
 	"testing"
@@ -48,7 +50,8 @@ var deployment_file = "../tests/usecases/github/deployment.yaml"
 var manifest_file = "../tests/usecases/github/manifest.yaml"
 
 func init() {
-	// TODO(): setup "trace" flag here (and in all unit test files)
+	// Setup "trace" flag for unit tests based upon "go test" -v flag
+	utils.Flags.Trace = wskprint.DetectGoTestVerbose()
 }
 
 // Check DeploymentReader could handle deployment yaml successfully.
diff --git a/deployers/manifestreader.go b/deployers/manifestreader.go
index f9fc5993..e9e8271b 100644
--- a/deployers/manifestreader.go
+++ b/deployers/manifestreader.go
@@ -243,13 +243,12 @@ func (reader *ManifestReader) SetActions(actions []utils.ActionRecord) error {
 }
 
 // TODO create named errors
+// Check action record before deploying it
+// action record is created by reading and composing action elements from manifest file
+// Action.kind is mandatory which is set to
+// (1) action runtime for an action and (2) set to "sequence" for a sequence
+// Also, action executable code should be specified for any action
 func (reader *ManifestReader) checkAction(action utils.ActionRecord) error {
-	if action.Filepath == "" {
-		// TODO(): i18n of error message (or create a new named error)
-		err := errors.New("Action [" + action.Action.Name + "] has no source code location set.")
-		return wskderrors.NewYAMLParserErr(reader.serviceDeployer.ManifestPath, err)
-	}
-
 	if action.Action.Exec.Kind == "" {
 		// TODO(): i18n of error message (or create a new named error)
 		err := errors.New("Action [" + action.Action.Name + "] has no kind set.")
@@ -258,7 +257,7 @@ func (reader *ManifestReader) checkAction(action utils.ActionRecord) error {
 
 	if action.Action.Exec.Code != nil {
 		code := *action.Action.Exec.Code
-		if code == "" && action.Action.Exec.Kind != "sequence" {
+		if code == "" && action.Action.Exec.Kind != parsers.YAML_KEY_SEQUENCE {
 			// TODO(): i18n of error message (or create a new named error)
 			err := errors.New("Action [" + action.Action.Name + "] has no source code.")
 			return wskderrors.NewYAMLParserErr(reader.serviceDeployer.ManifestPath, err)
diff --git a/deployers/manifestreader_test.go b/deployers/manifestreader_test.go
index 39999d8a..7d5acbc5 100644
--- a/deployers/manifestreader_test.go
+++ b/deployers/manifestreader_test.go
@@ -22,6 +22,8 @@ package deployers
 import (
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/parsers"
+	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
+	"github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 	"github.com/stretchr/testify/assert"
 	"testing"
 )
@@ -32,6 +34,9 @@ var ms *parsers.YAML
 
 func init() {
 
+	// Setup "trace" flag for unit tests based upon "go test" -v flag
+	utils.Flags.Trace = wskprint.DetectGoTestVerbose()
+
 	sd = NewServiceDeployer()
 	sd.ManifestPath = manifest_file
 	mr = NewManifestReader(sd)
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index f5429125..0ef55d8e 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -128,7 +128,16 @@ func (deployer *ServiceDeployer) ConstructDeploymentPlan() error {
 		return err
 	}
 
-	deployer.ProjectName = manifest.GetProject().Name
+	deployer.ProjectName = utils.Flags.ProjectName
+	if deployer.ProjectName == "" {
+		deployer.ProjectName = manifest.GetProject().Name
+	} else {
+		warningString := wski18n.T(
+			wski18n.ID_WARN_PROJECT_NAME_OVERRIDDEN,
+			map[string]interface{}{
+				wski18n.KEY_PROJECT: deployer.ProjectName})
+		wskprint.PrintOpenWhiskWarning(warningString)
+	}
 
 	// Generate Managed Annotations if its marked as a Managed Deployment
 	// Managed deployments are the ones when OpenWhisk entities are deployed with command line flag --managed.
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index d97a2a3b..63a55c19 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -432,6 +432,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 	var s1 []utils.ActionRecord = make([]utils.ActionRecord, 0)
 
 	for key, action := range actions {
+		var actionFilePath string
 		splitFilePath := strings.Split(filePath, string(os.PathSeparator))
 		// set the name of the action (which is the key)
 		action.Name = key
@@ -449,15 +450,63 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 			action.Function = action.Location
 		}
 
-		//bind action, and exposed URL
-		if action.Function != "" {
+		// Check if either one of action.Function and action.Code is defined
+		if len(action.Code) != 0 {
+			if len(action.Function) != 0 {
+				err := wski18n.T(wski18n.ID_ERR_ACTION_INVALID_X_action_X,
+					map[string]interface{}{
+						wski18n.KEY_ACTION: action.Name})
+				return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+			}
+			if len(action.Runtime) == 0 {
+				err := wski18n.T(wski18n.ID_ERR_ACTION_MISSING_RUNTIME_WITH_CODE_X_action_X,
+					map[string]interface{}{
+						wski18n.KEY_ACTION: action.Name})
+				return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+			}
+			code := action.Code
+			wskaction.Exec.Code = &code
+
+			// validate runtime from the manifest file
+			// error out if the specified runtime is not valid or not supported
+			// even if runtime is invalid, deploy action with specified runtime in strict mode
+			if utils.Flags.Strict {
+				wskaction.Exec.Kind = action.Runtime
+			} else if utils.CheckExistRuntime(action.Runtime, utils.SupportedRunTimes) {
+				wskaction.Exec.Kind = action.Runtime
+			} else if len(utils.DefaultRunTimes[action.Runtime]) != 0 {
+				wskaction.Exec.Kind = utils.DefaultRunTimes[action.Runtime]
+			} else {
+				err := wski18n.T(wski18n.ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X,
+					map[string]interface{}{
+						wski18n.KEY_RUNTIME: action.Runtime,
+						wski18n.KEY_ACTION:  action.Name})
+				return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+			}
+		}
 
-			filePath := strings.TrimRight(filePath, splitFilePath[len(splitFilePath)-1]) + action.Function
+		//bind action, and exposed URL
+		if len(action.Function) != 0 {
+			// check if action function is pointing to an URL
+			// we do not support if function is pointing to remote directory
+			// therefore error out if there is a combination of http/https ending in a directory
+			if strings.HasPrefix(action.Function, HTTP) || strings.HasPrefix(action.Function, HTTPS) {
+				if len(path.Ext(action.Function)) == 0 {
+					err := wski18n.T(wski18n.ID_ERR_ACTION_FUNCTION_REMOTE_DIR_NOT_SUPPORTED_X_action_X_url_X,
+						map[string]interface{}{
+							wski18n.KEY_ACTION: action.Name,
+							wski18n.KEY_URL:    action.Function})
+					return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+				}
+				actionFilePath = action.Function
+			} else {
+				actionFilePath = strings.TrimRight(filePath, splitFilePath[len(splitFilePath)-1]) + action.Function
+			}
 
-			if utils.IsDirectory(filePath) {
+			if utils.IsDirectory(actionFilePath) {
 				// TODO() define ext as const
-				zipName := filePath + ".zip"
-				err := utils.NewZipWritter(filePath, zipName).Zip()
+				zipName := actionFilePath + ".zip"
+				err := utils.NewZipWritter(actionFilePath, zipName).Zip()
 				if err != nil {
 					return nil, err
 				}
@@ -469,7 +518,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 					return nil, err
 				}
 			} else {
-				ext = path.Ext(filePath)
+				ext = path.Ext(actionFilePath)
 				// drop the "." from file extension
 				if len(ext) > 0 && ext[0] == '.' {
 					ext = ext[1:]
@@ -484,21 +533,20 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 				// and its not explicitly specified in the manifest YAML file
 				// and action source is not a zip file
 				if len(kind) == 0 && len(action.Runtime) == 0 && ext != utils.ZIP_FILE_EXTENSION {
-					errMessage := wski18n.T(wski18n.ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X,
+					errMessage := wski18n.T(wski18n.ID_ERR_RUNTIME_ACTION_SOURCE_NOT_SUPPORTED_X_ext_X_action_X,
 						map[string]interface{}{
-							wski18n.KEY_RUNTIME:   action.Runtime,
 							wski18n.KEY_EXTENSION: ext,
 							wski18n.KEY_ACTION:    action.Name})
 					return nil, wskderrors.NewInvalidRuntimeError(errMessage,
 						splitFilePath[len(splitFilePath)-1], action.Name,
-						action.Runtime,
+						utils.RUNTIME_NOT_SPECIFIED,
 						utils.ListOfSupportedRuntimes(utils.SupportedRunTimes))
 				}
 
 				wskaction.Exec.Kind = kind
 
-				action.Function = filePath
-				dat, err := utils.Read(filePath)
+				action.Function = actionFilePath
+				dat, err := utils.Read(actionFilePath)
 				if err != nil {
 					return s1, err
 				}
@@ -509,12 +557,12 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 				if ext == utils.ZIP_FILE_EXTENSION && len(action.Runtime) == 0 {
 					errMessage := wski18n.T(wski18n.ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X,
 						map[string]interface{}{
-							wski18n.KEY_RUNTIME: action.Runtime,
+							wski18n.KEY_RUNTIME: utils.RUNTIME_NOT_SPECIFIED,
 							wski18n.KEY_ACTION:  action.Name})
 					return nil, wskderrors.NewInvalidRuntimeError(errMessage,
 						splitFilePath[len(splitFilePath)-1],
 						action.Name,
-						action.Runtime,
+						utils.RUNTIME_NOT_SPECIFIED,
 						utils.ListOfSupportedRuntimes(utils.SupportedRunTimes))
 				}
 				wskaction.Exec.Code = &code
@@ -523,13 +571,13 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 		}
 
 		/*
-			 		 *  Action.Runtime
-					 *  Perform few checks if action runtime is specified in manifest YAML file
-					 *  (1) Check if specified runtime is one of the supported runtimes by OpenWhisk server
-					 *  (2) Check if specified runtime is consistent with action source file extensions
-					 *  Set the action runtime to match with the source file extension, if wskdeploy is not invoked in strict mode
-		*/
-		if action.Runtime != "" {
+		*  Action.Runtime
+		*  Perform few checks if action runtime is specified in manifest YAML file
+		*  (1) Check if specified runtime is one of the supported runtimes by OpenWhisk server
+		*  (2) Check if specified runtime is consistent with action source file extensions
+		*  Set the action runtime to match with the source file extension, if wskdeploy is not invoked in strict mode
+		 */
+		if len(action.Runtime) != 0 && len(action.Function) != 0 {
 			if utils.CheckExistRuntime(action.Runtime, utils.SupportedRunTimes) {
 				// for zip actions, rely on the runtimes from the manifest file as it can not be derived from the action source file extension
 				// pick runtime from manifest file if its supported by OpenWhisk server
@@ -585,7 +633,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 		}
 
 		// we can specify the name of the action entry point using main
-		if action.Main != "" {
+		if len(action.Main) != 0 {
 			wskaction.Exec.Main = action.Main
 		}
 
@@ -761,7 +809,7 @@ func (dm *YAMLParser) ComposeTriggers(filePath string, pkg Package, ma whisk.Key
 				map[string]interface{}{
 					wski18n.KEY_OLD:       YAML_KEY_SOURCE,
 					wski18n.KEY_NEW:       YAML_KEY_FEED,
-					wski18n.KEY_FILE_TYPE: wski18n.MANIFEST})
+					wski18n.KEY_FILE_TYPE: wski18n.MANIFEST_FILE})
 			wskprint.PrintOpenWhiskWarning(warningString)
 		}
 		if trigger.Feed == "" {
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index 3bc0a5e5..dcdff168 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -53,6 +53,7 @@ const (
 	TEST_ERROR_MANIFEST_PARSE_FAILURE   = "Manifest [%s]: Failed to parse."
 	TEST_ERROR_MANIFEST_READ_FAILURE    = "Manifest [%s]: Failed to ReadFile()."
 	TEST_ERROR_MANIFEST_DATA_UNMARSHALL = "Manifest [%s]: Failed to Unmarshall manifest."
+	TEST_ERROR_COMPOSE_ACTION_FAILURE   = "Manifest [%s]: Failed to compose actions."
 )
 
 func init() {
@@ -71,7 +72,6 @@ func testLoadParseManifest(t *testing.T, manifestFile string) (*YAMLParser, *YAM
 	if err != nil {
 		assert.Fail(t, fmt.Sprintf(TEST_ERROR_MANIFEST_PARSE_FAILURE, manifestFile))
 	}
-
 	return p, m, err
 }
 
@@ -491,27 +491,24 @@ func TestParseManifestForSingleLineParams(t *testing.T) {
 // when a runtime of an action is not provided, manifest_parser determines the runtime
 // based on the file extension of an action file
 func TestComposeActionsForImplicitRuntimes(t *testing.T) {
-
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_runtimes_implicit.yaml")
-
+	file := "../tests/dat/manifest_data_compose_runtimes_implicit.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
 	var expectedResult string
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "helloNodejs" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["js"]]
-			} else if actions[i].Action.Name == "helloJava" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["jar"]]
-			} else if actions[i].Action.Name == "helloPython" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["py"]]
-			} else if actions[i].Action.Name == "helloSwift" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["swift"]]
-			}
-			actualResult := actions[i].Action.Exec.Kind
-			assert.Equal(t, expectedResult, actualResult, TEST_MSG_ACTION_FUNCTION_RUNTIME_MISMATCH)
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "helloNodejs" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["js"]]
+		} else if actions[i].Action.Name == "helloJava" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["jar"]]
+		} else if actions[i].Action.Name == "helloPython" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["py"]]
+		} else if actions[i].Action.Name == "helloSwift" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["swift"]]
 		}
+		actualResult := actions[i].Action.Exec.Kind
+		assert.Equal(t, expectedResult, actualResult, TEST_MSG_ACTION_FUNCTION_RUNTIME_MISMATCH)
 	}
-
 }
 
 // Test 10(1): validate manifest_parser.ComposeActions() method for invalid runtimes
@@ -568,7 +565,8 @@ func TestComposeActionsForValidRuntime_ZipAction(t *testing.T) {
                 function: ../tests/src/integration/runtimetests/src/helloworld/helloworld.zip
                 runtime: nodejs:6`
 	p, m, tmpfile := testUnmarshalTemporaryFile([]byte(data), "manifest_parser_validate_runtime_")
-	actions, _ := p.ComposeActionsFromAllPackages(m, tmpfile, whisk.KeyValue{})
+	actions, err := p.ComposeActionsFromAllPackages(m, tmpfile, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, tmpfile))
 	for _, action := range actions {
 		if action.Action.Name == "hello" {
 			assert.Equal(t, action.Action.Exec.Kind, "nodejs:6", fmt.Sprintf(TEST_MSG_ACTION_FUNCTION_RUNTIME_MISMATCH, action))
@@ -580,177 +578,176 @@ func TestComposeActionsForValidRuntime_ZipAction(t *testing.T) {
 // Test 11: validate manifest_parser.ComposeActions() method for single line parameters
 // manifest_parser should be able to parse input section with different types of values
 func TestComposeActionsForSingleLineParams(t *testing.T) {
-
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_validate_singleline_params.yaml")
+	file := "../tests/dat/manifest_validate_singleline_params.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	// Call the method we are testing
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	// test # actions
+	assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
+
+	action := actions[0]
+
+	/*
+	 * Simple 'string' value tests
+	 */
+
+	// param_simple_string should value "foo"
+	paramName := "param_simple_string"
+	expectedResult := "foo"
+	actualResult := action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Simple 'integer' value tests
+	 */
+
+	// param_simple_integer_1 should have value 1
+	paramName = "param_simple_integer_1"
+	expectedResult = strconv.FormatInt(1, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_2 should have value 0
+	paramName = "param_simple_integer_2"
+	expectedResult = strconv.FormatInt(0, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_3 should have value -1
+	paramName = "param_simple_integer_3"
+	expectedResult = strconv.FormatInt(-1, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_4 should have value 99999
+	paramName = "param_simple_integer_4"
+	expectedResult = strconv.FormatInt(99999, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_5 should have value -99999
+	paramName = "param_simple_integer_5"
+	expectedResult = strconv.FormatInt(-99999, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Simple 'float' value tests
+	 */
+
+	// param_simple_float_1 should have value 1.1
+	paramName = "param_simple_float_1"
+	expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_float_2 should have value 0.0
+	paramName = "param_simple_float_2"
+	expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_float_3 should have value -1.1
+	paramName = "param_simple_float_3"
+	expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Environment Variable / dollar ($) notation tests
+	 */
+
+	// param_simple_env_var_1 should have value of env. variable $GOPATH
+	paramName = "param_simple_env_var_1"
+	expectedResult = os.Getenv("GOPATH")
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_2 should have value of env. variable $GOPATH
+	paramName = "param_simple_env_var_2"
+	expectedResult = os.Getenv("GOPATH")
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_3 should have value of env. variable "${}"
+	paramName = "param_simple_env_var_3"
+	expectedResult = "${}"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_invalid_env_var should have value of ""
+	paramName = "param_simple_invalid_env_var"
+	expectedResult = ""
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Environment Variable concatenation tests
+	 */
+
+	// param_simple_env_var_concat_1 should have value of env. variable "$GOPTH/test" empty string
+	paramName = "param_simple_env_var_concat_1"
+	expectedResult = os.Getenv("GOPATH") + "/test"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_concat_2 should have value of env. variable "" empty string
+	// as the "/test" is treated as part of the environment var. and not concatenated.
+	paramName = "param_simple_env_var_concat_2"
+	expectedResult = ""
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_concat_3 should have value of env. variable "" empty string
+	paramName = "param_simple_env_var_concat_3"
+	expectedResult = "ddd.ccc." + os.Getenv("GOPATH")
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Empty string tests
+	 */
+
+	// param_simple_implied_empty should be ""
+	paramName = "param_simple_implied_empty"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_explicit_empty_1 should be ""
+	paramName = "param_simple_explicit_empty_1"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_explicit_empty_2 should be ""
+	paramName = "param_simple_explicit_empty_2"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Test values that contain "Type names" (e.g., "string", "integer", "float, etc.)
+	 */
+
+	// param_simple_type_string should be "" when value set to "string"
+	paramName = "param_simple_type_string"
+	expectedResult = ""
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_type_integer should be 0.0 when value set to "integer"
+	paramName = "param_simple_type_integer"
+	expectedResult = strconv.FormatInt(0, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_type_float should be 0 when value set to "float"
+	paramName = "param_simple_type_float"
+	expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
 
-	if err == nil {
-		// test # actions
-		assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
-
-		action := actions[0]
-
-		/*
-		 * Simple 'string' value tests
-		 */
-
-		// param_simple_string should value "foo"
-		paramName := "param_simple_string"
-		expectedResult := "foo"
-		actualResult := action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Simple 'integer' value tests
-		 */
-
-		// param_simple_integer_1 should have value 1
-		paramName = "param_simple_integer_1"
-		expectedResult = strconv.FormatInt(1, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_2 should have value 0
-		paramName = "param_simple_integer_2"
-		expectedResult = strconv.FormatInt(0, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_3 should have value -1
-		paramName = "param_simple_integer_3"
-		expectedResult = strconv.FormatInt(-1, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_4 should have value 99999
-		paramName = "param_simple_integer_4"
-		expectedResult = strconv.FormatInt(99999, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_5 should have value -99999
-		paramName = "param_simple_integer_5"
-		expectedResult = strconv.FormatInt(-99999, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Simple 'float' value tests
-		 */
-
-		// param_simple_float_1 should have value 1.1
-		paramName = "param_simple_float_1"
-		expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_float_2 should have value 0.0
-		paramName = "param_simple_float_2"
-		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_float_3 should have value -1.1
-		paramName = "param_simple_float_3"
-		expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Environment Variable / dollar ($) notation tests
-		 */
-
-		// param_simple_env_var_1 should have value of env. variable $GOPATH
-		paramName = "param_simple_env_var_1"
-		expectedResult = os.Getenv("GOPATH")
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_2 should have value of env. variable $GOPATH
-		paramName = "param_simple_env_var_2"
-		expectedResult = os.Getenv("GOPATH")
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_3 should have value of env. variable "${}"
-		paramName = "param_simple_env_var_3"
-		expectedResult = "${}"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_invalid_env_var should have value of ""
-		paramName = "param_simple_invalid_env_var"
-		expectedResult = ""
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Environment Variable concatenation tests
-		 */
-
-		// param_simple_env_var_concat_1 should have value of env. variable "$GOPTH/test" empty string
-		paramName = "param_simple_env_var_concat_1"
-		expectedResult = os.Getenv("GOPATH") + "/test"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_concat_2 should have value of env. variable "" empty string
-		// as the "/test" is treated as part of the environment var. and not concatenated.
-		paramName = "param_simple_env_var_concat_2"
-		expectedResult = ""
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_concat_3 should have value of env. variable "" empty string
-		paramName = "param_simple_env_var_concat_3"
-		expectedResult = "ddd.ccc." + os.Getenv("GOPATH")
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Empty string tests
-		 */
-
-		// param_simple_implied_empty should be ""
-		paramName = "param_simple_implied_empty"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_explicit_empty_1 should be ""
-		paramName = "param_simple_explicit_empty_1"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_explicit_empty_2 should be ""
-		paramName = "param_simple_explicit_empty_2"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Test values that contain "Type names" (e.g., "string", "integer", "float, etc.)
-		 */
-
-		// param_simple_type_string should be "" when value set to "string"
-		paramName = "param_simple_type_string"
-		expectedResult = ""
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_type_integer should be 0.0 when value set to "integer"
-		paramName = "param_simple_type_integer"
-		expectedResult = strconv.FormatInt(0, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_type_float should be 0 when value set to "float"
-		paramName = "param_simple_type_float"
-		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-	}
 }
 
 // Test 12: validate manifest_parser.ComposeActions() method for multi line parameters
@@ -761,213 +758,232 @@ func TestComposeActionsForMultiLineParams(t *testing.T) {
 	defer os.Unsetenv("USERNAME")
 	defer os.Unsetenv("PASSWORD")
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_validate_multiline_params.yaml")
+	file := "../tests/dat/manifest_validate_multiline_params.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	// call the method we are testing
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	// test # actions
+	assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
+
+	action := actions[0]
+
+	// param_string_value_only should be "foo"
+	paramName := "param_string_value_only"
+	expectedResult := "foo"
+	actualResult := action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_int_value_only should be 123
+	paramName = "param_int_value_only"
+	expectedResult = strconv.FormatInt(123, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_float_value_only should be 3.14
+	paramName = "param_float_value_only"
+	expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_string_type_and_value_only should be foo
+	paramName = "param_string_type_and_value_only"
+	expectedResult = "foo"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_string_type_only should be ""
+	paramName = "param_string_type_only"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_integer_type_only should be 0
+	paramName = "param_integer_type_only"
+	expectedResult = strconv.FormatInt(0, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_float_type_only should be 0
+	paramName = "param_float_type_only"
+	expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_string_with_default should be "bar"
+	paramName = "param_string_with_default"
+	expectedResult = "bar"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_integer_with_default should be -1
+	paramName = "param_integer_with_default"
+	expectedResult = strconv.FormatInt(-1, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_float_with_default should be 2.9
+	paramName = "param_float_with_default"
+	expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_json_type_and_value_only_1 should be { "name": "Sam", "place": "Shire" }
+	paramName = "param_json_type_and_value_only_1"
+	expectedResult1 := map[string]interface{}{"name": "Sam", "place": "Shire"}
+	actualResult1 := action.Action.Parameters.GetValue(paramName)
+	assert.Equal(t, expectedResult1, actualResult1, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_json_type_and_value_only_2 should be { "name": "MY_USERNAME", "password": "MY_PASSWORD" }
+	paramName = "param_json_type_and_value_only_2"
+	expectedResult2 := map[string]interface{}{"name": "MY_USERNAME", "password": "MY_PASSWORD"}
+	actualResult2 := action.Action.Parameters.GetValue(paramName)
+	assert.Equal(t, expectedResult2, actualResult2, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_json_type_and_value_only_3 should be { "name": "${USERNAME}", "password": "${PASSWORD}" }
+	paramName = "param_json_type_and_value_only_3"
+	expectedResult3 := map[string]interface{}{"name": "${USERNAME}", "password": "${PASSWORD}"}
+	actualResult3 := action.Action.Parameters.GetValue(paramName)
+	assert.Equal(t, expectedResult3, actualResult3, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
 
-	if err == nil {
-		// test # actions
-		assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
-
-		action := actions[0]
-
-		// param_string_value_only should be "foo"
-		paramName := "param_string_value_only"
-		expectedResult := "foo"
-		actualResult := action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_int_value_only should be 123
-		paramName = "param_int_value_only"
-		expectedResult = strconv.FormatInt(123, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_float_value_only should be 3.14
-		paramName = "param_float_value_only"
-		expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_string_type_and_value_only should be foo
-		paramName = "param_string_type_and_value_only"
-		expectedResult = "foo"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_string_type_only should be ""
-		paramName = "param_string_type_only"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_integer_type_only should be 0
-		paramName = "param_integer_type_only"
-		expectedResult = strconv.FormatInt(0, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_float_type_only should be 0
-		paramName = "param_float_type_only"
-		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_string_with_default should be "bar"
-		paramName = "param_string_with_default"
-		expectedResult = "bar"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_integer_with_default should be -1
-		paramName = "param_integer_with_default"
-		expectedResult = strconv.FormatInt(-1, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_float_with_default should be 2.9
-		paramName = "param_float_with_default"
-		expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_json_type_and_value_only_1 should be { "name": "Sam", "place": "Shire" }
-		paramName = "param_json_type_and_value_only_1"
-		expectedResult1 := map[string]interface{}{"name": "Sam", "place": "Shire"}
-		actualResult1 := action.Action.Parameters.GetValue(paramName)
-		assert.Equal(t, expectedResult1, actualResult1, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_json_type_and_value_only_2 should be { "name": "MY_USERNAME", "password": "MY_PASSWORD" }
-		paramName = "param_json_type_and_value_only_2"
-		expectedResult2 := map[string]interface{}{"name": "MY_USERNAME", "password": "MY_PASSWORD"}
-		actualResult2 := action.Action.Parameters.GetValue(paramName)
-		assert.Equal(t, expectedResult2, actualResult2, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_json_type_and_value_only_3 should be { "name": "${USERNAME}", "password": "${PASSWORD}" }
-		paramName = "param_json_type_and_value_only_3"
-		expectedResult3 := map[string]interface{}{"name": "${USERNAME}", "password": "${PASSWORD}"}
-		actualResult3 := action.Action.Parameters.GetValue(paramName)
-		assert.Equal(t, expectedResult3, actualResult3, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-	}
 }
 
 // Test 13: validate manifest_parser.ComposeActions() method
-// TODO() - test is NOT complete. Manifest has code that is commented out for "hello2" action
 func TestComposeActionsForFunction(t *testing.T) {
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_function.yaml")
+	file := "../tests/dat/manifest_data_compose_actions_for_function.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
 	var expectedResult, actualResult string
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "hello1" {
-				expectedResult, _ = filepath.Abs("../tests/src/integration/helloworld/actions/hello.js")
-				actualResult, _ = filepath.Abs(actions[i].Filepath)
-				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-				// TODO() Uncomment the following condition, hello2
-				// TODO() after issue # 311 is fixed
-				//} else if actions[i].Action.Name == "hello2" {
-				//  assert.NotNil(t, actions[i].Action.Exec.Code, "Expected source code from an action file but found it empty")
-			}
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "hello1" {
+			expectedResult, _ = filepath.Abs("../tests/src/integration/helloworld/actions/hello.js")
+			actualResult, _ = filepath.Abs(actions[i].Filepath)
+			assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+		} else if actions[i].Action.Name == "hello2" {
+			assert.NotNil(t, actions[i].Action.Exec.Code, "Expected source code from an action file but found it empty")
 		}
 	}
+}
 
+// validate manifest_parser.ComposeActions() method
+func TestComposeActionsForFunctionAndCode(t *testing.T) {
+	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_function_and_code.yaml")
+	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.NotNil(t, err, "Compose actions should have exited with error when code and function both exist.")
+}
+
+// validate manifest_parser.ComposeActions() method
+func TestComposeActionsForCodeWithMissingRuntime(t *testing.T) {
+	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml")
+	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.NotNil(t, err, "Compose actions should have exited with error when code is specified but runtime is missing.")
+}
+
+// validate manifest_parser.ComposeActions() method
+func TestComposeActionsForFunctionWithRemoteDir(t *testing.T) {
+	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml")
+	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.NotNil(t, err, "Compose actions should have exited with error when code is specified but runtime is missing.")
 }
 
 // Test 14: validate manifest_parser.ComposeActions() method
 func TestComposeActionsForLimits(t *testing.T) {
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_limits.yaml")
+	file := "../tests/dat/manifest_data_compose_actions_for_limits.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
-
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "hello1" {
-				assert.Nil(t, actions[i].Action.Limits, "Expected limit section to be empty but got %s", actions[i].Action.Limits)
-			} else if actions[i].Action.Name == "hello2" {
-				assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to be not empty but found it empty")
-				assert.Equal(t, 180, *actions[i].Action.Limits.Timeout, "Failed to get Timeout")
-				assert.Equal(t, 128, *actions[i].Action.Limits.Memory, "Failed to get Memory")
-				assert.Equal(t, 1, *actions[i].Action.Limits.Logsize, "Failed to get Logsize")
-			}
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "hello1" {
+			assert.Nil(t, actions[i].Action.Limits, "Expected limit section to be empty but got %s", actions[i].Action.Limits)
+		} else if actions[i].Action.Name == "hello2" {
+			assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to be not empty but found it empty")
+			assert.Equal(t, 180, *actions[i].Action.Limits.Timeout, "Failed to get Timeout")
+			assert.Equal(t, 128, *actions[i].Action.Limits.Memory, "Failed to get Memory")
+			assert.Equal(t, 1, *actions[i].Action.Limits.Logsize, "Failed to get Logsize")
 		}
 	}
-
 }
 
 // Test 15: validate manifest_parser.ComposeActions() method
 func TestComposeActionsForWebActions(t *testing.T) {
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_web.yaml")
+	file := "../tests/dat/manifest_data_compose_actions_for_web.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "hello1" {
-				for _, a := range actions[i].Action.Annotations {
-					switch a.Key {
-					case "web-export":
-						assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
-					case "raw-http":
-						assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
-					case "final":
-						assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-					}
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "hello1" {
+			for _, a := range actions[i].Action.Annotations {
+				switch a.Key {
+				case "web-export":
+					assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+				case "raw-http":
+					assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+				case "final":
+					assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 				}
-			} else if actions[i].Action.Name == "hello2" {
-				for _, a := range actions[i].Action.Annotations {
-					switch a.Key {
-					case "web-export":
-						assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
-					case "raw-http":
-						assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
-					case "final":
-						assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello2" {
+			for _, a := range actions[i].Action.Annotations {
+				switch a.Key {
+				case "web-export":
+					assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+				case "raw-http":
+					assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+				case "final":
+					assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 				}
-			} else if actions[i].Action.Name == "hello3" {
-				for _, a := range actions[i].Action.Annotations {
-					switch a.Key {
-					case "web-export":
-						assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
-					case "raw-http":
-						assert.Equal(t, true, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
-					case "final":
-						assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello3" {
+			for _, a := range actions[i].Action.Annotations {
+				switch a.Key {
+				case "web-export":
+					assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+				case "raw-http":
+					assert.Equal(t, true, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+				case "final":
+					assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 				}
-			} else if actions[i].Action.Name == "hello4" {
-				for _, a := range actions[i].Action.Annotations {
-					switch a.Key {
-					case "web-export":
-						assert.Equal(t, false, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
-					case "raw-http":
-						assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
-					case "final":
-						assert.Equal(t, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello4" {
+			for _, a := range actions[i].Action.Annotations {
+				switch a.Key {
+				case "web-export":
+					assert.Equal(t, false, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+				case "raw-http":
+					assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+				case "final":
+					assert.Equal(t, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 				}
-			} else if actions[i].Action.Name == "hello5" {
-				for _, a := range actions[i].Action.Annotations {
-					switch a.Key {
-					case "web-export":
-						assert.Equal(t, false, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
-					case "raw-http":
-						assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
-					case "final":
-						assert.Equal(t, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello5" {
+			for _, a := range actions[i].Action.Annotations {
+				switch a.Key {
+				case "web-export":
+					assert.Equal(t, false, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+				case "raw-http":
+					assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+				case "final":
+					assert.Equal(t, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 				}
 			}
 		}
 	}
+
 }
 
 // Test 15-1: validate manifest_parser.ComposeActions() method
 func TestComposeActionsForInvalidWebActions(t *testing.T) {
-
 	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_invalid_web.yaml")
 	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
 	assert.NotNil(t, err, "Expected error for invalid web-export.")
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index 79748307..265ca9b1 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -37,7 +37,7 @@ const (
 	YAML_KEY_RULE       = "rule"
 	YAML_KEY_SEQUENCE   = "sequence"
 	YAML_KEY_TRIGGER    = "trigger"
-	YAML_KEY_SOURCE     = "source" // deprecated
+	YAML_KEY_SOURCE     = "source"
 )
 
 // YAML schema key values
@@ -87,25 +87,27 @@ type YAMLParser struct {
 	lastID    uint32
 }
 
+// Action is mapped to wsk.Action.*
+// Used in both manifest and deployment files
 type Action struct {
-	//mapping to wsk.Action.Version
-	Version  string `yaml:"version"`           //used in manifest.yaml
-	Location string `yaml:"location"`          //deprecated, used in manifest.yaml
-	Function string `yaml:"function"`          //used in manifest.yaml
-	Runtime  string `yaml:"runtime,omitempty"` //used in manifest.yaml
-	//mapping to wsk.Action.Namespace
-	Namespace  string               `yaml:"namespace"`  //used in deployment.yaml
-	Credential string               `yaml:"credential"` //used in deployment.yaml
-	Inputs     map[string]Parameter `yaml:"inputs"`     //used in both manifest.yaml and deployment.yaml
-	Outputs    map[string]Parameter `yaml:"outputs"`    //used in manifest.yaml
-	//mapping to wsk.Action.Name
+	Version string `yaml:"version"`
+	// TODO(): deprecate location in favor of function
+	Location    string               `yaml:"location"`
+	Function    string               `yaml:"function"`
+	Code        string               `yaml:"code"`
+	Runtime     string               `yaml:"runtime,omitempty"`
+	Namespace   string               `yaml:"namespace"`
+	Credential  string               `yaml:"credential"`
+	Inputs      map[string]Parameter `yaml:"inputs"`
+	Outputs     map[string]Parameter `yaml:"outputs"`
 	Name        string
 	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
-	//Parameters  map[string]interface{} `yaml:parameters` // used in manifest.yaml
-	ExposedUrl string  `yaml:"exposedUrl"` // used in manifest.yaml
-	Webexport  string  `yaml:"web-export"` // used in manifest.yaml
-	Main       string  `yaml:"main"`       // used in manifest.yaml
-	Limits     *Limits `yaml:"limits"`     // used in manifest.yaml
+	// TODO() this is propoagated from package to every action within that package
+	//Parameters  map[string]interface{} `yaml:parameters`
+	ExposedUrl string  `yaml:"exposedUrl"`
+	Webexport  string  `yaml:"web-export"`
+	Main       string  `yaml:"main"`
+	Limits     *Limits `yaml:"limits"`
 }
 
 type Limits struct {
@@ -119,7 +121,7 @@ type Limits struct {
 }
 
 type Sequence struct {
-	Actions     string                 `yaml:"actions"` //used in manifest.yaml
+	Actions     string                 `yaml:"actions"`
 	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
 }
 
@@ -133,7 +135,7 @@ type Dependency struct {
 type Parameter struct {
 	Type        string      `yaml:"type,omitempty"`
 	Description string      `yaml:"description,omitempty"`
-	Value       interface{} `yaml:"value,omitempty"` // JSON Value
+	Value       interface{} `yaml:"value,omitempty"`
 	Required    bool        `yaml:"required,omitempty"`
 	Default     interface{} `yaml:"default,omitempty"`
 	Status      string      `yaml:"status,omitempty"`
@@ -141,28 +143,28 @@ type Parameter struct {
 	multiline   bool
 }
 
+// Trigger is mapped wsk.Trigger.*
 type Trigger struct {
-	//mapping to ????
-	Feed string `yaml:"feed"` //used in manifest.yaml
-	//mapping to wsk.Trigger.Namespace
-	Namespace  string               `yaml:"namespace"`  //used in deployment.yaml
-	Credential string               `yaml:"credential"` //used in deployment.yaml
-	Inputs     map[string]Parameter `yaml:"inputs"`     //used in deployment.yaml
-	//mapping to wsk.Trigger.Name
+	Feed        string               `yaml:"feed"`
+	Namespace   string               `yaml:"namespace"`
+	Credential  string               `yaml:"credential"`
+	Inputs      map[string]Parameter `yaml:"inputs"`
 	Name        string
 	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
-	Source      string                 `yaml:source` // deprecated, used in manifest.yaml
-	//Parameters  map[string]interface{} `yaml:parameters` // used in manifest.yaml
+	// TODO() this is propoagated from package to trigger within that package
+	//Parameters  map[string]interface{} `yaml:parameters`
+	// TODO(): deprecated, please delete it
+	Source string `yaml:source`
 }
 
 type Feed struct {
-	Namespace  string            `yaml:"namespace"`  //used in deployment.yaml
-	Credential string            `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
-	Inputs     map[string]string `yaml:"inputs"`     //used in deployment.yaml
-	Location   string            `yaml:"location"`   //used in manifest.yaml
-	Action     string            `yaml:"action"`     //used in manifest.yaml
+	Namespace  string            `yaml:"namespace"`
+	Credential string            `yaml:"credential"`
+	Inputs     map[string]string `yaml:"inputs"`
+	Location   string            `yaml:"location"`
+	Action     string            `yaml:"action"`
 	// TODO(): need to define operation structure
-	Operations map[string]interface{} `yaml:"operations"` //used in manifest.yaml
+	Operations map[string]interface{} `yaml:"operations"`
 	Name       string
 }
 
@@ -185,46 +187,44 @@ type Repository struct {
 
 type Package struct {
 	//mapping to wsk.SentPackageNoPublish.Name
-	Packagename string `yaml:"name"` //used in manifest.yaml
+	Packagename string `yaml:"name"`
 	//mapping to wsk.SentPackageNoPublish.Version
-	Version      string                `yaml:"version"` //used in manifest.yaml, mandatory
-	License      string                `yaml:"license"` //used in manifest.yaml, mandatory
+	Version      string                `yaml:"version"` //mandatory
+	License      string                `yaml:"license"` //mandatory
 	Repositories []Repository          `yaml:"repositories,omitempty"`
-	Dependencies map[string]Dependency `yaml: dependencies` //used in manifest.yaml
+	Dependencies map[string]Dependency `yaml: dependencies`
 	//mapping to wsk.SentPackageNoPublish.Namespace
-	Namespace        string                 `yaml:"namespace"`  //used in both manifest.yaml and deployment.yaml
-	Credential       string                 `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
-	ApiHost          string                 `yaml:"apiHost"`    //used in both manifest.yaml and deployment.yaml
+	Namespace        string                 `yaml:"namespace"`
+	Credential       string                 `yaml:"credential"`
+	ApiHost          string                 `yaml:"apiHost"`
 	ApigwAccessToken string                 `yaml:"apigwAccessToken"`
-	Actions          map[string]Action      `yaml:"actions"`  //used in both manifest.yaml and deployment.yaml
-	Triggers         map[string]Trigger     `yaml:"triggers"` //used in both manifest.yaml and deployment.yaml
-	Feeds            map[string]Feed        `yaml:"feeds"`    //used in both manifest.yaml and deployment.yaml
-	Rules            map[string]Rule        `yaml:"rules"`    //used in both manifest.yaml and deployment.yaml
-	Inputs           map[string]Parameter   `yaml:"inputs"`   //deprecated, used in deployment.yaml
+	Actions          map[string]Action      `yaml:"actions"`
+	Triggers         map[string]Trigger     `yaml:"triggers"`
+	Feeds            map[string]Feed        `yaml:"feeds"`
+	Rules            map[string]Rule        `yaml:"rules"`
+	Inputs           map[string]Parameter   `yaml:"inputs"`
 	Sequences        map[string]Sequence    `yaml:"sequences"`
 	Annotations      map[string]interface{} `yaml:"annotations,omitempty"`
-
 	// TODO() this is a convenience we want for package-shared vars that would be
 	// propagated to every action within the package.
-	//Parameters  map[string]interface{} `yaml: parameters` // used in manifest.yaml
-	Apis map[string]map[string]map[string]map[string]string `yaml:"apis"` //used in manifest.yaml
+	//Parameters  map[string]interface{} `yaml: parameters`
+	Apis map[string]map[string]map[string]map[string]string `yaml:"apis"`
 }
 
 type Project struct {
-	Name             string             `yaml:"name"`      //used in deployment.yaml
-	Namespace        string             `yaml:"namespace"` //used in deployment.yaml
+	Name             string             `yaml:"name"`
+	Namespace        string             `yaml:"namespace"`
 	Credential       string             `yaml:"credential"`
 	ApiHost          string             `yaml:"apiHost"`
 	ApigwAccessToken string             `yaml:"apigwAccessToken"`
 	Version          string             `yaml:"version"`
-	Packages         map[string]Package `yaml:"packages"` //used in deployment.yaml
+	Packages         map[string]Package `yaml:"packages"`
 }
 
 type YAML struct {
-	Project  Project            `yaml:"project"`  //used in deployment.yaml
-	Packages map[string]Package `yaml:"packages"` //used in deployment.yaml
-	//Package     Package            `yaml:"package"`   // DEPRECATED.  Should we add warning if found?
-	Filepath string //file path of the yaml file
+	Project  Project            `yaml:"project"`
+	Packages map[string]Package `yaml:"packages"`
+	Filepath string             //file path of the yaml file
 }
 
 // function to return Project or Application depending on what is specified in
diff --git a/specification/README.md b/specification/README.md
index cb887353..3904a2fc 100644
--- a/specification/README.md
+++ b/specification/README.md
@@ -20,7 +20,7 @@
 
 [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
 
-Current version (link):  [openwhisk_v0.9.1.pdf](https://github.com/apache/incubator-openwhisk-wskdeploy/blob/master/specification/openwhisk_v0.9.1.pdf)
+The canonical specification is in PDF format; its current and past versions can be found listed above in this directory.  
 
 ## Purpose
 
diff --git a/tests/dat/manifest_data_compose_actions_for_function.yaml b/tests/dat/manifest_data_compose_actions_for_function.yaml
index 550d6c0a..2f42fd5c 100644
--- a/tests/dat/manifest_data_compose_actions_for_function.yaml
+++ b/tests/dat/manifest_data_compose_actions_for_function.yaml
@@ -18,8 +18,6 @@ packages:
   helloworld:
     actions:
       hello1:
-        function: ../tests/src/integration/helloworld/actions/hello.js
-
-# TODO() uncomment this after we add support for action file content from URL
-#     hello2:
-#	    function: https://raw.githubusercontent.com/apache/incubator-openwhisk-wskdeploy/master/tests/isrc/integration/helloworld/manifest.yaml
+        function: ../src/integration/helloworld/actions/hello.js
+      hello2:
+        function: https://raw.githubusercontent.com/apache/incubator-openwhisk-wskdeploy/master/tests/src/integration/helloworld/actions/hello.js
diff --git a/tests/dat/manifest_data_compose_actions_for_function_and_code.yaml b/tests/dat/manifest_data_compose_actions_for_function_and_code.yaml
new file mode 100644
index 00000000..8c9316c3
--- /dev/null
+++ b/tests/dat/manifest_data_compose_actions_for_function_and_code.yaml
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+packages:
+  helloworld:
+    actions:
+      hello:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        code: const main = ({ msg }) => { console.log(msg); return {msg}; }
+        runtime: nodejs
diff --git a/tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml b/tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml
new file mode 100644
index 00000000..f601c27a
--- /dev/null
+++ b/tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+packages:
+  helloworld:
+    actions:
+      hello:
+        function: https://raw.githubusercontent.com/apache/incubator-openwhisk-wskdeploy/master/tests/src/integration/helloworld/actions/
diff --git a/tests/dat/manifest_data_compose_actions_for_limits.yaml b/tests/dat/manifest_data_compose_actions_for_limits.yaml
index 069e35ec..2a4f84a8 100644
--- a/tests/dat/manifest_data_compose_actions_for_limits.yaml
+++ b/tests/dat/manifest_data_compose_actions_for_limits.yaml
@@ -18,11 +18,11 @@ packages:
   helloworld:
     actions:
       hello1:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         limits:
           timeout: 1
       hello2:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         limits:
           timeout: 180
           memorySize: 128
diff --git a/tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml b/tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml
new file mode 100644
index 00000000..9ab90126
--- /dev/null
+++ b/tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+packages:
+  helloworld:
+    actions:
+      hello:
+        code: |
+              function main(params) {
+                console.log(params);
+                return params || {};
+              }
diff --git a/tests/dat/manifest_data_compose_actions_for_web.yaml b/tests/dat/manifest_data_compose_actions_for_web.yaml
index e803c0f0..729c6191 100644
--- a/tests/dat/manifest_data_compose_actions_for_web.yaml
+++ b/tests/dat/manifest_data_compose_actions_for_web.yaml
@@ -18,17 +18,17 @@ packages:
   helloworld:
     actions:
       hello1:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: true
       hello2:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: yes
       hello3:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: raw
       hello4:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: false
       hello5:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: no
diff --git a/tests/dat/manifest_data_compose_runtimes_implicit.yaml b/tests/dat/manifest_data_compose_runtimes_implicit.yaml
index 3de7aff1..192d722d 100644
--- a/tests/dat/manifest_data_compose_runtimes_implicit.yaml
+++ b/tests/dat/manifest_data_compose_runtimes_implicit.yaml
@@ -18,11 +18,11 @@ packages:
   helloworld:
     actions:
       helloPython:
-        function: ../tests/src/integration/helloworld/actions/hello.py
+        function: ../src/integration/helloworld/actions/hello.py
       helloJava:
-        function: ../tests/src/integration/helloworld/actions/hello.jar
+        function: ../src/integration/helloworld/actions/hello.jar
         main: Hello
       helloSwift:
-        function: ../tests/src/integration/helloworld/actions/hello.swift
+        function: ../src/integration/helloworld/actions/hello.swift
       helloNodejs:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
diff --git a/tests/src/integration/common/wskdeploy.go b/tests/src/integration/common/wskdeploy.go
index caddc99a..82a34048 100644
--- a/tests/src/integration/common/wskdeploy.go
+++ b/tests/src/integration/common/wskdeploy.go
@@ -170,6 +170,10 @@ func (Wskdeploy *Wskdeploy) ManagedDeployment(manifestPath string, deploymentPat
 	return Wskdeploy.RunCommand("-m", manifestPath, "-d", deploymentPath, "--managed")
 }
 
+func (Wskdeploy *Wskdeploy) HeadlessManagedDeployment(manifestPath string, deploymentPath string, name string) (string, error) {
+	return Wskdeploy.RunCommand("-m", manifestPath, "-d", deploymentPath, "--managed", "--projectname", name)
+}
+
 func (Wskdeploy *Wskdeploy) ManagedUndeployment(manifestPath string, deploymentPath string) (string, error) {
 	return Wskdeploy.RunCommand("undeploy", "-m", manifestPath, "-d", deploymentPath, "--managed")
 }
diff --git a/tests/src/integration/helloworld/manifest.yaml b/tests/src/integration/helloworld/manifest.yaml
index 85b37631..b173abd0 100644
--- a/tests/src/integration/helloworld/manifest.yaml
+++ b/tests/src/integration/helloworld/manifest.yaml
@@ -32,6 +32,25 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello World!
+        helloNodejsWithCode:
+          code: |
+                function main(params) {
+                    msg = "Hello, " + params.name + " from " + params.place;
+                    console.log(msg)
+                    return { payload:  msg };
+                }
+          runtime: nodejs:6
+          inputs:
+            name:
+              type: string
+              description: name of a person
+            place:
+              type: string
+              description: location of a person
+          outputs:
+            payload:
+              type: string
+              description: a simple greeting message, Hello World!
         # helloworld action in Java
         helloJava:
           function: actions/hello.jar
@@ -45,6 +64,33 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello Bob!
+# Uncomment Java With Code once action creation is fixed.
+# this is failing with internal server application problem.
+#        helloJavaWithCode:
+#          code: |
+#                import com.google.gson.JsonObject;
+#                public class Hello {
+#                    private JsonObject response;
+#                    public static JsonObject main(JsonObject args) {
+#                        String name = "stranger";
+#                        if (args.has("name"))
+#                            name = args.getAsJsonPrimitive("name").getAsString();
+#                        JsonObject response = new JsonObject();
+#                        response.addProperty("greeting", "Hello " + name + "!");
+#                        System.out.println(response);
+#                        return response;
+#                    }
+#                }
+#          main: Hello
+#          runtime: java
+#          inputs:
+#            name:
+#              type: string
+#              description: name of a person
+#          outputs:
+#            payload:
+#              type: string
+#              description: a simple greeting message, Hello Bob!
         # helloworld action in python
         helloPython:
           function: actions/hello.py
@@ -57,6 +103,22 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello Henry!
+        helloPythonWithCode:
+          code: |
+                def main(args):
+                    name = args.get("name", "stranger")
+                    greeting = "Hello " + name + "!"
+                    print(greeting)
+                    return {"greeting": greeting}
+          runtime: python
+          inputs:
+            name:
+              type: string
+              description: name of a person
+          outputs:
+            payload:
+              type: string
+              description: a simple greeting message, Hello Henry!
         # helloworld action in swift
         helloSwift:
           function: actions/hello.swift
@@ -69,10 +131,31 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello stranger!
+        helloSwiftWithCode:
+          code: |
+                func main(args: [String:Any]) -> [String:Any] {
+                    var msg = ["greeting": "Hello stranger!"]
+                    if let name = args["name"] as? String {
+                        if !name.isEmpty {
+                            msg["greeting"] = "Hello \(name)!"
+                        }
+                    }
+                    print (msg)
+                    return msg
+                }
+          runtime: swift:3.1.1
+          inputs:
+            name:
+              type: string
+              description: name of a person
+          outputs:
+            payload:
+              type: string
+              description: a simple greeting message, Hello stranger!
       sequences:
         # sequence of helloworld in all four runtimes
         hello-world-series:
-          actions: helloNodejs, helloJava, helloPython, helloSwift
+          actions: helloNodejs, helloNodejsWithCode, helloJava, helloPython, helloPythonWithCode, helloSwift, helloSwiftWithCode
       triggers:
         # trigger to activate helloworld sequence
         triggerHelloworld:
diff --git a/tests/src/integration/managed-deployment/05-manifest-headless.yaml b/tests/src/integration/managed-deployment/05-manifest-headless.yaml
new file mode 100644
index 00000000..cf2b1c8e
--- /dev/null
+++ b/tests/src/integration/managed-deployment/05-manifest-headless.yaml
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+
+packages:
+  ManagedPackage-Headless:
+    actions:
+      HelloWorld-Headless:
+        function: actions/hello.js
+        runtime: nodejs:6
\ No newline at end of file
diff --git a/tests/src/integration/managed-deployment/managed-deployment_test.go b/tests/src/integration/managed-deployment/managed-deployment_test.go
index c3bf5d63..119296d2 100644
--- a/tests/src/integration/managed-deployment/managed-deployment_test.go
+++ b/tests/src/integration/managed-deployment/managed-deployment_test.go
@@ -20,10 +20,11 @@
 package tests
 
 import (
-	"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
-	"github.com/stretchr/testify/assert"
 	"os"
 	"testing"
+
+	"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestManagedDeployment(t *testing.T) {
@@ -58,4 +59,9 @@ func TestManagedDeployment(t *testing.T) {
 	wskdeploy = common.NewWskdeploy()
 	_, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath)
 	assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.")
+
+	manifestPath = os.Getenv("GOPATH") + path + "05-manifest-headless.yaml"
+	wskdeploy = common.NewWskdeploy()
+	_, err = wskdeploy.HeadlessManagedDeployment(manifestPath, deploymentPath, "Headless Managed")
+	assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.")
 }
diff --git a/utils/flags.go b/utils/flags.go
index e55983e2..9232fc03 100644
--- a/utils/flags.go
+++ b/utils/flags.go
@@ -31,7 +31,6 @@ type WskDeployFlags struct {
 	CfgFile          string
 	CliVersion       string
 	CliBuild         string
-	Verbose          bool
 	ProjectPath      string
 	DeploymentPath   string
 	ManifestPath     string
@@ -39,8 +38,11 @@ type WskDeployFlags struct {
 	Strict           bool // strict flag to support user defined runtime version.
 	Key              string
 	Cert             string
-	Managed          bool // OpenWhisk Managed Deployments
+	Managed          bool   // OpenWhisk Managed Deployments
+	ProjectName      string // Project name
 	ApigwAccessToken string
+	Verbose          bool
+	Trace            bool
 }
 
 func (flags *WskDeployFlags) Format() string {
diff --git a/utils/runtimes.go b/utils/runtimes.go
index 48f6af65..bf3cc770 100644
--- a/utils/runtimes.go
+++ b/utils/runtimes.go
@@ -39,6 +39,7 @@ const (
 	ZIP_FILE_EXTENSION      = "zip"
 	HTTP_CONTENT_TYPE_KEY   = "Content-Type"
 	HTTP_CONTENT_TYPE_VALUE = "application/json; charset=UTF-8"
+	RUNTIME_NOT_SPECIFIED   = "NOT SPECIFIED"
 )
 
 // Structs used to denote the OpenWhisk Runtime information
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index b8c1bdc8..ac088254 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -17,18 +17,18 @@
 
 package wski18n
 
-// descriptive key names
 // DO NOT TRANSLATE
+// descriptive key names
 const (
-	ACTION_CODE        = "Action source"
 	ACTIONS            = "Actions"
 	ACTIVATIONS        = "Activations"
 	API_HOST           = "API host"
+	APIGW_ACCESS_TOKEN = "API Gateway Access Token"
 	AUTH_KEY           = "authentication key"
 	COMMAND_LINE       = "wskdeploy command line"
-	DEPLOYMENT         = "deployment"
 	CONFIGURATION      = "Configuration"
-	MANIFEST           = "manifest"
+	DEPLOYMENT_FILE    = "deployment file"
+	MANIFEST_FILE      = "manifest file"
 	NAME_PROJECT       = "project name"
 	NAMESPACES         = "Namespaces"
 	PACKAGE_BINDING    = "package binding"
@@ -37,11 +37,44 @@ const (
 	PACKAGES           = "Packages"
 	RULES              = "Rules"
 	TRIGGER_FEED       = "trigger feed"
-	APIGW_ACCESS_TOKEN = "API Gateway Access Token"
+	CMD_DEPLOY         = "deploy"
+	CMD_UNDEPLOY       = "undeploy"
+	CMD_SYNC           = "sync"
+)
+
+// DO NOT TRANSLATE
+// Known keys used for text replacement in i18n translated strings
+const (
+	KEY_ACTION          = "action"
+	KEY_CMD             = "cmd"
+	KEY_CODE            = "code"
+	KEY_DEPLOYMENT_NAME = "dname"
+	KEY_DEPLOYMENT_PATH = "dpath"
+	KEY_ERR             = "err"
+	KEY_EXTENSION       = "ext"
+	KEY_FILE_TYPE       = "filetype"
+	KEY_HOST            = "host"
+	KEY_KEY             = "key"
+	KEY_LIMIT           = "limit"
+	KEY_MANIFEST_NAME   = "mname"
+	KEY_MANIFEST_PATH   = "mpath"
+	KEY_NAME            = "name"
+	KEY_NAMESPACE       = "namespace"
+	KEY_NEW             = "newkey"
+	KEY_OLD             = "oldkey"
+	KEY_PATH            = "path"
+	KEY_PROJECT         = "project"
+	KEY_RUNTIME         = "runtime"
+	KEY_SOURCE          = "source"
+	KEY_VALUE           = "value"
+	KEY_VALUE_MIN       = "min" // TODO() attempt to use this for Limit value range errors
+	KEY_VALUE_MAX       = "max" // TODO() attempt to use this for Limit value range errors
+	KEY_API             = "api"
+	KEY_URL             = "url"
 )
 
-// i18n Identifiers
 // DO NOT TRANSLATE
+// i18n Identifiers
 const (
 	// Debug / trace message prefixes
 	ID_MSG_PREFIX_ERROR   = "msg_prefix_error"   // "Error"
@@ -67,13 +100,17 @@ const (
 	ID_CMD_FLAG_INTERACTIVE = "msg_cmd_flag_interactive"
 	ID_CMD_FLAG_KEY_FILE    = "msg_cmd_flag_key_file"
 	ID_CMD_FLAG_MANAGED     = "msg_cmd_flag_allow_managed"
+	ID_CMD_FLAG_PROJECTNAME = "msg_cmd_flag_project_name"
 	ID_CMD_FLAG_MANIFEST    = "msg_cmd_flag_manifest"
 	ID_CMD_FLAG_NAMESPACE   = "msg_cmd_flag_namespace"
 	ID_CMD_FLAG_PROJECT     = "msg_cmd_flag_project"
 	ID_CMD_FLAG_STRICT      = "msg_cmd_flag_strict"
-	ID_CMD_FLAG_TOGGLE_HELP = "msg_cmd_flag_toggle_help"
+	ID_CMD_FLAG_TRACE       = "msg_cmd_flag_trace"
 	ID_CMD_FLAG_VERBOSE     = "msg_cmd_flag_allow_verbose"
 
+	// Root <command> using <manifest | deployment> file
+	ID_MSG_COMMAND_USING_X_cmd_X_filetype_X_path_X = "msg_command_using_filename_at_path"
+
 	// Configuration messages
 	ID_MSG_CONFIG_MISSING_AUTHKEY                       = "msg_config_missing_authkey"
 	ID_MSG_CONFIG_MISSING_APIHOST                       = "msg_config_missing_apihost"
@@ -98,9 +135,6 @@ const (
 	ID_MSG_UNDEPLOYMENT_FAILED    = "msg_undeployment_failed"
 	ID_MSG_UNDEPLOYMENT_SUCCEEDED = "msg_undeployment_succeeded"
 
-	ID_MSG_MANIFEST_DEPLOY_X_path_X   = "msg_manifest_using_deployment"
-	ID_MSG_MANIFEST_UNDEPLOY_X_path_X = "msg_manifest_using_undeployment"
-
 	ID_MSG_ENTITY_DEPLOYED_SUCCESS_X_key_X_name_X   = "msg_entity_deployed_success"
 	ID_MSG_ENTITY_DEPLOYING_X_key_X_name_X          = "msg_entity_deploying"
 	ID_MSG_ENTITY_UNDEPLOYED_SUCCESS_X_key_X_name_X = "msg_entity_undeployed_success"
@@ -127,20 +161,24 @@ const (
 	ID_MSG_PROMPT_UNDEPLOY  = "msg_prompt_undeploy"
 
 	// Errors
-	ID_ERR_DEPENDENCY_UNKNOWN_TYPE                               = "msg_err_dependency_unknown_type"
-	ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X                    = "msg_err_entity_create"
-	ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X                    = "msg_err_entity_delete"
-	ID_ERR_FEED_INVOKE_X_err_X_code_X                            = "msg_err_feed_invoke"
-	ID_ERR_KEY_MISSING_X_key_X                                   = "msg_err_key_missing_mandatory"
-	ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X                      = "msg_err_manifest_not_found"
-	ID_ERR_NAME_MISMATCH_X_key_X_dname_X_dpath_X_mname_X_moath_X = "msg_err_name_mismatch"
-	ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X                  = "msg_err_runtime_invalid"
-	ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X           = "msg_err_runtime_mismatch"
-	ID_ERR_RUNTIMES_GET_X_err_X                                  = "msg_err_runtimes_get"
-	ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X              = "msg_err_url_invalid"
-	ID_ERR_URL_MALFORMED_X_urltype_X_url_X                       = "msg_err_url_malformed"
-	ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X               = "msg_err_api_missing_web_action"
-	ID_ERR_API_MISSING_ACTION_X_action_X_api_X                   = "msg_err_api_missing_action"
+	ID_ERR_DEPENDENCY_UNKNOWN_TYPE                                   = "msg_err_dependency_unknown_type"
+	ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X                        = "msg_err_entity_create"
+	ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X                        = "msg_err_entity_delete"
+	ID_ERR_FEED_INVOKE_X_err_X_code_X                                = "msg_err_feed_invoke"
+	ID_ERR_KEY_MISSING_X_key_X                                       = "msg_err_key_missing_mandatory"
+	ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X                          = "msg_err_manifest_not_found"
+	ID_ERR_NAME_MISMATCH_X_key_X_dname_X_dpath_X_mname_X_moath_X     = "msg_err_name_mismatch"
+	ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X                      = "msg_err_runtime_invalid"
+	ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X               = "msg_err_runtime_mismatch"
+	ID_ERR_RUNTIMES_GET_X_err_X                                      = "msg_err_runtimes_get"
+	ID_ERR_RUNTIME_ACTION_SOURCE_NOT_SUPPORTED_X_ext_X_action_X      = "msg_err_runtime_action_source_not_supported"
+	ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X                  = "msg_err_url_invalid"
+	ID_ERR_URL_MALFORMED_X_urltype_X_url_X                           = "msg_err_url_malformed"
+	ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X                   = "msg_err_api_missing_web_action"
+	ID_ERR_API_MISSING_ACTION_X_action_X_api_X                       = "msg_err_api_missing_action"
+	ID_ERR_ACTION_INVALID_X_action_X                                 = "msg_err_action_invalid"
+	ID_ERR_ACTION_MISSING_RUNTIME_WITH_CODE_X_action_X               = "msg_err_action_missing_runtime_with_code"
+	ID_ERR_ACTION_FUNCTION_REMOTE_DIR_NOT_SUPPORTED_X_action_X_url_X = "msg_err_action_function_remote_dir_not_supported"
 
 	// Server-side Errors (wskdeploy as an Action)
 	ID_ERR_JSON_MISSING_KEY_CMD = "msg_err_json_missing_cmd_key"
@@ -163,45 +201,16 @@ const (
 	ID_WARN_ENTITY_NAME_EXISTS_X_key_X_name_X                 = "msg_warn_entity_name_exists"
 	ID_WARN_PACKAGES_NOT_FOUND_X_path_X                       = "msg_warn_packages_not_found"
 	ID_WARN_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X          = "msg_warn_deployment_name_not_found"
+	ID_WARN_PROJECT_NAME_OVERRIDDEN                           = "msg_warn_project_name_overridden"
 
 	// Verbose (Debug/Trace) messages
-	ID_DEBUG_DEPLOYING_USING                              = "msg_dbg_deploying_using"
-	ID_DEBUG_UNDEPLOYING_USING                            = "msg_dbg_undeploying_using"
 	ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X                = "msg_dbg_searching_project_directory"
 	ID_DEBUG_DEPLOYMENT_NAME_FOUND_X_key_X_name_X         = "msg_dbg_deployment_name_found"
 	ID_DEBUG_PACKAGES_FOUND_UNDER_ROOT_X_path_X           = "msg_dbg_packages_found_root"
 	ID_DEBUG_PACKAGES_FOUND_UNDER_PROJECT_X_path_X_name_X = "msg_dbg_packages_found_project"
 )
 
-// Known keys used for text replacement in i18n translated strings
-const (
-	KEY_ACTION          = "action"
-	KEY_CMD             = "cmd"
-	KEY_CODE            = "code"
-	KEY_DEPLOYMENT_NAME = "dname"
-	KEY_DEPLOYMENT_PATH = "dpath"
-	KEY_ERR             = "err"
-	KEY_EXTENSION       = "ext"
-	KEY_FILE_TYPE       = "filetype"
-	KEY_HOST            = "host"
-	KEY_KEY             = "key"
-	KEY_LIMIT           = "limit"
-	KEY_MANIFEST_NAME   = "mname"
-	KEY_MANIFEST_PATH   = "mpath"
-	KEY_NAME            = "name"
-	KEY_NAMESPACE       = "namespace"
-	KEY_NEW             = "newkey"
-	KEY_OLD             = "oldkey"
-	KEY_PATH            = "path"
-	KEY_PROJECT         = "project"
-	KEY_RUNTIME         = "runtime"
-	KEY_SOURCE          = "source"
-	KEY_VALUE           = "value"
-	KEY_VALUE_MIN       = "min" // TODO() attempt to use this for Limit value range errors
-	KEY_VALUE_MAX       = "max" // TODO() attempt to use this for Limit value range errors
-	KEY_API             = "api"
-)
-
+// DO NOT TRANSLATE
 // Used to unit test that translations exist with these IDs
 var I18N_ID_SET = [](string){
 	ID_CMD_DESC_LONG_REPORT,
@@ -222,15 +231,14 @@ var I18N_ID_SET = [](string){
 	ID_CMD_FLAG_MANIFEST,
 	ID_CMD_FLAG_NAMESPACE,
 	ID_CMD_FLAG_PROJECT,
+	ID_CMD_FLAG_PROJECTNAME,
 	ID_CMD_FLAG_STRICT,
-	ID_CMD_FLAG_TOGGLE_HELP,
+	ID_CMD_FLAG_TRACE,
 	ID_CMD_FLAG_VERBOSE,
-	ID_DEBUG_DEPLOYING_USING,
 	ID_DEBUG_DEPLOYMENT_NAME_FOUND_X_key_X_name_X,
 	ID_DEBUG_PACKAGES_FOUND_UNDER_PROJECT_X_path_X_name_X,
 	ID_DEBUG_PACKAGES_FOUND_UNDER_ROOT_X_path_X,
 	ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X,
-	ID_DEBUG_UNDEPLOYING_USING,
 	ID_ERR_DEPENDENCY_UNKNOWN_TYPE,
 	ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X,
 	ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X,
@@ -244,6 +252,7 @@ var I18N_ID_SET = [](string){
 	ID_ERR_RUNTIMES_GET_X_err_X,
 	ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X,
 	ID_ERR_URL_MALFORMED_X_urltype_X_url_X,
+	ID_MSG_COMMAND_USING_X_cmd_X_filetype_X_path_X,
 	ID_MSG_CONFIG_INFO_APIHOST_X_host_X_source_X,
 	ID_MSG_CONFIG_INFO_AUTHKEY_X_source_X,
 	ID_MSG_CONFIG_INFO_NAMESPACE_X_namespace_X_source_X,
@@ -266,8 +275,6 @@ var I18N_ID_SET = [](string){
 	ID_MSG_ENTITY_UNDEPLOYING_X_key_X_name_X,
 	ID_MSG_MANAGED_FOUND_DELETED_X_key_X_name_X_project_X,
 	ID_MSG_MANAGED_UNDEPLOYMENT_FAILED,
-	ID_MSG_MANIFEST_DEPLOY_X_path_X,
-	ID_MSG_MANIFEST_UNDEPLOY_X_path_X,
 	ID_MSG_PREFIX_ERROR,
 	ID_MSG_PREFIX_INFO,
 	ID_MSG_PREFIX_SUCCESS,
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 440b0726..f8a38356 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -97,7 +97,7 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
 	return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5a\x6d\x6f\x1b\x37\xf2\x7f\x9f\x4f\x31\x08\xfe\x40\x5a\xc0\x51\xd2\xfe\x71\xc0\x21\x80\x71\xc8\x5d\xd2\x36\xd7\x26\x0e\xec\xf8\x8a\x22\x35\x36\xd4\x72\xb4\xcb\x6a\x97\x5c\x90\x5c\x2b\xaa\xa1\xef\x7e\x18\x92\xfb\x20\xd9\xdc\xa5\x94\x06\xd7\x37\x55\xcc\xe1\xcc\x6f\x86\xe4\x3c\xee\xc7\x47\x00\x77\x8f\x00\x00\x1e\x0b\xfe\xf8\x05\x3c\xae\x4d\x91\x35\x1a\x57\xe2\x73\x86\x5a\x2b\xfd\xf8\xcc\xaf\x5a\xcd\xa4\xa9\x98\x15\x4a\x12\xd9\x6b\xb7\xf6\x08\x60\x77\x36\xc1\x41\xc8\x95\x8a\x30\x78\x43\x4b\x73\xfb\x4d\x9b\xe7\x68\x4c\x84\xc5\x55\x58\x9d\xe3\xb2\x61\x5a\x0a\x59\x44\xb8\xfc\x1a\x56\xa3\x5c\xf2\x9a\x67\x1c\x4d\x9e\x55\x4a\x16\x99\xc6\x46\x69\x1b\xe1\x75\xe9\x16\x0d\x28\x09\x1c\x9b\x4a\x6d\x91\x03\x4a\x2b\xac\x40\x03\xdf\x88\x05\x2e\xce\xe0\x3d\xcb\xd7\xac\x40\x73\x06\x2f\x73\xda\x67\xce\xe0\x83\x16\x45\x81\xda\x9c\xc1\x65\x5b\xd1\x0a\xda\x7c\xf1\x2d\x30\x03\x1b\xac\x2a\xfa\xbf\xc6\x1c\xa5\x75\x3b\x6e\x9d\x34\x03\x42\x82\x2d\x11\x4c\x83\xb9\x58\x09\xe4\x20\x59\x8d\xa6\x61\x39\x2e\x92\x75\x51\x2a\xa6\xc9\x4b\xb0\x4a\x55\x60\x55\x50\xe4\x0c\x5a\xe9\x7f\x01\x93\x1c\xcc\x56\xe6\xa0\x1a\x94\x9b\x52\x98\x35\x34\x41\x27\x68\x8d\x90\x05\x30\xa8\x99\x14\x2b\x34\xd6\x11\xab\x86\xb8\xb2\x2a\xb0\xaa\x49\x93\x95\xa8\x7a\xf2\xdf\x5e\xbe\xfd\x25\x05\xb3\x29\x95\xb6\xd3\x07\xf0\x5e\xab\x5b\xc1\xd1\x00\x03\xd3\xd6\x35\xd3\x5b\xf0\xf4\xa0\x56\xb0\x29\x99\x7d\x62\x60\x89\x38\x3a\x9e\x2f\x33\x63\x80\x34\x6b\x47\x83\x96\x6c\x59\x62\xd5\x04\xd1\xb0\x55\xad\x4e\x32\x21\x99\x2a\x1d\xcb\x2d\x6a\x43\xb2\x63\xf6\x11\xd2\x3a\x85\x03\x1d\xc8\xb6\x5e\xa2\x76\xe6\x31\x6b\x0f\x6d\x5a\xd6\xaa\x62\x45\xc6\x1a\x91\x95\xca\xc4\xb4\xf6\x2a\xbd\x7c\xff\x06\x3e\xfd\x74\x71\xf5\xe1\x53\x22\xc7\x69\xec\x23\xa6\xff\x79\x7d\x79\xf5\xe6\xe2\x5d\x12\xdf\xd6\x96\xd9\x1a\xb7\x11\xa6\xb4\xac\xb4\xf8\xd3\xfd\x01\x3e\xfd\xfc\xfa\xb7\x14\xa6\x39\x6a\x9b\xd1\xb9\x44\xb8\x36\xcc\x96\x64\x52\x32\xf4\x82\x88\xdd\x21\xa6\x30\x56\x72\x25\x62\x9e\xca\x2f\x3a\x56\xf0\x0d\xc7\x15\x6b\x2b\x0b\xc2\xc0\xff\xfd\x74\xf1\xf6\xf5\xb3\xc5\xc6\xac\x1b\xad\x1a\xf3\x6d\x8a\x55\xaa\x4a\x6d\xb2\xc0\x23\xe6\x5f\x1d\x11\xf4\x44\xf3\x5c\x87\xf7\x3d\x65\x97\xde\xa7\xf4\x8e\x20\x81\xb5\x90\x16\x35\x23\xf7\x17\xb3\xb9\x47\x3b\xa2\x83\x46\xab\xba\x49\x02\xbe\xc6\x6d\xf2\x71\xae\x71\x9b\x0a\xda\x5b\xb9\x66\x92\x15\xc8\x27\x61\x37\x5a\xfd\x81\xb9\x1d\x82\x85\x55\xb0\x44\xa8\x99\x5e\x23\x87\x8e\xc3\xbc\xc4\xce\x69\xcc\xd8\x7f\xcf\xb7\x24\xb0\xed\x7d\x62\x84\xef\xb0\x3e\xcf\x2b\xa8\x3a\x83\xd0\xa0\xbe\x45\x5d\xa1\x31\x9d\x6d\x12\x58\x1b\xab\x45\x94\xb3\x37\x74\x6b\x50\xd3\x95\x16\x12\x39\xe8\x56\x5a\x51\xf7\xbe\x30\x41\x82\x55\x45\x51\x61\x46\x7e\x3c\x22\xe6\x83\xa3\x80\x9f\xc8\xd3\xd7\x68\x0c\x2b\xd2\x6f\xca\x2d\xea\xa5\x32\x31\x23\x87\x55\x50\xad\x6d\xda\x29\x73\x38\x37\x91\xd5\xc2\x50\x24\x71\x0e\x30\xee\xff\x3e\x94\x08\x44\x41\x17\x2f\xf7\x4e\x90\x2e\xb8\x30\x20\x95\x05\xcf\xaa\xd5\xc8\x17\xbf\x4f\x99\xe7\x40\x62\x23\x26\x62\x03\x49\x24\x27\x4e\x24\x5f\x26\x67\xee\x56\x92\xa4\x9e\xe6\x34\x51\x41\x95\xa9\x44\xf6\x50\x9f\x8f\x77\x77\x0b\xfa\xbd\xdb\xdd\x9c\xc1\x4a\xab\x1a\xee\xee\x16\x46\xb5\x3a\xc7\xdd\x2e\x49\xa6\x3f\xb0\x39\x99\x44\xd6\x9d\x95\x41\x7b\x9a\xac\xde\x3c\x73\xd2\xf6\xec\x48\x2a\xf6\x7f\x38\x5d\xcf\x46\x14\x9b\x8c\xb9\x1c\x3e\xb3\x6a\x8d\x72\x56\x65\xda\x01\x7e\x07\xb8\x1d\xa7\x29\xdf\xca\x9a\x69\x53\xb2\x2a\xab\x54\xce\xaa\x88\xc4\xeb\x8e\x0a\x2e\x1a\x94\xbf\xba\xec\x23\x78\x0c\xe3\xe5\xb9\xdd\x70\xcb\xaa\x16\x4d\xa2\x40\x89\x76\xa3\xf4\xfa\x64\x91\x2e\xbe\x49\xb4\xc0\x2c\xa9\xdb\xea\x6a\x46\xd7\x21\xd4\x66\x39\x93\x39\x56\x55\x34\x14\x5d\xfc\xbc\x80\x7f\x79\x1a\x4a\x41\x87\x9d\xa9\x02\x56\x4c\xc4\xb9\xbf\x1a\x62\x3e\x17\x3c\xbc\xc5\xba\xa9\xd0\x22\x98\x96\x8e\x74\xd5\x56\xd5\x76\x01\x97\xad\x84\x4f\x7d\x32\xda\xd7\x1d\x9f\x28\x2c\x68\xac\x15\x45\x76\xa6\xad\x60\x55\xb5\x1d\xf2\x78\x66\x0c\xda\xe9\x53\x18\x21\xf5\x45\x41\x66\x2c\xb3\x6d\x2c\xfd\x79\xfa\xf4\xe9\xd3\xf3\xf3\xf3\xf3\xd1\x59\x8c\x74\xb8\x72\x5b\x81\x08\x88\x30\x49\xaa\x2b\x67\x91\xa7\x98\xa8\x33\x0d\x87\x50\x03\x7b\xe3\x4c\x5f\xb2\xd3\xcf\x7a\xbc\x37\x5d\xc8\xe4\x79\x5f\x8f\x28\xa7\x4f\x3c\x59\xde\x9c\xfd\xf6\x44\x9e\x60\xc1\x2e\x2d\xca\x5c\x0d\x36\x9f\xce\x5e\xbb\x52\x8d\xbc\x21\xa5\x2d\xbb\xdd\x0d\xac\x94\x4e\x7d\x37\x07\xc2\xc6\x8a\x1e\x25\x2e\xf9\xe8\x5c\x6e\xb9\xcd\xba\x17\x33\xd3\x5c\xb9\xbb\xa3\x4c\x77\xb7\xeb\x9d\x3d\xc9\x2b\x59\x28\x9f\xc7\x26\xed\xdf\x60\xba\xf4\x78\x37\xe6\x55\xb7\x0e\x0f\x02\x58\x2c\x26\x2a\xe1\x20\xa2\x33\xc8\x5f\xa9\xe2\xc0\x33\x45\xc9\x8e\x3a\xae\xe6\xf5\x40\x71\x82\xa2\x1c\x1b\x94\x1c\x65\x7e\x8c\x3d\x87\x4d\x63\x41\xc7\xc9\x19\x5e\x61\xd4\xa8\xaf\x1e\x14\xf3\x25\x37\xe7\x61\x14\xe4\x7b\x5a\x1d\x4b\xfd\x46\x9e\x54\xad\x22\xaa\xff\x0f\xc3\x50\xa7\xcf\x71\x17\xe5\xcb\x4e\xf0\xbe\x27\xfd\x6b\xce\x30\xf1\x69\xc4\x90\x4c\x9f\xe3\x9e\x47\x3f\xf1\x24\x67\x9c\x30\x55\xd6\xa7\x86\x35\x87\xc8\x07\x99\xbe\x72\x9f\xc2\x02\xbc\xd5\x74\x92\x41\xec\x38\x54\x7c\xbd\xfb\xd6\xe9\xb8\x52\xad\xe4\x59\xc0\x1b\x5c\x55\xf4\x02\x54\x68\xa3\xbe\x69\x53\x8a\xbc\x84\x8d\x6b\x4b\x13\x2e\xee\x53\x53\x5b\x22\xe4\xad\xd6\x64\x98\x4e\xc1\xae\xaf\xe1\x82\x96\xff\x4d\x1c\x98\x71\xba\x90\xfd\x92\xc3\x97\xef\xe6\xcc\x14\x97\xbf\xcb\xf7\x15\x32\xe3\x7a\x3f\xb7\x82\xa3\x03\x45\xf4\x84\xdd\x85\xcb\x3e\x99\x7b\x01\xf3\xb2\x26\x4b\xe7\x7b\xb2\x98\x3c\x2c\xa5\x5d\x8d\x92\x20\x28\xf4\x5d\x23\x87\xa1\x60\xab\x5a\xd0\xe8\x4e\x7e\xc3\xa4\x1d\x5a\x68\x60\x4b\x61\xfe\x01\xdf\x6c\x9f\xbd\xfb\x36\x41\xce\x5c\xc5\x7c\x5f\xa5\x51\xe1\xf7\xb1\x6b\x39\xba\x82\x87\x2a\xaf\xa2\x45\x63\x6f\x12\xe4\x76\x87\x7c\x94\x86\xfd\xc0\x21\x51\xc7\x00\x2f\x0b\x9d\xf4\x58\x07\xdc\xaf\x3a\xbd\x60\xd4\x44\xd5\xe8\x5a\x4e\xfc\x0c\x58\x35\x2e\xbf\xfa\x77\x4d\x70\x74\xbf\x23\x08\x01\xa6\xb1\x7f\x8c\xcf\x06\x57\x08\x5c\x68\xcc\x6d\x70\x8f\xda\x37\xfb\xe7\x26\x0b\xaf\x2f\x2f\x2f\x2e\xaf\x22\xb8\xcf\x0f\xff\x03\x4f\x0e\xf7\x16\xce\xcf\x27\x12\x14\xad\xf7\x3d\xf1\x5a\xaa\x8d\xcc\xec\xb6\x99\x88\xa4\x9d\xc7\x25\x2a\x32\x55\xd8\xb5\x80\x61\x64\x00\x4a\x56\x5b\x30\x6d\xe3\xe7\x5f\xcf\x5c\xaf\x7e\x61\xb6\xc6\x62\x0d\x4b\x21\xb9\x90\x85\x01\xa5\xa1\x10\xb6\x6c\x97\x8b\x5c\xd5\xfd\xc4\x63\x3a\xa3\xd2\xba\xcb\xaa\x72\x8d\xcc\xc6\x60\xba\x79\x24\x38\x92\x3d\xbf\xb5\x11\xb6\x04\x37\xc8\xec\xba\x71\x2f\x68\x11\xb5\xde\xed\xdc\x70\xca\xaf\xe5\x8a\xfb\x05\xfa\x31\x53\x51\x8f\x20\x79\x67\x3a\x09\x89\xdf\x73\xa5\x5f\x09\xd2\x0a\x91\x67\x42\xde\xaa\x75\x0c\xd0\x0f\x2e\xae\xd1\xd3\xf2\x64\xce\x39\xd2\x36\xd8\x94\x6e\x24\x16\x90\x5a\x3f\x8e\x0c\x4b\x5f\x07\xed\x1a\xb7\x7d\x1f\xaf\x66\x92\x33\xab\xf4\x54\x8f\xb2\xa7\x71\x2d\xaf\x8f\x9d\x31\x6f\xe8\x3e\x06\x3e\xb3\x32\xfb\x8a\x4b\x2a\xeb\xa3\x61\x44\xe0\xdb\x71\x7b\xdc\x05\x73\x47\x0d\x8c\xde\xbd\x2d\xc7\x25\xd8\xac\x50\x7a\xf4\xa4\x69\xcd\x6c\x5e\x4e\x28\xd8\x5f\x0f\xda\xc0\x9d\x08\xde\x05\x5c\x21\x0f\x27\x26\x7e\xbd\x2b\x03\xb9\x42\xdf\xdc\x74\x42\xdc\xb1\x3a\xf7\x46\x44\xf5\x88\xc9\x5e\xdb\xdf\xaf\x76\x6a\x4c\x2b\x11\x7a\x50\x74\xbd\x58\x25\x62\x66\x7b\xe3\x57\xe9\x99\x87\x23\xe9\x3b\xec\x24\x2b\xfc\x26\x2c\xc3\xb4\x75\x0f\x95\xd2\x0e\x3b\x73\x73\x71\xb7\xc7\xff\x4c\xb1\x73\x07\x71\xc6\xd4\x97\xc7\x00\x3a\xb0\xab\x7b\x0a\x1e\xd1\x13\x03\xbe\xd3\xe8\x4d\x89\x9f\x2d\x4a\xd3\x81\xc6\xcf\xb6\x2b\xce\xbf\x44\x15\x93\x15\x18\xcb\x73\x86\xa7\x5c\xa0\x9f\xe7\x06\xdf\x3b\x4c\x35\x42\xc3\x70\x88\x64\x14\xdf\x44\x3e\x7a\xbe\xb3\x40\x5a\x5d\x1d\x7f\xe4\xbe\x2b\x49\xb1\x62\xb7\x83\xeb\xcb\x5f\x9c\xf2\xae\x4f\xe9\xee\x20\xfd\x8b\x6c\xe6\x09\x6e\xfc\x74\x3b\x05\x48\xcd\xaa\x95\xd2\x75\x34\x31\x7f\xdb\xad\x4f\x21\x58\xc0\x07\xbd\x05\x56\x30\x21\x17\x8b\x59\xb1\x7f\x18\x25\x7b\x2f\x95\xd7\x7c\x62\x8e\xfc\xef\xab\x8b\x77\x20\x64\xd3\x5a\xe0\xcc\x32\x78\x1b\xac\xf1\x24\xaf\xf9\x13\xf2\x59\xd3\x92\x58\x23\x7a\x41\x1b\x5c\x66\xfe\xb2\xc4\xbe\x29\x78\xe0\x52\x75\xe3\x0d\x06\x1b\x5c\x86\x6b\x77\xe6\xe6\x12\x8e\xac\x11\x44\x93\x33\xe9\x03\xf5\x12\x7d\xa8\x44\x1e\x3e\x37\x18\x36\x2d\x20\xa4\x80\x6d\xc3\x99\xc5\x03\x9f\x61\x15\xe4\x4a\xde\xa2\xb6\x07\xe2\xad\x1a\xf3\x98\x33\xec\x58\xdd\x93\x54\xed\x2e\x9b\xbb\xe2\x7b\x10\x93\x94\x5e\x32\x83\x1c\x94\x1c\xbb\x9b\xfb\xac\x66\x4d\x21\x64\x5e\xb5\x1c\x0f\xe0\x31\xb3\x77\x0a\x51\x63\xfc\xfa\xf2\xf2\xdd\x9b\x77\x3f\xa6\x27\x7c\xdd\x86\xe3\x52\xbe\x0d\xd3\x32\xcb\x55\x4d\x11\x34\xd3\x68\xa3\x61\xf6\x92\xd6\xba\x0e\x63\x5e\x73\xa7\xcb\xca\xa2\xf6\x21\xfe\x85\xf7\x6d\xe4\x38\x6e\xa6\xce\x37\xc8\x73\x23\x9e\xa3\x9d\xc7\xf8\x13\x87\x71\xa3\x93\xa3\xc5\xdc\xce\xb4\x18\x9c\x64\x4a\x2c\x38\x36\x1a\x73\x3a\xe9\x4c\x63\x53\xb1\x3c\xea\x34\x28\xf2\x92\x1c\x55\xf1\x90\x4f\xb8\x89\x9a\xbf\x18\x7b\x9e\xca\x63\xda\x88\xaa\x02\xa3\x94\xa4\xdb\x34\x88\x39\x83\x26\xdc\x14\xe3\xb3\x2a\x57\x2e\xe3\x66\x8f\xa7\xb1\xc8\x12\x15\x08\xe6\x38\x25\x1f\x32\xa5\x6a\x2b\x4e\xf0\x0c\xda\x05\xf8\x9e\xf1\x7e\xe5\x46\xd4\xee\x97\xef\x1e\x25\x21\x72\xf4\x33\xe7\x49\xb8\xbc\x04\x0a\x7d\xf7\xf3\x34\xf2\x4f\x6e\xff\x31\x22\x29\x57\x33\xec\x76\xf2\x04\xe7\x84\xba\xfd\xdd\xa9\x76\x2d\x8a\xee\x03\xa8\xf1\x97\x4f\xf3\xc0\x2a\x51\x0b\x9b\x89\x42\x2a\x1d\x85\xd4\xdd\xeb\xe0\x58\xdc\x16\x87\xca\xfd\x3a\xcc\xc5\x84\x81\xc0\x2e\x55\x7a\x5e\x32\x59\x20\x5b\x46\xbf\x57\xf9\xa5\x97\xd8\x27\x7f\xa6\xd3\xbb\xda\xfa\xee\x54\xcf\x63\x01\x6f\x48\x3c\x25\xd0\x09\x77\xc1\x21\x30\x59\xa5\x8a\xcc\x88\x3f\x63\x00\x2a\x55\x5c\x89\x3f\x91\x6c\xeb\x37\xec\x69\x3c\x5c\x51\x26\xdd\x40\x93\x8a\x8d\x25\xda\x0d\xa2\x84\xe7\xae\xa8\xf8\xee\x79\x32\x94\x1a\x6b\xa5\xb7\x53\x68\x3c\xc5\xa9\x80\xbe\xfb\xfe\xef\x0e\xd2\xdf\xbe\xfb\x3e\x19\x13\xe5\x5f\xaa\x8d\x25\x6f\x61\xf5\x24\x30\xcf\xbd\x7d\xfe\xff\x39\xfd\x37\x8f\xc7\xd5\xe1\x59\xa3\x55\x83\xda\x0a\x8c\x35\x7c\x3b\x37\x38\xf2\x57\xbe\xbd\x67\xb5\xc0\xbe\xc1\xe7\x8b\xfa\x81\x59\xd7\x08\x7c\xd8\x27\x76\x2e\x91\x2b\x77\xe1\xc8\x33\x0a\x0b\xaa\xb5\x46\x70\x77\x10\x1f\x34\xbb\x15\x06\x96\xad\xa8\xf8\x74\x13\xc0\xa9\xe2\xdd\x81\xa6\x6b\x9b\xe4\x0a\xfa\xdb\xbf\xe7\x10\xe4\x81\x57\x0f\xd6\x76\xad\x8d\xbb\xbb\x45\xf8\x6b\x67\x6e\xaa\x90\x84\x0c\x85\x2e\xfd\x83\xe5\x33\x69\xb3\x83\xda\xd5\x22\xfe\x91\xc5\xdc\x44\x57\x8a\x04\x2a\x4a\x28\x0e\xaa\x92\x07\xd2\x94\x68\xe1\x71\x52\xb5\xe1\xd0\x86\x5e\x86\x2b\x54\xf1\xb3\x30\xd1\xef\x01\xef\x95\xa9\x7b\x2e\x86\x55\x1a\x19\xdf\x82\x67\xd1\xe7\x4e\x06\x2b\xcc\x2d\x30\xa9\x6c\x89\xbe\x07\x36\x0f\xa9\x6b\x0d\xcd\x56\xea\x21\x14\x1e\x54\xb5\x5d\xd6\x90\x2b\x69\x99\xfb\xd2\x4b\xaa\xb4\x76\x93\x93\x3e\x1a\x05\x38\xa3\xa4\x80\x78\xb0\x51\x1e\x22\xce\x61\xed\x4e\x4f\x6b\x68\x2a\x04\xa2\xfd\xcc\x33\x86\xf1\xd5\xeb\x7f\x5e\xff\x98\x9c\x30\x3a\xea\xe3\xb2\x45\xbe\x2c\x86\x99\xa2\x1f\x4d\xcf\x4e\x16\x1d\xd5\x8b\xc9\xe1\xcf\xb2\x18\xcf\xba\x26\xf9\x8e\x27\x5e\x69\x9c\x0d\x32\x9d\x97\xc4\x37\x8c\x18\x32\xdf\x7d\x8d\x77\x94\xae\xba\x1d\xfd\x80\xa2\xdf\x71\x6f\xbe\x3e\x78\x8f\x99\xf8\x38\x98\x6e\xb8\x3a\x7f\xf5\xb5\x39\xe1\xca\x74\xd0\xfa\x37\xe5\xe7\x40\x13\xdf\xac\xbf\x7a\xa0\xd7\x14\x2c\xf2\x02\x7e\x70\x08\x86\xaf\xd5\x5d\x7b\x9b\x98\x1d\x0b\x60\xfa\x3b\xd0\xe3\x31\x8c\x47\x4d\xdd\x68\x34\x40\x7a\x74\xf3\xe8\xbf\x01\x00\x00\xff\xff\x0d\x20\x90\xa6\xe8\x32\x00\x00")
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5b\x6f\x8f\xdb\x36\xd2\x7f\x9f\x4f\x31\x08\x1e\x20\x2d\xe0\x28\x69\x1f\x1c\x70\x08\xb0\x38\xe4\x2e\x69\xbb\xd7\x26\x1b\xec\x26\x17\x14\xe9\x42\xa1\xc5\xb1\xcd\x5a\x22\x05\x92\xb2\xe3\x1a\xfe\xee\x87\xe1\x1f\x49\xf6\x2e\x25\xad\xd3\xe2\xf2\xa6\x6e\x38\x9c\xf9\xcd\x90\xfc\x71\x66\xa8\x7c\x7a\x04\xb0\x7f\x04\x00\xf0\x58\xf0\xc7\x2f\xe0\x71\x65\x96\x79\xad\x71\x21\xbe\xe4\xa8\xb5\xd2\x8f\x67\x7e\xd4\x6a\x26\x4d\xc9\xac\x50\x92\xc4\x5e\xbb\xb1\x47\x00\x87\xd9\x80\x06\x21\x17\x2a\xa1\xe0\x92\x86\xc6\xe6\x9b\xa6\x28\xd0\x98\x84\x8a\x9b\x30\x3a\xa6\x65\xcb\xb4\x14\x72\x99\xd0\xf2\x31\x8c\x26\xb5\x14\x15\xcf\x39\x9a\x22\x2f\x95\x5c\xe6\x1a\x6b\xa5\x6d\x42\xd7\xb5\x1b\x34\xa0\x24\x70\xac\x4b\xb5\x43\x0e\x28\xad\xb0\x02\x0d\x7c\x23\x32\xcc\x66\xf0\x8e\x15\x6b\xb6\x44\x33\x83\x97\x05\xcd\x33\x33\x78\xaf\xc5\x72\x89\xda\xcc\xe0\xba\x29\x69\x04\x6d\x91\x7d\x0b\xcc\xc0\x16\xcb\x92\xfe\xab\xb1\x40\x69\xdd\x8c\x8d\xb3\x66\x40\x48\xb0\x2b\x04\x53\x63\x21\x16\x02\x39\x48\x56\xa1\xa9\x59\x81\xd9\x64\x5f\x94\x4a\x79\xf2\x12\xac\x52\x25\x58\x15\x1c\x99\x41\x23\xfd\x2f\x60\x92\x83\xd9\xc9\x02\x54\x8d\x72\xbb\x12\x66\x0d\x75\xf0\x09\x1a\x23\xe4\x12\x18\x54\x4c\x8a\x05\x1a\xeb\x84\x55\x4d\x5a\x59\x19\x54\x55\xe4\xc9\x42\x94\xad\xf8\xaf\x2f\xdf\xfc\x32\x05\xb3\x59\x29\x6d\x87\x17\xe0\x9d\x56\x1b\xc1\xd1\x00\x03\xd3\x54\x15\xd3\x3b\xf0\xf2\xa0\x16\xb0\x5d\x31\xfb\xc4\xc0\x1c\xb1\xb7\x3c\x5f\x17\xc6\x00\x69\x34\x8e\x06\x2d\xc5\x72\x85\x65\x1d\x4c\xc3\x4e\x35\x7a\x52\x08\x29\x54\xd3\xb1\x6c\x50\x1b\xb2\x9d\x8a\x8f\x90\xd6\x39\x1c\xe4\x40\x36\xd5\x1c\xb5\x0b\x8f\x59\x7b\x68\xc3\xb6\x16\x25\x5b\xe6\xac\x16\xf9\x4a\x99\x94\xd7\xde\xa5\x97\xef\x2e\xe1\xf3\x4f\x57\x37\xef\x3f\x4f\xd4\x38\x8c\xbd\xa7\xf4\x3f\xaf\xaf\x6f\x2e\xaf\xde\x4e\xd2\xdb\xd8\x55\xbe\xc6\x5d\x42\x29\x0d\x2b\x2d\xfe\x70\x7f\x01\x9f\x7f\x7e\xfd\xeb\x14\xa5\x05\x6a\x9b\xd3\xba\x24\xb4\xd6\xcc\xae\x28\xa4\x14\xe8\x8c\x84\xdd\x22\x4e\x51\xac\xe4\x42\xa4\x98\xca\x0f\x3a\x55\xf0\x0d\xc7\x05\x6b\x4a\x0b\xc2\xc0\xff\xfd\x74\xf5\xe6\xf5\xb3\x6c\x6b\xd6\xb5\x56\xb5\xf9\x76\x4a\x54\xca\x52\x6d\xf3\xa0\x23\xc5\xaf\x4e\x08\x5a\xa1\x71\xad\xdd\xf9\x1e\x8a\x4b\xcb\x29\x2d\x11\x4c\x50\x2d\xa4\x45\xcd\x88\xfe\x52\x31\xf7\x68\x7b\x72\x50\x6b\x55\xd5\x93\x80\xaf\x71\x37\x79\x39\xd7\xb8\x9b\x0a\xda\x47\xb9\x62\x92\x2d\x91\x0f\xc2\xae\xb5\xfa\x1d\x0b\xdb\x5d\x16\x56\xc1\x1c\xa1\x62\x7a\x8d\x1c\xa2\x86\x71\x8b\x41\x4f\x4e\x24\x96\x72\x26\x98\x72\x22\xe3\x1a\x23\x0d\x8d\xac\xe8\x11\x5b\x4d\x50\xdb\xb2\x6c\x42\x6f\x37\x3e\xd9\xe9\x11\x84\x06\xf5\x06\x75\x89\xc6\xc4\x68\x4f\x50\x6d\xac\x16\x49\xcd\x7e\xe9\x1a\x83\x9a\x0e\x89\x90\xc8\x41\x37\xd2\x8a\xaa\x65\xd7\x09\x16\xac\x4e\x07\xc1\x8d\x81\x6a\x6c\xdd\x4c\x01\xeb\xb7\xdb\x06\xf5\x5c\x99\x94\xca\x30\x3a\xae\xd4\x71\x4d\x5e\x09\x43\xd7\x91\x63\xd1\x34\x89\xbe\x5f\x21\x90\x04\xed\xde\xc2\x33\x29\x9d\x12\x61\x40\x2a\x0b\x5e\x55\xa3\x91\x67\xbf\x0d\x45\xe4\xc4\x62\x2d\x06\x2e\x18\xb2\x48\x37\x01\x89\x7c\x9d\x9d\xb1\x8d\x48\x96\x5a\x99\xf3\x4c\x05\x57\x86\xb2\xe1\x53\x7f\x3e\xed\xf7\x19\xfd\x3e\x1c\x6e\x67\xb0\xd0\xaa\x82\xfd\x3e\x33\xaa\xd1\x05\x1e\x0e\x93\x6c\xfa\x05\x1b\xb3\x49\x62\x71\xad\x0c\xda\xf3\x6c\xb5\xe1\x19\xb3\x76\x14\x47\x72\xb1\xfd\x8b\xf3\xfd\xac\xc5\x72\x9b\x33\x57\x08\xe4\x56\xad\x51\x8e\xba\x4c\x33\xc0\xcf\x00\x37\xe3\x3c\xe7\x1b\x59\x31\x6d\x56\xac\xcc\x4b\x55\xb0\x32\x61\xf1\x43\x94\x82\xab\x1a\xe5\x47\x97\xc2\x04\x92\x30\xde\x9e\x9b\x0d\x1b\x56\x36\x68\x26\x1a\x94\x68\xb7\x4a\xaf\xcf\x36\xe9\x2e\x49\x89\x16\x98\x25\x77\x1b\x5d\x8e\xf8\xda\xdd\xd7\x79\xc1\x64\x81\x65\x99\xbc\xcf\xae\x7e\xce\xe0\x5f\x5e\x86\xf2\xd8\x6e\xe6\x54\x03\x0b\x26\xd2\xda\x5f\x75\x89\x03\x17\x3c\x9c\xc5\xaa\x2e\xd1\x22\x98\x86\x96\x74\xd1\x94\xe5\x2e\x83\xeb\x46\xc2\xe7\x36\xa3\x6d\x8b\x97\xcf\x74\x13\x68\xac\x14\xa5\x07\x4c\x5b\xc1\xca\x72\xd7\x15\x03\xcc\x18\xb4\xc3\xab\xd0\x43\xea\x2b\x8b\xdc\x58\x66\x9b\x54\x0e\xf5\xf4\xe9\xd3\xa7\x17\x17\x17\x17\xbd\xb5\xe8\xf9\x70\xe3\xa6\x02\x09\x90\xe0\x24\xab\xae\x26\x46\x3e\x25\x44\x31\x34\x1c\x42\x21\xed\x83\x33\xbc\xc9\xce\x5f\xeb\xfe\xdc\xe9\x46\x06\xd7\xfb\x43\x4f\x72\x78\xc5\x27\xdb\x1b\x8b\xdf\x91\xc9\x33\x22\x58\xa8\xaa\x62\x92\xe7\xae\x8e\x73\x59\x25\xb1\x5c\xce\x6c\x4e\x99\x48\xc2\xe8\x7e\x9f\x15\x15\x3f\x1c\x42\xf5\xb7\xdf\x67\x34\xd1\xee\x6a\x3c\x1c\x1c\x53\xd2\xdc\xc3\xe1\x36\xcb\x06\x6d\xbb\xf4\x71\x97\xc7\xfd\x3c\xd2\x3f\xd9\xef\x29\x99\x0d\x06\x08\xe4\xe1\x70\x0b\x2b\x16\x2a\xe4\xbe\xc3\xed\x09\x99\x6e\x3d\xdd\x70\x79\x15\xc7\xe1\x5e\x00\x59\x36\x50\xec\x06\x13\x71\x41\xff\x4c\x17\x3b\x9d\x53\x9c\x8c\xd2\x69\x37\x3f\x74\x12\xf7\x3a\x3a\xe8\x27\xc7\x1a\x25\x47\x59\x3c\x24\x9c\xdd\xa4\xf3\xed\x74\x47\x24\x19\xd3\x57\xf7\x9a\xf9\x9a\x8d\x73\x3f\x0a\x22\x86\x46\xa7\xf2\xb2\x1e\xcd\xa9\x45\xc2\xf5\xff\xe1\x1d\x11\xfd\x79\xd8\x3e\xf9\xba\x15\xbc\x4b\x73\x7f\xce\x1a\x4e\x3c\x19\x29\x24\xc3\xeb\x78\x44\xb7\x67\xae\xe4\x10\xaa\x50\x3b\x9f\x7b\xe7\x38\x44\xfe\x06\x68\x6b\xf3\x21\x2c\xc0\x1b\x4d\x2b\x19\xcc\xf6\xf3\x9f\xbf\x6e\xbf\x45\x1f\x17\xaa\x91\x3c\x0f\x78\x03\x53\x25\x37\x40\x89\x36\xc9\xc1\xdb\x95\x28\x56\xb0\x75\x8d\x67\xc2\xc5\x7d\xde\x68\x57\x08\x45\xa3\x35\x05\x26\x3a\x18\xdb\x09\xee\x92\xf2\xbf\x49\x03\x33\xce\x17\x8a\xdf\xe4\xb4\xc0\xf7\x6b\x46\x2a\xbf\xdf\xe4\xbb\x12\x99\x71\xdd\x9d\x8d\xe0\xe8\x40\x91\x3c\x61\x87\x85\xd2\x5d\xa6\xf5\x02\xc6\x6d\x0d\xd6\xb5\x77\x6c\x31\x79\x5a\xe7\xba\x02\x62\x82\xa1\xd0\x59\x4d\x2c\x86\x82\x9d\x6a\x40\xa3\x5b\xf9\x2d\x93\xb6\x6b\x92\x81\x5d\x09\xf3\x0f\xf8\x66\xf7\xec\xed\xb7\x13\xec\x8c\x95\xb3\x77\x5d\xea\x55\x65\x9f\x62\x53\xd1\x55\x23\x54\x16\x2d\x1b\x34\xf6\x76\x82\xdd\xb8\xc8\x0f\xf2\xb0\x7d\x52\x98\xe8\x63\x80\x97\x87\x5e\x79\xaa\xc7\xed\x47\x9d\x5f\xd0\x6b\x93\x6a\x74\x2d\x20\x3e\x03\x56\xf6\x6b\xa3\xf6\x5c\x13\x1c\xdd\xce\x08\x46\x80\x69\x6c\x0f\xe3\xb3\x8e\x0a\x81\x0b\x8d\x85\x0d\xf4\xa8\x7d\x3b\x7f\xec\xed\xe0\xf5\xf5\xf5\xd5\xf5\x4d\x02\xf7\xc5\xe9\x1f\xf0\xe2\x70\x67\xe0\xe2\x62\x20\x3f\xd1\xfa\x98\x89\xd7\x52\x6d\x65\x4e\xa9\xe4\xf8\x5d\x40\x52\x14\xaa\x30\x2b\x83\xee\x51\x00\x94\x2c\x77\x60\x9a\xda\xbf\x70\x3d\x73\xdd\xf8\xcc\xec\x8c\xc5\x0a\xe6\x42\x72\x21\x97\x06\x94\x86\xa5\xb0\xab\x66\x9e\x15\xaa\x6a\xdf\x34\x86\x13\x2a\xad\x63\x52\x55\x68\x64\x36\x05\xd3\xbd\x38\x82\x13\x39\xe2\xad\xad\xb0\x2b\x70\x4f\x95\x50\xa1\x31\x6c\x89\x2f\x68\x10\xb5\x3e\x1c\xdc\xf3\x93\x1f\x2b\x14\xf7\x03\xf4\x63\xa4\xdc\xed\x41\xf2\x64\x3a\x08\x89\xdf\xa1\xd2\xbf\x08\xd2\x02\x91\xe7\x42\x6e\xd4\x3a\x05\xe8\x07\x77\xaf\xd1\xd1\xf2\x62\x8e\x1c\x69\x1a\x6c\x57\xee\xd1\x2b\x20\xb5\xfe\xc1\x31\x0c\xfd\x35\x68\xd7\xb8\x6b\x9b\x6c\x54\x10\x31\xab\xf4\x50\x03\xb1\x95\x71\xfd\xa8\x4f\x31\x98\xb7\xb4\x1f\x83\x9e\x51\x9b\xb1\x0b\x9d\x4b\x65\xfd\x6d\x98\x30\xf8\xa6\xdf\xae\x76\x97\xb9\x93\x06\x46\xe7\xde\xae\x8e\x4a\xae\x31\xa3\xae\xbc\xab\x84\xa9\x98\x2d\x52\xf5\x1d\x39\xd8\x6e\x0f\x9a\xc0\x9d\x09\x1e\x2f\x5c\x21\x4f\xdf\x44\xfc\x78\xc0\x00\x5c\xa1\xef\x3c\x3a\x23\x6e\x59\x1d\xbd\x91\x50\xd5\x53\x72\xd4\x86\xf7\xa3\xd1\x8d\x61\x27\x42\x83\x88\xb6\x17\x2b\x45\x2a\x6c\x97\x7e\x94\x8e\x79\x58\x92\xb6\xe3\x4d\xb6\xc2\x6f\xc2\xd2\xbd\xa7\x1e\xa1\x52\xda\x61\x67\xee\xe5\xdb\xcd\xf1\x3f\xa7\xc4\x39\x42\x1c\x09\xf5\xf5\x43\x00\x9d\xc4\xd5\x1d\x05\x8f\xe8\x89\x01\xdf\x06\xf4\xa1\xc4\x2f\x16\xa5\x89\xa0\xf1\x8b\x4b\x72\xc8\x9d\xaf\x71\xc5\xe4\x4b\x4c\xe5\x39\xdd\x51\x5e\xa2\x7f\xb1\x0d\xdc\xdb\xbd\x32\x84\x6e\x5e\x77\x93\xd1\xfd\x26\x8a\xde\xf1\x9d\x1c\x53\x0f\x3d\xf7\x1e\xbb\xd3\xd3\x5a\x4b\xe0\x3b\x72\xd8\x15\x0e\x14\xc6\x2e\xca\x4c\xee\xda\xbd\x41\x24\xd2\x5b\xf6\xd1\xb8\x86\x2e\x7b\x0b\x61\xd4\x8d\x46\x97\x0f\xdf\xb9\xbe\xf3\x19\x7a\x2c\x1f\xae\x7f\x71\x08\x5c\x2f\xd4\x1d\xa5\x4f\x47\x4d\x98\x5b\xff\x0c\x3f\x05\x48\xc5\xca\x85\xd2\x55\x32\x72\x6f\xe2\xf8\x10\x82\x0c\xde\xeb\x1d\xb0\x25\x13\x72\xac\xe7\xa3\x75\xfe\xbb\x51\xb2\x25\xdb\xa2\xe2\x03\x0f\xde\xff\xbe\xb9\x7a\x0b\x42\xd6\x8d\x05\xce\x2c\x83\x37\x21\x1a\x4f\x8a\x8a\x3f\x21\xea\x1d\xb6\xc4\x6a\xd1\x1a\xda\xe2\x3c\x6c\x9c\xd4\xc7\x0f\xf7\x9c\x8d\xb8\xb8\x0c\xb6\x38\x0f\x3b\x62\xe6\xde\x3e\x9c\x58\x2d\x48\xa6\x60\xd2\xe7\x1b\x73\xf4\x37\x3e\xf2\xd0\x19\xeb\x26\x65\x10\x32\xd9\xa6\xe6\xcc\xe2\x09\xf5\x59\x05\x85\x92\x1b\xd4\xf6\xc4\xbc\x55\x7d\x1d\x63\x81\xed\xbb\x7b\x96\xab\x71\xb3\xb9\x93\x7a\x04\x71\x92\xd3\x73\x66\x90\x83\x92\xfd\xe3\x73\x57\xd5\x68\x28\x84\x2c\xca\x86\xe3\x09\x3c\x66\x8e\x56\x61\x3c\x18\x9e\x24\x86\x0f\x5a\x2a\x10\x61\x56\x06\x97\xd6\xb7\x19\x94\x5d\xb9\x9c\xc2\xb1\xc3\xa2\x91\x81\x1b\x22\x81\xcc\x7c\x2c\x94\xc4\xf0\xf2\x5e\x91\x16\xfc\x52\x63\x31\x85\x11\x02\xd6\xb8\x76\x91\xe7\x88\xe0\x73\xb2\xfa\x95\xe8\x1d\xf0\x8e\xec\x48\xad\x6a\x6c\x9f\xf4\x32\xf8\xd8\x5d\x26\x91\xf2\x68\xda\xac\xa5\x45\xda\x1e\x31\xe9\x19\xb9\x9e\x83\x3b\x31\x4c\x39\x95\xe5\x16\x73\x2e\xf4\x24\xb2\xbe\xd7\x2d\xf2\xa3\x8d\x7b\xad\x84\xf4\xa9\xa1\xef\x45\x58\x0c\x05\x0e\x25\x64\x1d\x2d\xcd\xc0\x34\x45\xf4\xca\xb8\xda\xe8\x98\xa9\xef\x77\xe3\xe3\xcb\xeb\xb7\x97\x6f\x7f\x9c\x5e\xf9\xc4\x09\x0f\xab\x7d\xb6\x4c\xcb\xb6\xff\xae\xd1\x26\xf3\xcd\x6b\x1a\x23\x6f\x3f\xc5\xc6\xfb\x2d\xb0\x85\x45\xed\x73\xdd\x17\xfe\x32\xa2\x1b\xf4\x76\x68\xa3\x05\x7b\xee\x21\xf2\xc1\xd7\x4f\xff\x6b\x9e\x5e\xba\x09\x1c\xed\xf8\x16\x77\x96\x29\xc3\xe6\x58\x6b\x2c\x88\x2b\x72\x8d\x75\xc9\x8a\xe4\x1e\xa0\x14\x94\xec\xa8\x92\x87\xc4\xda\xbd\xfb\x7a\x6a\x39\x7e\x70\xd8\x8a\xb2\x04\xa3\x94\x24\x2a\xea\x2c\xcc\xa0\x0e\x34\x63\x7c\x65\xe1\x5a\x46\xb8\x3d\x52\x67\x2c\xb2\x89\xd8\x43\x24\xce\xa9\x09\xcc\x4a\x35\x25\x27\x78\x06\x6d\x06\x1f\x8c\xef\x9e\xf6\xbb\x17\x24\xed\x7e\x8d\x3f\x9b\xb4\x88\x9c\xfc\xc8\x52\x12\x2e\x6f\x81\xd2\xbf\xbb\xb5\x0a\x9d\x07\x4f\x16\x0f\x30\xe9\x0e\x31\xdb\x0c\x2e\xde\x98\x51\x37\x3f\x2e\x68\x6c\xd3\xc5\xcf\xfc\xfa\xdf\xf7\x8d\x03\x2b\x45\x25\x6c\x2e\x96\x52\xe9\x24\xa4\xb8\xa5\x03\xc3\xb9\x29\x0e\x95\xfb\x75\x5a\x8f\x10\x87\x7a\x75\x53\xad\x17\x2b\x26\x97\xc8\xe6\xc9\xaf\xb2\x7e\x69\x2d\xb6\x05\x90\x89\x7e\x97\x3b\xdf\xa1\x6d\x75\x64\x70\x49\xe6\xa9\x88\x9c\xb0\x17\x1c\x02\x93\x97\x6a\x99\x1b\xf1\x47\x0a\x40\xa9\x96\x37\xe2\x0f\x77\x3f\xf9\x09\x47\x1e\x77\x5b\x94\x49\xf7\xe2\x4e\x05\xf7\x1c\xed\x16\x51\xc2\x73\x77\xeb\x7d\xf7\x7c\x32\x94\x0a\x2b\xa5\x77\x43\x68\xbc\xc4\xb9\x80\xbe\xfb\xfe\xef\x0e\xd2\xdf\xbe\xfb\x7e\x32\x26\xba\xc4\x54\x93\x2a\x60\xc2\xe8\x59\x60\x9e\xfb\xf8\xfc\xff\x73\xfa\x33\x8e\xc7\xf5\xa2\xf2\x5a\xab\x1a\xb5\x15\x98\x7a\xf4\x88\x0c\xd8\xe3\x2b\xdf\xe2\xb6\x5a\x60\xdb\xe4\xf6\x8d\xad\x4e\x59\x6c\x86\xdf\xcf\x89\x91\x12\xb9\x72\x1b\x8e\x98\x51\x58\x50\x8d\x35\x82\xbb\x85\x78\xaf\xd9\x46\x18\x98\x37\xa2\xe4\xc3\x8d\x30\xe7\x8a\xa7\x03\x4d\xdb\x76\x12\x15\xb4\xbb\xff\x88\x10\xe4\x09\xa1\x87\x68\xbb\xf6\xde\x7e\x9f\x85\xbf\x8d\xe1\xde\xef\xb3\x4a\xc8\xd0\xec\xa1\xff\x61\xc5\x48\xe9\xe8\xa0\xc6\x9c\xca\x1f\xb2\x14\x4d\xc4\x72\x3c\x48\x51\x7e\x71\x52\x99\xdf\x93\xe3\x26\x8b\xef\xb3\x2a\x6e\x87\x36\xf4\xf3\x5c\xb3\x06\xbf\x08\x93\xfc\xea\xf5\x4e\xab\xe6\x88\x62\x58\xa9\x91\xf1\x1d\x78\x15\x6d\xe2\x6d\xb0\xc4\x82\xf2\x3f\x65\x57\xe8\xfb\xc0\xe3\x90\x62\x7b\x74\xb4\x5b\x15\xae\xc2\x93\xce\x4e\x4c\x18\x0a\x25\x2d\x73\x5f\x1f\x4a\x35\xad\xe5\xea\xac\xf7\x9e\xc3\x5c\x50\xa6\x80\xb8\xf7\xb1\x28\xdc\x38\xa7\xfd\xab\x6d\x68\x09\xf8\xc6\x5a\x10\x3a\x2e\x5b\xc6\x23\xd4\xfb\x9c\x35\x57\x1b\xd4\x5a\x70\x8e\xa9\x1a\x8c\x10\xf6\xbf\x6e\xed\x9e\x33\xbb\xa9\x31\x57\xe8\xbf\x56\xa5\x60\xbc\x7a\xfd\xcf\x0f\x3f\x4e\x4e\x59\x9d\xf4\xc3\xf2\x55\x3e\x5f\xe6\x06\x99\x2e\x56\x54\xa3\x44\x67\xdb\xbc\x3b\xf5\xcf\x5e\xe2\x8c\xd6\xd9\xe3\x4c\x3d\xee\x0b\x3a\x2b\x1d\x29\x8c\x5c\x7b\x04\xe5\x74\x47\xfc\xd9\xbb\xe1\xcc\x9d\x40\xd0\xda\xa3\xe2\x9f\x38\x07\xfe\xc1\xc5\xab\x7b\xda\xa8\x21\x22\x2f\xe0\x07\x87\xa0\xfb\xa7\x16\xee\xe5\x86\x94\x3d\x14\xc0\xf0\x27\xc7\x0f\xc7\xd0\x7f\x45\x8d\xaf\xfe\x01\xd2\xa3\xdb\x47\xff\x0d\x00\x00\xff\xff\x2f\x60\x92\x0a\xa5\x35\x00\x00")
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
 	return bindataRead(
@@ -112,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 13032, mode: os.FileMode(420), modTime: time.Unix(1520362388, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 13733, mode: os.FileMode(420), modTime: time.Unix(1520546400, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 7d1a2d77..6370f942 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -75,6 +75,10 @@
     "id": "msg_cmd_flag_allow_managed",
     "translation": "allow project entities to be marked managed"
   },
+  {
+    "id": "msg_cmd_flag_project_name",
+    "translation": "project name"
+  },
   {
     "id": "msg_cmd_flag_manifest",
     "translation": "path to manifest file"
@@ -92,8 +96,8 @@
     "translation": "allow user defined runtime version"
   },
   {
-    "id": "msg_cmd_flag_toggle_help",
-    "translation": "Toggle Help message"
+    "id": "msg_cmd_flag_trace",
+    "translation": "trace output"
   },
   {
     "id": "msg_cmd_flag_allow_verbose",
@@ -164,12 +168,8 @@
     "translation": "Undeployment completed successfully.\n"
   },
   {
-    "id": "msg_manifest_using_deployment",
-    "translation": "Using [{{.path}}] for deployment.\n"
-  },
-  {
-    "id": "msg_manifest_using_undeployment",
-    "translation": "Using [{{.path}}] for undeployment.\n"
+    "id": "msg_command_using_filename_at_path",
+    "translation": "{{.cmd}} using {{.filetype}} [{{.path}}]...\n"
   },
   {
     "id": "msg_entity_deployed_success",
@@ -185,7 +185,7 @@
   },
   {
     "id": "msg_entity_undeploying",
-    "translation": "Undeploying {{.key}} [{{.name}}] ..."
+    "translation": "Undeploying {{.key}} [{{.name}}]..."
   },
   {
     "id": "msg_dependency_deploying",
@@ -287,6 +287,10 @@
     "id": "msg_err_runtimes_get",
     "translation": "Failed to get the supported runtimes from OpenWhisk service: {{.err}}.\n"
   },
+  {
+    "id": "msg_err_runtime_action_source_not_supported",
+    "translation": "[{{.action}}] has not specified any runtime and the action source file extension [{{.ext}}] is not supported.\n"
+  },
   {
     "id": "msg_err_url_invalid",
     "translation": "Invalid or missing {{.urltype}} URL [{{.url}}] in [{{.filetype}}] file.\n"
@@ -307,6 +311,18 @@
     "id": "msg_err_api_missing_action",
     "translation": "Action [{{.action}}] is missing from manifest file, API [{{.api}}] can only be created based on the action from manifest file. Please update manifest file to include [{{.action}}] as a web action.\n"
   },
+  {
+    "id": "msg_err_action_invalid",
+    "translation": "Action [{{.action}}] is invalid. It has both code and function specified, only one of them is expected.\n"
+  },
+  {
+    "id": "msg_err_action_missing_runtime_with_code",
+    "translation": "Action [{{.action}}] is invalid. It has code specified without any runtime. With action source code, runtime is mandatory."
+  },
+  {
+    "id": "msg_err_action_function_remote_dir_not_supported",
+    "translation": "Action [{{.action}}] has function pointing to remote directory [{{.url}}], such actions are not supported."
+  },
   {
     "id": "WARNINGS",
     "translation": "================= WARNINGS ==================="
@@ -321,7 +337,7 @@
   },
   {
     "id": "msg_warn_key_deprecated_replaced",
-    "translation": "The [{{.oldkey}}] key in the {{.filetype}} file will soon be deprecated, please use the [{{.newkey}}] key instead.\n"
+    "translation": "The [{{.oldkey}}] key in the {{.filetype}} will soon be deprecated, please use the [{{.newkey}}] key instead.\n"
   },
   {
     "id": "msg_warn_key_missing",
@@ -380,16 +396,12 @@
     "translation": "The {{.key}} [{{.name}}] in the deployment file was not found in the manifest file.\n"
   },
   {
-    "id": "DEBUG",
-    "translation": "================= DEBUG ==================="
+    "id": "msg_warn_project_name_overridden",
+    "translation": "The project name has been overridden. Using {{.project}}\n"
   },
   {
-    "id": "msg_dbg_deploying_using",
-    "translation": "Deploying using:\n"
-  },
-  {
-    "id": "msg_dbg_undeploying_using",
-    "translation": "Undeploying using:\n"
+    "id": "DEBUG",
+    "translation": "================= DEBUG ==================="
   },
   {
     "id": "msg_dbg_searching_project_directory",
diff --git a/wskprint/console.go b/wskprint/console.go
index 6e745650..62228bc0 100644
--- a/wskprint/console.go
+++ b/wskprint/console.go
@@ -23,6 +23,8 @@ import (
 	"github.com/fatih/color"
 	"github.com/mattn/go-colorable"
 	"os"
+	"path/filepath"
+	"runtime"
 	"strings"
 )
 
@@ -104,16 +106,26 @@ func PrintlnOpenWhiskVerbose(verbose bool, message string) {
 	PrintOpenWhiskVerbose(verbose, message+"\n")
 }
 
+func PrintlnOpenWhiskTrace(trace bool, message string) {
+
+	if trace {
+		_, fname, lineNum, _ := runtime.Caller(2)
+		out := fmt.Sprintf("%s [%v]: %s\n", filepath.Base(fname), lineNum, message)
+		PrintOpenWhiskVerbose(trace, out)
+	}
+}
+
 // Display "trace" output if either param is true OR we are running Go test verbose (i.e., "go test -v")
-// arg[0] = [/var/folders/nj/2blqqtm500l5ch2d5k0hvqvm0000gn/T/go-build041478919/github.com/apache/incubator-openwhisk-wskdeploy/deployers/_test/deployers.test
+// Typical Args for "go test" looks as follows:
+// arg[0] = [/var/folders/nj/<uuid>/T/<build-id>/github.com/apache/incubator-openwhisk-wskdeploy/deployers/_test/deployers.test
 // arg[1] = -test.v=true
 // arg[2] = -test.run=TestDeploymentReader_PackagesBindTrigger]
-// TODO() introduce "trace" as an optional flag (perhaps hidden or picked up from environment)
-func PrintlnOpenWhiskTrace(trace bool, message string) {
-	GO_TEST_VERBOSE := false
-	if len(os.Args) >= 2 {
-		// TODO() move this to an init() routine
-		GO_TEST_VERBOSE = strings.Contains(os.Args[1], "-test.v=true")
+func DetectGoTestVerbose() bool {
+	arguments := os.Args
+	for i := range arguments {
+		if strings.HasPrefix(arguments[i], "-test.v=true") {
+			return true
+		}
 	}
-	PrintOpenWhiskVerbose(GO_TEST_VERBOSE || trace, message+"\n")
+	return false
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services