diff --git a/DEV.md b/DEV.md
new file mode 100644
index 0000000000000000000000000000000000000000..b7ca3a95abbf38ddc74f0fb3d8ef3ebdb90e58e3
--- /dev/null
+++ b/DEV.md
@@ -0,0 +1,96 @@
+## Develop your own function
+
+### TestDrive
+
+Before you start development, you may want to take FaaS for a test drive which sets up a stack of sample functions from docker-compose.yml. You can then build your own functions and add them to the stack.
+
+> You can test-drive FaaS with a set of sample functions as defined in docker-compose.yml on play-with-docker.com for free, or on your own laptop.
+
+* [Begin the TestDrive instructions](https://github.com/alexellis/faas/blob/master/TestDrive.md)
+
+### Working on the API Gateway or Watchdog
+
+To work on either of the FaaS Golang components checkout the "./build.sh" scripts and acompanying Dockerfiles.
+
+* ![Roadmap and Contributing](https://github.com/alexellis/faas/blob/master/ROADMAP.md)
+
+### Creating a function
+
+Functions run as Docker containers with the Watchdog component embedded to handle communication with the API Gateway.
+
+**Markdown Parser**
+
+This is the basis of a function which generates HTML from MarkDown:
+
+```
+FROM golang:1.7.3
+RUN mkdir -p /go/src/app
+COPY handler.go /go/src/app
+WORKDIR /go/src/app
+RUN go get github.com/microcosm-cc/bluemonday && \
+    go get github.com/russross/blackfriday
+
+RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
+
+ADD https://github.com/alexellis/faas/releases/download/v0.3-alpha/fwatchdog /usr/bin
+RUN chmod +x /usr/bin/fwatchdog
+
+ENV fprocess="/go/src/app/app"
+
+CMD ["/usr/bin/watchdog"]
+```
+
+The base Docker container is not important, you just need to add the watchdog component and then set the fprocess to execute your binary at runtime.
+
+Update the Docker stack with this:
+
+```
+    markdown:
+        image: alexellis2/faas-markdownrender:latest
+        labels:
+            function: "true"
+        depends_on:
+            - gateway
+        networks:
+            - functions
+```
+
+**Word counter with busybox**
+
+```
+FROM alpine:latest
+
+ADD https://github.com/alexellis/faas/releases/download/v0.3-alpha/fwatchdog /usr/bin
+RUN chmod +x /usr/bin/fwatchdog
+
+ENV fprocess="wc"
+CMD ["fwatchdog"]
+```
+
+Update your Docker stack with this definition:
+
+```
+    wordcount:
+        image: alexellis2/faas-alpinefunction:latest
+        labels:
+            function: "true"
+        depends_on:
+            - gateway
+        networks:
+            - functions
+        environment:
+            fprocess:	"wc"
+```
+
+### Testing your function
+
+You can test your function through a webbrowser against the UI portal on port 8080.
+
+http://localhost:8080/
+
+You can also invoke a function by name with curl:
+
+```
+curl --data-binary @README.md http://localhost:8080/function/func_wordcount
+```
+
diff --git a/README.md b/README.md
index 5702b829282928e915a1e129e6cec10cb86a8586..763fe428ebc91d315a91980eac7aa16df553b373 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# faas - Functions As A Service
+## faas - Functions As A Service
 
 FaaS is a platform for building serverless functions on Docker Swarm Mode with first class metrics. Any UNIX process can be packaged as a function in FaaS enabling you to consume a range of web events without repetitive boiler-plate coding.
 
@@ -11,227 +11,38 @@ FaaS is a platform for building serverless functions on Docker Swarm Mode with f
 Status](https://travis-ci.org/alexellis/faas.svg?branch=master)](https://travis-ci.org/alexellis/faas)
 
 ## Minimum requirements: 
-* Docker 1.13-RC (to support attachable overlay networks)
+* Docker 1.13 (to support attachable overlay networks)
 * At least a single host in Swarm Mode. (run `docker swarm init`)
 
-> For more information on Swarm mode and configuration please read the [Swarm Mode tutorial](https://docs.docker.com/engine/swarm/swarm-tutorial/).
+## TestDrive
 
-Check your `docker version` and upgrade to one of the latest 1.13-RCs from the [Docker Releases page](https://github.com/docker/docker/releases). This is already available through the Beta channel in Docker for Mac.
+You can test-drive FaaS with a set of sample functions as defined in docker-compose.yml on play-with-docker.com for free, or on your own laptop.
 
-## Quickstart with `docker stack deploy`
+* [Begin the TestDrive instructions](https://github.com/alexellis/faas/blob/master/TestDrive.md)
 
-For a complete stack of Prometheus, the gateway and the DockerHubStats function: 
+## Roadmap and contributing
+* [Read the Roadmap]((https://github.com/alexellis/faas/blob/master/ROADMAP.md))
 
-* Simply run `./deploy_stack.sh` - following that you can find out information about the services like this:
+## Develop your own functions
+* [Read the Roadmap]((https://github.com/alexellis/faas/blob/master/DEV.md))
 
-```
-# docker stack ls
-NAME  SERVICES
-func  3
+#### Would you prefer a video overview?
 
-# docker stack ps func
-ID            NAME               IMAGE                                  NODE  DESIRED STATE  CURRENT STATE         
-rhzej73haufd  func_gateway.1     alexellis2/faas-gateway:latest         moby  Running        Running 26 minutes ago
-fssz6unq3e74  func_hubstats.1    alexellis2/faas-dockerhubstats:latest  moby  Running        Running 27 minutes ago
-nnlzo6u3pilg  func_prometheus.1  quay.io/prometheus/prometheus:latest   moby  Running        Running 27 minutes ago
-```
+See how to deploy FaaS onto play-with-docker.com and Docker Swarm in 1-2 minutes. See the sample functions in action and watch the graphs in Prometheus as we ramp up the amount of requests. 
 
-* Then head over to http://localhost:9090 for your Prometheus metrics
+* [Deep Dive into Functions as a Service (FaaS) on Docker](https://www.youtube.com/watch?v=sp1B7l5mEzc)
 
-* Your function can be accessed via the gateway like this:
+#### Prometheus metrics are built-in
 
-**Sample function: Docker Hub Stats (hubstats)**
+Prometheus is built into FaaS and the sample stack, so you can check throughput for each function individually with a rate function in Prometheus like this:
 
-```
-# curl -X POST http://localhost:8080/function/func_hubstats -d "alexellis2"
-The organisation or user alexellis2 has 99 repositories on the Docker hub.
+![](https://pbs.twimg.com/media/C2d9IkbXAAI58fz.jpg)
 
-# curl -X POST http://localhost:8080/function/func_hubstats -d "library"
-The organisation or user library has 128 repositories on the Docker hub.
-```
+### More resources:
 
-The `-d` value passes in the argument for your function. This is read via STDIN and used to query the Docker Hub to see how many images you've created/pushed.
+FaaS is still expanding and growing, check out the developments around:
 
-**Sample function: webhook stasher (webhookstash)**
-
-Another cool sample function is the Webhook Stasher which saves the body of any data posted to the service to the container's filesystem. Each file is written with the filename of the UNIX time.
-
-```
-# curl -X POST http://localhost:8080/function/func_webhookstash -d '{"event": "fork", "repo": "alexellis2/faas"}'
-Webhook stashed
-
-# docker ps|grep stash
-d769ca70729d        alexellis2/faas-webhookstash@sha256:b378f1a144202baa8fb008f2c8896f5a8
-
-# docker exec d769ca70729d find .
-.
-./1483999546817280727.txt
-./1483999702130689245.txt
-./1483999702533419188.txt
-./1483999702978454621.txt
-./1483999703284879767.txt
-./1483999719981227578.txt
-./1483999720296180414.txt
-./1483999720666705381.txt
-./1483999720961054638.txt
-```
-
-**Sample function: Node OS Info (nodeinfo)**
-
-Grab OS, CPU and other info via a Node.js container using the `os` module.
-
-```
-# curl -X POST http://localhost:8080/function/func_nodeinfo -d ''
-
-linux x64 [ { model: 'Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz',
-    speed: 2500,
-    times: 
-     { user: 3754430800,
-       nice: 2450200,
-       sys: 885352200,
-       idle: 25599742200,
-       irq: 0 } },
-...
-```
-
-> Why not start the code on play-with-docker.com and then configure a Github repository to send webhook to the function?
-
-If you're looking for a UI checkout the [Postman plugin for Chrome](https://www.getpostman.com) where you can send POSTs without needing `curl`.
-
-## Manual quickstart
-
-#### Create an attachable network for the gateway and functions to join
-
-```
-# docker network create --driver overlay --attachable functions
-```
-
-#### Start the gateway
-
-```
-# docker pull alexellisio/faas-gateway:latest
-# docker rm -f gateway;
-# docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name gateway -p 8080:8080 \
-  --network=functions alexellisio/faas-gateway:latest
-```
-
-#### Start at least one of the serverless functions:
-
-Here we start an echo service using the `cat` command found in a shell.
-
-```
-# docker service rm catservice
-# docker service create --network=functions --name catservice alexellisio/faas-catservice:latest
-```
-
-#### Now send an event to the API gateway
-
-* Method 1 - use the service name as a URL:
-
-```
-# curl -X POST --data-binary @$HOME/.ssh/known_hosts -v http://localhost:8080/function/catservice
-```
-
-* Method 2 - use the X-Function header:
-
-```
-# curl -X POST -H 'x-function: catservice' --data-binary @$HOME/.ssh/known_hosts -v http://localhost:8080/
-```
-
-#### Build your own function
-
-Visit the accompanying blog post to find out how to build your own function in whatever programming language you prefer.
-
-[FaaS blog post](http://blog.alexellis.io/functions-as-a-service/)
-
-#### Setup a Prometheus instance
-
-Please review the following quickstart example and edit the configuration in `monitor/prometheus.yml`.
-
-* [Quickstart-Prometheus](https://github.com/alexellis/quickstart-prometheus)
-
-# Overview
-
-## the gateway
-
-This container acts in a similar way to the API Gateway on AWS. Requests can be made to this endpoint with a JSON body.
-
-**Incoming requests and routing**
-
-There are three options for routing:
-
-* Functions created on the overlay network can be invoked by: http://localhost:8080/function/{servicename}
-* Routing automatically detects Alexa SDK requests and forwards to a service name (function) that matches the Intent name
-* Routing is enabled through a `X-Function` header which matches a service name (function) directly.
-
-Features:
-
-* [todo] auto-scaling of replicas as load increases
-* [todo] backing off of replicas as load reduces
-* [todo] unique URL routes for serverless functions
-* instrumentation via Prometheus metrics at GET /metrics
-
-## the watchdog
-
-
-This binary fwatchdog acts as a watchdog for your function. Features:
-
-* Static binary in Go
-* Listens to HTTP requests over swarm overlay network
-* Spawns process set in `fprocess` ENV variable for each HTTP connection
-* [todo] Only lets processes run for set duration i.e. 500ms, 2s, 3s.
-* Language/binding independent
-
-### Additional technical debt:
-
-* Must switch over to timeouts for HTTP.post via HttpClient.
-* Coverage with unit tests
-* Update quick-start to use `docker stack deploy`
- * Have `docker stack deploy` include a pre-configured Prometheus instance.
-
-## Development
-
-For development of the FaaS framework / library read on. If you would like to consume the project with your own functions then you can use the public images and the supplied `docker stack` file as a template (docker-compose.yml)
-
-### License
-
-This project is licensed until the MIT License.
-
-## Contributing
-
-Here are a few guidelines for contributing:
-
-* If you have found a bug please raise an issue.
-* If the documentation can be improved / translated etc please raise an issue to discuss.
-* If you would like to contribute to the codebase please raise an issue to propose the change.
-
-> Please provide a summary of what you changed, how you did it and how it can be tested.
-
-### Building a development environment:
-
-To use multiple hosts you should push your services (functions) to the Docker Hub or a registry accessible to all nodes.
-
-```
-# docker network create --driver overlay --attachable functions
-# git clone https://github.com/alexellis/faas && cd faas
-# cd watchdog
-# ./build.sh
-# cd ../sample-functions/catservice/
-# cp ../../watchdog/fwatchdog ./
-# docker build -t catservice . ; docker service rm catservice ; docker service create --network=functions --name catservice catservice
-# cd ../../
-# cd gateway
-# docker build -t server . ;docker rm -f server; docker run -v /var/run/docker.sock:/var/run/docker.sock --name server -p 8080:8080 --network=functions server
-```
-
-Accessing the `cat` (read echo) service:
-
-```
-# curl -X POST -H 'x-function: catservice' --data-binary @$HOME/.ssh/known_hosts -v http://localhost:8080/
-
-# curl -X POST -H 'x-function: catservice' --data-binary @/etc/hostname -v http://localhost:8080/
-```
-
-## Prometheus metrics / instrumentation
-
-Standard go metrics and function invocation count / duration are available at http://localhost:8080/metrics/
+* [Auto-scaling](https://twitter.com/alexellisuk/status/823262200236277762)
+* Prometheus alerts
+* More sample functions
+* [Brand new UI](https://twitter.com/alexellisuk/status/823262200236277762)
diff --git a/ROADMAP.md b/ROADMAP.md
new file mode 100644
index 0000000000000000000000000000000000000000..7f48d2577bc701486fe577d9a7af8d536318bbe9
--- /dev/null
+++ b/ROADMAP.md
@@ -0,0 +1,59 @@
+# Roadmap
+
+## 1. Current items
+
+### The API Gateway
+
+This container acts in a similar way to the API Gateway on AWS. Requests can be made to this endpoint with a JSON body.
+
+Features:
+
+* UI for viewing and testing functions deployed through stack
+* Auto-scaling of replicas as load increases
+* Backing off of replicas as load reduces
+* Unique URL routes for serverless functions
+* Instrumentation via Prometheus metrics at GET /metrics
+* Bundled Prometheus stack with AlertManager
+
+**Incoming requests and routing**
+
+There are three options for routing:
+
+* Functions created on the overlay network can be invoked by: http://localhost:8080/function/{servicename}
+* Automatic routing is also enabled through the `/` endpoint via a `X-Function` header which matches a service name (function) directly.
+
+### The watchdog
+
+This binary fwatchdog acts as a watchdog for your function. Features:
+
+* Static binary in Go
+* Listens to HTTP requests over swarm overlay network
+* Spawns process set in `fprocess` ENV variable for each HTTP connection
+* Only lets processes run for set duration i.e. 500ms, 2s, 3s.
+* Language/binding independent - can invoke any UNIX process, including built-ins such as `wc` or `cat`
+
+## 2. Future items
+
+* UI enhancements to create new function through a form
+* Asynchronous / long-running tasks
+* Built-in TLS termination
+* Deeper tests coverage and integration tests
+* Documentation about Alexa sample function
+
+## 3. Development and Contributing
+
+For development of the FaaS framework / library read on. If you would like to consume the project with your own functions then you can use the public images and the supplied `docker stack` file as a template (docker-compose.yml)
+
+### License
+
+This project is licensed until the MIT License.
+
+## Contributing
+
+Here are a few guidelines for contributing:
+
+* If you have found a bug please raise an issue.
+* If the documentation can be improved / translated etc please raise an issue to discuss.
+* If you would like to contribute to the codebase please raise an issue to propose the change.
+
+> Please provide a summary of what you changed, how you did it and how it can be tested.
diff --git a/TestDrive.md b/TestDrive.md
index d82f7fcc3eed06a790bcabe6569ddd21ac1d503d..e9a8b605fbca8e90cd4d7e3bbd5766dcf79d31e3 100644
--- a/TestDrive.md
+++ b/TestDrive.md
@@ -1,4 +1,4 @@
-## faas - Functions As A Service
+## Functions As A Service - TestDrive
 
 FaaS is a platform for building serverless functions on Docker Swarm Mode with first class metrics. Any UNIX process can be packaged as a function in FaaS enabling you to consume a range of web events without repetitive boiler-plate coding.
 
@@ -28,9 +28,7 @@ This one-shot script clones the code, initialises Docker swarm mode and then dep
 
 ![](https://pbs.twimg.com/media/C1wDi_tXUAIphu-.jpg)
 
-* Head over to the README to see how to invoke the sample function for Docker Hub Stats via the `curl` commands.
-
-#### The sample functions are:
+#### Some of the sample functions are:
 
 * Webhook stasher function (webhookstash) - saves webhook body into container's filesystem (Golang)
 * Docker Hub Stats function (hubstats) - queries the count of images for a user on the Docker Hub (Golang)
@@ -38,33 +36,82 @@ This one-shot script clones the code, initialises Docker swarm mode and then dep
 
 #### Invoke the sample functions with curl or Postman:
 
-Head over to the Github repo now for the quick-start to test out the sample functions:
+Head over to the [Github repo to fork the code](https://github.com/alexellis/faas), or read on to see the input/output from the sample functions.
+
+#### Working with the sample functions
+
+> If you're looking for a UI head over to http://localhost:8080/ for a list of functions deployed on your swarm.
 
-[Quickstart documentation with `docker-stack deploy`](https://github.com/alexellis/faas/tree/stack_1#quickstart-with-docker-stack-deploy)
+You can find out which services are deployed like this:
+
+```
+# docker stack ls
+NAME  SERVICES
+func  3
+
+# docker stack ps func
+ID            NAME               IMAGE                                  NODE  DESIRED STATE  CURRENT STATE         
+rhzej73haufd  func_gateway.1     alexellis2/faas-gateway:latest         moby  Running        Running 26 minutes ago
+fssz6unq3e74  func_hubstats.1    alexellis2/faas-dockerhubstats:latest  moby  Running        Running 27 minutes ago
+nnlzo6u3pilg  func_prometheus.1  quay.io/prometheus/prometheus:latest   moby  Running        Running 27 minutes ago
+```
 
-Once you're up and running checkout the `gateway_functions_count` metrics on your Prometheus endpoint on *port 9090*.
+* Head over to http://localhost:9090 for your Prometheus metrics
 
-### More resources:
+* Your function can be accessed via the gateway like this:
 
-FaaS is still expanding and growing, check out the development branch for:
+**Sample function: Docker Hub Stats (hubstats)**
 
-* [Auto-scaling](https://twitter.com/alexellisuk/status/823262200236277762)
-* Prometheus alerts
-* More sample functions
-* [Brand new UI](https://twitter.com/alexellisuk/status/823262200236277762)
+```
+# curl -X POST http://localhost:8080/function/func_hubstats -d "alexellis2"
+The organisation or user alexellis2 has 99 repositories on the Docker hub.
 
-[Development branch](https://github.com/alexellis/faas/commits/labels_metrics)
+# curl -X POST http://localhost:8080/function/func_hubstats -d "library"
+The organisation or user library has 128 repositories on the Docker hub.
+```
 
-#### Would you prefer a video overview?
+The `-d` value passes in the argument for your function. This is read via STDIN and used to query the Docker Hub to see how many images you've created/pushed.
 
-See how to deploy FaaS onto play-with-docker.com and Docker Swarm in 1-2 minutes. See the sample functions in action and watch the graphs in Prometheus as we ramp up the amount of requests. 
+**Sample function: webhook stasher (webhookstash)**
 
-* [Deep Dive into Functions as a Service (FaaS) on Docker](https://www.youtube.com/watch?v=sp1B7l5mEzc)
+Another cool sample function is the Webhook Stasher which saves the body of any data posted to the service to the container's filesystem. Each file is written with the filename of the UNIX time.
 
-#### Prometheus metrics are built-in
+```
+# curl -X POST http://localhost:8080/function/func_webhookstash -d '{"event": "fork", "repo": "alexellis2/faas"}'
+Webhook stashed
+
+# docker ps|grep stash
+d769ca70729d        alexellis2/faas-webhookstash@sha256:b378f1a144202baa8fb008f2c8896f5a8
+
+# docker exec d769ca70729d find .
+.
+./1483999546817280727.txt
+./1483999702130689245.txt
+./1483999702533419188.txt
+./1483999702978454621.txt
+./1483999703284879767.txt
+./1483999719981227578.txt
+./1483999720296180414.txt
+./1483999720666705381.txt
+./1483999720961054638.txt
+```
 
-Prometheus is built into FaaS and the sample stack, so you can check throughput for each function individually with a rate function in Prometheus like this:
+**Sample function: Node OS Info (nodeinfo)**
 
-![](https://pbs.twimg.com/media/C2d9IkbXAAI58fz.jpg)
+Grab OS, CPU and other info via a Node.js container using the `os` module.
 
+```
+# curl -X POST http://localhost:8080/function/func_nodeinfo -d ''
+
+linux x64 [ { model: 'Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz',
+    speed: 2500,
+    times: 
+     { user: 3754430800,
+       nice: 2450200,
+       sys: 885352200,
+       idle: 25599742200,
+       irq: 0 } },
+...
+```
 
+> Why not start the code on play-with-docker.com and then configure a Github repository to send webhook to the function?
diff --git a/docker-compose.yml b/docker-compose.yml
index cf66e1daf0c45439a02e416a4287254075cd552d..a87d581f30772dbeba6ed5800909d341040f5e7d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -53,8 +53,11 @@ services:
 
 
     # Sample functions go here.
+    # Service label of "function" allows functions to show up in UI on http://gateway:8080/
     webhookstash:
         image: alexellis2/faas-webhookstash:latest
+        labels:
+            function: "true"
         depends_on:
             - gateway
         networks:
@@ -65,6 +68,8 @@ services:
 
     hubstats:
         image: alexellis2/faas-dockerhubstats:latest
+        labels:
+            function: "true"
         depends_on:
             - gateway
         networks:
@@ -72,8 +77,11 @@ services:
         environment:
             no_proxy:   "gateway"
             https_proxy: $https_proxy
+
     nodeinfo:
         image: alexellis2/faas-nodeinfo:latest
+        labels:
+            function: "true"
         depends_on:
             - gateway
         networks:
@@ -84,6 +92,8 @@ services:
 
     echoit:
         image: alexellis2/faas-alpinefunction:latest
+        labels:
+            function: "true"
         depends_on:
             - gateway
         networks:
@@ -95,6 +105,8 @@ services:
 
     wordcount:
         image: alexellis2/faas-alpinefunction:latest
+        labels:
+            function: "true"
         depends_on:
             - gateway
         networks:
@@ -106,6 +118,8 @@ services:
 
     markdown:
         image: alexellis2/faas-markdownrender:latest
+        labels:
+            function: "true"
         depends_on:
             - gateway
         networks:
@@ -114,15 +128,17 @@ services:
             no_proxy:   "gateway"
             https_proxy: $https_proxy
 
-    # alexacolorchange:
-    #     image: alexellis2/faas-alexachangecolorintent 
-    #     depends_on:
-    #         - gateway
-    #     networks:
-    #         - functions
-    #     environment:
-    #         no_proxy:   "gateway"
-    #         https_proxy: $https_proxy
+    alexacolorchange:
+        labels:
+            function: "true"
+        image: alexellis2/faas-alexachangecolorintent 
+        depends_on:
+            - gateway
+        networks:
+            - functions
+        environment:
+            no_proxy:   "gateway"
+            https_proxy: $https_proxy
 
 
 
diff --git a/gateway/assets/index.html b/gateway/assets/index.html
index 6f6f5d13814b6fba7066556c8e6f9e6293032be3..ae9cb38f1a96ef1f0fad3e065c362e2b08429220 100644
--- a/gateway/assets/index.html
+++ b/gateway/assets/index.html
@@ -1,4 +1,5 @@
-<html ng-app="faasGateway" >
+<html ng-app="faasGateway">
+
 <head>
     <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic" />
     <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
@@ -7,117 +8,123 @@
 
     <link rel="stylesheet" href="style/bootstrap.css">
 
-  </head>
-
-  <body ng-controller="home">
-  <div layout="column" style="height:100%;" ng-cloak>
-
-  <section id="popupContainer" layout="row" flex>
-    <md-sidenav
-        class="md-sidenav-left"
-        md-component-id="left"
-        md-is-locked-open="$mdMedia('gt-sm')"
-        md-whiteframe="4" layout="column">
-
-      <md-toolbar class="md-theme-indigo">
-        <h1 class="md-toolbar-tools">FaaS Gateway</h1>
-      </md-toolbar>
-      
-      <md-content layout-padding>
-        <md-button ng-click="newFunction()" ng-disabled="isFunctionBeingCreated" class="md-primary">New function</md-button>
-
-        <md-list>
-          <md-list-item ng-switch class="md-3-line" ng-click="showFunction(function)" ng-repeat="function in functions | orderBy: '-invocationCount'" ng-class="function.name == selectedFunction.name ? 'selected' : false">
-              <md-icon ng-switch-when="true" style="color: blue" md-svg-icon="person"></md-icon>
-              <md-icon ng-switch-when="false" md-svg-icon="person-outline"></md-icon>
-              <p>{{function.name}}</p>
-              <md-divider ng-if="!$last"></md-divider>
-          </md-list-item>
-        </md-list>
-      </md-content>
-    </md-sidenav>
-
-    <md-content flex layout-padding ng-if="!selectedFunction" ng-show="functions.length">
-      <div layout="column" layout-align="top center">
-        <p>Select a function.</p>
-      </div>
-      <div flex></div>
-    </md-content>
-
-    <md-content flex layout-padding ng-if="!functions.length">
-      <div layout="column" layout-align="top center">
-        <p>No functions found in FaaS.</p>
-      </div>
-      <div flex></div>
-    </md-content>
-
-    <md-content flex layout="column" ng-repeat="function in functions" ng-show="function.name == selectedFunction.name">
-
-        <md-card md-theme="default" md-theme-watch>
-            <md-card-title>
-                <md-card-title-text>
-
-                    <span class="md-headline">
+</head>
+
+<body ng-controller="home">
+    <div layout="column" style="height:100%;" ng-cloak>
+
+        <section id="popupContainer" layout="row" flex>
+            <md-sidenav class="md-sidenav-left" md-component-id="left" md-is-locked-open="$mdMedia('gt-sm')" md-whiteframe="4" layout="column">
+
+                <md-toolbar class="md-theme-indigo">
+                    <h1 class="md-toolbar-tools">FaaS Gateway</h1>
+                </md-toolbar>
+
+                <md-content layout-padding>
+                    <md-button ng-click="newFunction()" ng-disabled="isFunctionBeingCreated" class="md-primary">New function</md-button>
+
+                    <md-list>
+                        <md-list-item ng-switch class="md-3-line" ng-click="showFunction(function)" ng-repeat="function in functions | orderBy: '-invocationCount'" ng-class="function.name == selectedFunction.name ? 'selected' : false">
+                            <md-icon ng-switch-when="true" style="color: blue" md-svg-icon="person"></md-icon>
+                            <md-icon ng-switch-when="false" md-svg-icon="person-outline"></md-icon>
+                            <p>{{function.name}}</p>
+                            <md-divider ng-if="!$last"></md-divider>
+                        </md-list-item>
+                    </md-list>
+                </md-content>
+            </md-sidenav>
+
+            <md-content flex layout-padding ng-if="!selectedFunction" ng-show="functions.length">
+                <div layout="column" layout-align="top center">
+                    <p>Select a function.</p>
+                </div>
+                <div flex></div>
+            </md-content>
+
+            <md-content flex layout-padding ng-if="!functions.length">
+                <div layout="column" layout-align="top center">
+                    <p>No functions found in FaaS.</p>
+                </div>
+                <div flex></div>
+            </md-content>
+
+            <md-content flex layout="column" ng-repeat="function in functions" ng-show="function.name == selectedFunction.name">
+
+                <md-card md-theme="default" md-theme-watch>
+                    <md-card-title>
+                        <md-card-title-text>
+
+                            <span class="md-headline">
                       {{function.name}}
                     </span>
-                    <div layout-gt-sm="row">
-                      <md-input-container class="md-icon-float md-block">
-                        <label>Replicas</label>
-                        <input ng-model="function.replicas" type="text" readonly="readonly">
-                      </md-input-container>
-                      <md-input-container class="md-block" flex-gt-sm>
-                        <label>Invocation count</label>
-                        <input ng-model="function.invocationCount" type="text" readonly="readonly">
-                      </md-input-container>
-                    </div>
-
-                    <div layout-gt-sm="row">
-                      <md-input-container class="md-block" flex-gt-sm>
-                        <label>Image</label>
-                        <input ng-model="function.image" type="text" readonly="readonly">
-                      </md-input-container>
-                    </div>
-                <md-card-title-text>
-            </md-card-title>
-        </md-card>
-        <md-card>
-         <md-card-title>
-            <md-card-title-text>
-
-                <span class="md-headline">
+                            <div layout-gt-sm="row">
+                                <md-input-container class="md-icon-float md-block">
+                                    <label>Replicas</label>
+                                    <input ng-model="function.replicas" type="text" readonly="readonly">
+                                </md-input-container>
+                                <md-input-container class="md-block" flex-gt-sm>
+                                    <label>Invocation count</label>
+                                    <input ng-model="function.invocationCount" type="text" readonly="readonly">
+                                </md-input-container>
+                            </div>
+
+                            <div layout-gt-sm="row">
+                                <md-input-container class="md-block" flex-gt-sm>
+                                    <label>Image</label>
+                                    <input ng-model="function.image" type="text" readonly="readonly">
+                                </md-input-container>
+                            </div>
+                            <md-card-title-text>
+                    </md-card-title>
+                </md-card>
+                <md-card>
+                    <md-card-title>
+                        <md-card-title-text>
+
+                            <span class="md-headline">
                   Invoke function
                 </span>
-                <div layout-gt-sm="row">
-                  <md-input-container class="md-block" flex-gt-sm>
-                    <button ng-click="fireRequest()" class="md-raised md-button md-ink-ripple" type="button">
+                            <div layout-gt-sm="row">
+                                <md-input-container class="md-block" flex-gt-sm>
+                                    <button ng-click="fireRequest()" class="md-raised md-button md-ink-ripple" type="button">
                       <span class="ng-scope">Invoke</span><div class="md-ripple-container"></div>
                     </button>
-                  </md-input-container>
-                </div>
-                <div layout-gt-sm="row">
-                  <md-input-container class="md-block" flex-gt-sm>
-                    <label>Request body</label>
-                    <textarea ng-model="invocation.request" cols="80" rows="4"></textarea>
-                  </md-input-container>
-                </div>
-                <div layout-gt-sm="row">
-                  <md-input-container class="md-block" flex-gt-sm>
-                    <label>Response status</label>
-                    <input ng-model="invocationStatus" type="text" readonly="readonly">
-                  </md-input-container>
-                </div>
-                <div layout-gt-sm="row">
-                  <md-input-container class="md-block" flex-gt-sm>
-                    <label>Response body</label>
-                    <textarea ng-model="invocationResponse" cols="80" rows=10></textarea>
-                  </md-input-container>
-                </div>
-            <md-card-title-text>
-        </md-card-title>
-    </md-card>
-    </md-content>
-  </section>
-  </div>
+                                </md-input-container>
+                            </div>
+
+                            <div layout-gt-sm="row">
+                                <md-input-container class="md-block" flex-gt-sm>
+                                    <md-radio-group ng-model="invocation.contentType">
+                                        <md-radio-button value="text" class="md-primary"> Text </md-radio-button>
+                                        <md-radio-button value="json"> JSON </md-radio-button>
+                                    </md-radio-group>
+                                </md-input-container>
+                            </div>
+
+                            <div layout-gt-sm="row">
+                                <md-input-container class="md-block" flex-gt-sm>
+                                    <label>Request body</label>
+                                    <textarea ng-model="invocation.request" cols="80" rows="4"></textarea>
+                                </md-input-container>
+                            </div>
+                            <div layout-gt-sm="row">
+                                <md-input-container class="md-block" flex-gt-sm>
+                                    <label>Response status</label>
+                                    <input ng-model="invocationStatus" type="text" readonly="readonly">
+                                </md-input-container>
+                            </div>
+                            <div layout-gt-sm="row">
+                                <md-input-container class="md-block" flex-gt-sm>
+                                    <label>Response body</label>
+                                    <textarea ng-model="invocationResponse" cols="80" rows=10></textarea>
+                                </md-input-container>
+                            </div>
+                            <md-card-title-text>
+                    </md-card-title>
+                </md-card>
+            </md-content>
+        </section>
+    </div>
 
 
     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
@@ -126,6 +133,6 @@
     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
     <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>
     <script src="script/bootstrap.js"></script>
-  </body>
+</body>
 
-</html>
+</html>
\ No newline at end of file
diff --git a/gateway/assets/script/bootstrap.js b/gateway/assets/script/bootstrap.js
index d147be427e1203a974787c7ea3258616f8ab1d21..72425375f9f1d46985be1b24c71a63aa3a78f507 100644
--- a/gateway/assets/script/bootstrap.js
+++ b/gateway/assets/script/bootstrap.js
@@ -1,13 +1,13 @@
 "use strict"
 var app = angular.module('faasGateway', ['ngMaterial']);
 
-app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', function($scope, $log, $http, $location, $timeout) {
+app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$mdDialog', function($scope, $log, $http, $location, $timeout, $mdDialog) {
     $scope.functions = [];
     $scope.invocationRequest = "";
     $scope.invocationResponse = "";
     $scope.invocationStatus = "";
     $scope.invocation = {
-
+        contentType: "text"
     };
     $scope.invocation.request = ""
     setInterval(function() {
@@ -15,33 +15,42 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', func
     }, 1000);
 
     $scope.fireRequest = function() {
-        $http({url:"/function/"+$scope.selectedFunction.name, data: $scope.invocation.request, method: "POST",  headers: {"Content-Type": "text/plain"}, responseType: "text"}).
-        then(function(response) {
-            $scope.invocationResponse = response.data;
-            $scope.invocationStatus = response.status;
-        }).catch(function(error1) {
-            $scope.invocationResponse = error1;
-            $scope.invocationStatus = null;
-        });
+
+        var options = {
+            url: "/function/" + $scope.selectedFunction.name,
+            data: $scope.invocation.request,
+            method: "POST",
+            headers: { "Content-Type": $scope.invocation.contentType == "json" ? "application/json" : "text/plain" },
+            responseType: $scope.invocation.contentType
+        };
+
+        $http(options)
+            .then(function(response) {
+                $scope.invocationResponse = response.data;
+                $scope.invocationStatus = response.status;
+            }).catch(function(error1) {
+                $scope.invocationResponse = error1;
+                $scope.invocationStatus = null;
+            });
 
         // console.log("POST /function/"+ $scope.selectedFunction.name);
         // console.log("Body: " + $scope.invocation.request);
     };
 
-    var refreshData = function () {
+    var refreshData = function() {
         var previous = $scope.functions;
 
         var cl = function(previousItems) {
             $http.get("/system/functions").then(function(response) {
-                if(response && response.data) {
-                    if(previousItems.length !=response.data.length) {
+                if (response && response.data) {
+                    if (previousItems.length != response.data.length) {
                         $scope.functions = response.data;
                     } else {
-                        for(var i =0;i<$scope.functions.length;i++) {
-                            for(var j =0;j<response.data.length;j++) {
-                                if($scope.functions[i].name == response.data[j].name) {
-                                    $scope.functions[i].replicas=response.data[j].replicas;
-                                    $scope.functions[i].invocationCount=response.data[j].invocationCount;
+                        for (var i = 0; i < $scope.functions.length; i++) {
+                            for (var j = 0; j < response.data.length; j++) {
+                                if ($scope.functions[i].name == response.data[j].name) {
+                                    $scope.functions[i].replicas = response.data[j].replicas;
+                                    $scope.functions[i].invocationCount = response.data[j].invocationCount;
                                 }
                             }
                         }
@@ -59,22 +68,38 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', func
     };
 
     $scope.showFunction = function(fn) {
-        if($scope.selectedFunction!=fn) {
+        if ($scope.selectedFunction != fn) {
             $scope.selectedFunction = fn;
             $scope.invocation.request = "";
             $scope.invocationResponse = "";
             $scope.invocationStatus = "";
+            $scope.invocation.contentType = "";
         }
     };
 
+    var showDialog = function() {
+        var alert = $mdDialog.alert({
+            title: 'New function',
+            textContent: 'New functions are not supported yet, but will be defined here.',
+            ok: 'Close'
+        });
+        $mdDialog
+            .show(alert)
+            .finally(function() {
+                alert = undefined;
+            });
+    };
+
     // TODO: popup + form to create new Docker service.
+    // More to follow @ https://material.angularjs.org/latest/demo/dialog
     $scope.newFunction = function() {
-        $scope.functions.push({
-            name: "f" +($scope.functions.length+2),
-            replicas: 0,
-            invokedCount: 0
-        });
+        // $scope.functions.push({
+        //     name: "f" + ($scope.functions.length + 2),
+        //     replicas: 0,
+        //     invokedCount: 0
+        // });
+        showDialog()
     };
 
     fetch();
-}]);
+}]);
\ No newline at end of file
diff --git a/gateway/handlers/functionshandler.go b/gateway/handlers/functionshandler.go
index e2c377db97e4feaf510747a385371631cb7cc220..675eeb76bd9cfac84a538a7bb4dfad895f26dbc8 100644
--- a/gateway/handlers/functionshandler.go
+++ b/gateway/handlers/functionshandler.go
@@ -30,22 +30,27 @@ func MakeFunctionReader(metricsOptions metrics.MetricOptions, c *client.Client)
 		}
 
 		// TODO: Filter only "faas" functions (via metadata?)
-		functions := make([]requests.Function, 0)
+		var functions []requests.Function
+
 		for _, service := range services {
-			counter, _ := metricsOptions.GatewayFunctionInvocation.GetMetricWithLabelValues(service.Spec.Name)
-
-			// Get the metric's value from ProtoBuf interface (idea via Julius Volz)
-			var protoMetric io_prometheus_client.Metric
-			counter.Write(&protoMetric)
-			invocations := protoMetric.GetCounter().GetValue()
-
-			f := requests.Function{
-				Name:            service.Spec.Name,
-				Image:           service.Spec.TaskTemplate.ContainerSpec.Image,
-				InvocationCount: invocations,
-				Replicas:        *service.Spec.Mode.Replicated.Replicas,
+
+			if len(service.Spec.TaskTemplate.ContainerSpec.Labels["function"]) > 0 {
+
+				counter, _ := metricsOptions.GatewayFunctionInvocation.GetMetricWithLabelValues(service.Spec.Name)
+
+				// Get the metric's value from ProtoBuf interface (idea via Julius Volz)
+				var protoMetric io_prometheus_client.Metric
+				counter.Write(&protoMetric)
+				invocations := protoMetric.GetCounter().GetValue()
+
+				f := requests.Function{
+					Name:            service.Spec.Name,
+					Image:           service.Spec.TaskTemplate.ContainerSpec.Image,
+					InvocationCount: invocations,
+					Replicas:        *service.Spec.Mode.Replicated.Replicas,
+				}
+				functions = append(functions, f)
 			}
-			functions = append(functions, f)
 		}
 
 		functionBytes, _ := json.Marshal(functions)
diff --git a/sample-functions/NodeInfo/main.js b/sample-functions/NodeInfo/main.js
index 9bd247a955512e292b635d31ca9ae142d73629a4..fd477e6e14da7ba0f60e949da164fbffb3235184 100644
--- a/sample-functions/NodeInfo/main.js
+++ b/sample-functions/NodeInfo/main.js
@@ -1,7 +1,19 @@
 'use strict'
 let os = require('os');
+let fs = require('fs');
+
 const getStdin = require('get-stdin');
- 
-getStdin().then(content => {
-  console.log(os.platform(), os.arch(), os.cpus(), os.uptime(), os.userInfo());
-});
+
+getStdin().then((content) => {
+    fs.readFile("/etc/hostname", "utf8", (err, data) => {
+        console.log("Hostname: " + data);
+        console.log("Platform: " + os.platform());
+        console.log("Arch: " + os.arch());
+        console.log("CPU count: " + os.cpus().length);
+        console.log("Uptime: " + os.uptime())
+        console.log("User info: " + os.userInfo());
+        if (content && content.length && content.indexOf("verbose") > -1) {
+            console.log(os.cpus());
+        }
+    });
+});
\ No newline at end of file