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
new file mode 100644
index 0000000..1768e16
--- /dev/null
+++ b/tools/build/conf/src/main/java/org/onosproject/checkstyle/CheckstyleRunner.java
@@ -0,0 +1,178 @@
+/*
+ * 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.google.common.io.ByteStreams;
+import com.puppycrawl.tools.checkstyle.Checker;
+import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
+import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
+import com.puppycrawl.tools.checkstyle.PropertiesExpander;
+import com.puppycrawl.tools.checkstyle.api.AuditEvent;
+import com.puppycrawl.tools.checkstyle.api.AuditListener;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.Configuration;
+
+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;
+
+public class CheckstyleRunner {
+
+    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()));
+
+        // 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", 2);
+        if (split.length < 2 || split[1].length() == 0) {
+            return "";
+        }
+        String base = split[0];
+        String files = split[1];
+
+        // create a listener for output
+        StringAuditor listener = new StringAuditor();
+        listener.setBase(base);
+
+        // create Checker object and run it
+        final Checker checker = new Checker();
+        final ClassLoader moduleClassLoader = Checker.class.getClassLoader();
+        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());
+            int errorCounter = checker.process(fileList);
+            if (errorCounter > 0) {
+                listener.append("CHECKSTYLE ERROR\n");
+            }
+        } finally {
+            checker.destroy();
+        }
+
+        return listener.getAudit();
+    }
+}
+
+class StringAuditor implements AuditListener {
+
+    private CountDownLatch finishedLatch = new CountDownLatch(1);
+    private StringBuilder output = new StringBuilder();
+    private String base = "";
+
+    public void setBase(String base) {
+        this.base = base;
+    }
+
+    public void append(String s) {
+        output.append(s);
+    }
+
+    public String getAudit() throws InterruptedException {
+        finishedLatch.await();
+        return output.toString();
+    }
+
+    @Override
+    public void auditStarted(AuditEvent evt) {
+
+    }
+
+    @Override
+    public void auditFinished(AuditEvent evt) {
+        finishedLatch.countDown();
+    }
+
+    @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();
+                int index = fileName.indexOf(base);
+                if (index >= 0) {
+                    fileName = fileName.substring(index + base.length() + 1);
+                }
+                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;
+        }
+    }
+
+    @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
new file mode 100644
index 0000000..99c5d3c
--- /dev/null
+++ b/tools/build/conf/src/main/java/org/onosproject/checkstyle/Main.java
@@ -0,0 +1,136 @@
+/*
+ * 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
+            }
+        }
+    }
+}
