diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java
new file mode 100644
index 0000000..aa529fc
--- /dev/null
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java
@@ -0,0 +1,392 @@
+/*
+ * 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.onosjar;
+
+import aQute.bnd.header.Attrs;
+import aQute.bnd.header.Parameters;
+import aQute.bnd.osgi.Analyzer;
+import aQute.bnd.osgi.Builder;
+import aQute.bnd.osgi.FileResource;
+import aQute.bnd.osgi.Jar;
+import aQute.bnd.osgi.Resource;
+import com.facebook.buck.step.ExecutionContext;
+import com.facebook.buck.step.Step;
+import com.facebook.buck.step.StepExecutionResult;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+
+import static java.nio.file.Files.walkFileTree;
+
+/**
+ * BND-based wrapper to convert Buck JARs to OSGi-compatible JARs.
+ */
+public class OSGiWrapper implements Step {
+
+    private Path inputJar;
+    private Path outputJar;
+    private Path sourcesDir;
+    private Path classesDir;
+    private List<String> classpath;
+
+    private String bundleName;
+    private String groupId;
+    private String bundleSymbolicName;
+    private String bundleVersion;
+
+    private String importPackages;
+    private String dynamicimportPackages;
+
+    private String exportPackages;
+    private String includeResources;
+    private Set<String> includedResources = Sets.newHashSet();
+
+    private String bundleDescription;
+    private String bundleLicense;
+
+    private String webContext;
+
+    private PrintStream stderr = System.err;
+
+    public OSGiWrapper(Path inputJar,
+                       Path outputJar,
+                       Path sourcesDir,
+                       Path classesDir,
+                       ImmutableSortedSet<Path> classpath,
+                       String bundleName,
+                       String groupId,
+                       String bundleVersion,
+                       String bundleLicense,
+                       String importPackages,
+                       String exportPackages,
+                       String includeResources,
+                       String webContext,
+                       String dynamicimportPackages,
+                       String bundleDescription) {
+        this.inputJar = inputJar;
+        this.sourcesDir = sourcesDir;
+        this.classesDir = classesDir;
+        this.classpath = Lists.newArrayList(
+                classpath.stream().map(Path::toString).collect(Collectors.toList()));
+        if (!this.classpath.contains(inputJar.toString())) {
+            this.classpath.add(0, inputJar.toString());
+        }
+        this.outputJar = outputJar;
+
+        this.bundleName = bundleName;
+        this.groupId = groupId;
+        this.bundleSymbolicName = String.format("%s.%s", groupId, bundleName);
+
+        this.bundleVersion = bundleVersion;
+        this.bundleLicense = bundleLicense;
+        this.bundleDescription = bundleDescription;
+
+        this.importPackages = importPackages;
+        this.dynamicimportPackages = dynamicimportPackages;
+        this.exportPackages = exportPackages;
+        this.includeResources = includeResources;
+
+        this.webContext = webContext;
+    }
+
+    private void setProperties(Analyzer analyzer) {
+        analyzer.setProperty(Analyzer.BUNDLE_NAME, bundleName);
+        analyzer.setProperty(Analyzer.BUNDLE_SYMBOLICNAME, bundleSymbolicName);
+        analyzer.setProperty(Analyzer.BUNDLE_VERSION, bundleVersion.replace('-', '.'));
+
+        if (bundleDescription != null) {
+            analyzer.setProperty(Analyzer.BUNDLE_DESCRIPTION, bundleDescription);
+        }
+        if (bundleLicense != null) {
+            analyzer.setProperty(Analyzer.BUNDLE_LICENSE, bundleLicense);
+        }
+
+        //TODO consider using stricter version policy
+        //analyzer.setProperty("-provider-policy", "${range;[===,==+)}");
+        //analyzer.setProperty("-consumer-policy", "${range;[===,==+)}");
+
+        // There are no good defaults so make sure you set the Import-Package
+        analyzer.setProperty(Analyzer.IMPORT_PACKAGE, importPackages);
+
+        analyzer.setProperty(Analyzer.DYNAMICIMPORT_PACKAGE, dynamicimportPackages);
+
+        // TODO include version in export, but not in import
+        analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages);
+
+        // TODO we may need INCLUDE_RESOURCE, or that might be done by Buck
+        if (includeResources != null) {
+            analyzer.setProperty(Analyzer.INCLUDE_RESOURCE, includeResources);
+        }
+
+        if (isWab()) {
+            analyzer.setProperty(Analyzer.WAB, "src/main/webapp/");
+            analyzer.setProperty("Web-ContextPath", webContext);
+            analyzer.setProperty(Analyzer.IMPORT_PACKAGE, "*,org.glassfish.jersey.servlet,org.jvnet.mimepull\n");
+        }
+    }
+
+    public boolean execute() {
+        Analyzer analyzer = new Builder();
+        try {
+
+            Jar jar = new Jar(inputJar.toFile());  // where our data is
+            analyzer.setJar(jar);                   // give bnd the contents
+
+            // You can provide additional class path entries to allow
+            // bnd to pickup export version from the packageinfo file,
+            // Version annotation, or their manifests.
+            analyzer.addClasspath(classpath);
+
+            setProperties(analyzer);
+
+            //analyzer.setBase(classesDir.toFile());
+
+//            analyzer.setProperty("DESTDIR");
+//            analyzer.setBase();
+
+            // ------------- let's begin... -------------------------
+
+            // Analyze the target JAR first
+            analyzer.analyze();
+
+            // Scan the JAR for Felix SCR annotations and generate XML files
+            Map<String, String> properties = Maps.newHashMap();
+            properties.put("destdir", classesDir.toAbsolutePath().toString());
+            SCRDescriptorBndPlugin scrDescriptorBndPlugin = new SCRDescriptorBndPlugin();
+            scrDescriptorBndPlugin.setProperties(properties);
+            scrDescriptorBndPlugin.setReporter(analyzer);
+            scrDescriptorBndPlugin.analyzeJar(analyzer);
+
+            if (includeResources != null) {
+                doIncludeResources(analyzer);
+            }
+
+            // Repack the JAR as a WAR
+            doWabStaging(analyzer);
+
+            // Calculate the manifest
+            Manifest manifest = analyzer.calcManifest();
+            //OutputStream s = new FileOutputStream("/tmp/foo2.txt");
+            //manifest.write(s);
+            //s.close();
+
+            if (analyzer.isOk()) {
+                analyzer.getJar().setManifest(manifest);
+                if (analyzer.save(outputJar.toFile(), true)) {
+                    log("Saved!\n");
+                } else {
+                    warn("Failed to create jar \n");
+                    return false;
+                }
+            } else {
+                warn("Analyzer Errors:\n%s\n", analyzer.getErrors());
+                return false;
+            }
+
+            analyzer.close();
+
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    private boolean isWab() {
+        return webContext != null;
+    }
+
+    private void doWabStaging(Analyzer analyzer) throws Exception {
+        if (!isWab()) {
+            return;
+        }
+        String wab = analyzer.getProperty(analyzer.WAB);
+        Jar dot = analyzer.getJar();
+
+        log("wab %s", wab);
+        analyzer.setBundleClasspath("WEB-INF/classes," +
+                                    analyzer.getProperty(analyzer.BUNDLE_CLASSPATH));
+
+        Set<String> paths = new HashSet<>(dot.getResources().keySet());
+
+        for (String path : paths) {
+            if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) {
+                log("wab: moving: %s", path);
+                dot.rename(path, "WEB-INF/classes/" + path);
+            }
+        }
+
+        Path wabRoot = Paths.get(wab);
+        includeFiles(dot, null, wabRoot.toString());
+    }
+
+    /**
+     * Parse the Bundle-Includes header. Files in the bundles Include header are
+     * included in the jar. The source can be a directory or a file.
+     *
+     * @throws Exception
+     */
+    private void doIncludeResources(Analyzer analyzer) throws Exception {
+        String includes = analyzer.getProperty(Analyzer.INCLUDE_RESOURCE);
+        if (includes == null) {
+            return;
+        }
+        Parameters clauses = analyzer.parseHeader(includes);
+        Jar jar = analyzer.getJar();
+
+        for (Map.Entry<String, Attrs> entry : clauses.entrySet()) {
+            String name = entry.getKey();
+            Map<String, String> extra = entry.getValue();
+            // TODO consider doing something with extras
+
+            String[] parts = name.split("\\s*=\\s*");
+            String source = parts[0];
+            String destination = parts[0];
+            if (parts.length == 2) {
+                source = parts[1];
+            }
+
+            includeFiles(jar, destination, source);
+        }
+    }
+
+    private void includeFiles(Jar jar, String destinationRoot, String sourceRoot)
+            throws IOException {
+
+        Path classesBasedPath = classesDir.resolve(sourceRoot);
+        Path sourceBasedPath = sourcesDir.resolve(sourceRoot);
+
+        File classFile = classesBasedPath.toFile();
+        File sourceFile = sourceBasedPath.toFile();
+
+        if (classFile.isFile()) {
+            addFileToJar(jar, destinationRoot, classesBasedPath.toAbsolutePath().toString());
+        } else if (sourceFile.isFile()) {
+            addFileToJar(jar, destinationRoot, sourceBasedPath.toAbsolutePath().toString());
+        } else if (classFile.isDirectory()) {
+            includeDirectory(jar, destinationRoot, classesBasedPath);
+        } else if (sourceFile.isDirectory()) {
+            includeDirectory(jar, destinationRoot, sourceBasedPath);
+        } else {
+            warn("Skipping resource in bundle %s: %s (File Not Found)\n",
+                 bundleSymbolicName, sourceRoot);
+        }
+    }
+
+    private void includeDirectory(Jar jar, String destinationRoot, Path sourceRoot)
+            throws IOException {
+        // iterate through sources
+        // put each source on the jar
+        FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                Path relativePath = sourceRoot.relativize(file);
+                String destination = destinationRoot != null ?
+                        destinationRoot + "/" + relativePath.toString() : //TODO
+                        relativePath.toString();
+
+                addFileToJar(jar, destination, file.toAbsolutePath().toString());
+                return FileVisitResult.CONTINUE;
+            }
+        };
+
+        walkFileTree(sourceRoot, visitor);
+    }
+
+    private boolean addFileToJar(Jar jar, String destination, String sourceAbsPath) {
+        if (includedResources.contains(sourceAbsPath)) {
+            log("Skipping already included resource: %s\n", sourceAbsPath);
+            return false;
+        }
+        File file = new File(sourceAbsPath);
+        if (!file.isFile()) {
+            throw new RuntimeException(
+                    String.format("Skipping non-existent file: %s\n", sourceAbsPath));
+        }
+        Resource resource = new FileResource(file);
+        if (jar.getResource(destination) != null) {
+            warn("Skipping duplicate resource: %s\n", destination);
+            return false;
+        }
+        jar.putResource(destination, resource);
+        includedResources.add(sourceAbsPath);
+        log("Adding resource: %s\n", destination);
+        return true;
+    }
+
+    private void log(String format, Object... objects) {
+        //System.err.printf(format, objects);
+    }
+
+    private void warn(String format, Object... objects) {
+        stderr.printf(format, objects);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("inputJar", inputJar)
+                .add("outputJar", outputJar)
+                .add("classpath", classpath)
+                .add("bundleName", bundleName)
+                .add("groupId", groupId)
+                .add("bundleSymbolicName", bundleSymbolicName)
+                .add("bundleVersion", bundleVersion)
+                .add("bundleDescription", bundleDescription)
+                .add("bundleLicense", bundleLicense)
+                .toString();
+
+    }
+
+    @Override
+    public StepExecutionResult execute(ExecutionContext executionContext)
+            throws IOException, InterruptedException {
+        stderr = executionContext.getStdErr();
+        boolean success = execute();
+        stderr = System.err;
+        return success ? StepExecutionResult.SUCCESS : StepExecutionResult.ERROR;
+    }
+
+    @Override
+    public String getShortName() {
+        return "osgiwrap";
+    }
+
+    @Override
+    public String getDescription(ExecutionContext executionContext) {
+        return "osgiwrap"; //FIXME
+    }
+}
