diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/SwaggerGenerator.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/SwaggerGenerator.java
new file mode 100644
index 0000000..898be8c
--- /dev/null
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/SwaggerGenerator.java
@@ -0,0 +1,494 @@
+/*
+ * 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.onosjar;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.io.ByteStreams;
+import com.google.common.io.Files;
+import com.thoughtworks.qdox.JavaProjectBuilder;
+import com.thoughtworks.qdox.model.DocletTag;
+import com.thoughtworks.qdox.model.JavaAnnotation;
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaParameter;
+import com.thoughtworks.qdox.model.JavaType;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+
+/**
+ * Generates Swagger JSON artifacts from the Java source files.
+ */
+public class SwaggerGenerator {
+
+    private final ObjectMapper mapper = new ObjectMapper();
+
+    private static final String JSON_FILE = "swagger.json";
+    private static final String GEN_SRC = "generated-sources";
+    private static final String REG_SRC = "/registrator.javat";
+
+    private static final String PATH = "javax.ws.rs.Path";
+    private static final String PATH_PARAM = "javax.ws.rs.PathParam";
+    private static final String QUERY_PARAM = "javax.ws.rs.QueryParam";
+    private static final String POST = "javax.ws.rs.POST";
+    private static final String GET = "javax.ws.rs.GET";
+    private static final String PUT = "javax.ws.rs.PUT";
+    private static final String DELETE = "javax.ws.rs.DELETE";
+    private static final String PRODUCES = "javax.ws.rs.Produces";
+    private static final String CONSUMES = "javax.ws.rs.Consumes";
+    private static final String JSON = "MediaType.APPLICATION_JSON";
+    private static final String OCTET_STREAM = "MediaType.APPLICATION_OCTET_STREAM";
+
+    private final List<File> srcs;
+    private final List<File> resources;
+    private final File srcDirectory;
+    private final File resourceDirectory;
+    private final File genSrcOutputDirectory;
+    private final File genResourcesOutputDirectory;
+    private final String webContext;
+    private final String apiTitle;
+    private final String apiVersion;
+    private final String apiPackage;
+    private final String apiDescription;
+
+    public SwaggerGenerator(List<File> srcs, List<File> resources,
+                            File srcDirectory, File resourceDirectory,
+                            File genSrcOutputDirectory, File genResourcesOutputDirectory,
+                            String webContext, String apiTitle, String apiVersion,
+                            String apiPackage, String apiDescription) {
+        this.srcs = srcs;
+        this.resources = resources;
+        this.srcDirectory = srcDirectory;
+        this.resourceDirectory = resourceDirectory;
+        this.genSrcOutputDirectory = genSrcOutputDirectory;
+        this.genResourcesOutputDirectory = genResourcesOutputDirectory;
+        this.webContext = webContext;
+
+        this.apiTitle = apiTitle;
+        this.apiVersion = apiVersion;
+        this.apiPackage = apiPackage;
+        this.apiDescription = apiDescription;
+    }
+
+    public void execute() {
+        try {
+            JavaProjectBuilder builder = new JavaProjectBuilder();
+            if (srcDirectory != null) {
+                builder.addSourceTree(new File(srcDirectory, "src/main/java"));
+            }
+            if (srcs != null) {
+                srcs.forEach(src -> {
+                    try {
+                        builder.addSource(src);
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+            }
+
+            ObjectNode root = initializeRoot(webContext, apiTitle, apiVersion, apiDescription);
+            ArrayNode tags = mapper.createArrayNode();
+            ObjectNode paths = mapper.createObjectNode();
+            ObjectNode definitions = mapper.createObjectNode();
+
+            root.set("tags", tags);
+            root.set("paths", paths);
+            root.set("definitions", definitions);
+
+            // TODO: Process resources to allow lookup of files by name
+
+            builder.getClasses().forEach(jc -> processClass(jc, paths, tags, definitions, srcDirectory));
+
+            if (paths.size() > 0) {
+                genCatalog(genResourcesOutputDirectory, root);
+                if (!isNullOrEmpty(apiPackage)) {
+                    genRegistrator(genSrcOutputDirectory, webContext, apiTitle, apiVersion,
+                                   apiPackage, apiDescription);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unable to generate ONOS REST API documentation", e);
+        }
+    }
+
+    // initializes top level root with Swagger required specifications
+    private ObjectNode initializeRoot(String webContext, String apiTitle,
+                                      String apiVersion, String apiDescription) {
+        ObjectNode root = mapper.createObjectNode();
+        root.put("swagger", "2.0");
+        ObjectNode info = mapper.createObjectNode();
+        root.set("info", info);
+
+        root.put("basePath", webContext);
+        info.put("version", apiVersion);
+        info.put("title", apiTitle);
+        info.put("description", apiDescription);
+
+        ArrayNode produces = mapper.createArrayNode();
+        produces.add("application/json");
+        root.set("produces", produces);
+
+        ArrayNode consumes = mapper.createArrayNode();
+        consumes.add("application/json");
+        root.set("consumes", consumes);
+
+        return root;
+    }
+
+    // Checks whether javaClass has a path tag associated with it and if it does
+    // processes its methods and creates a tag for the class on the root
+    void processClass(JavaClass javaClass, ObjectNode paths, ArrayNode tags,
+                      ObjectNode definitions, File srcDirectory) {
+        // If the class does not have a Path tag then ignore it
+        JavaAnnotation annotation = getPathAnnotation(javaClass);
+        if (annotation == null) {
+            return;
+        }
+
+        String path = getPath(annotation);
+        if (path == null) {
+            return;
+        }
+
+        String resourcePath = "/" + path;
+        String tagPath = path.isEmpty() ? "/" : path;
+
+        // Create tag node for this class.
+        ObjectNode tagObject = mapper.createObjectNode();
+        tagObject.put("name", tagPath);
+        if (javaClass.getComment() != null) {
+            tagObject.put("description", shortText(javaClass.getComment()));
+        }
+        tags.add(tagObject);
+
+        // Create an array node add to all methods from this class.
+        ArrayNode tagArray = mapper.createArrayNode();
+        tagArray.add(tagPath);
+
+        processAllMethods(javaClass, resourcePath, paths, tagArray, definitions, srcDirectory);
+    }
+
+    private JavaAnnotation getPathAnnotation(JavaClass javaClass) {
+        Optional<JavaAnnotation> optional = javaClass.getAnnotations()
+                .stream().filter(a -> a.getType().getName().equals(PATH)).findAny();
+        return optional.orElse(null);
+    }
+
+    // Checks whether a class's methods are REST methods and then places all the
+    // methods under a specific path into the paths node
+    private void processAllMethods(JavaClass javaClass, String resourcePath,
+                                   ObjectNode paths, ArrayNode tagArray, ObjectNode definitions,
+                                   File srcDirectory) {
+        // map of the path to its methods represented by an ObjectNode
+        Map<String, ObjectNode> pathMap = new HashMap<>();
+
+        javaClass.getMethods().forEach(javaMethod -> {
+            javaMethod.getAnnotations().forEach(annotation -> {
+                String name = annotation.getType().getName();
+                if (name.equals(POST) || name.equals(GET) || name.equals(DELETE) || name.equals(PUT)) {
+                    // substring(12) removes "javax.ws.rs."
+                    String method = annotation.getType().toString().substring(12).toLowerCase();
+                    processRestMethod(javaMethod, method, pathMap, resourcePath, tagArray, definitions, srcDirectory);
+                }
+            });
+        });
+
+        // for each path add its methods to the path node
+        for (Map.Entry<String, ObjectNode> entry : pathMap.entrySet()) {
+            paths.set(entry.getKey(), entry.getValue());
+        }
+
+
+    }
+
+    private void processRestMethod(JavaMethod javaMethod, String method,
+                                   Map<String, ObjectNode> pathMap,
+                                   String resourcePath, ArrayNode tagArray,
+                                   ObjectNode definitions, File srcDirectory) {
+        String fullPath = resourcePath, consumes = "", produces = "",
+                comment = javaMethod.getComment();
+        DocletTag tag = javaMethod.getTagByName("onos.rsModel");
+        for (JavaAnnotation annotation : javaMethod.getAnnotations()) {
+            String name = annotation.getType().getName();
+            if (name.equals(PATH)) {
+                fullPath = resourcePath + "/" + getPath(annotation);
+                fullPath = fullPath.replaceFirst("^//", "/");
+            }
+            if (name.equals(CONSUMES)) {
+                consumes = getIOType(annotation);
+            }
+            if (name.equals(PRODUCES)) {
+                produces = getIOType(annotation);
+            }
+        }
+        ObjectNode methodNode = mapper.createObjectNode();
+        methodNode.set("tags", tagArray);
+
+        addSummaryDescriptions(methodNode, comment);
+        addJsonSchemaDefinition(srcDirectory, definitions, tag);
+
+        processParameters(javaMethod, methodNode, method, tag);
+
+        processConsumesProduces(methodNode, "consumes", consumes);
+        processConsumesProduces(methodNode, "produces", produces);
+        if (tag == null || ((method.toLowerCase().equals("post") || method.toLowerCase().equals("put"))
+                && !(tag.getParameters().size() > 1))) {
+            addResponses(methodNode, tag, false);
+        } else {
+            addResponses(methodNode, tag, true);
+        }
+
+        ObjectNode operations = pathMap.get(fullPath);
+        if (operations == null) {
+            operations = mapper.createObjectNode();
+            operations.set(method, methodNode);
+            pathMap.put(fullPath, operations);
+        } else {
+            operations.set(method, methodNode);
+        }
+    }
+
+    private void addJsonSchemaDefinition(File srcDirectory, ObjectNode definitions, DocletTag tag) {
+        final File definitionsDirectory;
+        if (resourceDirectory != null) {
+            definitionsDirectory = new File(resourceDirectory, "definitions");
+        } else if (srcDirectory != null) {
+            definitionsDirectory = new File(srcDirectory + "/src/main/resources/definitions");
+        } else {
+            definitionsDirectory = null;
+        }
+        if (tag != null) {
+            tag.getParameters().forEach(param -> {
+                try {
+                    File config;
+                    if (definitionsDirectory != null) {
+                        config = new File(definitionsDirectory.getAbsolutePath() + "/" + param + ".json");
+                    } else {
+                        config = resources.stream().filter(f -> f.getName().equals(param + ".json")).findFirst().orElse(null);
+                    }
+                    definitions.set(param, mapper.readTree(config));
+                } catch (IOException e) {
+                    throw new RuntimeException(String.format("Could not process %s in %s@%s: %s",
+                                                             tag.getName(), tag.getContext(), tag.getLineNumber(),
+                                                             e.getMessage()), e);
+                }
+            });
+        }
+    }
+
+    private void processConsumesProduces(ObjectNode methodNode, String type, String io) {
+        if (!io.equals("")) {
+            ArrayNode array = mapper.createArrayNode();
+            methodNode.set(type, array);
+            array.add(io);
+        }
+    }
+
+    private void addSummaryDescriptions(ObjectNode methodNode, String comment) {
+        String summary = "", description;
+        if (comment != null) {
+            if (comment.contains(".")) {
+                int periodIndex = comment.indexOf(".");
+                summary = comment.substring(0, periodIndex);
+                description = comment.length() > periodIndex + 1 ?
+                        comment.substring(periodIndex + 1).trim() : "";
+            } else {
+                description = comment;
+            }
+            methodNode.put("summary", summary);
+            methodNode.put("description", description);
+        }
+    }
+
+    // Temporary solution to add responses to a method
+    private void addResponses(ObjectNode methodNode, DocletTag tag, boolean responseJson) {
+        ObjectNode responses = mapper.createObjectNode();
+        methodNode.set("responses", responses);
+
+        ObjectNode success = mapper.createObjectNode();
+        success.put("description", "successful operation");
+        responses.set("200", success);
+        if (tag != null && responseJson) {
+            ObjectNode schema = mapper.createObjectNode();
+            tag.getParameters().stream().forEach(
+                    param -> schema.put("$ref", "#/definitions/" + param));
+            success.set("schema", schema);
+        }
+
+        ObjectNode defaultObj = mapper.createObjectNode();
+        defaultObj.put("description", "Unexpected error");
+        responses.set("default", defaultObj);
+    }
+
+    // Checks if the annotations has a value of JSON and returns the string
+    // that Swagger requires
+    private String getIOType(JavaAnnotation annotation) {
+        if (annotation.getNamedParameter("value").toString().equals(JSON)) {
+            return "application/json";
+        } else if (annotation.getNamedParameter("value").toString().equals(OCTET_STREAM)) {
+            return "application/octet_stream";
+        }
+        return "";
+    }
+
+    // If the annotation has a Path tag, returns the value with leading and
+    // trailing double quotes and slash removed.
+    private String getPath(JavaAnnotation annotation) {
+        String path = annotation.getNamedParameter("value").toString();
+        return path == null ? null : path.replaceAll("(^[\\\"/]*|[/\\\"]*$)", "");
+    }
+
+    // Processes parameters of javaMethod and enters the proper key-values into the methodNode
+    private void processParameters(JavaMethod javaMethod, ObjectNode methodNode, String method, DocletTag tag) {
+        ArrayNode parameters = mapper.createArrayNode();
+        methodNode.set("parameters", parameters);
+        boolean required = true;
+
+        for (JavaParameter javaParameter : javaMethod.getParameters()) {
+            ObjectNode individualParameterNode = mapper.createObjectNode();
+            Optional<JavaAnnotation> optional = javaParameter.getAnnotations().stream().filter(
+                    annotation -> annotation.getType().getName().equals(PATH_PARAM) ||
+                            annotation.getType().getName().equals(QUERY_PARAM)).findAny();
+            JavaAnnotation pathType = optional.orElse(null);
+
+            String annotationName = javaParameter.getName();
+
+
+            if (pathType != null) { //the parameter is a path or query parameter
+                individualParameterNode.put("name",
+                                            pathType.getNamedParameter("value")
+                                                    .toString().replace("\"", ""));
+                if (pathType.getType().getName().equals(PATH_PARAM)) {
+                    individualParameterNode.put("in", "path");
+                } else if (pathType.getType().getName().equals(QUERY_PARAM)) {
+                    individualParameterNode.put("in", "query");
+                }
+                individualParameterNode.put("type", getType(javaParameter.getType()));
+            } else { // the parameter is a body parameter
+                individualParameterNode.put("name", annotationName);
+                individualParameterNode.put("in", "body");
+
+                // Adds the reference to the Json model for the input
+                // that goes in the post or put operation
+                if (tag != null && (method.toLowerCase().equals("post") ||
+                        method.toLowerCase().equals("put"))) {
+                    ObjectNode schema = mapper.createObjectNode();
+                    tag.getParameters().stream().forEach(param -> {
+                        schema.put("$ref", "#/definitions/" + param);
+                    });
+                    individualParameterNode.set("schema", schema);
+                }
+            }
+            for (DocletTag p : javaMethod.getTagsByName("param")) {
+                if (p.getValue().contains(annotationName)) {
+                    String description = "";
+                    if (p.getValue().split(" ", 2).length >= 2) {
+                        description = p.getValue().split(" ", 2)[1].trim();
+                        if (description.contains("optional")) {
+                            required = false;
+                        }
+                    } else {
+                        throw new RuntimeException(String.format("No description for parameter \"%s\" in " +
+                                                                         "method \"%s\" in %s (line %d)",
+                                                                 p.getValue(), javaMethod.getName(),
+                                                                 javaMethod.getDeclaringClass().getName(),
+                                                                 javaMethod.getLineNumber()));
+                    }
+                    individualParameterNode.put("description", description);
+                }
+            }
+            individualParameterNode.put("required", required);
+            parameters.add(individualParameterNode);
+        }
+    }
+
+    // Returns the Swagger specified strings for the type of a parameter
+    private String getType(JavaType javaType) {
+        String type = javaType.getFullyQualifiedName();
+        String value;
+        if (type.equals(String.class.getName())) {
+            value = "string";
+        } else if (type.equals("int")) {
+            value = "integer";
+        } else if (type.equals(boolean.class.getName())) {
+            value = "boolean";
+        } else if (type.equals(long.class.getName())) {
+            value = "number";
+        } else {
+            value = "";
+        }
+        return value;
+    }
+
+    // Writes the swagger.json file using the supplied JSON root.
+    private void genCatalog(File dstDirectory, ObjectNode root) {
+        File swaggerCfg = new File(dstDirectory, JSON_FILE);
+        if (dstDirectory.exists() || dstDirectory.mkdirs()) {
+            try (FileWriter fw = new FileWriter(swaggerCfg);
+                 PrintWriter pw = new PrintWriter(fw)) {
+                pw.println(root.toString());
+            } catch (IOException e) {
+                throw new RuntimeException("Unable to write " + JSON_FILE, e);
+            }
+        } else {
+            throw new RuntimeException("Unable to create " + dstDirectory);
+        }
+    }
+
+    // Generates the registrator Java component.
+    private void genRegistrator(File dstDirectory, String webContext,
+                                String apiTitle, String apiVersion,
+                                String apiPackage, String apiDescription) {
+        File dir = new File(dstDirectory, resourceDirectory != null ? GEN_SRC : ".");
+        File reg = new File(dir, apiRegistratorPath(apiPackage));
+        File pkg = reg.getParentFile();
+        if (pkg.exists() || pkg.mkdirs()) {
+            try {
+                String src = new String(ByteStreams.toByteArray(getClass().getResourceAsStream(REG_SRC)));
+                src = src.replace("${api.package}", apiPackage)
+                        .replace("${web.context}", webContext)
+                        .replace("${api.title}", apiTitle)
+                        .replace("${api.description}", apiDescription);
+                Files.write(src.getBytes(), reg);
+            } catch (IOException e) {
+                throw new RuntimeException("Unable to write " + reg, e);
+            }
+        } else {
+            throw new RuntimeException("Unable to create " + reg);
+        }
+    }
+
+    private String shortText(String comment) {
+        int i = comment.indexOf('.');
+        return i > 0 ? comment.substring(0, i) : comment;
+    }
+
+    public static String apiRegistratorPath(String apiPackage) {
+        return apiPackage.replaceAll("\\.", "/") + "/ApiDocRegistrator.java";
+    }
+}
\ No newline at end of file
