diff --git a/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin.html b/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin.html
new file mode 100644
index 00000000..d8688f81
--- /dev/null
+++ b/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin.html
@@ -0,0 +1 @@
+
Hello World
\ No newline at end of file
diff --git a/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin.js b/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin.js
new file mode 100644
index 00000000..3dca2f71
--- /dev/null
+++ b/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin.js
@@ -0,0 +1,155 @@
+define(function(require, exports, module) {
+ main.consumes = [
+ "Plugin", "ui", "commands", "menus", "preferences", "settings"
+ ];
+ main.provides = ["myplugin"];
+ return main;
+
+ function main(options, imports, register) {
+ var Plugin = imports.Plugin;
+ var ui = imports.ui;
+ var menus = imports.menus;
+ var commands = imports.commands;
+ var settings = imports.settings;
+ var prefs = imports.preferences;
+
+ /***** Initialization *****/
+
+ var plugin = new Plugin("Ajax.org", main.consumes);
+ var emit = plugin.getEmitter();
+
+ var showing;
+ function load() {
+ commands.addCommand({
+ name: "mycommand",
+ bindKey: { mac: "Command-I", win: "Ctrl-I" },
+ isAvailable: function(){ return true; },
+ exec: function() {
+ showing ? hide() : show();
+ }
+ }, plugin);
+
+ menus.addItemByPath("Tools/My Menu Item", new ui.item({
+ command: "mycommand"
+ }), 300, plugin);
+
+ settings.on("read", function(e){
+ settings.setDefaults("user/my-plugin", [
+ ["first", "1"],
+ ["second", "all"]
+ ]);
+ });
+
+ prefs.add({
+ "Example" : {
+ position: 450,
+ "My Plugin" : {
+ position: 100,
+ "First Setting": {
+ type: "checkbox",
+ path: "user/my-plugin/@first",
+ position: 100
+ },
+ "Second Setting": {
+ type: "dropdown",
+ path: "user/my-plugin/@second",
+ width: "185",
+ position: 200,
+ items: [
+ { value: "you", caption: "You" },
+ { value: "me", caption: "Me" },
+ { value: "all", caption: "All" }
+ ]
+ }
+ }
+ }
+ }, plugin);
+ }
+
+ var drawn = false;
+ function draw() {
+ if (drawn) return;
+ drawn = true;
+
+ // Insert HTML
+ var markup = require("text!./plugin.html");
+ ui.insertHtml(document.body, markup, plugin);
+
+ // Insert CSS
+ ui.insertCss(require("text!./style.css"), options.staticPrefix, plugin);
+
+ emit("draw");
+ }
+
+ /***** Methods *****/
+
+ function show() {
+ draw();
+
+ var div = document.querySelector(".helloworld");
+ div.style.display = "block";
+ div.innerHTML = settings.get("user/my-plugin/@second");
+
+ emit("show");
+ showing = true;
+ }
+
+ function hide() {
+ if (!drawn) return;
+
+ document.querySelector(".helloworld").style.display = "none";
+
+ emit("hide");
+ showing = false;
+ }
+
+ /***** Lifecycle *****/
+
+ plugin.on("load", function() {
+ load();
+ });
+ plugin.on("unload", function() {
+ drawn = false;
+ showing = false;
+ });
+
+ /***** Register and define API *****/
+
+ /**
+ * This is an example of an implementation of a plugin.
+ * @singleton
+ */
+ plugin.freezePublicAPI({
+ /**
+ * @property showing whether this plugin is being shown
+ */
+ get showing(){ return showing; },
+
+ _events: [
+ /**
+ * @event show The plugin is shown
+ */
+ "show",
+
+ /**
+ * @event hide The plugin is hidden
+ */
+ "hide"
+ ],
+
+ /**
+ * Show the plugin
+ */
+ show: show,
+
+ /**
+ * Hide the plugin
+ */
+ hide: hide,
+ });
+
+ register(null, {
+ "myplugin": plugin
+ });
+ }
+});
\ No newline at end of file
diff --git a/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin_test.js b/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin_test.js
new file mode 100644
index 00000000..3ae2262d
--- /dev/null
+++ b/plugins/c9.ide.plugins/mock/c9.ide.example3/plugin_test.js
@@ -0,0 +1,41 @@
+"use client";
+"use mocha";
+
+define(function(require, exports, module) {
+ main.consumes = ["plugin.test", "myplugin"];
+ main.provides = [];
+ return main;
+
+ function main(options, imports, register) {
+ var test = imports["plugin.test"];
+ var myplugin = imports.myplugin;
+
+ var describe = test.describe;
+ var it = test.it;
+ var before = test.before;
+ var after = test.after;
+ var beforeEach = test.beforeEach;
+ var afterEach = test.afterEach;
+ var assert = test.assert;
+ var expect = test.expect;
+
+ /***** Initialization *****/
+
+ describe(myplugin.name, function(){
+ this.timeout(2000);
+
+ it("shows a helloworld div", function() {
+ myplugin.show();
+ expect(document.querySelector(".helloworld")).to.ok;
+ expect(document.querySelector(".helloworld").innerText).to.equal("all");
+ });
+
+ it("hides the div", function() {
+ myplugin.hide();
+ expect(document.querySelector(".helloworld").offsetHeight).to.not.ok;
+ });
+ });
+
+ register(null, {});
+ }
+});
\ No newline at end of file