diff --git a/app/actors/FizzBuzzActor.java b/app/actors/FizzBuzzActor.java
new file mode 100644
index 0000000000000000000000000000000000000000..2279274199bf0e80fdfff6f59f32a583480dc1d6
--- /dev/null
+++ b/app/actors/FizzBuzzActor.java
@@ -0,0 +1,73 @@
+package actors;
+
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.actor.UntypedActor;
+
+/**
+ * A rather trivial Actor that just plays FizzBuzz
+ */
+public class FizzBuzzActor extends UntypedActor {
+
+    int nextNum = 0;
+
+    /**
+     * The marshall. We'll also send them the messages
+     */
+    ActorRef marshallActor;
+
+    /**
+     *
+     */
+    public static Props props = Props.create(FizzBuzzActor.class);
+
+
+    @Override
+    public void onReceive(Object message) {
+        if (message.equals("Marshall")) {
+            /*
+             * We're given the marshall's ActorRef by a message saying "Marshall". The Marshall will appear
+             * to be the sender (even though it's actually been sent by Setup)
+             */
+            marshallActor = getSender();
+        } else if (message instanceof ActorRef) {
+            // If we're sent an ActorRef, that's the marshall telling us who our opponent is and to get started
+            ((ActorRef) message).tell(1, getSelf());
+            marshallActor.tell(1, getSelf());
+        } else if (message instanceof Integer) {
+            nextNum = (Integer) message + 1;
+            reply();
+        } else  {
+            nextNum = nextNum + 2;
+
+            // Stop at 1000 so we don't blow the heap by writing forever into a StringBuilder
+            if (nextNum < 1000) {
+                reply();
+            }
+        }
+    }
+
+    void reply() {
+        if (nextNum % 15 == 0) {
+            getSender().tell("fizzbuzz", getSelf());
+            marshallActor.tell("fizzbuzz", getSelf());
+        } else if (nextNum % 5 == 0) {
+            getSender().tell("buzz", getSelf());
+            marshallActor.tell("buzz", getSelf());
+        } else if (nextNum % 3 == 0) {
+            getSender().tell("fizz", getSelf());
+            marshallActor.tell("fizz", getSelf());
+        } else {
+            getSender().tell(nextNum, getSelf());
+            marshallActor.tell(nextNum, getSelf());
+        }
+
+        // Put this Actor to sleep for 250ms before it checks its next message
+        try {
+            Thread.sleep(250);
+        } catch (InterruptedException ex) {
+            // do nothing
+        }
+    }
+
+}
diff --git a/app/actors/MarshallActor.java b/app/actors/MarshallActor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f3dfbd39a2577aa10b2a129ef5248e6aeb866f51
--- /dev/null
+++ b/app/actors/MarshallActor.java
@@ -0,0 +1,36 @@
+package actors;
+
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.actor.UntypedActor;
+
+import javax.inject.Inject;
+
+/**
+ * You might or might not want this actor in the end. In this example, its role is to be the central point of
+ * contact between your web app and the actor system that might be receiving outside events.
+ */
+public class MarshallActor extends UntypedActor {
+
+    StringBuilder messages = new StringBuilder();
+
+    public static Props props = Props.create(MarshallActor.class);
+
+    public MarshallActor() {
+
+    }
+
+    @Override
+    public void onReceive(Object message) {
+        if (message.equals("Report!")) {
+            getSender().tell(messages.toString(), getSelf());
+        } else {
+            messages.append(getSender().toString());
+            messages.append(" said ");
+            messages.append(message);
+            messages.append("\n");
+        }
+
+    }
+
+}
diff --git a/app/actors/Setup.java b/app/actors/Setup.java
new file mode 100644
index 0000000000000000000000000000000000000000..834a9c6745bef1c050a224d285a7f3de2c74327c
--- /dev/null
+++ b/app/actors/Setup.java
@@ -0,0 +1,36 @@
+package actors;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Holds all the "famous" Actors in our system. This hopefully makes things convenient, because if you @Inject Setup,
+ * you'll then be able to look up ActorRefs to all the actors just by Setup.marshallActor, etc.
+ *
+ * It's a Singleton, so Google Guice will only create one of these for us.
+ */
+@Singleton
+public class Setup {
+
+    /**
+     * This is a reference to an Actor
+     */
+    public final ActorRef marshallActor;
+
+    @Inject
+    public Setup(ActorSystem system) {
+        marshallActor = system.actorOf(MarshallActor.props);
+
+        ActorRef fb1 = system.actorOf(FizzBuzzActor.props, "Player1");
+        ActorRef fb2 = system.actorOf(FizzBuzzActor.props, "Player2");
+        fb1.tell("Marshall", marshallActor);
+        fb2.tell("Marshall", marshallActor);
+
+        fb1.tell(fb2, fb2);
+
+    }
+
+}
\ No newline at end of file
diff --git a/app/controllers/Application.java b/app/controllers/Application.java
index 20304f43ab21070c2f616f0ff2ed6a66fbeacf1b..7fa68bf2cff2d1b727f5f7d3af78aa354a82be8a 100644
--- a/app/controllers/Application.java
+++ b/app/controllers/Application.java
@@ -1,42 +1,50 @@
 package controllers;
 
-import model.BCryptExample;
-import model.Captcha;
+import actors.Setup;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import play.mvc.Controller;
 import play.mvc.Result;
+import scala.compat.java8.FutureConverters;
+import play.libs.ws.*;
 
-import java.util.Arrays;
+import java.util.concurrent.CompletionStage;
+import static akka.pattern.Patterns.ask;
 
+@Singleton
 public class Application extends Controller {
 
-    public static Result index() {
-        int arrayLength = 5;
-        int[] indexes = new int[arrayLength];
-        for (int i = 0; i < arrayLength; i++) {
-            indexes[i] = (int)(Captcha.numPhotos() * Math.random());
-        }
+    Setup actorSetup;
 
-        return ok(views.html.application.index.render(indexes));
-    }
+    WSClient wsClient;
 
-    private static int countBeagles(String[] indexes) {
-        int i = 0;
-        for (String s : indexes) {
-            if (Captcha.isCorrect(Integer.valueOf(s))) {
-                i++;
-            }
-        }
-        return i;
+    @Inject
+    public Application(Setup actorSetup, WSClient wsClient) {
+        this.actorSetup = actorSetup;
+        this.wsClient = wsClient;
     }
 
-    public static Result matches() {
-        String[] sent = request().body().asFormUrlEncoded().get("sent");
-        String[] beagles = request().body().asFormUrlEncoded().get("beagle");
-
-        int numBeagles = countBeagles(sent);
-        int numFound = countBeagles(beagles);
-
-        return ok(views.html.application.matches.render(numBeagles, numFound));
+    /**
+     * Play framework suppors asynchronous controller methods -- that is, methods that instead of returning a Result
+     * return a CompletionStage, which will produce a Result some time in the future
+     */
+    public CompletionStage<Result> index() {
+        /*
+         * This code might look a little complex.
+         *
+         * ask sends a message to an ActorRef, and then returns a Future that will eventually contain the response.
+         * But Future is a Scala class, so FutureConverters.toJava converts it into a CompletionStage, which is Java's equivalent.
+         * thenApply is a method on CompletionStage that means "when you get the result, do this with it, and return a new CompletionStage"
+         */
+        return FutureConverters.toJava(ask(actorSetup.marshallActor, "Report!", 1000))
+                .thenApply(response -> ok(response.toString()));
     }
 
+    /**
+     * This controller method uses Play's Web Service client to make another HTTP call, and do something with the
+     * response
+     */
+    public CompletionStage<Result> whatDidGitLabSay() {
+        return wsClient.url("http://www.une.edu.au/foo").get().thenApply(r -> ok(r.getStatusText()));
+    }
 }
diff --git a/build.sbt b/build.sbt
index d8d59d2431e4629d14111842ed344454299570da..faca572fb7ee0fbb27f468d91dd72253f8247be1 100644
--- a/build.sbt
+++ b/build.sbt
@@ -2,10 +2,14 @@ name := "chirper"
 
 version := "1.0"
 
-scalaVersion := "2.11.6"
+scalaVersion := "2.11.7"
 
 lazy val root = (project in file(".")).enablePlugins(PlayJava)
 
+routesGenerator := InjectedRoutesGenerator
+
 libraryDependencies ++= Seq(
+  javaWs,
   "org.mindrot" % "jbcrypt" % "0.3m"
 )
+
diff --git a/conf/routes b/conf/routes
index 88b0c087c9f12b5fdb988757ff1e94e67347db3a..8fd27619f0706985e55aba011fe4211026d82edd 100644
--- a/conf/routes
+++ b/conf/routes
@@ -3,7 +3,7 @@
 # ~~~~
 
 GET     /                           controllers.Application.index()
-POST    /matches                    controllers.Application.matches()
+GET     /ws                         controllers.Application.whatDidGitLabSay()
 
 # Map static resources from the /public folder to the /assets URL path
 GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)
\ No newline at end of file
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 6d2584df5d4de6c2326478db31dcd04a3117afd5..f9cdc994ad9fcc7d8efbb539aad9bc7d530c1a02 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,2 +1,2 @@
 // Use the Play sbt plugin for Play projects
-addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.2")
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.4")