diff --git a/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckDaemon.java b/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckDaemon.java
new file mode 100644
index 0000000..2c79b5f
--- /dev/null
+++ b/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckDaemon.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed 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.
+ */
+
+package org.onosproject.buckdaemon;
+
+import com.google.common.io.ByteStreams;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import org.onosproject.checkstyle.CheckstyleRunner;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static java.nio.file.StandardOpenOption.*;
+
+/**
+ * Buck daemon process.
+ */
+public final class BuckDaemon {
+
+    private static long POLLING_INTERVAL = 1000; //ms
+
+    private final Map<String, BuckTask> tasks = new HashMap<>();
+    private final String portLock;
+    private final String buckPid;
+
+    // Public construction forbidden
+    private BuckDaemon(String[] args) {
+        portLock = args[0];
+        buckPid = args[1];
+    }
+
+    /**
+     * Main entry point for the daemon.
+     *
+     * @param args command-line arguments
+     */
+    public static void main(String[] args)
+            throws CheckstyleException, IOException {
+        BuckDaemon daemon = new BuckDaemon(args);
+        daemon.registerTasks();
+        daemon.startServer();
+    }
+
+    /**
+     * Registers re-entrant tasks by their task name.
+     */
+    private void registerTasks() {
+        tasks.put("checkstyle", new CheckstyleRunner(System.getProperty("checkstyle.config"),
+                                                     System.getProperty("checkstyle.suppressions")));
+        // tasks.put("swagger", new SwaggerGenerator());
+    }
+
+    /**
+     * Monitors another PID and exit when that process exits.
+     */
+    private void watchProcess(String pid) {
+        if (pid == null || pid.equals("0")) {
+            return;
+        }
+        Timer timer = new Timer(true); // start as a daemon, so we don't hang shutdown
+        timer.scheduleAtFixedRate(new TimerTask() {
+            private String cmd = "kill -s 0 " + pid;
+
+            @Override
+            public void run() {
+                try {
+                    Process p = Runtime.getRuntime().exec(cmd);
+                    p.waitFor();
+                    if (p.exitValue() != 0) {
+                        System.err.println("shutting down...");
+                        System.exit(0);
+                    }
+                } catch (IOException | InterruptedException e) {
+                    //no-op
+                    e.printStackTrace();
+                }
+            }
+        }, POLLING_INTERVAL, POLLING_INTERVAL);
+    }
+
+    /**
+     * Initiates a server.
+     */
+    private void startServer() throws IOException, CheckstyleException {
+        // Use a file lock to ensure only one copy of the daemon runs
+        Path portLockPath = Paths.get(portLock);
+        FileChannel channel = FileChannel.open(portLockPath, WRITE, CREATE);
+        FileLock lock = channel.tryLock();
+        if (lock == null) {
+            System.out.println("Server is already running");
+            System.exit(1);
+        } //else, hold the lock until the JVM exits
+
+        // Start the server and bind it to a random port
+        ServerSocket server = new ServerSocket(0);
+
+        // Monitor the parent buck process
+        watchProcess(buckPid);
+
+        // Set up hook to clean up after ourselves
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            try {
+                channel.truncate(0);
+                channel.close();
+                System.err.println("tear down...");
+                Files.delete(portLockPath);
+            } catch (IOException e) {
+                //no-op: shutting down
+                e.printStackTrace();
+            }
+        }));
+
+        // Write the bound port to the port file
+        int port = server.getLocalPort();
+        channel.truncate(0);
+        channel.write(ByteBuffer.wrap(Integer.toString(port).getBytes()));
+
+        // Instantiate a Checkstyle runner and executor; serve until exit...
+        ExecutorService executor = Executors.newCachedThreadPool();
+        while (true) {
+            try {
+                executor.submit(new BuckTaskRunner(server.accept()));
+            } catch (Exception e) {
+                e.printStackTrace();
+                //no-op
+            }
+        }
+    }
+
+    /**
+     * Runnable capable of invoking the appropriate Buck task with input
+     * consumed form the specified socket and output produced back to that
+     * socket.
+     */
+    private class BuckTaskRunner implements Runnable {
+
+        private final Socket socket;
+
+        public BuckTaskRunner(Socket socket) {
+            this.socket = socket;
+        }
+
+        @Override
+        public void run() {
+            try {
+                BuckTaskContext context = new BuckTaskContext(socket.getInputStream());
+                String taskName = context.taskName();
+                if (!taskName.isEmpty()) {
+                    BuckTask task = tasks.get(taskName);
+                    if (task != null) {
+                        System.out.println(String.format("Executing task '%s'", taskName));
+                        task.execute(context);
+                        for (String line : context.output()) {
+                            output(socket, line);
+                        }
+                    } else {
+                        String message = String.format("No task named '%s'", taskName);
+                        System.out.print(message);
+                        output(socket, message);
+                    }
+                }
+                socket.getOutputStream().flush();
+                socket.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        private void output(Socket socket, String line) throws IOException {
+            socket.getOutputStream().write((line + "\n").getBytes());
+        }
+    }
+}
diff --git a/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckTask.java b/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckTask.java
new file mode 100644
index 0000000..fb6a8dc
--- /dev/null
+++ b/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckTask.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed 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.
+ */
+
+package org.onosproject.buckdaemon;
+
+/**
+ * Abstraction of a Buck task that can be spawned by the Buck daemon
+ */
+public interface BuckTask {
+
+    /**
+     * Executes the task, consuming the specified input and producing output.
+     *
+     * @param context context for the tast operation
+     */
+    void execute(BuckTaskContext context);
+
+}
diff --git a/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckTaskContext.java b/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckTaskContext.java
new file mode 100644
index 0000000..dc5b753
--- /dev/null
+++ b/tools/build/conf/src/main/java/org/onosproject/buckdaemon/BuckTaskContext.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed 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.
+ */
+
+package org.onosproject.buckdaemon;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.ByteStreams;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Context for executing a single Buck task.
+ */
+public class BuckTaskContext {
+
+    private final String taskName;
+    private final ImmutableList<String> input;
+    private final List<String> output = new ArrayList<>();
+
+    BuckTaskContext(InputStream inputString) throws IOException {
+        String[] split = new String(ByteStreams.toByteArray(inputString)).split("\n");
+        checkArgument(split.length >= 1, "Request must contain at least task type");
+        this.taskName = split[0];
+        ImmutableList.Builder<String> builder = ImmutableList.builder();
+        for (int i = 1; i < split.length; i++) {
+            builder.add(split[i]);
+        }
+        input = builder.build();
+    }
+
+    /**
+     * Returns the symbolic task name.
+     */
+    public String taskName() {
+        return taskName;
+    }
+
+    /**
+     * Returns the input data a list of strings.
+     *
+     * @return input data
+     */
+    public List<String> input() {
+        return ImmutableList.copyOf(input);
+    }
+
+    /**
+     * Returns the output data a list of strings.
+     *
+     * @return output data
+     */
+    List<String> output() {
+        return ImmutableList.copyOf(output);
+    }
+
+    /**
+     * Adds a line to the output data.
+     *
+     * @param line line of output data
+     */
+    public void output(String line) {
+        output.add(line);
+    }
+
+}
diff --git a/tools/build/conf/src/main/java/org/onosproject/checkstyle/CheckstyleRunner.java b/tools/build/conf/src/main/java/org/onosproject/checkstyle/CheckstyleRunner.java
index e2a89b7..25f3d53 100644
--- a/tools/build/conf/src/main/java/org/onosproject/checkstyle/CheckstyleRunner.java
+++ b/tools/build/conf/src/main/java/org/onosproject/checkstyle/CheckstyleRunner.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.checkstyle;
 
-import com.google.common.io.ByteStreams;
 import com.puppycrawl.tools.checkstyle.Checker;
 import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
@@ -24,64 +23,51 @@
 import com.puppycrawl.tools.checkstyle.api.AuditListener;
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 import com.puppycrawl.tools.checkstyle.api.Configuration;
+import org.onosproject.buckdaemon.BuckTask;
+import org.onosproject.buckdaemon.BuckTaskContext;
 
 import java.io.File;
-import java.io.IOException;
-import java.net.Socket;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 
-public class CheckstyleRunner {
+/**
+ * Buck task for executing checkstyle on the specified project files.
+ */
+public class CheckstyleRunner implements BuckTask {
 
     private final Configuration config;
 
-    public CheckstyleRunner(String configLocation, String suppressionLocation)
-            throws CheckstyleException {
-        // create a configuration
-        DefaultConfiguration config = (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
-                configLocation, new PropertiesExpander(System.getProperties()));
+    public CheckstyleRunner(String configLocation, String suppressionLocation) {
+        try {
+            // create a configuration
+            DefaultConfiguration config = (DefaultConfiguration) ConfigurationLoader
+                    .loadConfiguration(configLocation, new PropertiesExpander(System.getProperties()));
 
-        // add the suppression file to the configuration
-        DefaultConfiguration suppressions = new DefaultConfiguration("SuppressionFilter");
-        suppressions.addAttribute("file", suppressionLocation);
-        config.addChild(suppressions);
+            // add the suppression file to the configuration
+            DefaultConfiguration suppressions = new DefaultConfiguration("SuppressionFilter");
+            suppressions.addAttribute("file", suppressionLocation);
+            config.addChild(suppressions);
 
-        this.config = config;
-    }
-
-    public Runnable checkClass(Socket socket) {
-        return () -> {
-            try {
-                String input = new String(ByteStreams.toByteArray(socket.getInputStream()));
-                String output = checkClass(input);
-                socket.getOutputStream().write(output.getBytes());
-                socket.getOutputStream().flush();
-                socket.close();
-            } catch (IOException e) {
-                e.printStackTrace();
-            } catch (CheckstyleException e) {
-                e.printStackTrace();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        };
-    }
-
-    public String checkClass(String input) throws CheckstyleException, InterruptedException {
-        String[] split = input.split("\n", 3);
-        if (split.length < 3 || split[2].length() == 0) {
-            return "";
+            this.config = config;
+        } catch (CheckstyleException e) {
+            throw new RuntimeException(e);
         }
-        String project = split[0];
-        String baseDir = split[1];
-        String files = split[2];
+    }
+
+    @Override
+    public void execute(BuckTaskContext context) {
+        List<String> input = context.input();
+        if (input.size() < 3 || input.get(2).length() == 0) {
+            return;
+        }
+        String project = input.get(0);
+        String baseDir = input.get(1);
 
         // create a listener for output
-        StringAuditor listener = new StringAuditor();
+        StringAuditor listener = new StringAuditor(context);
         listener.setProjectName(project);
         listener.setBaseDir(baseDir);
 
@@ -91,102 +77,102 @@
         checker.setModuleClassLoader(moduleClassLoader);
 
         try {
-
             checker.configure(config);
             checker.addListener(listener);
 
             // run Checker
-            List<File> fileList = Stream.of(files.split("\n"))
-                                        .map(File::new)
-                                        .collect(Collectors.toList());
+            List<File> fileList = input.subList(2, input.size() - 1).stream()
+                    .map(File::new)
+                    .collect(Collectors.toList());
             int errorCounter = checker.process(fileList);
             if (errorCounter > 0) {
-                listener.append("CHECKSTYLE ERROR\n");
+                context.output("CHECKSTYLE ERROR");
             }
+
+            listener.await();
+        } catch (CheckstyleException | InterruptedException e) {
+            throw new RuntimeException(e);
         } finally {
             checker.destroy();
         }
 
-        return listener.getAudit();
-    }
-}
-
-class StringAuditor implements AuditListener {
-
-    private CountDownLatch finishedLatch = new CountDownLatch(1);
-    private StringBuilder output = new StringBuilder();
-    private String baseDir = "";
-    private String project = "";
-
-    public void setBaseDir(String base) {
-        this.baseDir = base;
     }
 
-    public void setProjectName(String projectName) {
-        this.project = projectName;
-    }
+    static class StringAuditor implements AuditListener {
 
-    public void append(String s) {
-        output.append(s);
-    }
+        private final BuckTaskContext context;
+        private CountDownLatch finishedLatch = new CountDownLatch(1);
+        private String baseDir = "";
+        private String project = "";
 
-    public String getAudit() throws InterruptedException {
-        finishedLatch.await();
-        return output.toString();
-    }
+        StringAuditor(BuckTaskContext context) {
+            this.context = context;
+        }
 
-    @Override
-    public void auditStarted(AuditEvent evt) {
+        public void setBaseDir(String base) {
+            this.baseDir = base;
+        }
 
-    }
+        public void setProjectName(String projectName) {
+            this.project = projectName;
+        }
 
-    @Override
-    public void auditFinished(AuditEvent evt) {
-        finishedLatch.countDown();
-    }
+        public void await() throws InterruptedException {
+            finishedLatch.await();
+        }
 
-    @Override
-    public void fileStarted(AuditEvent evt) {
+        @Override
+        public void auditStarted(AuditEvent evt) {
+        }
 
-    }
+        @Override
+        public void auditFinished(AuditEvent evt) {
+            finishedLatch.countDown();
+        }
 
-    @Override
-    public void fileFinished(AuditEvent evt) {
+        @Override
+        public void fileStarted(AuditEvent evt) {
+        }
 
-    }
+        @Override
+        public void fileFinished(AuditEvent evt) {
+        }
 
-    @Override
-    public void addError(AuditEvent evt) {
-        switch (evt.getSeverityLevel()) {
-            case ERROR:
-                String fileName = evt.getFileName();
-                if (!isNullOrEmpty(baseDir)) {
-                    int index = fileName.indexOf(baseDir);
-                    if (index >= 0) {
-                        fileName = fileName.substring(index + baseDir.length() + 1);
-                        if (!isNullOrEmpty(project)) {
-                            output.append(project).append(':');
+        @Override
+        public void addError(AuditEvent evt) {
+            switch (evt.getSeverityLevel()) {
+                case ERROR:
+                    StringBuilder output = new StringBuilder();
+                    String fileName = evt.getFileName();
+                    if (!isNullOrEmpty(baseDir)) {
+                        int index = fileName.indexOf(baseDir);
+                        if (index >= 0) {
+                            fileName = fileName.substring(index + baseDir.length() + 1);
+                            if (!isNullOrEmpty(project)) {
+                                output.append(project).append(':');
+                            }
                         }
                     }
-                }
-                output.append(fileName).append(':').append(evt.getLine());
-                if (evt.getColumn() > 0) {
-                    output.append(':').append(evt.getColumn());
-                }
-                output.append(": ").append(evt.getMessage());
-                output.append('\n');
-                break;
-            case IGNORE:
-            case INFO:
-            case WARNING:
-            default:
-                break;
+                    output.append(fileName).append(':').append(evt.getLine());
+                    if (evt.getColumn() > 0) {
+                        output.append(':').append(evt.getColumn());
+                    }
+                    output.append(": ").append(evt.getMessage());
+                    context.output(output.toString());
+                    break;
+                case IGNORE:
+                case INFO:
+                case WARNING:
+                default:
+                    break;
+            }
+        }
+
+        @Override
+        public void addException(AuditEvent evt, Throwable throwable) {
+            addError(evt);
+            context.output(throwable.getMessage());
         }
     }
 
-    @Override
-    public void addException(AuditEvent evt, Throwable throwable) {
-        addError(evt);
-        output.append(throwable.getMessage());
-    }
-}
\ No newline at end of file
+}
diff --git a/tools/build/conf/src/main/java/org/onosproject/checkstyle/Main.java b/tools/build/conf/src/main/java/org/onosproject/checkstyle/Main.java
deleted file mode 100644
index 99c5d3c..0000000
--- a/tools/build/conf/src/main/java/org/onosproject/checkstyle/Main.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed 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.
- */
-
-package org.onosproject.checkstyle;
-
-import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import static java.nio.file.StandardOpenOption.*;
-
-/**
- * Main program for executing scenario test warden.
- */
-public final class Main {
-
-    private static long POLLING_INTERVAL = 1000; //ms
-
-    // Public construction forbidden
-    private Main(String[] args) {
-    }
-
-    /**
-     * Main entry point for the cell warden.
-     *
-     * @param args command-line arguments
-     */
-    public static void main(String[] args)
-            throws CheckstyleException, IOException {
-        startServer(args);
-    }
-
-    // Monitors another PID and exit when that process exits
-    private static void watchProcess(String pid) {
-        if (pid == null || pid.equals("0")) {
-            return;
-        }
-        Timer timer = new Timer(true); // start as a daemon, so we don't hang shutdown
-        timer.scheduleAtFixedRate(new TimerTask() {
-            private String cmd = "kill -s 0 " + pid;
-            @Override
-            public void run() {
-                try {
-                    Process p = Runtime.getRuntime().exec(cmd);
-                    p.waitFor();
-                    if (p.exitValue() != 0) {
-                        System.err.println("shutting down...");
-                        System.exit(0);
-                    }
-                } catch (IOException | InterruptedException e) {
-                    //no-op
-                    e.printStackTrace();
-                }
-            }
-        }, POLLING_INTERVAL, POLLING_INTERVAL);
-    }
-
-    // Initiates a server.
-    private static void startServer(String[] args) throws IOException, CheckstyleException {
-        String portLock = args[0];
-        String buckPid = args[1];
-        String checkstyleFile = args[2];
-        String suppressionsFile = args[3];
-
-        // Use a file lock to ensure only one copy of the daemon runs
-        Path portLockPath = Paths.get(portLock);
-        FileChannel channel = FileChannel.open(portLockPath, WRITE, CREATE);
-        FileLock lock = channel.tryLock();
-        if (lock == null) {
-            System.out.println("Server is already running");
-            System.exit(1);
-        } //else, hold the lock until the JVM exits
-
-        // Start the server and bind it to a random port
-        ServerSocket server = new ServerSocket(0);
-
-        // Monitor the parent buck process
-        watchProcess(buckPid);
-
-        // Set up hook to clean up after ourselves
-        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
-            try {
-                if (channel != null) {
-                    channel.truncate(0);
-                    channel.close();
-                }
-                System.err.println("tear down...");
-                Files.delete(portLockPath);
-            } catch (IOException e) {
-                //no-op: shutting down
-                e.printStackTrace();
-            }
-        }));
-
-        // Write the bound port to the port file
-        int port = server.getLocalPort();
-        channel.truncate(0);
-        channel.write(ByteBuffer.wrap(Integer.toString(port).getBytes()));
-
-        // Instantiate a Checkstyle runner and executor; serve until exit...
-        CheckstyleRunner runner = new CheckstyleRunner(checkstyleFile, suppressionsFile);
-        ExecutorService executor = Executors.newCachedThreadPool();
-        while (true) {
-            try {
-                executor.submit(runner.checkClass(server.accept()));
-            } catch (Exception e) {
-                e.printStackTrace();
-                //no-op
-            }
-        }
-    }
-}
