You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/01 18:45:57 UTC

[49/51] [abbrv] [partial] brooklyn-docs git commit: move subdir from incubator up a level as it is promoted to its own repo (first non-incubator commit!)

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_extra/simple_java_examples/example_files/tomcat_nginx.java
----------------------------------------------------------------------
diff --git a/_extra/simple_java_examples/example_files/tomcat_nginx.java b/_extra/simple_java_examples/example_files/tomcat_nginx.java
new file mode 100644
index 0000000..20db33d
--- /dev/null
+++ b/_extra/simple_java_examples/example_files/tomcat_nginx.java
@@ -0,0 +1,17 @@
+// TODO Untested code; see brooklyn-example for better maintained examples!
+public class TomcatClusterWithNginxApp extends AbstractApplication {
+    @Override
+    public void init() {
+        addChild(EntitySpec.create(NginxController.class)
+                .configure("domain", "brooklyn.geopaas.org")
+                .configure("port", "8000+")
+                .configure("portNumberSensor", Attributes.HTTP_PORT));
+        
+        addChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
+                .configure("controller", nginxController)
+                .configure("memberSpec", : EntitySpec.create(TomcatServer.class)
+                        .configure("httpPort", "8080+")
+                        .configure("war", "/path/to/booking-mvc.war"))
+                .configure("initialSize", 2));
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_extra/simple_java_examples/example_files/tomcat_simple.java
----------------------------------------------------------------------
diff --git a/_extra/simple_java_examples/example_files/tomcat_simple.java b/_extra/simple_java_examples/example_files/tomcat_simple.java
new file mode 100644
index 0000000..480a333
--- /dev/null
+++ b/_extra/simple_java_examples/example_files/tomcat_simple.java
@@ -0,0 +1,9 @@
+// TODO Untested code; see brooklyn-example for better maintained examples!
+public class TomcatServerApp extends AbstractApplication {
+    @Override
+    public void init() {
+        addChild(EntitySpec.create(TomcatServer.class)
+                .configure("httpPort", "8080+")
+                .configure("war", "/path/to/booking-mvc.war")));
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_extra/simple_java_examples/examples.md
----------------------------------------------------------------------
diff --git a/_extra/simple_java_examples/examples.md b/_extra/simple_java_examples/examples.md
new file mode 100644
index 0000000..334b2ec
--- /dev/null
+++ b/_extra/simple_java_examples/examples.md
@@ -0,0 +1,121 @@
+---
+title: Examples
+layout: website-normal
+toc: ../guide_toc.json
+categories: [use, guide, defining-applications]
+---
+
+** TODO: this examples page is deprecated;
+code is out-of-date, and better examples are described on the web site.
+need to figure out if this page should be kept at all
+(indeed if the "guide" is even still relevant)**
+
+
+### Integrating with a Maven project
+
+If you have a Maven-based project, integrate this XML fragment with your pom.xml:
+
+<!-- TODO this should import from the downloads page -->
+
+{% highlight xml %}
+<dependencies>
+	<dependency>
+		<groupId>io.brooklyn</groupId>
+		<artifactId>brooklyn-all</artifactId>
+		<version>0.9.0-SNAPSHOT</version>  <!-- BROOKLYN_VERSION -->
+	</dependency>
+</dependencies>
+ 
+<repository>
+    <id>cloudsoft-releases</id>
+    <url>http://developers.cloudsoftcorp.com/download/maven2/</url>
+</repository>
+<repository>
+    <id>libs-snapshot-local</id>
+    <url>http://ccweb.cloudsoftcorp.com/maven/libs-snapshot-local/</url>
+    <snapshots>
+        <enabled>true</enabled>
+        <updatePolicy>never</updatePolicy>
+        <checksumPolicy>fail</checksumPolicy>
+    </snapshots>
+</repository>
+{% endhighlight %}
+
+
+### Starting a Tomcat Server
+
+The code below starts a Tomcat server on the local machine.
+
+The ``main`` method defines the application, and passes it to the ``BrooklynLauncher`` to be managed. 
+It is then started in a localhost location (other locations are shown in the next section).
+
+The Tomcat's configuration indicates that the given WAR should be deployed to the Tomcat server when it is started.
+
+{% highlight java %}
+{% readj example_files/tomcat_simple.java %}
+{% endhighlight %}
+
+The ``wars`` config is also supported (with config keys ``ROOT_WAR`` and ``NAMED_WARS`` the long-hand syntax);
+they accept EARs and other common archives, and can be described as files or as URLs (as Strings), 
+with URLs supporting an optional ``classpath://org/acme/resources/xxx.war`` syntax.
+
+
+### Starting Tomcat in Amazon EC2
+
+To start a tomcat node or cluster in Amazon EC2, the application is identical to that for localhost. 
+The only difference is the location supplied.
+
+The Brooklyn CLI can be used to launch the application in your choice of location, such as:
+
+{% highlight bash %}
+brooklyn launch --app TomcatServerApp --location localhost
+brooklyn launch --app TomcatServerApp --location aws-ec2:eu-west-1
+{% endhighlight %}
+
+ 
+### Starting a Tomcat Cluster with Nginx
+
+The code below starts a Tomcat cluster along with an Nginx instance, where each Tomcat server in the cluster is registered with the Nginx instance.
+
+{% highlight java %}
+{% readj example_files/tomcat_nginx.java %}
+{% endhighlight %}
+
+This creates a cluster that of Tomcat servers, along with an Nginx instance. The ``NginxController`` instance
+is notified whenever a member of the cluster joins or leaves; the entity is configured to look at the ``HTTP_PORT``
+attribute of that instance so that the Nginx configuration can be updated with the ip:port of the cluster member.
+
+<!---
+TODO things may need tidying (paragraphs, and/or eliminating any extra setConfig calls, though looks like these have gone)
+-->
+
+
+Starting a Multi-location Tomcat Fabric
+---------------------------------------
+
+<!---
+TODO this example should use several cloud providers, including Openshift, and use GeoDNS, 
+and maybe a data store and/or messaging service; it is the last "most advanced" example
+-->
+
+<!---
+FIXME Discuss above comment with Aled/Alex as it is contentious
+-->
+
+The ``ControlledDynamicWebAppCluster`` entity used above can also be used with a DynamicFabric to start
+a web-cluster in each location.
+
+{% highlight java %}
+{% readj example_files/tomcat_multi-location.java %}
+{% endhighlight %}
+
+
+Examples Source
+---------------
+
+Source code for (more up-to-date!) examples is available for download from GitHub. To retrieve the source, execute the following command:
+
+    git clone git@github.com:apache/incubator-brooklyn.git
+    cd incubator-brooklyn/examples
+
+You can also [browse the code](https://github.com/apache/incubator-brooklyn/tree/examples) on the web.

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_extra/update-docs.md
----------------------------------------------------------------------
diff --git a/_extra/update-docs.md b/_extra/update-docs.md
new file mode 100644
index 0000000..5abb056
--- /dev/null
+++ b/_extra/update-docs.md
@@ -0,0 +1,14 @@
+---
+layout: website-normal
+title: Updating the Docs
+toc: /guide/toc.json
+---
+
+<!-- TODO retire this page -->
+
+The Brooklyn docs live in the **docs** project in the Brooklyn codebase.
+It's built using standard jekyll/markdown with a few extensions.
+
+Instructions for building and working with docs are in a `README.md` file
+in that folder; for the most recent version of instructions click
+[here](https://github.com/apache/incubator-brooklyn/tree/master/docs/README.md).

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/base-head.html
----------------------------------------------------------------------
diff --git a/_includes/base-head.html b/_includes/base-head.html
new file mode 100644
index 0000000..0773dc2
--- /dev/null
+++ b/_includes/base-head.html
@@ -0,0 +1,30 @@
+
+<title>{{ page.title }} - Apache Brooklyn (incubating)</title>
+
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
+<link href="{% dependency_url bootstrap.css %}" rel="stylesheet">
+<link href="{{site.path.style}}/deps/octicons/octicons.css" rel="stylesheet">
+<link href="{{site.path.style}}/deps/bootstrap-theme.css" rel="stylesheet">
+<link href="{{site.path.style}}/deps/tooltip.css" rel="stylesheet">
+
+<link rel="stylesheet" href="{{ site.path.style }}/css/code.css" type="text/css" media="screen" />
+
+<link href="{{site.path.style}}/css/website.css" rel="stylesheet">
+
+<script src="{% dependency_url jquery.js %}"></script>
+<script src="{% dependency_url glossarizer.js %}"></script>
+<script src="{% dependency_url bootstrap.js %}"></script>
+<script src="{% dependency_url tooltip.js %}"></script>
+<script type="text/javascript" src="{{ site.path.style }}/deps/jquery.cookie.js"></script>
+<script>
+$(function(){
+  $('body').glossarizer({
+    sourceURL: '/guide/glossary.json?'+Math.random(),
+    caseSensitive : true,
+    lookupTagName : 'p, ul',
+    callback: function(){ new tooltip(); }
+  });
+});
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/base-scss.scss
----------------------------------------------------------------------
diff --git a/_includes/base-scss.scss b/_includes/base-scss.scss
new file mode 100644
index 0000000..aec3e2f
--- /dev/null
+++ b/_includes/base-scss.scss
@@ -0,0 +1,36 @@
+
+$fonts: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
+$header_fonts: Avenir, $fonts;
+
+// colors
+
+/* this green is approx what is in the logo (taken from image picker) */
+$brooklyn_green: #6db34b;
+$bootstrap_theme_green_gradient_upper: #5cb85c;
+$bootstrap_theme_green_gradient_lower: #48a648;
+$vibrant_bg_green: $bootstrap_theme_green_gradient_lower;
+$vibrant_fg_green: #483;
+
+$white_fa: #fafafa;
+$white_f5: #f5f5f5;
+$white_ee: #eee;
+$white_dd: #ddd;  // for borders and tooltip bg
+$gray_aa: #aaa;
+$gray_88: #888;
+$gray_66: #666;
+
+$blackish: #393939;
+
+$bootstrap_blue_border: #428bca;
+
+// roles for colors
+
+$text_color: $blackish;
+
+$a_color: $vibrant_fg_green;
+$a_hover_color: $brooklyn_green;
+
+//$code_bg_color: #e8eded;
+$code_bg_color: $white_f5;
+
+$footer_icon_gray: $gray_88;

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/feature-image.html
----------------------------------------------------------------------
diff --git a/_includes/feature-image.html b/_includes/feature-image.html
new file mode 100644
index 0000000..89bedcd
--- /dev/null
+++ b/_includes/feature-image.html
@@ -0,0 +1,4 @@
+
+<div class="feature-image">
+  <img src="{{ include.src }}"/>
+</div>

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/feature-item-end.html
----------------------------------------------------------------------
diff --git a/_includes/feature-item-end.html b/_includes/feature-item-end.html
new file mode 100644
index 0000000..f208df5
--- /dev/null
+++ b/_includes/feature-item-end.html
@@ -0,0 +1,14 @@
+
+{% if include.img %}
+{% comment %}
+  does not work to do: { % include feature-image.html src='{{ include.img }}' % }
+  so we repeat that snippet :(
+{% endcomment %}
+
+<div class="feature-image">
+  <img src="{{ include.img }}"/>
+</div>
+
+{% endif %}
+
+</div></div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/feature-item.html
----------------------------------------------------------------------
diff --git a/_includes/feature-item.html b/_includes/feature-item.html
new file mode 100644
index 0000000..e91d6c2
--- /dev/null
+++ b/_includes/feature-item.html
@@ -0,0 +1,4 @@
+
+<div class="feature-item">
+  <div class="feature-title">{{ include.title }}</div>
+  <div class="feature-body">

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/fields.md
----------------------------------------------------------------------
diff --git a/_includes/fields.md b/_includes/fields.md
new file mode 100644
index 0000000..d9e74b7
--- /dev/null
+++ b/_includes/fields.md
@@ -0,0 +1,32 @@
+
+{% if site.brooklyn-version contains 'SNAPSHOT' %}{% capture SNAPSHOT %}true{% endcapture %}{% endif %}
+
+{% capture brooklyn_properties_url_path %}{{ site.path.guide }}/start/brooklyn.properties{% endcapture %}
+{% capture brooklyn_properties_url_live %}{{ site.url_root }}{{ brooklyn_properties_url_path }}{% endcapture %}
+
+{% capture brooklyn_group_id %}org.apache.brooklyn{% endcapture %}
+{% capture brooklyn_group_id_path %}org/apache/brooklyn{% endcapture %}
+
+{% capture this_repo_base_url %}https://repository.apache.org{% endcapture %}
+{% capture this_repo_base_url_search %}{{ this_repo_base_url }}/index.html#nexus-search{% endcapture %}
+{% capture this_repo_base_url_artifact %}{{ this_repo_base_url }}/service/local/artifact/maven/redirect{% endcapture %}
+
+{% capture apache_snapshots_repo_groupid_url %}{{ this_repo_base_url }}/content/repositories/snapshots/{{ brooklyn_group_id_path }}{% endcapture %}
+{% capture apache_releases_repo_groupid_url %}{{ this_repo_base_url }}/content/repositories/releases/{{ brooklyn_group_id_path }}{% endcapture %}
+
+{% capture this_repo_base_url_content %}{% if SNAPSHOT %}{{ apache_snapshots_repo_groupid_url }}{% else %}{{ apache_releases_repo_groupid_url }}{% endif %}{% endcapture %}
+{% capture this_dist_url_list %}{{ this_repo_base_url_content }}/brooklyn-dist/{{ site.brooklyn-version }}/{% endcapture %}
+
+{% if SNAPSHOT %}
+  <!-- put e field last, so we can append .sha1 -->
+  {% capture this_dist_url_zip %}{{ this_repo_base_url_artifact }}?r=snapshots&g={{ brooklyn_group_id }}&a=brooklyn-dist&v={{ site.brooklyn-version }}&c=dist&e=zip{% endcapture %}
+  {% capture this_dist_url_tgz %}{{ this_repo_base_url_artifact }}?r=snapshots&g={{ brooklyn_group_id }}&a=brooklyn-dist&v={{ site.brooklyn-version }}&c=dist&e=tar.gz{% endcapture %}
+{% else %}<!--- RELEASE -->
+  {% capture this_dist_url_zip %}{{ this_dist_url_list }}/brooklyn-dist-{{ site.brooklyn-version }}-dist.zip{% endcapture %}
+  {% capture this_dist_url_tgz %}{{ this_dist_url_list }}/brooklyn-dist-{{ site.brooklyn-version }}-dist.tar.gz{% endcapture %}
+{% endif %}
+
+{% capture this_anything_url_search %}{{ this_repo_base_url_search }};gav~{{ brooklyn_group_id }}~~{{ site.brooklyn-version }}~~{% endcapture %}
+{% capture this_dist_url_search %}{{ this_repo_base_url_search }};gav~{{ brooklyn_group_id }}~brooklyn-dist~{{ site.brooklyn-version }}~~{% endcapture %}
+
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/footer.html
----------------------------------------------------------------------
diff --git a/_includes/footer.html b/_includes/footer.html
new file mode 100644
index 0000000..316fe5a
--- /dev/null
+++ b/_includes/footer.html
@@ -0,0 +1,16 @@
+<div id="footer">
+    <div class="container">
+        <div class="row">
+            <div class="col-md-10 text-muted">
+                Apache Brooklyn is distributed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License v2.0</a>.
+            </div>
+            <div class="col-md-2">
+                <a class="btn btn-sm btn-default" href="https://github.com/apache/incubator-brooklyn/edit/master/docs/{{ page.path }}">Edit This Page</a>
+                <a href="{{ site.url_root }}{{ site.path.website }}/community/how-to-contribute-docs.html"
+                    data-toggle="tooltip" data-placement="top" title="How to Edit Documentation" data-delay="400"/>
+                  <span class="octicon octicon-question octicon-footer"></span>
+                </a>
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/java_link.html
----------------------------------------------------------------------
diff --git a/_includes/java_link.html b/_includes/java_link.html
new file mode 100644
index 0000000..9411877
--- /dev/null
+++ b/_includes/java_link.html
@@ -0,0 +1,18 @@
+{% comment %}
+
+includes a code-formatted class name with link to its javadoc and optionally its source code
+
+usage:  
+
+{ % include java_link.html class_name="JcloudsLocationConfig" package_path="org/apache/brooklyn/location/jclouds" project_subpath="location/jclouds" % }
+
+
+{% endcomment %}{% if include.project_subpath %}<code>{{ include.class_name }}</code>
+  (<a href="{{ site.path.guide }}/misc/javadoc/{{ include.package_path }}/{{ include.class_name }}.html">javadoc</a>, 
+   <a href="{{ site.brooklyn.url.git }}/{{ include.project_subpath }}/src/main/java/{{ include.package_path }}/{{ include.class_name }}.java">src</a>){% comment %}
+{% endcomment %}{% else %}<a href="{{ site.path.guide }}/misc/javadoc/{{ include.package_path }}/{{ include.class_name }}.html">
+<code>{{ include.class_name }}</code></a>
+{% endif %}{% comment %}
+
+must NOT have a newline at the end here, as the include is often done inline
+{% endcomment %}

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/list-children.html
----------------------------------------------------------------------
diff --git a/_includes/list-children.html b/_includes/list-children.html
new file mode 100644
index 0000000..0c327f3
--- /dev/null
+++ b/_includes/list-children.html
@@ -0,0 +1,9 @@
+{% comment %}
+TODO style this much better
+{% endcomment %}
+
+<div class="list-children"><ul>
+{% for item in page.menu %}
+<li> <a href="{{ item.url }}">{{ item.title }}</a> </li>
+{% endfor %}
+</ul></div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/sidemenu.html
----------------------------------------------------------------------
diff --git a/_includes/sidemenu.html b/_includes/sidemenu.html
new file mode 100644
index 0000000..ec3cf1c
--- /dev/null
+++ b/_includes/sidemenu.html
@@ -0,0 +1,244 @@
+<div class="list-group side-menu" id="side-menu">
+{% comment %}
+
+  Case 1) If we're the landing page show nothing.
+  Case 2) If we're contained in the top (landing page) menu, show our menu if we have one.
+  Case 3a) Otherwise if we're contained in a menu, show that menu.
+  Case 3b) And if we have a menu, show our menu nested.
+  
+  Note the breadcrumbs are offset:1. This is because usually breadcrumbs include the root;
+  but also if we're overriding breadcrumbs it gives us a way to set a topmenu item (making it breadcrumb[0])
+  while customizing the side menu (make self breadcrumb[1]).
+{% endcomment %}
+
+{% unless page.landing %}
+  {% if page.menu_parent %}
+    {% if page.menu_parent.landing %} {% comment %} case 2 {% endcomment %}
+              {% for item in page.breadcrumb_pages offset:1 %}
+                  <h4 class="{% if forloop.index0 > 0 %} with_preceding{% endif %}{% if forloop.rindex0 > 0 %} with_following{% endif %}">
+                    <a href="{{item.url}}" class="list-group-item{% if item.path == page.menu_path %} active{% endif %} breadcrumb breadcrumb{{ forloop.index0 }}">
+                      {{ item.title_in_menu }}</a></h4>
+              {% endfor %}
+              
+              {% for item in page.menu %}
+                <a href="{{item.url}}" class="list-group-item{% if page.breadcrumbs contains item %} active{% endif %}">{{ item.title_in_menu }}
+                  {% if item.external %}&nbsp;<span class="octicon octicon-link-external"></span>{% endif %}</a>
+              {% endfor %}
+    
+    {% else %} {% comment %} case 3a {% endcomment %}
+              {% for item in page.menu_parent.breadcrumb_pages offset:1 %}
+                  <h4 class="{% if forloop.index0 > 0 %} with_preceding{% endif %}{% if forloop.rindex0 > 0 %} with_following{% endif %}">
+                    <a href="{{item.url}}" class="list-group-item{% if item.path == page.menu_path %}{% unless item.menu_customization.force_inactive %} active{% endunless %}{% endif %} breadcrumb breadcrumb{{ forloop.index0 }}">
+                      {{ item.title_in_menu }}
+                      {% if item.external %}&nbsp;<span class="octicon octicon-link-external"></span>{% endif %}</a></h4>
+              {% endfor %}
+              {% for item in page.menu_parent.menu %}
+                {% if page.breadcrumb_paths contains item.menu_path %}{% assign in_menu = true %}{% else %}{% assign in_menu = false %}{% endif %} 
+                {% if in_menu and page.menu %}
+                  {% comment %} case 3b {% endcomment %}
+                  <a href="{{item.url}}" class="list-group-item active with-sub-item">{{ item.title_in_menu }}
+                    {% if item.external %}&nbsp;<span class="octicon octicon-link-external"></span>{% endif %}</a>
+                  <div class="sub-item">
+                    {% for item2 in page.menu %}
+                      {% capture item_section_classes %}{% if item2.section %} section{% endif %}{% endcapture %}
+                      <a href="{{item2.url}}" class="list-group-item sub-item {{ item_section_classes }}" {% if item2.section %}section-target="#{{ item2.section }}"{% endif %}>
+                        {{ item2.title_in_menu }}
+                        {% if item2.external %}&nbsp;<span class="octicon octicon-link-external"></span>{% endif %}</a>
+                    {% endfor %}
+                  </div>
+                {% else %}
+                  {% comment %} case 3a side menu item {% endcomment %}
+                  <a href="{{item.url}}" class="list-group-item{% if page.breadcrumb_paths contains item.menu_path %}{% unless item.menu_customization.force_inactive %} active{% endunless %}{% endif %}">{{ item.title_in_menu }}
+                    {% if item.external %}&nbsp;<span class="octicon octicon-link-external"></span>{% endif %}</a>
+                {% endif %}
+              {% endfor %}
+        
+    {% endif %}    
+  {% elsif page.menu %}
+    <!-- no pages have a menu without being in the top menu, won't come here -->
+  {% endif %}
+{% endunless %}
+        
+</div>
+<div id="width_reference"></div>
+
+
+<script language="JavaScript" type="application/javascript">
+
+{% comment %} 
+the menu is css position:fixed so won't scroll; 
+but also it will not obey its parents width.
+set the width on load and on resize.
+{% endcomment %} 
+sidemenu_x_sizer=function(){ $('#side-menu').width($('#side-menu').parent().find('#width_reference').outerWidth()); };
+$(sidemenu_x_sizer);
+$(window).resize(sidemenu_x_sizer);
+
+{% comment %} 
+also ensure the screen is big enough, else revert to non-floating menu:
+check y-height, and check widths (in case it was moved to after the other column)
+{% endcomment %} 
+sidemenu_y_nonfloater=function(){
+  if ($('#side-menu').outerHeight(true) + $('#header').outerHeight(true) + $('#footer').outerHeight(true) > window.innerHeight ||
+      $('#side-menu').width() >= $('#content_container').width()/2) {
+    $('#side-menu').css('position', 'inherit');
+  } else {
+    // restore if screen has grown
+    $('#side-menu').css('position', 'fixed');
+  }
+};
+$(sidemenu_y_nonfloater);
+$(window).resize(sidemenu_y_nonfloater);
+
+{% comment %} 
+auto-advance "sections" in menu on scroll
+{% endcomment %} 
+
+var sideMenu = $("#side-menu"),
+    sideItems = sideMenu.find("a"),
+    // Anchors corresponding to menu items
+    scrollItems = sideItems.map(function(){
+      var item = $(this).attr("section-target");
+      if (item && item.length) { return item; }
+    });
+
+var highlight_section_last_top = -1;
+var highlight_section_completed = false;
+
+var highlight_section = function() {
+   // Get container scroll position
+   var highlight_section_new_top = $(this).scrollTop();
+   if (highlight_section_new_top == highlight_section_last_top) return;
+   var highlight_section_new_bottom = highlight_section_new_top + $(window).height();
+   var scroll_advancing = (highlight_section_new_top > highlight_section_last_top);
+
+   var last_item = null, active_item = $("#side-menu a.section#active");
+   
+   var found_top = false;
+   var displayable_items = scrollItems.map(function(itemI){
+     item = $(scrollItems[itemI]);
+     if (item && item.length) {
+       if (highlight_section_last_top == -1 || !highlight_section_completed) {
+         // just opening page - take item matching hash, or otherwise the first item visible
+         if (item.selector === window.location.hash || (item.offset().top > highlight_section_new_top - 20 && !found_top)) {
+           found_top = true;
+           if (item.selector === window.location.hash && item.offset().top < highlight_section_new_top + 60) {
+             // because of our top header, we need to scroll 64px down from any link
+             $('html, body').animate({scrollTop: item.offset().top - 64}, 0);
+           }
+           return item;
+         }
+       } else if (scroll_advancing) {
+         // if scrolling advance, pick up a section when title starts before 1/3 height 
+         if (item.offset().top < highlight_section_new_top + $(window).height()/3)
+           return item;
+           
+         // or if containing div is finished (usu the whole main content)
+         div_containing_item = item.closest("div");
+         if (div_containing_item.offset().top + div_containing_item.height() < highlight_section_new_bottom + 15)
+           return item;
+         // or when next title is visible
+         if (last_item && item.offset().top < highlight_section_new_bottom + 15)
+           return last_item;
+       } else {
+         // if scrolling back, pick up a section as soon as the title is visible,
+         if (item.offset().top < highlight_section_new_top)
+           return item;
+         // or if title is before the 2/3 point
+         // (not sure about this, probably want also to have 
+         // "AND the id.top is <= displayable_itemsrent_active_it.top" so we don't jump FORWARD a section
+         // when scrolling BACK, with lots of tiny sections) 
+         if ((item.offset().top < highlight_section_new_top + 2*$(window).height()/3)
+             && (!active_item || !active_item.offset() || active_item.offset().top >= item.offset().top))
+           return item;
+         
+       }
+       last_item = item;
+     }
+   });
+   if (!highlight_section_completed && document.readyState === "complete") {
+     highlight_section_completed = true;
+   }
+   if (!displayable_items.length) {
+     $("#side-menu a.section").removeClass("active");
+   } else {
+     displayable_items = displayable_items[displayable_items.length-1];
+     var id = displayable_items && displayable_items.length ? displayable_items[0].id : "";
+   // Set/remove active class
+     new_active = $("#side-menu a.section").filter("[section-target='#"+id+"']");
+     if (new_active.hasClass("active")) {
+       // nothing needed
+     } else {
+       $("#side-menu a.section").removeClass("active");
+       $("#side-menu a.section").filter("[section-target='#"+id+"']").addClass("active");
+     }
+   }
+   
+   highlight_section_last_top = highlight_section_new_top;
+};
+var highlight_new_section = function() {
+  highlight_section_completed = false;
+  highlight_section_last_top = -1;
+  highlight_section();
+}
+
+$(window).scroll(highlight_section);
+$(highlight_new_section);
+
+// detect link change - courtesy http://www.bennadel.com/blog/1520-binding-events-to-non-dom-objects-with-jquery.htm
+    (
+        function( $ ){
+            // Default to the current location.
+            var strLocation = window.location.href;
+            var strHash = window.location.hash;
+            var strPrevLocation = "";
+            var strPrevHash = "";
+
+            // This is how often we will be checkint for
+            // changes on the location.
+            var intIntervalTime = 100;
+
+            // This method removes the pound from the hash.
+            var fnCleanHash = function( strHash ){
+                return(
+                    strHash.substring( 1, strHash.length )
+                    );
+            }
+
+            // This will be the method that we use to check
+            // changes in the window location.
+            var fnCheckLocation = function(){
+                // Check to see if the location has changed.
+                if (strLocation != window.location.href){
+
+                    // Store the new and previous locations.
+                    strPrevLocation = strLocation;
+                    strPrevHash = strHash;
+                    strLocation = window.location.href;
+                    strHash = window.location.hash;
+
+                    // The location has changed. Trigger a
+                    // change event on the location object,
+                    // passing in the current and previous
+                    // location values.
+                    $( window.location ).trigger(
+                        "change",
+                        {
+                            currentHref: strLocation,
+                            currentHash: fnCleanHash( strHash ),
+                            previousHref: strPrevLocation,
+                            previousHash: fnCleanHash( strPrevHash )
+                        }
+                        );
+
+                }
+            }
+
+            // Set an interval to check the location changes.
+            setInterval( fnCheckLocation, intIntervalTime );
+        }
+    )( jQuery );
+// and trigger highlight section on link change
+$(window.location).bind("change", highlight_new_section);
+
+</script>

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/sitemap-item.html
----------------------------------------------------------------------
diff --git a/_includes/sitemap-item.html b/_includes/sitemap-item.html
new file mode 100644
index 0000000..e2034f5
--- /dev/null
+++ b/_includes/sitemap-item.html
@@ -0,0 +1,36 @@
+{% pop site_items item %}
+{% set_hash_entry item path item_path %}
+{% set_hash_entry item url item_url %}
+
+{% unless item_path %}
+ {% unless item_url %}
+  {% puts error, null item_url %}
+  {% putp item %}
+  {% putv item_url %}
+  {% fail item missing path and url (jekyll block evaluation order can cause this) %}
+ {% endunless %}
+{% endunless %}
+
+<a id="{{ item_path }}" name="{{ item_path }}" href="javascript:void(0);"></a>
+<li>
+ {% if visited contains item_path %}
+  {{ item['title'] }} &nbsp; <a href="#{{ item_path }}"><span class="octicon octicon-link-external flip"></span></a>
+ {% elsif item['external'] %}
+  {{ item['title'] }} &nbsp; <a href="{{ item['url'] }}"><span class="octicon octicon-link-external"></span></a>
+  
+ {% else %}
+  <a href="{{ item['url'] }}">{{ item['title'] }}</a>
+  {% if item['menu'] %}
+   {% push visited item_path %}
+   <ul>
+    {% push site_items item %}
+    {% assign last_item = site_items[-1] %}
+    {% for item in last_item['menu'] %}
+     {% push site_items item %}
+     {% include sitemap-item.html %}
+    {% endfor %}
+    {% pop site_items item %}
+   </ul>
+  {% endif %}
+ {% endif %}
+</li>

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_includes/topmenu.html
----------------------------------------------------------------------
diff --git a/_includes/topmenu.html b/_includes/topmenu.html
new file mode 100644
index 0000000..0275794
--- /dev/null
+++ b/_includes/topmenu.html
@@ -0,0 +1,75 @@
+<nav class="navbar navbar-default navbar-fixed-top" id="header" role="navigation">
+    <div class="container-and-sidebars">
+
+        <div class="container-sidebar-left feather{% if page.landing %} landing{% endif %}">
+          <a href="http://www.apache.org/">
+            <img src="{{ site.path.style }}/img/feather.png" alt="[Apache]" width="80" class="flip navbar-feather">
+          </a>
+        </div>
+
+        <div class="container container-between-sidebars top-menu">
+          <div class="container-fluid">
+            <!-- Brand and toggle get grouped for better mobile display -->
+            <div class="navbar-header">
+                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
+                    <span class="sr-only">Toggle navigation</span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                </button>
+                {% unless page.landing %}<a class="navbar-brand" href="{{site.path.website}}/"><img src="{{site.path.style}}/img/apache-brooklyn-logo-244px-wide.png" alt="brooklyn"></a>{% endunless %}
+            </div>
+
+            <!-- Collect the nav links, forms, and other content for toggling -->
+            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
+                <ul class="nav navbar-nav navbar-right">
+                  {% for item in site.data.menu %}
+                   {% if item.menu %}
+                    <li class="dropdown{% if page.breadcrumb_paths contains item.path %} active{% endif %}">
+                        <a href="{{item.url}}">{{ item.title_in_menu | downcase }}</a>
+                        <ul class="dropdown-menu" role="menu">
+                            <li>
+                                <a href="{{item.url}}">{{item.title_in_menu}}</a>
+                            </li>
+                            <li class="divider"></li>
+                            {% for item2 in item.menu %}
+                              <li>
+                                {% if item2.menu_customization.dropdown_new_section %}
+                                  <div class="dropdown_new_section"><hr></div>
+                                {% endif %}
+                                <a href="{{item2.url}}">{{item2.title_in_menu}}
+                                  {% if item2.external %}&nbsp;<span class="octicon octicon-link-external"></span>{% endif %}</a>
+                                {% if item2.menu_customization.dropdown_section_header %}
+                                  <div class="dropdown_section_header"><hr></div>
+                                {% endif %}
+                              </li>
+                            {% endfor %}
+                        </ul>
+                    </li>
+                   {% else %}
+                    <li class="{% if page.breadcrumb_paths contains item.path %}active{% endif %}">
+                      <a href="{{item.url}}">{{ item.title_in_menu | downcase }}</a>
+                    </li>
+                   {% endif %}
+                  {% endfor %}
+                </ul>
+            </div><!-- /.navbar-collapse -->
+          </div><!-- /.container-fluid -->
+        </div><!-- /.container -->
+        
+        <div class="container-sidebar-right">
+          <div class="navbar-sidebar-right-icons">
+            <a href="https://github.com/apache/incubator-brooklyn" class="navbar-icon navbar-icon-shift icon-github"
+              data-toggle="tooltip" data-placement="bottom" title="GitHub: apache/incubator-brooklyn"/>
+            <a href="https://twitter.com/#!/search?q=brooklyncentral" class="navbar-icon navbar-icon-shift icon-twitter"
+              data-toggle="tooltip" data-placement="bottom" title="Twitter: @brooklyncentral"/>
+            <a href="http://webchat.freenode.net/?channels=brooklyncentral" class="navbar-icon icon-irc"
+              data-toggle="tooltip" data-placement="bottom" title="IRC: freenode #brooklyncentral"/>
+            <!-- extra a element seems needed as landing page seems to copy the last element here (!?) 
+            -->
+            <a href="/" style="width: 0px; height: 0px;"></a>
+         </div>
+      </div>
+      
+  </div>
+</nav>

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_layouts/base.html
----------------------------------------------------------------------
diff --git a/_layouts/base.html b/_layouts/base.html
new file mode 100644
index 0000000..29b735f
--- /dev/null
+++ b/_layouts/base.html
@@ -0,0 +1,186 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+
+
+{{ content }}
+
+
+<script src="//cdnjs.cloudflare.com/ajax/libs/zeroclipboard/1.3.1/ZeroClipboard.min.js"></script>
+
+<script language="JavaScript" type="application/javascript">
+    fix_padding_function = function () { 
+        $('body').css('padding-top', parseInt($('#header').css("height"))+10);
+        $('body').css('padding-bottom', parseInt($('#footer').css("height"))+10);
+    };
+    $(window).resize(fix_padding_function);
+    $(window).load(fix_padding_function);
+    
+    $(function () {
+        $('[data-toggle="tooltip"]').tooltip({ delay: { show: 600, hide: 100 }})
+    });
+    
+/* generate anchors for headers, a la github and http://blog.parkermoore.de/2014/08/01/header-anchor-links-in-vanilla-javascript-for-github-pages-and-jekyll/ */
+var anchorForId = function (id, text) {
+  var anchor = document.createElement("a");
+  anchor.className = "header-link";
+  anchor.href      = "#" + id;
+  anchor.innerHTML = "<i class=\"fa fa-link\"></i>";
+  return anchor;
+};
+
+var linkifyAnchors = function (level, containingElement) {
+  var headers = contentBlock.find("h" + level);
+  for (var h = 0; h < headers.length; h++) {
+    var header = headers[h];
+    if (typeof header.id !== "undefined" && header.id !== "") {
+      header.appendChild(anchorForId(header.id, $(header).text()));
+    }
+  }
+};
+
+$(function () {
+    contentBlock = $("#content_container");
+    if (!contentBlock) return;
+    for (var level = 1; level <= 6; level++) {
+      linkifyAnchors(level, contentBlock);
+    }
+});
+
+<!-- Clipboard support -->
+  ZeroClipboard.config({ moviePath: '//cdnjs.cloudflare.com/ajax/libs/zeroclipboard/1.3.1/ZeroClipboard.swf' });
+
+$(function() {
+  $('div.highlight').prepend(
+  $('<div class="clipboard_container" title="Copy to Clipboard">'+
+    '<div class="fa clipboard_button">'+
+    '<div class="on-active"><div>Copied to Clipboard</div></div>'+
+  '</div></div>'));
+  $('div.clipboard_container').each(function(index) {
+    var clipboard = new ZeroClipboard();
+    clipboard.clip( $(this).find(":first")[0], $(this)[0] );
+    var target = $(this).next();
+    var txt = target.text().trim();
+    if (target.find('code.bash')) {
+      // Strip out bash prompts from the start of each line (i.e. '$' or '%' characters
+      // at the very start, or immediately following any newline). Correctly handles continuation
+      // lines, where a leading '$' or '%' is *not* a prompt character.
+      txt = txt.replace(/(^|[^\\]\n)[$%] /g, "$1");
+    }
+    clipboard.on( 'dataRequested', function (client, args) {
+      client.setText( txt );
+    });
+  });
+});
+
+<!-- search -->
+    $(function() {
+        $('#simple_google')
+            .submit(function() {
+                $('input[name="q"]').val("site:" + document.location.hostname + " " + $('input[name="brooklyn-search"]').val());
+            return true;
+            });
+        $('input[name="brooklyn-search"]').focus(function() {
+                if ($(this).val() === $(this).attr('placeholder')) {
+                    $(this).val('');
+                }
+            })
+            .blur(function() {
+                if ($(this).val() === '') {
+                    $(this).val($(this).attr('placeholder'));
+                }
+            })
+            .blur();
+    });
+
+
+ <!-- analytics -->
+    var _gaq = _gaq || [];
+    _gaq.push(['_setAccount', 'UA-30530918-1']);
+    _gaq.push(['_trackPageview']);
+    
+    (function() {
+      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+    })();
+
+
+<!-- page warning (for archive pages) -->
+{% comment %}
+TODO insert the warning html at generation-time (jekyll) rather than runtime (JS)
+{% endcomment %}
+{% if page.path contains 'guide/' %} 
+    $(function() {
+        if (document.location.pathname.replace(/^\/([^\/]*).*$/, '$1') === "v"){
+            var thisversion = document.location.pathname.split("/")[2],
+                msg = "";
+            if (thisversion != 'latest' && (!$.cookie('brooklyn_versions') || 
+                    (($.inArray('ALL', $.cookie('brooklyn_versions').split(",")) === -1) &&
+                    ($.inArray(thisversion, $.cookie('brooklyn_versions').split(",")) === -1))) ){
+                msg += "<div class='warning_banner_image'><img src='{{ site.path.style }}/img/warning.png'/></div>";
+                msg += "<p>You are browsing the archive site for version <strong>"+thisversion+"</strong>.</p>";
+                if (thisversion.indexOf("SNAPSHOT") >= 0) {
+                  msg += "<p>Note that SNAPSHOT versions have not been voted on and are not endorsed by the Apache Software Foundation.</p>";
+                  msg += "<p>Do you understand and accept the risks?</p>";
+                } else {
+                  msg += "<p>Is this deliberate?</p>";
+                }
+                msg += "<center><p class='warning_banner_buttons'>";
+                msg += "<a href = 'javascript:void(0);' onclick=\"set_user_version('"+thisversion+"');\">Yes, hide this warning</a>";
+                msg += "<a href = '{{ site.path.v }}/latest/'>No, take me to the latest version guide</a>";
+                msg += "<a href = '{{ site.path.website }}/meta/versions.html'>Show all versions</a>";
+                msg += "</p></center>"
+                            
+                $('#page_notes').html(msg);
+                $('#page_notes').fadeIn('slow');
+            }
+        }
+    });
+{% endif %}
+    function get_user_versions() {
+        return $.cookie("brooklyn_versions") ? $.cookie("brooklyn_versions").split(",") : [];
+    };
+    function set_user_version(version) {
+        var version_cookie = get_user_versions();
+        version_cookie.push(version);
+        $.cookie('brooklyn_versions', version_cookie, { expires: 365, path: '/' });
+        $('#page_notes').fadeOut();
+        event.preventDefault ? event.preventDefault() : event.returnValue = false;
+    };
+    function set_user_versions_all() {
+        var version_cookie = get_user_versions();
+        version_cookie.push("ALL");
+        $.cookie('brooklyn_versions', version_cookie, { expires: 365, path: '/' });
+        $('#page_notes').fadeOut();
+        event.preventDefault ? event.preventDefault() : event.returnValue = false;
+    };
+    function clear_user_versions() {
+        $.removeCookie('brooklyn_versions', { path: '/' });
+        $('#page_notes').fadeIn('slow');
+        event.preventDefault ? event.preventDefault() : event.returnValue = false;
+    };
+
+</script>
+
+</body>
+
+</html>

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_layouts/website-base.html
----------------------------------------------------------------------
diff --git a/_layouts/website-base.html b/_layouts/website-base.html
new file mode 100644
index 0000000..8f8c24a
--- /dev/null
+++ b/_layouts/website-base.html
@@ -0,0 +1,33 @@
+---
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+layout: base
+---
+
+<head>
+
+    {% include base-head.html %}
+
+</head>
+
+
+<body>
+
+{% include topmenu.html %}
+
+{{ content }}

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_layouts/website-landing.html
----------------------------------------------------------------------
diff --git a/_layouts/website-landing.html b/_layouts/website-landing.html
new file mode 100644
index 0000000..7d2a6e4
--- /dev/null
+++ b/_layouts/website-landing.html
@@ -0,0 +1,43 @@
+---
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+# layout for front page, contianing only the footer, with a bit more text
+layout: website-base
+---
+<div class="container slightlyNarrowContainer">
+    {{ content }}
+</div>
+
+<div id="footer">
+    <div class="container">
+        <div class="row">
+            <div class="col-md-9 text-muted">
+                Apache Brooklyn is distributed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License v2.0</a>.
+            </div>
+            <div class="col-md-3">
+                <p>
+                <a class="btn btn-sm btn-default" href="https://github.com/apache/incubator-brooklyn/edit/master/docs/{{ page.path }}">Edit This Page</a>
+                <a href="{{ site.url_root }}{{ site.path.website }}/community/how-to-contribute-docs.html"
+                    data-toggle="tooltip" data-placement="top" title="How to Edit Documentation" data-delay="400"/>
+                  <span class="octicon octicon-question octicon-footer"></span>
+                </a>
+                </p>
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_layouts/website-normal.html
----------------------------------------------------------------------
diff --git a/_layouts/website-normal.html b/_layouts/website-normal.html
new file mode 100644
index 0000000..a89bb91
--- /dev/null
+++ b/_layouts/website-normal.html
@@ -0,0 +1,39 @@
+---
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+# layout for most website pages, inheriting base for the menu bar, and providing a main column of content and a menu column
+# (not used for the landing page, and not used for the guide)
+#
+# menu_customizations can be used, including force_inactive to prevent highlighting
+layout: website-base
+---
+<div class="container" id="main_container">
+    <div class="row">
+        <div class="col-md-9" id="content_container">
+            <div id="page_notes"></div>
+            <h1>{{ page.title }}</h1>
+            {{ content }}
+        </div>
+
+        <div class="col-md-3">
+            {% include sidemenu.html %}
+        </div>
+    </div>
+</div>
+
+{% include footer.html %}

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_licensing/README
----------------------------------------------------------------------
diff --git a/_licensing/README b/_licensing/README
new file mode 100644
index 0000000..2fc5f2e
--- /dev/null
+++ b/_licensing/README
@@ -0,0 +1,24 @@
+
+We don't distribute docs as part of the source build so we're not obliged to report the JS we include
+or generate a special LICENSE file as brooklyn-dist/dist/licensing does for the distributed projects.
+
+(This project just gets the usual brooklyn license.)
+
+However we might consider recording the licenses used in the docs.  So we note
+that third-party software bundled by the docs include:
+
+* bloodhound (aka typeahead)
+* glossarizer
+
+And other things used by brooklyn, in style/{deps,js}.
+
+---
+
+This project includes the software: glossarizer
+   Available at: https://github.com/PebbleRoad/glossarizer
+   Developed by: Vinay M, PebbleRoad Pte Ltd (http://www.pebbleroad.com)
+   Version used: 1.5
+   Used under the following license: The MIT License (http://opensource.org/licenses/MIT)
+   Copyright (c) Vinay M, PebbleRoad Pte Ltd (2004-2016)
+ 
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/brooklyn_jekyll_util.rb
----------------------------------------------------------------------
diff --git a/_plugins/brooklyn_jekyll_util.rb b/_plugins/brooklyn_jekyll_util.rb
new file mode 100644
index 0000000..fd3688d
--- /dev/null
+++ b/_plugins/brooklyn_jekyll_util.rb
@@ -0,0 +1,129 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+# useful tags:
+
+# printing
+#     puts message
+#     putv variable_to_print_raw
+#     putp variable_to_pretty_print
+
+# eval and control flow
+#     set_hash_entry hash key variable_to_set  # because sometimes jekyll eval order is different
+#     fail message                             # to fail with a message
+
+# stack manipulation:
+#     push stack x  # pushs x to stack and clears x
+#     pop stack x   # pops from stack into x
+# useful e.g. in recursive include calls where x might overwritten
+
+require 'pp'
+
+module BrooklynJekyllUtil
+  class PutsTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      puts "#{@text}"
+    end
+  end
+  class PutvTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      puts "#{@text}: #{context[@text]}"
+    end
+  end
+  class PutpTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      puts "#{@text}:"
+      PP.pp(context[@text])
+      nil
+    end
+  end
+  
+  class SetHashEntryTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      args = @text.split(/\W+/)
+      raise "Need 3 args, the hash, the key, and the var to set" unless args.length == 3
+#      puts "getting #{args[0]}['#{args[1]}']"
+#      PP.pp(context[args[0]])
+#      PP.pp(context[args[0]][args[1]])
+      
+      context[args[2]] = context[args[0]][args[1]]
+      nil
+    end
+  end
+
+  class FailTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      raise "Fail#{@text.length>0 ? ": #{@text}" : ""}"
+    end
+  end
+  
+  class PushTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      args = @text.split(/\W+/)
+      raise "Need 2 args, the stack and the var" unless args.length == 2
+      context[args[0]] = [] unless context[args[0]]
+      context[args[0]].push(context[args[1]])
+      context[args[1]] = nil
+    end
+  end
+  class PopTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      args = @text.split(/\W+/)
+      raise "Need 2 args, the stack and the var" unless args.length == 2
+      context[args[1]] = context[args[0]].pop();
+      nil
+    end
+  end
+end
+
+Liquid::Template.register_tag('puts', BrooklynJekyllUtil::PutsTag)
+Liquid::Template.register_tag('putv', BrooklynJekyllUtil::PutvTag)
+Liquid::Template.register_tag('putp', BrooklynJekyllUtil::PutpTag)
+Liquid::Template.register_tag('set_hash_entry', BrooklynJekyllUtil::SetHashEntryTag)
+Liquid::Template.register_tag('fail', BrooklynJekyllUtil::FailTag)
+Liquid::Template.register_tag('push', BrooklynJekyllUtil::PushTag)
+Liquid::Template.register_tag('pop', BrooklynJekyllUtil::PopTag)

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/brooklyn_metadata.rb
----------------------------------------------------------------------
diff --git a/_plugins/brooklyn_metadata.rb b/_plugins/brooklyn_metadata.rb
new file mode 100644
index 0000000..ee0ba7b
--- /dev/null
+++ b/_plugins/brooklyn_metadata.rb
@@ -0,0 +1,64 @@
+# Inserts several useful fields that can be referenced using {{ name }} syntax
+#
+# TODO: move things from fields.md to here
+#
+# site.brooklyn.version: brooklyn version, such as 0.7.0-M1 (taken from brooklyn-version in _config.yml)
+# site.brooklyn.is_snapshot: true if this is a snapshot version, otherwise false
+#
+module BrooklynMetadata
+
+  BROOKLYN_VERSION = "0.9.0-SNAPSHOT" unless defined? BROOKLYN_VERSION
+
+  class Generator < Jekyll::Generator
+    def generate(site)
+      raise "Brooklyn version mismatch" if BrooklynMetadata::BROOKLYN_VERSION != site.config['brooklyn-version']
+
+      is_snapshot = BrooklynMetadata::BROOKLYN_VERSION.end_with?('-SNAPSHOT')
+      
+      if is_snapshot
+        git_branch = 'master' unless site.data['git_branch']
+        url_set = {
+            "search" => {
+                "all" => "https://oss.sonatype.org/index.html#nexus-search;gav~io.brooklyn~~#{ BrooklynMetadata::BROOKLYN_VERSION }~~",
+                "dist" => "https://oss.sonatype.org/index.html#nexus-search;gav~io.brooklyn~brooklyn-dist~#{ BrooklynMetadata::BROOKLYN_VERSION }~~",
+            },
+            "dist" => {
+                "base" => "https://oss.sonatype.org/content/groups/public/io/brooklyn/brooklyn-dist/#{ BrooklynMetadata::BROOKLYN_VERSION }/",
+                "zip" => "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn&v=#{ BrooklynMetadata::BROOKLYN_VERSION }&a=brooklyn-dist&c=dist&e=zip",
+                "tgz" => "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn&v=#{ BrooklynMetadata::BROOKLYN_VERSION }&a=brooklyn-dist&c=dist&e=tar.gz"
+            }
+        }
+        
+      else
+        git_branch = BrooklynMetadata::BROOKLYN_VERSION unless site.data['git_branch']
+        url_set = {
+            "search" => {
+                "all" => "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.brooklyn%22%20AND%20v%3A%22#{ BrooklynMetadata::BROOKLYN_VERSION }%22",
+                "dist" => "http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.brooklyn%22%20AND%20a%3A%22brooklyn-dist%22%20AND%20v%3A%22#{ BrooklynMetadata::BROOKLYN_VERSION }%22",
+            },
+            "dist" => {
+                "base" => "http://repo1.maven.org/maven2/io/brooklyn/brooklyn-dist/#{ BrooklynMetadata::BROOKLYN_VERSION }/",
+                "zip" => "http://repo1.maven.org/maven2/io/brooklyn/brooklyn-dist/#{ BrooklynMetadata::BROOKLYN_VERSION }/brooklyn-dist-#{ BrooklynMetadata::BROOKLYN_VERSION }-dist.zip",
+                "tgz" => "http://repo1.maven.org/maven2/io/brooklyn/brooklyn-dist/#{ BrooklynMetadata::BROOKLYN_VERSION }/brooklyn-dist-#{ BrooklynMetadata::BROOKLYN_VERSION }-dist.tar.gz"
+            }
+        }
+      end
+      
+      url_set["git"] = "https://github.com/apache/incubator-brooklyn/tree/#{ git_branch }"
+      
+      site.config['brooklyn'] = {
+          "version" => BrooklynMetadata::BROOKLYN_VERSION,
+          "is_snapshot" => is_snapshot,
+          "is_release" => !is_snapshot,
+          "url" => url_set,
+          "git_branch" => git_branch
+      }
+
+      # config is preferred of data, because you can write just {{ site.brooklyn.xxx }},
+      # also note {{ site.brooklyn-version }} v {{ site.brooklyn-stable-version }} from _config.yml
+      # but some places referenced site.data.brooklyn (i think these have been remove)
+      site.data['brooklyn'] = site.config['brooklyn']
+  
+    end
+  end
+end

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/dependency_url.rb
----------------------------------------------------------------------
diff --git a/_plugins/dependency_url.rb b/_plugins/dependency_url.rb
new file mode 100644
index 0000000..8a72e17
--- /dev/null
+++ b/_plugins/dependency_url.rb
@@ -0,0 +1,31 @@
+# tag to write the correct URL depending whether we are running with dependencies local (for offline) or remote (eg using a CDN)
+
+# specify a map of <basename>: <remote_url> in the key `dependency_urls` in your `_config.yml`,
+# then, if `dependency_mode: local` is defined, the path `{{site.path.style}}/deps/<basename>` will be used,
+# otherwise the <remote_url> will be used
+
+module JekyllDependencyUrl
+  class DependencyUrlTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+	jekyllSite = context.registers[:site]
+        mode = context['site']['dependency_mode']
+        if mode != 'local'
+          result = context['site']['dependency_urls'][@text.strip]
+          if result.to_s == ''
+            raise 'No value in dependency_urls specified for ' + @text.strip
+          end
+        end
+        if result.to_s == ''
+          result = context['site']['path']['style'] + "/deps/" + @text.strip
+        end
+        return result
+    end
+  end
+end
+
+Liquid::Template.register_tag('dependency_url', JekyllDependencyUrl::DependencyUrlTag)
+

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/json.rb
----------------------------------------------------------------------
diff --git a/_plugins/json.rb b/_plugins/json.rb
new file mode 100644
index 0000000..b36a6b2
--- /dev/null
+++ b/_plugins/json.rb
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+require 'json'
+
+module JsonFilter
+  def json(input)
+    input.to_json
+  end
+
+  Liquid::Template.register_filter self
+end

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/jsonball.rb
----------------------------------------------------------------------
diff --git a/_plugins/jsonball.rb b/_plugins/jsonball.rb
new file mode 100644
index 0000000..c12a441
--- /dev/null
+++ b/_plugins/jsonball.rb
@@ -0,0 +1,103 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+require 'json'
+
+# JSON parser tag, creating map for use in jekyll markdown
+
+# usage:  {% jsonball varname from TYPE PARAM %}
+#
+# where TYPE is one of {data,var,file,page}, described below
+
+# drop this into your _plugins/ folder, then you can write, e.g.
+#
+#   {% jsonball foo from data { "a": "b" } %}
+#
+# and then later refer to {{ foo.a }} to get b inserted
+
+# more usefully, you can load it from a variable x, e.g.
+#   {% capture x %}{% include toc.json %}{% endcapture %}
+#
+#   {% jsonball foo from var x %}
+
+# even better, to read from a file, say toc.json
+# (absolute, or relative to the page being jekylled):
+#
+#   {% jsonball foo from file toc.json %}
+#
+# then e.g. {% for record in jsonball %} {{ record.name }} {% endfor %}
+# to print out all the name entries (or build a fancy TOC sidebar)
+
+# and finally, if that json file might itself contain liquid tags,
+# or need jekylling, treat it as a page and it will get jekylled
+# (we use this for toc.json reading from subdirs' toc.json files):
+#
+#   {% jsonball foo from page toc.json %}
+
+module JekyllJsonball
+  class JsonballTag < Liquid::Tag
+
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+
+    def render(context)
+	if /(.+) from var (.+)/.match(@text)
+		context[$1] = JSON context[$2]
+		return ''
+	end
+	if /(.+) from data (.+)/.match(@text)
+		context[$1] = JSON $2
+		return ''
+	end
+	if /(.+) from file (.+)/.match(@text)
+		context[$1] = JSON page_relative_file_contents(context, $2.strip)
+		return ''
+	end
+	if /(.+) from page (.+)/.match(@text)
+		context[$1] = JSON jekylled_page_relative_file_contents(context, $2.strip)
+		return ''
+	end
+	# syntax error
+	return 'ERROR:bad_jsonball_syntax'
+    end
+
+    def page_relative_file_contents(context, filename)
+	jekyllSite = context.registers[:site]
+	dir = jekyllSite.source+'/'+File.dirname(context['page']['url'])
+        filename = context[filename] || filename
+	if !filename.match(/\/.*/)
+		filename = dir + '/' + filename
+	end
+	file = File.open(filename, "rb")
+	return file.read
+    end
+
+    def jekylled_page_relative_file_contents(context, filename)
+	jekyllSite = context.registers[:site]
+        filename = context[filename] || filename
+	targetPage = Jekyll::Page.new(jekyllSite, jekyllSite.source, File.dirname(context['page']['url']), filename)
+	targetPage.render(jekyllSite.layouts, jekyllSite.site_payload)
+	targetPage.output
+    end
+
+  end
+end
+
+Liquid::Template.register_tag('jsonball', JekyllJsonball::JsonballTag)

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/read.rb
----------------------------------------------------------------------
diff --git a/_plugins/read.rb b/_plugins/read.rb
new file mode 100644
index 0000000..23cf0f2
--- /dev/null
+++ b/_plugins/read.rb
@@ -0,0 +1,81 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+# tag to read and insert a file relative to the current working directory
+# (like include, but in the dir where it is invoked)
+
+# there is also readj which reads a file and applies jekyll processing to it
+# handy if we want to include a toc.json file which itself calls {% readj child/toc.json %}
+# (note however variables do not seem to be exported when use readj (TODO),
+# although they are exported if you have _includes/file.md and use the standard include file)
+
+# the argument can be a variable or a filename literal (not quoted)
+# TODO: figure out how to accept a quoted string as an argument
+
+require 'pathname'
+
+module JekyllRead
+  class ReadTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      filename = @text.strip
+      filename = context[filename] || filename
+
+      # Pathname API ignores first arg below if second is absolute
+      file = Pathname.new(File.dirname(context['page']['path'])) + filename
+      file = file.cleanpath
+      # is there a better way to trim a leading / ?
+      file = file.relative_path_from(Pathname.new("/")) unless file.relative?
+      raise "No such file #{file} in read call (from #{context['page']['path']})" unless file.exist?
+
+      file = File.open(file, "rb")
+      return file.read
+    end
+  end
+
+  class ReadjTag < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      filename = @text.strip
+      filename = context[filename] || filename
+      # Pathname API ignores first arg below if second is absolute
+      page = context['page'] || context.registers[:page]
+      file = Pathname.new(File.dirname(page['path'])) + filename
+      file = file.cleanpath
+      # is there a better way to trim a leading / ?
+      file = file.relative_path_from(Pathname.new("/")) unless file.relative?
+      raise "No such file #{file} in readj call (from #{context['page']['path']})" unless file.exist?
+
+      # with readj we support vars and paths relative to a file being readj'd
+      jekyllSite = context.registers[:site]
+      targetPage = Jekyll::Page.new(jekyllSite, jekyllSite.source, File.dirname(file), File.basename(file))
+      targetPage.render(jekyllSite.layouts, jekyllSite.site_payload)
+      return targetPage.output
+    end
+  end
+end
+
+Liquid::Template.register_tag('read', JekyllRead::ReadTag)
+Liquid::Template.register_tag('readj', JekyllRead::ReadjTag)

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/site_structure.rb
----------------------------------------------------------------------
diff --git a/_plugins/site_structure.rb b/_plugins/site_structure.rb
new file mode 100644
index 0000000..5b0c488
--- /dev/null
+++ b/_plugins/site_structure.rb
@@ -0,0 +1,344 @@
+#
+# Builds a hierarchical structure for the site, based on the YAML front matter of each page
+#
+# Starts from a page called "/index.md" (or the value of `root_menu_page` in _config.yml),
+# and follows `children` links in the YAML front matter, building up a variable called `data` 
+# on `site` and on each referred `page`.
+#
+# In Ruby data is in page.data['menu'], but in templates `page.data` is promoted, 
+# so you should just refer to things in markdown as `{{ page.menu }}`.
+#
+# Each `page.menu` entry will contain:
+# * `url` - URL (relative or absolute) to link to
+# * `title_in_menu` - title to show
+# * `menu_path` - the path of this page for the purposes of looking in breadcrumbs (usually page.path, unless overriden) 
+# * `breadcrumbs_pages` - page items for ancestor items (and self)
+# * `breadcrumbs_paths` - paths of breadcrumb pages (useful for `if .. contains` jekyll tests)
+# * `menu_parent` - the parent menu which contains this page
+# * `menu_customization` - a hash of customization set in front matter or in children (can be any data you like)
+# * (in addition the entry may *be* the actual page object when the item is a page whose menu is not overridden)
+#
+# To build, set `children` as a list of either strings (the relative or absolute path to the child .md file),
+# or as maps indicating the target, one of:
+# * `path` to a markdownfile
+# * `link` as an URL 
+# * `section` anchored in this file (annotated with `<a name="#section"></a>`)
+# And optionally:
+# * a `title` (required for `link`), to override the title from the file
+# * an optional `menu` block  (for `path` only) to override the menu inherited from the `children` record noted at `path`
+# * `menu_customization` to set arbitrary data available (e.g. for templates to use when styling)
+# * `href_path` (for `path` only) to specify that a click should send to a different page than the path used to produce the menu
+#
+# For instance:
+#
+#children:
+#- child.md
+#- { path: child.md }  
+#  # identical to above
+#- { path: subchild.md, title: "Sub Child" }   
+#  # different child, with custom title
+#- { path: subchild.md, href_path: subchild_alt.md }  
+#  # takes title and menu from subchild page, but links to subchild_alt
+#- { path: child.md, menu: [ { path: subchild.md, title: "Sub-Child with New Name" } ] } 
+#  # child, but with custom sub-menu and custom title in there 
+#- { path: child.md, menu: null }  # suppress sub-menu (note `null` not `nil` because this is yaml)
+#  # child again, but suppressing sub-menu (note `null` not `nil` because this is yaml)
+#- { section: Foo }
+#- { section: Bar }
+#  # various sections in *this* doc (to make highlighting work for sections requires
+#  # extra JS responding to scrolls; otherwise the parent page remains highlighted)
+#
+# The menu is automatically generated for all files referenced from the root menu.
+# You can also set `breadcrumbs` as a list of paths in a page to force breadcrumbs, and
+# `menu_proxy_for` to have `menu_path` set differently to the usual `path` (highlight another page in a menu via breadcrumbs)
+# or `menu_parent` to a path to the menu which should be the parent of the current node.
+# 
+# The hash `menu_customization` allows you to pass arbitrary data around, e.g. for use in styling.
+# 
+# Additionally URL rewriting is done if a path map is set in _config.yaml,
+# with `path: { xxx: /new_xxx }` causing `/xxx/foo.html` to be rewritten as `/new_xxx/foo.html`.
+#
+module SiteStructure
+
+  DEBUG = false
+
+  require 'yaml'  
+#  require 'pp'
+
+  class RewritePaths < Liquid::Tag
+    def initialize(tag_name, text, tokens)
+      super
+      @text = text
+    end
+    def render(context)
+      page = context['page']
+      site = context['site']
+      RewritePaths.rewrite_paths(site, page)
+    end
+    
+    def self.rewrite_paths(site, page)
+      path = page['path']
+      page_hash = (page.is_a? Hash) ? page : page.data
+      # set url_basedir and apply path mapping
+      page_hash['url_basedir'] = File.dirname(path)+"/"
+      page_hash['url_basedir'].prepend("/") unless page_hash['url_basedir'].start_with? "/"
+      
+      config_hash = (site.is_a? Hash) ? site : site.config
+      
+      if ((config_hash['path']) && (config_hash['path'].is_a? Hash))
+        config_hash['path'].each {|key, value| 
+          if (path.start_with?(key))
+            if ((!page.is_a? Hash) && page.url)
+              page.url.slice!("/"+key)
+              page.url.prepend(value)
+            end
+            
+            page_hash['url_basedir'].slice!("/"+key)
+            page_hash['url_basedir'].prepend(value)
+          end
+        }
+      end
+      
+      nil
+    end
+  end
+  
+  Liquid::Template.register_tag('rewrite_paths', SiteStructure::RewritePaths)
+
+  
+  class Generator < Jekyll::Generator
+
+    @@verbose = false;
+    
+    def self.find_page_with_path_absolute_or_relative_to(site, path, referrent, structure_processed_pages)
+      uncleaned_path = path
+      
+      # Pathname API ignores first arg below if second is absolute
+#      puts "converting #{path} wrt #{referrent ? referrent.path : ""}"
+      file = Pathname.new(File.dirname(referrent ? referrent.path : "")) + path
+
+      if file.to_s.end_with? "/"
+        if File.exist? File.join(file, 'index.md')
+          file += 'index.md'
+        elsif File.exist? File.join(file, 'index.html')
+          file += 'index.html'
+        else
+          file += 'index.md'
+        end
+      end
+
+      file = file.cleanpath
+      # is there a better way to trim a leading / ?
+      file = file.relative_path_from(Pathname.new("/")) unless file.relative?
+      path = "#{file}"
+        
+      # look in our cache        
+      page = structure_processed_pages[path]
+      return page if page != nil
+      
+      # look in site cache
+      page = site.pages.detect { |page| page.path == path }
+      if !page
+        page = site.pages.detect { |page| '/'+page.path == uncleaned_path }
+        puts "WARNING: link to #{path} in #{referrent ? referrent.path : "root"} uses legacy absolute syntax without leading slash" if page
+      end
+
+      unless page
+        # could not load it from pages, look on disk
+
+        if file.exist?                 
+          puts "INFO: reading excluded file #{file} for site structure generation" if SiteStructure::DEBUG
+          page = Jekyll::Page.new(site, site.source, File.dirname(file), File.basename(file))
+          # make sure right url is set
+          RewritePaths.rewrite_paths(site, page)
+        end
+ 
+        unless page
+          raise "No such file #{path} in site_structure call (from #{referrent ? referrent.path : ""})" unless SiteStructure::DEBUG
+          puts "Could not find a page called: #{path} (referenced from #{referrent ? referrent.path : "root"}); skipping"
+          return nil
+        end
+      end
+      
+      # and put in cache
+      structure_processed_pages[path] = page
+ 
+      page     
+    end
+
+    def generate(site)
+      # rewrite paths
+      site.pages.each { |p| RewritePaths.rewrite_paths(site, p) }
+      structure_processed_pages = {}
+      # process root page
+      root_menu_page = site.config['root_menu_page']
+      puts "site_structure processing root menu page #{root_menu_page}" if @@verbose
+      site.data.merge!( Generator.gen_structure(site, { 'path' => root_menu_page }, nil, [], [], structure_processed_pages).data ) if root_menu_page
+      # process all pages
+      puts "site_structure now processing all pages" if @@verbose
+      site.pages.each { |p| 
+        Generator.gen_structure(site, { 'path' => p.path }, nil, [], [], structure_processed_pages) if (p.path.end_with?(".md") || p.path.end_with?(".html")) && (!p['menu_processed'])
+      }
+      site.data['structure_processed_pages'] = structure_processed_pages
+#      puts "ROOT menu is #{site.data['menu']}"
+#      puts "PAGE menu is #{structure_processed_pages['website/documentation/index.'].data['menu']}"
+# (but note, in the context hash map 'data' on pages is promoted, so you access it like {{ page.menu }})
+    end
+
+    # processes liquid tags, e.g. in a link or path object
+    def self.render_liquid(site, page, content)
+      return content unless page
+      info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => page } }
+      page.render_liquid(content, site.site_payload, info)
+    end
+    
+    def self.gen_structure(site, item, parent, breadcrumb_pages_in, breadcrumb_paths_in, structure_processed_pages)
+      puts "gen_structure #{item} from #{parent ? parent.path : 'root'} (#{breadcrumb_paths_in})" if @@verbose
+      breadcrumb_pages = breadcrumb_pages_in.dup
+      breadcrumb_paths = breadcrumb_paths_in.dup
+      if (item.is_a? String)
+        item = { 'path' => item }
+      end
+      if (item['path'])      
+        page = find_page_with_path_absolute_or_relative_to(site, render_liquid(site, parent, item['path']), parent, structure_processed_pages)
+        # if nil and find_page doesn't raise, we are in debug mode, silently ignore
+        return nil unless page
+        # build up the menu info
+        if (item.length==1 && !page['menu_processed'])
+          puts "setting up #{item} from #{page.path} as original" if @@verbose
+          data = page.data
+          result = page
+        else
+          puts "setting up #{item} from #{page.path} as copy" if @@verbose
+          # if other fields are set on 'item' then we are overriding, so we have to take a duplicate
+          unless page['menu_processed']
+            # force processing if not yet processed, breadcrumbs etc set from that page
+            puts "making copy of #{page.path}" if @@verbose
+            page = gen_structure(site, "/"+page.path, parent, breadcrumb_pages_in, breadcrumb_paths_in, structure_processed_pages)
+            puts "copy is #{page.path}" if @@verbose
+          end
+          data = page.data.dup
+          data['data'] = data
+          result = data
+        end 
+        data['path'] = page.path
+        if item['href_path']
+          href_page = find_page_with_path_absolute_or_relative_to(site, render_liquid(site, page, item['href_path']), parent, structure_processed_pages)
+        else
+          href_page = page
+        end
+        data['url'] = href_page.url
+        puts "data is #{data}" if @@verbose
+        data['page'] = page
+        breadcrumb_pages << page
+        breadcrumb_paths << page.path
+        
+      elsif (item['section'])
+        puts "setting up #{item} as section" if @@verbose
+        section = item['section']
+        section_cleaned = section.gsub(%r{[^A-Za-z0-9]+}, "-").downcase;
+        section_cleaned.slice!(1) if section_cleaned.start_with?("-")
+        section_cleaned.chomp!("-") # 0..-1) if section_cleaned.end_with?("-")
+        link = (parent ? parent.url : "") + '#' + section_cleaned
+        data = { 'link' => link, 'url' => link, 'section' => section_cleaned, 'section_title' => section }
+        data['title'] = item['title'] if item['title']
+        data['title'] = section unless data['title']
+        # nothing for breadcrumbs
+        data['data'] = data
+        result = data
+        
+      elsif (item['link'])
+        puts "setting up #{item} as link" if @@verbose
+        link = render_liquid(site, parent, item['link'])
+        data = { 'link' => link, 'url' => link, 'external' => true }
+        data['title'] = item['title'] if item['title']
+        breadcrumb_pages << data
+        breadcrumb_paths << data['link']
+        data['data'] = data
+        result = data
+      else
+        raise "Link to #{item} in #{parent ? parent.path : nil} must have path or section or link"
+      end
+
+      data['menu_customization'] = {}.merge(data['menu_customization'] || {}).merge(item['menu_customization'] || {})
+      
+      data['breadcrumb_pages'] ||= breadcrumb_pages
+      data['breadcrumb_paths'] ||= breadcrumb_paths
+      data['menu_parent'] ||= parent
+      
+      data['title_in_menu'] = render_liquid(site, parent, item['title_in_menu'] || item['title'] || data['title_in_menu'] || data['title'])
+      data['title'] ||= data['title_in_menu']
+#      puts "built #{data}, now looking at children"
+
+      # if already processed then return now that we have set custom item overrides (don't recurse through children)
+      return result if data['menu']
+      
+      data['menu_path'] = page.path if page
+      
+      if data['menu_proxy_for']
+        menu_proxy_for = gen_structure(site, { 'path' => data['menu_proxy_for'], 'no_copy' => "because breadcrumbs won't be right" }, page, [], [], structure_processed_pages)
+        raise "missing menu_proxy_for #{data['menu_proxy_for']} in #{page.path}" unless menu_proxy_for
+        data['menu_path'] = menu_proxy_for['path']
+        # copy other data across
+        data.merge!(menu_proxy_for.select {|key, value| ['breadcrumb_paths', 'breadcrumb_pages', 'menu', 'title_in_menu', 'menu_parent', 'menu_customization'].include?(key) })
+      end
+      
+      if data['breadcrumbs']
+        # if custom breadcrumbs set on page, use them instead
+        breadcrumb_pages = data['breadcrumb_pages'] = data['breadcrumbs'].collect { |path|
+          result = find_page_with_path_absolute_or_relative_to(site, render_liquid(site, parent, path), page, structure_processed_pages)
+          raise "missing breadcrumb #{path} in #{page.path}" unless result
+          result
+        }
+        breadcrumb_paths = data['breadcrumb_paths'] = data['breadcrumb_pages'].collect { |p| p.path }
+      end
+
+      if data['menu_parent'] 
+        if data['menu_parent'].is_a? String
+          # if custom menu_parent was set as a string then load it
+          parent_result = find_page_with_path_absolute_or_relative_to(site, render_liquid(site, parent, data['menu_parent']), page, structure_processed_pages)        
+          raise "missing parent #{data['menu_parent']} in #{page['path']}" unless parent_result
+          data['menu_parent'] = parent_result
+          if !data['breadcrumbs']
+            # TODO should we inherit actual menu parent breadcrumbs if not set on page?
+          end
+        end
+      else
+        # set menu_parent from breadcrumbs if not set (e.g. we are loading an isolated page)
+        data['menu_parent'] = page['breadcrumb_pages'][-1]
+      end
+
+      if (data['children'])
+        data['menu'] = []
+        puts "children of #{data['path']} - #{data['children']}" if @@verbose
+        data['children'].each do |child|
+          sub = gen_structure(site, child, page, breadcrumb_pages, breadcrumb_paths, structure_processed_pages)
+          if sub
+            if (!(child.is_a? String) && child.has_key?('menu'))
+              # process custom menu override
+              sub['menu'] = child['menu']
+              if (sub['menu'] != nil)
+                if sub['menu'].is_a? String
+                  sub['menu'] = YAML.load(render_liquid(site, page, sub['menu'])) if sub['menu'].is_a? String
+                end
+                sub['menu'] = sub['menu'].collect { |mi| 
+                  gen_structure(site, mi, page, breadcrumb_pages, breadcrumb_paths, structure_processed_pages)
+                }
+                sub['menu'].compact!
+              end
+            end
+            data['menu'] << sub
+            puts "sub is #{sub['url']}" if @@verbose
+          else
+            raise "could not find #{child} in #{page.path}"
+          end
+        end
+        puts "end children of #{data['path']}" if @@verbose
+      end
+      
+      data['menu_processed']=true
+      puts "done #{item}" if @@verbose
+      result
+    end
+  end
+end

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/_plugins/trim.rb
----------------------------------------------------------------------
diff --git a/_plugins/trim.rb b/_plugins/trim.rb
new file mode 100644
index 0000000..047a346
--- /dev/null
+++ b/_plugins/trim.rb
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+module TrimFilter
+  def trim(input)
+    input.strip
+  end
+
+  Liquid::Template.register_filter self
+end

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/brooklyn-docs/.gitattributes
----------------------------------------------------------------------
diff --git a/brooklyn-docs/.gitattributes b/brooklyn-docs/.gitattributes
deleted file mode 100644
index 7920d0e..0000000
--- a/brooklyn-docs/.gitattributes
+++ /dev/null
@@ -1,6 +0,0 @@
-#Don't auto-convert line endings for shell scripts on Windows (breaks the scripts)
-* text=auto
-*.sh text eol=lf
-*.bat text eol=crlf
-*.ps1 text eol=crlf
-*.ini text eol=crlf

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/brooklyn-docs/.gitignore
----------------------------------------------------------------------
diff --git a/brooklyn-docs/.gitignore b/brooklyn-docs/.gitignore
deleted file mode 100644
index 806a062..0000000
--- a/brooklyn-docs/.gitignore
+++ /dev/null
@@ -1,36 +0,0 @@
-\#*\#
-*~
-*.bak
-*.swp
-*.swo
-.DS_Store
-
-atlassian-ide-plugin.xml
-*.class
-
-target/
-test-output/
-
-.project
-.classpath
-.settings/
-.metadata/
-
-.idea/
-*.iml
-
-nbactions.xml
-nb-configuration.xml
-
-prodDb.*
-
-*.log
-brooklyn*.log.*
-
-*brooklyn-persisted-state/
-
-ignored
-_site
-_config_local.yml
-.sass-cache
-style/js/catalog/items.js

http://git-wip-us.apache.org/repos/asf/brooklyn-docs/blob/6e86cb02/brooklyn-docs/Gemfile
----------------------------------------------------------------------
diff --git a/brooklyn-docs/Gemfile b/brooklyn-docs/Gemfile
deleted file mode 100644
index 11d388b..0000000
--- a/brooklyn-docs/Gemfile
+++ /dev/null
@@ -1,11 +0,0 @@
-#ruby=ruby-2.1.2
-#ruby-gemset=incubator-brooklyn-site
-
-source 'https://rubygems.org'
-ruby '2.1.2'
-
-gem 'jekyll'
-gem 'therubyracer'
-gem 'html-proofer'
-gem 'json'
-